bits 16
minreg 10
minheap 2048

@define a0 r1
@define a1 r2
@define a2 r3
@define v0 r4
@define v1 r5
@define v2 r6
@define v3 r7
@define s0 r8
@define s1 r9
@define s2 r10

@define num_mines 40

//////////////////////////////////////////////////

.game
    str .saved_sp sp
    str .game_state 0
    
    cal .populate_grid
    .game_loop
        cal .handle_mouse
        out %buffer 1
        cal .draw_grid
        out %buffer 0
    //out %wait 10
    //in r0 %wait
    jmp .game_loop
ret

.populate_grid
    imm v0 0
    .populate_fill
        lstr .grid v0 12
    inc v0 v0
    brl .populate_fill v0 256

    imm v0 0
    .populate_plant
        in v1 %rng
        and v1 v1 0xFF
        llod v2 .grid v1
        bre .populate_plant v2 13
        lstr .grid v1 13
        inc v0 v0
    brl .populate_plant v0 num_mines
ret

//////////////////////////////////////////////////

.handle_mouse
    in v0 %mouse_buttons
    lod v1 .mouse_prev
    str .mouse_prev v0
    bre .mouse_end v0 v1
    brz .mouse_end v0
    imm v1 .mouse_jmp_table
    .mouse_loop
        bev .mouse_next v0
            in v0 %mouse_y
            and v0 v0 0xFFF8
            in a0 %mouse_x
            bsr a0 a0 3
            bge .mouse_end v0 128
            bge .mouse_end a0 16
            lsh v0 v0
            or a0 a0 v0
            lod v1 v1
            cal v1
            jmp .mouse_end
        .mouse_next
        inc v1 v1
        rsh v0 v0
    jmp .mouse_loop
    .mouse_end
ret

.mouse_left
    lod v0 .game_state
    bnz .mouse_end v0
    llod v0 .grid a0
    rsh v1 v0
    bne .mouse_end v1 6
    bev .clicked_safe v0
    jmp .clicked_mine


.mouse_right
    lod v0 .game_state
    bnz .mouse_end v0
    llod v0 .grid a0
    and v0 v0 0xF
    bsr v1 v0 2
    bne .mouse_end v1 3
    add v0 v0 2
    ble .right_skip v0 15
    sub v0 v0 4
    .right_skip
    lstr .grid a0 v0
ret

.mouse_middle
    lod sp .saved_sp
    jmp .game

//////////////////////////////////////////////////

.clicked_safe
psh s0
psh s1
psh s2
    imm s0 0
    imm s1 0
    mov s2 a0
    .safe_search_loop
        bsr v2 a0 4
        and v1 a0 0xF
        llod v0 .neighbor_offsets_x s0
        add v1 v1 v0
        llod v0 .neighbor_offsets_y s0
        add v2 v2 v0
        bge .safe_search_outside v1 16
        bge .safe_search_outside v2 16
        mov a0 v2
        bsl a0 a0 4
        or a0 a0 v1
        cal .check_is_mine
        add s1 s1 a1
        .safe_search_outside
        mov a0 s2
    inc s0 s0
    brl .safe_search_loop s0 8
    lstr .grid s2 s1
    bnz .safe_spread_skip s1
        cal .spread_zeros
    .safe_spread_skip
pop s2
pop s1
pop s0
ret

.clicked_mine
    str .game_state 1
    lstr .grid a0 11
    imm v0 0
    .mine_search_loop
        llod v1 .grid v0
        bne .mine_skip_1 v1 13
        lstr .grid v0 10
        .mine_skip_1
        bne .mine_skip_2 v1 14
        lstr .grid v0 9
        .mine_skip_2
    inc v0 v0
    brl .mine_search_loop v0 256
ret

.check_is_mine
    llod v0 .grid a0
    bev .is_not_mine v0
    bsr v0 v0 2
    bne .is_not_mine v0 3
    imm a1 1
ret
    .is_not_mine
    imm a1 0
ret

.spread_zeros
    imm s0 0
    mov s1 a0
    .spread_search_loop
        bsr v2 a0 4
        and v1 a0 0xF
        llod v0 .neighbor_offsets_x s0
        add v1 v1 v0
        llod v0 .neighbor_offsets_y s0
        add v2 v2 v0
        bge .spread_search_outside v1 16
        bge .spread_search_outside v2 16
        mov a0 v2
        bsl a0 a0 4
        or a0 a0 v1
        cal .mouse_left
        .spread_search_outside
        mov a0 s1
    inc s0 s0
    brl .spread_search_loop s0 8
