summaryrefslogtreecommitdiff
path: root/source.asm
diff options
context:
space:
mode:
Diffstat (limited to 'source.asm')
-rw-r--r--source.asm480
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