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

.align
scrolling_addr: .word 0x000F00A0
scrolling_count_addr: .word 0x000F00A4

// scrolling_cnt_value: .word 0x20FC000 // for real board
scrolling_cnt_value: .word 0x500 // for simulation

// w_cnt_top:  .word 0x3FC000 // for real board
w_cnt_top:    .word 0x100 //for simulation

pattern_ptr: .word =pattern1

pattern1:
    .word 0x01030204
    .word 0x05070608
    .word 0x090B0A0C
    .word 0x0D0F0E00

pattern2:
    .word 0x0F0E0E0B
    .word 0x100D0A0E
    .word 0x0D101010

pattern3:
    .word 0x01101010

pattern4:
    .word 0x02031010

pattern5:
    .word 0x00000000
    .word 0x00101010

write_mask:
    .word 0x1000000

clear_mask:
    .word 0x100

display_char:
    // Read from ptr r3
    ld08 r4, r3
    lsh r4, r4, 16
    or r4, r4, r1
    st32 r0, r4
    ret
    nop

main:
    ldr r8, >w_cnt_top

    ldr r0, >scrolling_addr
    ldr r1, >write_mask
    ldr r2, >clear_mask
    ldr r10, >pattern_ptr

number_loop:
    // (Re)set scrolling speed
    ldr r5, >scrolling_count_addr
    ldr r7, >scrolling_cnt_value
    st32 r5, r7

    // --------- 132457689BACDFE0 ---------
    clr r3
    add r3, r3, r10
    call >display_char
    nop

    clr r7 
    clr r11
    addi r11, 15 // iterations
display_loop0:
    addi r3, 0x01
    call >display_char
    nop

    addi r7, 1
    cmp neq r7, r11
    br true >display_loop0
    nop

    // Turn on
    clr r4
    addi r4, 0x1
    st32 r0, r4

    call >wait
    nop

    // Turn off
    clr r4
    addi r4, 0x1
    st32 r0, r4

    // Double scrolling speed
    ldr r5, >scrolling_count_addr
    ldr r7, >scrolling_cnt_value
    rsh r7, r7, 1 // Divide by 2
    st32 r5, r7

    // Clear
    clr r4
    or r4, r4, r2
    st32 r0, r4

    // --------- DEAD BEEF ---------
    clr r7 
    clr r11
    addi r11, 12 // iterations
display_loop1:
    addi r3, 0x01
    call >display_char
    nop

    addi r7, 1
    cmp neq r7, r11
    br true >display_loop1
    nop

    // Turn on
    clr r4
    addi r4, 0x1
    st32 r0, r4

    call >wait
    nop

    // Turn off
    clr r4
    addi r4, 0x1
    st32 r0, r4

    // Clear
    clr r4
    or r4, r4, r2
    st32 r0, r4

    // --------- 1 ---------
    clr r7 
    clr r11
    addi r11, 4 // iterations
display_loop2:
    addi r3, 0x01
    call >display_char
    nop

    addi r7, 1
    cmp neq r7, r11
    br true >display_loop2
    nop

    // Turn on
    clr r4
    addi r4, 0x1
    st32 r0, r4

    call >wait
    nop

    // Turn off
    clr r4
    addi r4, 0x1
    st32 r0, r4

    // Clear
    clr r4
    or r4, r4, r2
    st32 r0, r4

    // --------- 2 3 ---------
    clr r7 
    clr r11
    addi r11, 4 // iterations
display_loop3:
    addi r3, 0x01
    call >display_char
    nop

    addi r7, 1
    cmp neq r7, r11
    br true >display_loop3
    nop

    // Turn on
    clr r4
    addi r4, 0x1
    st32 r0, r4

    call >wait
    nop

    // Turn off
    clr r4
    addi r4, 0x1
    st32 r0, r4

    // Clear
    clr r4
    or r4, r4, r2
    st32 r0, r4

    // --------- 0 0 0 0 0 ---------
    clr r7 
    clr r11
    addi r11, 8
    
     // iterations
display_loop4:
    addi r3, 0x01
    call >display_char
    nop

    addi r7, 1
    cmp neq r7, r11
    br true >display_loop4
    nop

    // Turn on
    clr r4
    addi r4, 0x1
    st32 r0, r4

    call >wait
    nop

    // Turn off
    clr r4
    addi r4, 0x1
    st32 r0, r4

    br always >number_loop
    nop

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