ret

//////////////////////////////////////////////////

.draw_grid
psh a0
psh a1
psh a2
psh s0
    imm s0 0
    .draw_loop
        and a0 s0 0x0F
        and a1 s0 0xF0
        bsr a1 a1 4
        llod a2 .grid s0
        and a2 a2 0x0F
        cal .put_texture
    inc s0 s0
    ble .draw_loop s0 255
    
    out %y 128
    imm s0 0
    .draw_border_loop_x
        out %x s0
        out %color 0x3186
    inc s0 s0
    ble .draw_border_loop_x s0 128
    
    out %x 128
    imm s0 0
    .draw_border_loop_y
        out %y s0
        out %color 0x3186
    inc s0 s0
    ble .draw_border_loop_y s0 127
pop s0
pop a2
pop a1
pop a0
ret

.put_texture
    bsl a0 a0 3
    bsl a1 a1 3
    bsl a2 a2 6
    add a2 a2 .textures
    
    imm v0 8
    .texture_loop_y
        out %y a1
        imm v1 8
        .texture_loop_x
            out %x a0
            lod v2 a2
            inc a2 a2
            out %color v2
            inc a0 a0
        dec v1 v1
        bnz .texture_loop_x v1
        sub a0 a0 8
        inc a1 a1
    dec v0 v0
    bnz .texture_loop_y v0
ret

//////////////////////////////////////////////////

.mouse_jmp_table
dw [ .mouse_left .mouse_right .mouse_middle ]
.mouse_prev
dw [ 0 ]
.game_state
dw [ 0 ]
.saved_sp
dw [ 0 ]
.neighbor_offsets_x
dw [ -1 0 1 -1 1 -1 0 1 ]
.neighbor_offsets_y
dw [ -1 -1 -1 0 0 1 1 1 ]

// Tiles grid
.grid
dw [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]
dw [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]
dw [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]
dw [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]
dw [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]
dw [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]
dw [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]
dw [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]

// Stride: 64 words
// Entries: 16 * 8x8
.textures
dw [ 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]

dw [ 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x5d9f 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x5d9f 0x5d9f 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x5d9f 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x5d9f 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x5d9f 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]

dw [ 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x36ed 0x36ed 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x36ed 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x36ed 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x36ed 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x36ed 0x36ed 0x36ed 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]

dw [ 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0xc9e7 0xc9e7 0xc9e7 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0xc9e7 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0xc9e7 0xc9e7 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0xc9e7 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0xc9e7 0xc9e7 0xc9e7 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]

dw [ 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0xc2fc 0x4a69 0xc2fc 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0xc2fc 0x4a69 0xc2fc 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0xc2fc 0xc2fc 0xc2fc 0xc2fc 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0xc2fc 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0xc2fc 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]

dw [ 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0xe664 0xe664 0xe664 0xe664 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0xe664 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0xe664 0xe664 0xe664 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0xe664 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0xe664 0xe664 0xe664 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]

dw [ 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x04f4 0x04f4 0x04f4 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x04f4 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x04f4 0x04f4 0x04f4 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x04f4 0x4a69 0x4a69 0x04f4 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x04f4 0x04f4 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]

dw [ 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x6ab9 0x6ab9 0x6ab9 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x6ab9 0x4a69 0x6ab9 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x6ab9 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x6ab9 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x6ab9 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]

dw [ 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0xcb45 0xcb45 0xcb45 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0xcb45 0x4a69 0xcb45 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0xcb45 0xcb45 0xcb45 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0xcb45 0x4a69 0xcb45 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0xcb45 0xcb45 0xcb45 0x4a69 0x4a69 ]
dw [ 0x3186 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 0x4a69 ]

dw [ 0x8410 0x8410 0x8410 0x8410 0x8410 0x8410 0x8410 0x630c ]
dw [ 0x8410 0xec83 0x630c 0xc9e7 0xc9e7 0x630c 0xec83 0x4208 ]
dw [ 0x8410 0xc9e7 0xec83 0xc9e7 0xc9e7 0xec83 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0xc9e7 0xec83 0xec83 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0xec83 0xec83 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0xec83 0x630c 0xce59 0xec83 0x630c 0x4208 ]
dw [ 0x8410 0xec83 0x630c 0xce59 0xce59 0xce59 0xec83 0x4208 ]
dw [ 0x630c 0x4208 0x4208 0x4208 0x4208 0x4208 0x4208 0x4208 ]

