dw DISPLAY: 0x30000
dw stack: 0x10000

// registers:
// rg0 = x position
// rg1 = y position
// rg2 = x direction (1 = right, 0 = left)
// rg3 = y direction (1 = down,  0 = up)

_init:
    ldw stack, bpr
    mov bpr, spr

start:
    lli 0, rg0
    lli 0, rg1
    lli 1, rg2
    lli 1, rg3

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

clear_loop:
    stw zero, rg4
    addi rg4, 4, rg4
    subi rg5, 1, rg5
    jnz rg5, 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

    lli 0xFFFF, rg9
    lui 0xFFFF, rg9
    stw rg9, rg8

    addi rg7, 1, rg7
    jmp draw_x_loop

draw_x_done:
    addi rg6, 1, rg6
    jmp draw_y_loop

draw_done:
    // --- check x walls before moving ---
    lli 1, rg8
    ieq rg2, rg8, rg9
    jez rg9, check_x_left_wall

check_x_right_wall:
    // moving right: if x >= 300 flip direction
    lli 300, rg8
    ige rg0, rg8, rg9
    jez rg9, move_x
    lli 0, rg2
    jmp move_x

check_x_left_wall:
    // moving left: if x == 0 flip direction
    ieq rg0, zero, rg9
    jez rg9, move_x
    lli 1, rg2

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:
    // --- check y walls before moving ---
    lli 1, rg8
    ieq rg3, rg8, rg9
    jez rg9, check_y_up_wall

check_y_down_wall:
    // moving down: if y >= 220 flip direction
    lli 220, rg8
    ige rg1, rg8, rg9
    jez rg9, move_y
    lli 0, rg3
    jmp move_y

check_y_up_wall:
    // moving up: if y == 0 flip direction
    ieq rg1, zero, rg9
    jez rg9, move_y
    lli 1, rg3

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

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

    jmp frame_loop

    hlt
