reset:
    br always >main
    nop
hardfault:
    reti
    nop
memfault:
    reti
    nop

.align
led_addr: .word 0x000F0000
switches_addr: .word 0x000F0004
dmem_start_addr: .word 0x00000400
dmem_end_addr: .word 0x000004FF
base_prescaler: .word 0x1
priority_mask: .word 0xFFFFFF03

main:
    // Initialize stack pointer to the end of the data memory
    ldr r12, >dmem_end_addr

    // Set runtime priority
    ldr r0, >priority_mask
    and r14, r0, r14

    ldr r0,>led_addr    //LED addr
    addi r6,8        //outer counter top
    clr r7            //wait counter
    ldr r8,>base_prescaler

out_loop:
    clr r1
    st08 r0,r1
    call >wait_prescaled
    nop

fill:
    lsh r1,r1,1
    addi r1,1
    st08 r0,r1
    call >wait_prescaled
    nop

    addi r5,1
    cmp neq r5,r6
    br true >fill
    nop
    clr r5

flush:
    lsh r1,r1,1
    st08 r0,r1
    call >wait_prescaled
    nop

    addi r5,1
    cmp neq r5,r6
    br true >flush
    nop
    clr r5
    br always >out_loop
    nop

wait_prescaled:
    // Load value from the switches
    ldr r11,  >switches_addr
    ld32 r9, r11
    addi r9, 1

    clr r11
    add r11, r13, r11 // save link register

    clr r10
inc_j:
    call >wait
    cmp neq r10,r9
    br true >inc_j
    addi r10,1

    clr r13
    add r13, r13, r11 // restore link register

    ret
    nop


//subroutine to iterate until counter overflow
wait:
    clr r7                //inititalize inner counter
inc_i:
    cmp neq r7,r8
    br true >inc_i        //if i=cnt_top
    addi r7,1
    ret                    //else
    nop