dw [ 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 ]
dw [ 0x3186 0xce59 0x4a69 0x4a69 0xce59 0x4a69 0x4a69 0xce59 ]
dw [ 0x3186 0x4a69 0xce59 0xce59 0xce59 0xce59 0xce59 0x4a69 ]
dw [ 0x3186 0x4a69 0xce59 0x9cf3 0xce59 0xce59 0xce59 0x4a69 ]
dw [ 0x3186 0xce59 0xce59 0xce59 0xce59 0xce59 0xce59 0xce59 ]
dw [ 0x3186 0x4a69 0xce59 0xce59 0xce59 0xce59 0xce59 0x4a69 ]
dw [ 0x3186 0x4a69 0xce59 0xce59 0xce59 0xce59 0xce59 0x4a69 ]
dw [ 0x3186 0xce59 0x4a69 0x4a69 0xce59 0x4a69 0x4a69 0xce59 ]

dw [ 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 0x3186 ]
dw [ 0x3186 0xce59 0xc9e7 0xc9e7 0xce59 0xc9e7 0xc9e7 0xce59 ]
dw [ 0x3186 0xc9e7 0xce59 0xce59 0xce59 0xce59 0xce59 0xc9e7 ]
dw [ 0x3186 0xc9e7 0xce59 0x9cf3 0xce59 0xce59 0xce59 0xc9e7 ]
dw [ 0x3186 0xce59 0xce59 0xce59 0xce59 0xce59 0xce59 0xce59 ]
dw [ 0x3186 0xc9e7 0xce59 0xce59 0xce59 0xce59 0xce59 0xc9e7 ]
dw [ 0x3186 0xc9e7 0xce59 0xce59 0xce59 0xce59 0xce59 0xc9e7 ]
dw [ 0x3186 0xce59 0xc9e7 0xc9e7 0xce59 0xc9e7 0xc9e7 0xce59 ]

dw [ 0x8410 0x8410 0x8410 0x8410 0x8410 0x8410 0x8410 0x630c ]
dw [ 0x8410 0x630c 0x630c 0x630c 0x630c 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0x630c 0x630c 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0x630c 0x630c 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0x630c 0x630c 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0x630c 0x630c 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0x630c 0x630c 0x630c 0x630c 0x4208 ]
dw [ 0x630c 0x4208 0x4208 0x4208 0x4208 0x4208 0x4208 0x4208 ]

dw [ 0x8410 0x8410 0x8410 0x8410 0x8410 0x8410 0x8410 0x630c ]
dw [ 0x8410 0x630c 0x630c 0x630c 0x630c 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0x630c 0x630c 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0x630c 0x630c 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0x630c 0x630c 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0x630c 0x630c 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0x630c 0x630c 0x630c 0x630c 0x4208 ]
dw [ 0x630c 0x4208 0x4208 0x4208 0x4208 0x4208 0x4208 0x4208 ]

dw [ 0x8410 0x8410 0x8410 0x8410 0x8410 0x8410 0x8410 0x630c ]
dw [ 0x8410 0x630c 0x630c 0xc9e7 0xc9e7 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0xc9e7 0xc9e7 0xc9e7 0xc9e7 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0xc9e7 0xc9e7 0xc9e7 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0x630c 0xce59 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0x630c 0xce59 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0xce59 0xce59 0xce59 0x630c 0x4208 ]
dw [ 0x630c 0x4208 0x4208 0x4208 0x4208 0x4208 0x4208 0x4208 ]

dw [ 0x8410 0x8410 0x8410 0x8410 0x8410 0x8410 0x8410 0x630c ]
dw [ 0x8410 0x630c 0x630c 0xc9e7 0xc9e7 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0xc9e7 0xc9e7 0xc9e7 0xc9e7 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0xc9e7 0xc9e7 0xc9e7 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0x630c 0xce59 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0x630c 0xce59 0x630c 0x630c 0x4208 ]
dw [ 0x8410 0x630c 0x630c 0xce59 0xce59 0xce59 0x630c 0x4208 ]
dw [ 0x630c 0x4208 0x4208 0x4208 0x4208 0x4208 0x4208 0x4208 ]
