; ARM assembly tutorial for Asmonite, example 03: read, change, write (Raspberry Pi Pico 2, Arm Cortex-M33).
; Adapted from the ARM-ASM-Tutorial by Niklas Guertler (example SetPin2); see LICENSE.txt.
;
; The same as 02_set_pin.asm, but a register is read, a few bits of it are changed with "bic" (bit clear)
; and "orr" (or), and the value is written back: the other bits keep their value. Example 02 used the
; clear alias of the RP2350 instead, which changes only the given bits by itself.
.target pico2
.arch thumb
.imagebase 0x20000000

_start:
    ldr  r1, resets_reset
    ldr  r0, [r1]               ; read RESETS.RESET
    bic  r0, r0, #0x240         ; clear bit 6 (IO_BANK0) and bit 9 (PADS_BANK0)
    str  r0, [r1]               ; write it back
    ldr  r1, resets_done
wait_reset:
    ldr  r2, [r1]
    and  r2, r2, #0x240
    cmp  r2, #0x240
    bne  wait_reset

    ldr  r1, pad25
    ldr  r0, [r1]               ; read PADS_BANK0.GPIO25
    bic  r0, r0, #0x100         ; clear ISO
    str  r0, [r1]

    ldr  r1, gpio25_ctrl
    ldr  r0, [r1]
    bic  r0, r0, #0x1f          ; FUNCSEL is bits 4..0
    orr  r0, r0, #5             ; 5 = SIO
    str  r0, [r1]

    ldr  r1, sio_oe_set
    ldr  r0, led_bit
    str  r0, [r1]               ; GPIO 25 is an output
    ldr  r1, sio_out_set
    str  r0, [r1]               ; and high

    b    $

    align 4
resets_reset: dd 0x40020000     ; RESETS.RESET
resets_done:  dd 0x40020008     ; RESETS.RESET_DONE
pad25:        dd 0x40038068     ; PADS_BANK0.GPIO25
gpio25_ctrl:  dd 0x400280cc     ; IO_BANK0.GPIO25_CTRL
sio_oe_set:   dd 0xd0000038     ; SIO.GPIO_OE_SET
sio_out_set:  dd 0xd0000018     ; SIO.GPIO_OUT_SET
led_bit:      dd 0x02000000     ; bit 25
