diff options
Diffstat (limited to 'source.asm')
-rw-r--r-- | source.asm | 480 |
1 files changed, 480 insertions, 0 deletions
diff --git a/source.asm b/source.asm new file mode 100644 index 0000000..0612e56 --- /dev/null +++ b/source.asm @@ -0,0 +1,480 @@ +covered_color equ 0x70 +controls_color equ 0x0f +flag_character equ 'F' +bombs_per_65535 equ 5000 + +board_width equ 26 +board_height equ 7 +offset_x equ 1 +offset_y equ 1 + +org 0x0100 + + mov ax, 0x0501 + int 0x10 + + xor ah, ah + int 0x1a + + test dx, dx + jnz nonzero + inc dx +nonzero: + mov word [xorshift_state], dx + + mov cx, board_width * board_height + mov si, cx + mov di, board_flags +bomb_loop: + call xorshift + cmp ax, bombs_per_65535 + ja .no_bomb + mov byte [di], board_bomb + dec si +.no_bomb: + inc di + loop bomb_loop + mov word [non_bombs_left], si + + xor bx, bx + mov di, board_numbers +number_loop: + call get_number_of_bx + mov byte [di], al + inc di + inc bl + cmp bl, board_width + jne number_loop + xor bl, bl + inc bh + cmp bh, board_height + jne number_loop + + push 0xb900 + pop es + + xor di, di + mov ax, ' ' + mov cx, 80 * 25 + rep stosw + + mov di, offset_y * 80 * 2 + offset_x * 2 + mov ax, (covered_color << 8) | ' ' +gray_loop: + mov cx, board_width * 3 + rep stosw + add di, (80 - board_width * 3) * 2 + cmp di, (offset_y + board_height * 3) * 80 * 2 + offset_x * 2 + jne gray_loop + + mov si, controls_str + mov di, (offset_y + board_height * 3 + 1) * 80 * 2 + offset_x * 2 + ((board_width * 3 - controls_str.len) / 4) * 2 + mov cx, controls_str.len + mov ah, controls_color +show_controls_loop: + mov al, byte [si] + mov word [es:di], ax + inc si + add di, 2 + loop show_controls_loop + + call set_cursor + +main_loop: + xor ah, ah + int 0x16 + + cmp ah, 0x48 + je up_arrow + + cmp ah, 0x50 + je down_arrow + + cmp ah, 0x4b + je left_arrow + + cmp ah, 0x4d + je right_arrow + + cmp ah, 0x20 + je dig + + cmp ah, 0x21 + je flag + + cmp ah, 0x10 + jne main_loop + + mov ax, 0x0500 + int 0x10 + + mov ax, 0x4c00 + int 0x21 + +xorshift_state: + dw 0 + +xorshift: + mov ax, word [xorshift_state] + mov dx, ax + shl dx, 7 + xor ax, dx + mov dx, ax + shr dx, 9 + xor ax, dx + xor ah, al + mov word [xorshift_state], ax + ret + +;bx - y:x +;preserves bx, di, and si +;returns in ax +bx_has_bomb: + push bx + movzx ax, bh + mov cx, board_width + mul cx + xor bh, bh + add bx, ax + mov ax, 0x1 + and al, byte [board_flags + bx] + pop bx + ret + +;bx - y:x +;preserves bx and di +;returns in al +get_number_of_bx: + xor si, si + + test bh, bh + jz .no_ups + + dec bh + + test bl, bl + jz .no_ul + + dec bl + call bx_has_bomb + add si, ax + inc bl + +.no_ul: + call bx_has_bomb + add si, ax + + cmp bl, board_width - 1 + je .no_ur + + inc bl + call bx_has_bomb + add si, ax + dec bl + +.no_ur: + inc bh + +.no_ups: + test bl, bl + jz .no_cl + + dec bl + call bx_has_bomb + add si, ax + inc bl + +.no_cl: + cmp bl, board_width - 1 + je .no_cr + + inc bl + call bx_has_bomb + add si, ax + dec bl + +.no_cr: + cmp bh, board_height - 1 + je .no_downs + + inc bh + + test bl, bl + jz .no_bl + + dec bl + call bx_has_bomb + add si, ax + inc bl + +.no_bl: + call bx_has_bomb + add si, ax + + cmp bl, board_width - 1 + je .no_br + + inc bl + call bx_has_bomb + add si, ax + dec bl + +.no_br: + dec bh + +.no_downs: + mov ax, si + ret + +set_cursor: + mov ah, 0x02 + mov bh, 0x01 + mov cx, word [cursor_x] + mov dl, cl + add dl, cl + add dl, cl + add dl, offset_x + 1 + mov dh, ch + add dh, ch + add dh, ch + add dh, offset_y + 1 + int 0x10 + jmp main_loop + +up_arrow: + mov al, byte [cursor_y] + test al, al + jz main_loop + + dec al + mov byte [cursor_y], al + call set_cursor + jmp main_loop + +down_arrow: + mov al, byte [cursor_y] + cmp al, board_height - 1 + je main_loop + + inc al + mov byte [cursor_y], al + call set_cursor + jmp main_loop + +left_arrow: + mov al, byte [cursor_x] + test al, al + jz main_loop + + dec al + mov byte [cursor_x], al + call set_cursor + jmp main_loop + +right_arrow: + mov al, byte [cursor_x] + cmp al, board_width - 1 + je main_loop + + inc al + mov byte [cursor_x], al + call set_cursor + jmp main_loop + +dig: + call get_board_flags_at_cursor + test al, board_uncovered | board_flagged + jnz main_loop + + test al, board_bomb + jnz lose + + or al, board_uncovered + call set_board_flags_at_cursor + + push ax + call get_cursor_vram_offset + mov di, ax + pop ax + + call get_number_at_cursor + movzx bx, al + mov al, byte [bx + uncovered_numbers] + mov ah, byte [bx + uncovered_colors] + mov word [es:di], ax + + mov byte [es:di - 80 * 2 - 2 + 1], ah + mov byte [es:di - 80 * 2 + 1], ah + mov byte [es:di - 80 * 2 + 2 + 1], ah + mov byte [es:di - 2 + 1], ah + mov byte [es:di + 1], ah + mov byte [es:di + 2 + 1], ah + mov byte [es:di + 80 * 2 - 2 + 1], ah + mov byte [es:di + 80 * 2 + 1], ah + mov byte [es:di + 80 * 2 + 2 + 1], ah + + mov ax, word [non_bombs_left] + dec ax + + test ax, ax + jz win + + mov word [non_bombs_left], ax + + jmp main_loop + +uncovered_colors: + db 0x08, 0x08, 0x0a, 0x0c, 0x0b, 0x0e, 0x09, 0x07, 0x0f +uncovered_numbers: + db " 12345678" + +flag: + call get_board_flags_at_cursor + test al, board_uncovered + jnz main_loop + xor al, board_flagged + push ax + call get_cursor_vram_offset + mov di, ax + pop ax + call set_board_flags_at_cursor + + test al, board_flagged + jz .not_flagged + + mov byte [es:di], flag_character + jmp main_loop + +.not_flagged: + mov byte [es:di], ' ' + jmp main_loop + +;as rows +board_flags: + times board_width * board_height db 0 +board_bomb equ 1 +board_uncovered equ 2 +board_flagged equ 4 + +board_numbers: + times board_width * board_height db 0 + +get_board_flags_at_cursor: + movzx ax, byte [cursor_y] + mov cx, board_width + mul cx + movzx bx, byte [cursor_x] + add bx, ax + mov al, byte [board_flags + bx] + ret + +get_cursor_vram_offset: + mov cx, word [cursor_x] + + mov bl, cl + add bl, cl + add bl, cl + add bl, offset_x + 1 + + mov bh, ch + add bh, ch + add bh, ch + add bh, offset_y + 1 + + mov cx, 80 + movzx ax, bh + mul cx + xor bh, bh + add ax, bx + add ax, ax + + ret + +;preserves ax and di +set_board_flags_at_cursor: + mov si, ax + movzx ax, byte [cursor_y] + mov cx, board_width + mul cx + movzx bx, byte [cursor_x] + add bx, ax + mov ax, si + mov byte [board_flags + bx], al + ret + +;preserves di +get_number_at_cursor: + movzx ax, byte [cursor_y] + mov cx, board_width + mul cx + movzx bx, byte [cursor_x] + add bx, ax + mov al, byte [board_numbers + bx] + ret + +cursor_x: + db 0 +cursor_y: + db 0 + +non_bombs_left: + dw 0 + +controls_str: + db "Controls: Arrows - Move Cursor D - Dig F - Flag Q - Quit" +.len equ $ - controls_str + +win: + push ds + pop es + + mov ax, 0x1300 + mov bx, 0x010f + mov cx, .len + mov dx, 0x0a24 + mov bp, .str + int 0x10 + + jmp win_or_lose + +.str: + db "You win!" +.len equ $ - .str + +lose: + push ds + pop es + + mov ax, 0x1300 + mov bx, 0x010f + mov cx, .len + mov dx, 0x0a23 + mov bp, .str + int 0x10 + + jmp win_or_lose + +.str: + db "You lose!" +.len equ $ - .str + +win_or_lose: + mov ax, 0x1300 + mov bx, 0x010f + mov cx, .len + mov dx, 0x0c1d + mov bp, .str + int 0x10 + + xor ax, ax + int 0x16 + + mov ax, 0x0500 + int 0x10 + + mov ax, 0x4c00 + int 0x21 + +.str: + db "Press any key to quit." +.len equ $ - .str |