; ARM assembly tutorial for Asmonite, example 08: a program for the flash (Raspberry Pi Pico 2, Arm Cortex-M33).
; Adapted from the ARM-ASM-Tutorial by Niklas Guertler (examples LinkerScriptSymbols and
; LinkerScriptAbsolutePlacement); see LICENSE.txt.
;
; 06_blink_registers.asm as a program for the flash at 0x10000000: after a reset or a power cycle the Pico 2
; starts it by itself. F7 writes it into the flash over the debug probe and stops at _start. The file
; begins with two blocks that the boot ROM of the RP2350 reads:
;   - the vector table of the Cortex-M33: the first word is the start value of the stack pointer, the
;     second the address of the first instruction (+1: Thumb code), then the handlers of the exceptions
;   - the IMAGE_DEF block: says that this is a program for the Arm cores (the RP2350 has RISC-V cores too)
.target pico2
.arch thumb
.imagebase 0x10000000

SRAM_END equ 0x20082000         ; the end of the RAM: the stack grows down from here

vectors:
    dd SRAM_END                 ; stack pointer at the start
    dd _start + 1               ; reset: the first instruction (+1: Thumb code)
    dd hang + 1                 ; NMI
    dd hang + 1                 ; HardFault

image_def:
    dd 0xffffded3               ; start marker of the block
    db 0x42, 1                  ; item IMAGE_TYPE, 1 word
    dw 0x1021                   ; executable, Arm, Secure, RP2350
    db 0xff                     ; last item
    dw 1                        ; the size of the items so far, in words
    db 0
    dd 0                        ; no further block
    dd 0xab123579               ; end marker

_start:
    ldr  r1, resets_clr
    ldr  r0, reset_bits
    str  r0, [r1]
    ldr  r1, resets_done
wait_reset:
    ldr  r2, [r1]
    and  r2, r2, r0
    cmp  r2, r0
    bne  wait_reset
    ldr  r1, pad25_clr
    mov  r0, #0x100
    str  r0, [r1]
    ldr  r1, gpio25_ctrl
    movs r0, #5
    str  r0, [r1]
    ldr  r1, sio_oe_set
    ldr  r0, led_bit
    str  r0, [r1]

    ldr  r0, sio_base
    ldr  r1, led_bit
    ldr  r3, delay_count
blink_loop:
    str  r1, [r0, #0x18]        ; LED on
    mov  r4, r3
delay1:
    subs r4, r4, #1
    bne  delay1
    str  r1, [r0, #0x20]        ; LED off
    mov  r4, r3
delay2:
    subs r4, r4, #1
    bne  delay2
    b    blink_loop

hang:
    b    hang                   ; NMI and HardFault end here

    align 4
resets_clr:  dd 0x40023000
reset_bits:  dd 0x00000240
resets_done: dd 0x40020008
pad25_clr:   dd 0x4003b068
gpio25_ctrl: dd 0x400280cc
sio_oe_set:  dd 0xd0000038
sio_base:    dd 0xd0000000
led_bit:     dd 0x02000000
delay_count: dd 1000000
