; ARM assembly tutorial for Asmonite, example 08 for the Blue Pill (STM32F103, Arm Cortex-M3).
; Adapted from the ARM-ASM-Tutorial by Niklas Guertler (examples BlinkDelay and LinkerScriptSymbols); see ..\LICENSE.txt.
;
; 05_blink_delay.asm for the flash at 0x08000000, the way all programs of the original tutorial run: F7
; writes it there (only the pages of 1 KB that differ), resets the chip and stops at _start; after a reset or
; a power cycle the Blue Pill starts it by itself. The STM32 needs no other block than the vector table of the
; Cortex-M3 at the start of the flash: the stack pointer (the end of the 20 KB of RAM), then the start address
; (+1: Thumb code). The original writes 0x20000400 there and reserves 0xe4 bytes for the other entries.
.target stm32f103
.arch thumb
.imagebase 0x08000000

vectors:
    dd 0x20005000               ; the stack pointer at the start: the end of the RAM
    dd _start + 1               ; reset: the first instruction (+1: Thumb code)
    dd hang + 1                 ; NMI
    dd hang + 1                 ; HardFault

_start:
    ldr  r1, rcc_apb2enr
    ldr  r0, [r1]
    orr  r0, r0, #0x10
    str  r0, [r1]               ; set IOPCEN in RCC_APB2ENR: the clock of port C on

    ldr  r1, gpioc_crh
    ldr  r0, [r1]
    bic  r0, r0, #0x00f00000
    orr  r0, r0, #0x00200000
    str  r0, [r1]               ; CNF13:MODE13 in GPIOC_CRH = 2: PC13 is an output

blink_loop:
    ldr  r1, gpioc_bsrr
    ldr  r0, led_on
    str  r0, [r1]               ; BR13 in GPIOC_BSRR: PC13 low, LED on
    ldr  r2, delay_count
delay1:
    subs r2, r2, #1
    bne  delay1
    ldr  r1, gpioc_bsrr
    ldr  r0, led_off
    str  r0, [r1]               ; BS13 in GPIOC_BSRR: PC13 high, LED off
    ldr  r2, delay_count
delay2:
    subs r2, r2, #1
    bne  delay2
    b    blink_loop

hang:
    b    hang

    align 4
rcc_apb2enr: dd 0x40021018      ; RCC_APB2ENR
gpioc_crh:   dd 0x40011004      ; GPIOC_CRH
gpioc_bsrr:  dd 0x40011010      ; GPIOC_BSRR
led_on:      dd 0x20000000      ; BR13 (bit 29)
led_off:     dd 0x00002000      ; BS13 (bit 13)
delay_count: dd 500000
