dw DISPLAY: 0x30000
dw stack: 0x10000

// colour table — AABBGGRR format
dw COL0: 0xFFFFFFFF   // white
dw COL1: 0xFF0000FF   // red
dw COL2: 0xFF00FF00   // green
dw COL3: 0xFFFF0000   // blue
dw COL4: 0xFF00FFFF   // yellow
dw COL_IDX: 0
 
// registers:
// rg0 = x position
// rg1 = y position
// rg2 = x direction (1 = right, 0 = left)
// rg3 = y direction (1 = down,  0 = up)
// rg5 = current colour

_init:
    ldw stack, bpr
    mov bpr, spr

start:
    lli 0, rg0
    lli 0, rg1
    lli 1, rg2
    lli 1, rg3
    lli 0, rg8
    stw rg8, COL_IDX
    ldw COL0, rg5

frame_loop:
    // --- clear display ---
    ldw DISPLAY, rg4
    lwi 76800, rga

clear_loop:
    stw zero, rg4
    addi rg4, 4, rg4
    subi rga, 1, rga
    jnz rga, clear_loop

    // --- draw square ---
    mov rg1, rg6

draw_y_loop:
    lli 20, rg8
    add rg1, rg8, rg8
    ilt rg6, rg8, rg9
    jez rg9, draw_done
    mov rg0, rg7

draw_x_loop:
    lli 20, rg8
    add rg0, rg8, rg8
    ilt rg7, rg8, rg9
    jez rg9, draw_x_done
    shl rg6, 8, rg8
    shl rg6, 6, rg9
    add rg8, rg9, rg8
    add rg8, rg7, rg8
    shl rg8, 2, rg8
    ldw DISPLAY, rg9
    add rg9, rg8, rg8
    stw rg5, rg8
    addi rg7, 1, rg7
    jmp draw_x_loop

draw_x_done:
    addi rg6, 1, rg6
    jmp draw_y_loop

draw_done:
    // --- track bounces this frame ---
    lli 0, rgb
    lli 0, rgc

    // --- check x walls ---
    lli 1, rg8
    ieq rg2, rg8, rg9
    jez rg9, check_x_left_wall

check_x_right_wall:
    lli 300, rg8
    ige rg0, rg8, rg9
    jez rg9, move_x
    lli 0, rg2
    lli 1, rgb
    jmp move_x

check_x_left_wall:
    ieq rg0, zero, rg9
    jez rg9, move_x
    lli 1, rg2
    lli 1, rgb

move_x:
    lli 1, rg8
    ieq rg2, rg8, rg9
    jez rg9, do_x_left
    addi rg0, 1, rg0
    jmp check_y_walls
do_x_left:
    subi rg0, 1, rg0

check_y_walls:
    lli 1, rg8
    ieq rg3, rg8, rg9
    jez rg9, check_y_up_wall

check_y_down_wall:
    lli 220, rg8
    ige rg1, rg8, rg9
    jez rg9, move_y
    lli 0, rg3
    lli 1, rgc
    jmp move_y

check_y_up_wall:
    ieq rg1, zero, rg9
    jez rg9, move_y
    lli 1, rg3
    lli 1, rgc

move_y:
    lli 1, rg8
    ieq rg3, rg8, rg9
    jez rg9, do_y_up
    addi rg1, 1, rg1
    jmp check_corner
do_y_up:
    subi rg1, 1, rg1

check_corner:
    and rgb, rgc, rg8
    jez rg8, delay

    // advance colour index
    ldw COL_IDX, rg8
    addi rg8, 1, rg8
    lli 5, rg9
    ige rg8, rg9, rg9
    jez rg9, store_col_idx
    lli 0, rg8

store_col_idx:
    stw rg8, COL_IDX

    // load colour from table: address = COL0 + idx * 4
    shl rg8, 2, rg8
    lwi COL0, rg9
    add rg9, rg8, rg8
    ldw rg8, rg5

delay:
    lwi 2000000, rg8
delay_loop:
    subi rg8, 1, rg8
    jnz rg8, delay_loop
    jmp frame_loop

    hlt