2020-06-07 14:10:33 +02:00
|
|
|
format MZ ;Specify the .EXE format
|
|
|
|
entry MainSeg:start
|
|
|
|
org 0100h
|
|
|
|
stack $3000
|
2020-06-06 13:17:39 +02:00
|
|
|
|
2020-06-07 14:10:33 +02:00
|
|
|
;org 100h ;specify origin
|
2020-06-06 13:47:22 +02:00
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;Constants
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
2020-06-09 13:46:06 +02:00
|
|
|
COLUMNS = 16
|
|
|
|
LINES = 16
|
2020-06-09 13:54:05 +02:00
|
|
|
FIELDX = 20 - (COLUMNS/2)
|
|
|
|
FIELDY = 4
|
|
|
|
MAXMINES = 40
|
2020-06-06 13:47:22 +02:00
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;Code
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
2020-06-07 14:10:33 +02:00
|
|
|
segment MainSeg
|
|
|
|
use16
|
|
|
|
|
2020-06-06 13:17:39 +02:00
|
|
|
start:
|
2020-06-08 20:10:53 +02:00
|
|
|
mov al,13h ;AX=0000 at program start
|
|
|
|
int 10h ;init mode 13h
|
|
|
|
push word 0A000h ;Requires 80186 or higher to PUSH IMMED
|
|
|
|
pop es ;ES now points to mode 13h screen segment
|
|
|
|
mov ax, DataSeg
|
|
|
|
mov ds, ax ;DS now points to our data segment
|
|
|
|
call createminefield ;Initialize the map with mines
|
|
|
|
call calculateminenumbers ;Populate the numbers
|
|
|
|
call drawfield ;Draw the map
|
|
|
|
jmp mainloop ;Main event and game loop
|
2020-06-07 17:47:54 +02:00
|
|
|
|
|
|
|
|
|
|
|
; Draw the field
|
|
|
|
drawfield:
|
|
|
|
mov cx, 00h
|
|
|
|
mov ax, 00h
|
|
|
|
drawfieldloop:
|
|
|
|
push cx
|
|
|
|
push ax
|
2020-06-07 18:36:43 +02:00
|
|
|
call getbmp
|
2020-06-07 17:47:54 +02:00
|
|
|
add cx, FIELDY ; Make sure we get the field displaced correctly
|
|
|
|
add ax, FIELDX
|
|
|
|
call drawbox
|
|
|
|
pop ax
|
|
|
|
pop cx
|
|
|
|
inc cx
|
2020-06-09 11:51:30 +02:00
|
|
|
cmp cx, LINES
|
2020-06-07 17:47:54 +02:00
|
|
|
jne drawfieldloop
|
2020-06-07 18:36:43 +02:00
|
|
|
mov cx, 0h
|
2020-06-07 17:47:54 +02:00
|
|
|
inc ax
|
2020-06-09 11:51:30 +02:00
|
|
|
cmp ax, COLUMNS
|
2020-06-07 17:47:54 +02:00
|
|
|
jne drawfieldloop
|
2020-06-08 22:16:22 +02:00
|
|
|
mov ax, [cursorx]
|
|
|
|
add ax, FIELDX
|
|
|
|
mov cx, [cursory]
|
|
|
|
add cx, FIELDY ; Make sure we get the cursor displaced correctly
|
|
|
|
mov bx, cursorbmp
|
|
|
|
call drawbox
|
2020-06-07 17:47:54 +02:00
|
|
|
ret
|
|
|
|
getbmp:
|
2020-06-08 00:07:37 +02:00
|
|
|
push cx ; Store the values before scr$%&ing them
|
|
|
|
push ax
|
2020-06-08 20:10:53 +02:00
|
|
|
call peektable
|
2020-06-08 00:07:37 +02:00
|
|
|
pop ax ; Recover the values of AX and BX
|
|
|
|
pop cx
|
2020-06-08 23:13:39 +02:00
|
|
|
|
|
|
|
;;;;; Normal reading of the field, covering the cells
|
|
|
|
|
2020-06-09 11:35:45 +02:00
|
|
|
cmp dh, 01h ; Covered cell
|
|
|
|
je iscovered
|
|
|
|
cmp dh, 02h ; Flagged cell
|
|
|
|
je isflagged
|
|
|
|
cmp dx, 00009h ; There's a mine
|
|
|
|
je mine
|
|
|
|
cmp dx, 00008h
|
|
|
|
je puteight
|
|
|
|
cmp dx, 00007h
|
|
|
|
je putseven
|
|
|
|
cmp dx, 00006h
|
|
|
|
je putsix
|
|
|
|
cmp dx, 00005h
|
|
|
|
je putfive
|
|
|
|
cmp dx, 00004h
|
|
|
|
je putfour
|
|
|
|
cmp dx, 00003h
|
|
|
|
je putthree
|
|
|
|
cmp dx, 00002h
|
|
|
|
je puttwo
|
|
|
|
cmp dx, 00001h
|
|
|
|
je putone
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;; Uncomment this to see the field uncovered
|
2020-06-08 23:13:39 +02:00
|
|
|
; cmp dh, 02h ; Flagged cell
|
|
|
|
; je isflagged
|
2020-06-09 11:35:45 +02:00
|
|
|
; cmp dx, 00109h ; There's a mine
|
2020-06-08 23:13:39 +02:00
|
|
|
; je mine
|
2020-06-09 11:35:45 +02:00
|
|
|
; cmp dx, 00108h
|
2020-06-08 23:13:39 +02:00
|
|
|
; je puteight
|
2020-06-09 11:35:45 +02:00
|
|
|
; cmp dx, 00107h
|
2020-06-08 23:13:39 +02:00
|
|
|
; je putseven
|
2020-06-09 11:35:45 +02:00
|
|
|
; cmp dx, 00106h
|
2020-06-08 23:13:39 +02:00
|
|
|
; je putsix
|
2020-06-09 11:35:45 +02:00
|
|
|
; cmp dx, 00105h
|
2020-06-08 23:13:39 +02:00
|
|
|
; je putfive
|
2020-06-09 11:35:45 +02:00
|
|
|
; cmp dx, 00104h
|
2020-06-08 23:13:39 +02:00
|
|
|
; je putfour
|
2020-06-09 11:35:45 +02:00
|
|
|
; cmp dx, 00103h
|
2020-06-08 23:13:39 +02:00
|
|
|
; je putthree
|
2020-06-09 11:35:45 +02:00
|
|
|
; cmp dx, 00102h
|
2020-06-08 23:13:39 +02:00
|
|
|
; je puttwo
|
2020-06-09 11:35:45 +02:00
|
|
|
; cmp dx, 00101h
|
2020-06-08 23:13:39 +02:00
|
|
|
; je putone
|
|
|
|
|
2020-06-08 20:23:12 +02:00
|
|
|
mov bx, emptycell ; Point to the emptycell bitmap
|
2020-06-07 17:47:54 +02:00
|
|
|
ret
|
2020-06-08 20:23:12 +02:00
|
|
|
iscovered:
|
|
|
|
mov bx, covercell ; Point to the covered cell
|
|
|
|
ret
|
|
|
|
isflagged:
|
|
|
|
mov bx, flagbmp ; Point to the flag bitmap
|
2020-06-08 22:21:36 +02:00
|
|
|
ret
|
2020-06-08 00:07:37 +02:00
|
|
|
mine:
|
2020-06-08 20:23:12 +02:00
|
|
|
mov bx, minebmp ; Point to the mine cell
|
2020-06-08 00:07:37 +02:00
|
|
|
ret
|
|
|
|
putone:
|
2020-06-08 20:23:12 +02:00
|
|
|
mov bx, numone ; Point to the corresponding number cell
|
2020-06-08 00:07:37 +02:00
|
|
|
ret
|
|
|
|
puttwo:
|
2020-06-08 20:23:12 +02:00
|
|
|
mov bx, numtwo ; Point to the corresponding number cell
|
2020-06-08 00:07:37 +02:00
|
|
|
ret
|
|
|
|
putthree:
|
2020-06-08 20:23:12 +02:00
|
|
|
mov bx, numthree ; Point to the corresponding number cell
|
2020-06-08 00:07:37 +02:00
|
|
|
ret
|
|
|
|
putfour:
|
2020-06-08 20:23:12 +02:00
|
|
|
mov bx, numfour ; Point to the corresponding number cell
|
2020-06-08 00:07:37 +02:00
|
|
|
ret
|
|
|
|
putfive:
|
2020-06-08 20:23:12 +02:00
|
|
|
mov bx, numfive ; Point to the corresponding number cell
|
2020-06-08 00:07:37 +02:00
|
|
|
ret
|
|
|
|
putsix:
|
2020-06-08 20:23:12 +02:00
|
|
|
mov bx, numsix ; Point to the corresponding number cell
|
2020-06-08 00:07:37 +02:00
|
|
|
ret
|
|
|
|
putseven:
|
2020-06-08 20:23:12 +02:00
|
|
|
mov bx, numseven ; Point to the corresponding number cell
|
2020-06-08 00:07:37 +02:00
|
|
|
ret
|
|
|
|
puteight:
|
2020-06-08 20:23:12 +02:00
|
|
|
mov bx, numeight ; Point to the corresponding number cell
|
2020-06-07 17:47:54 +02:00
|
|
|
ret
|
|
|
|
|
|
|
|
;Random subroutines here
|
|
|
|
initseed:
|
|
|
|
mov ah, 02Ch ;Select Get System Time function
|
|
|
|
int 021h ;Call DOS
|
|
|
|
add cx, dx ;Add the seconds and milliseconds to add more randomness
|
|
|
|
mov word [seed], cx ;In CX we have our new seed
|
|
|
|
ret
|
|
|
|
|
|
|
|
random:
|
2020-06-07 18:36:43 +02:00
|
|
|
mov ax, 25173 ;LCG multiplier
|
|
|
|
mul word [seed] ;DX:AX = LCG multiplier * seed
|
|
|
|
add ax, 13849 ;Add LCG increment value
|
|
|
|
mov word [seed], ax ;Update seed, AX has the random number now
|
2020-06-07 17:47:54 +02:00
|
|
|
ret
|
2020-06-07 14:10:33 +02:00
|
|
|
|
|
|
|
;This is thought to pick up from the registers the address of what we need to draw
|
|
|
|
;Draw it, and return. The params are:
|
|
|
|
;- AX -> X position
|
|
|
|
;- CX -> Y position
|
|
|
|
;- BX -> base memory address of the bitmap
|
|
|
|
drawbox:
|
|
|
|
push ax ;Save the X value for later
|
|
|
|
mov ax, cx ;Prepare for multiplications
|
2020-06-09 11:51:30 +02:00
|
|
|
mov dx, 320 * 8 ;The box is 8x8, the screen width is 320
|
2020-06-07 17:47:54 +02:00
|
|
|
mul dx
|
2020-06-07 14:10:33 +02:00
|
|
|
mov cx, ax ;Retrieve the line into CX
|
|
|
|
pop ax ;Retrieve the X value into AX register
|
2020-06-09 11:51:30 +02:00
|
|
|
mov dx, 8 ;The box is 8x8, each box is 8 pixel wide
|
2020-06-07 17:47:54 +02:00
|
|
|
mul dx ;We multiply the X value too for the 8x8
|
2020-06-07 14:10:33 +02:00
|
|
|
add cx, ax ;Now we've put in AX the pointer value
|
|
|
|
mov si, cx ;Set SI to the correct address we'll draw
|
|
|
|
mov cx, 00
|
|
|
|
mov ax, 00
|
|
|
|
mov dx, 00
|
|
|
|
drawloop:
|
|
|
|
mov al, byte [ds:bx] ;Current address in BX
|
2020-06-08 22:16:22 +02:00
|
|
|
cmp al, 0ffh ;This is transparent pixel, don't draw
|
|
|
|
je dontdraw
|
2020-06-07 14:10:33 +02:00
|
|
|
mov byte [es:si], al ;Put the pixel into RAM
|
2020-06-08 22:16:22 +02:00
|
|
|
dontdraw:
|
2020-06-07 14:10:33 +02:00
|
|
|
inc bx
|
|
|
|
inc cx
|
|
|
|
inc dx
|
2020-06-09 11:51:30 +02:00
|
|
|
cmp dx, 8 ;Sort of modulo
|
2020-06-07 14:10:33 +02:00
|
|
|
je jumplinedraw ;Time to increment SI in a more complex way
|
|
|
|
inc si
|
|
|
|
continuecomp:
|
2020-06-09 13:46:06 +02:00
|
|
|
cmp cx, 64 ;Compare CX the max the field will be
|
2020-06-07 14:10:33 +02:00
|
|
|
jne drawloop ;Continue
|
|
|
|
ret ;Return
|
|
|
|
jumplinedraw:
|
|
|
|
mov dx, 00h
|
|
|
|
add si, 313 ;Jump a whole line
|
|
|
|
jmp continuecomp ;Continue the routine
|
2020-06-07 17:47:54 +02:00
|
|
|
|
|
|
|
;This function populates the minefield with mines
|
|
|
|
createminefield:
|
|
|
|
call initseed ;Make sure we have a good seed
|
|
|
|
mov dx, 00h ;DX will be our pointer
|
2020-06-07 18:36:43 +02:00
|
|
|
mov bx, map ;BX our base pointer
|
2020-06-07 17:47:54 +02:00
|
|
|
cmfloop:
|
|
|
|
push dx ;Save our counters before generating random number
|
|
|
|
push bx
|
|
|
|
call random ;This leaves a random num in AX
|
2020-06-07 18:36:43 +02:00
|
|
|
pop bx ;Recover our counters
|
2020-06-07 17:47:54 +02:00
|
|
|
pop dx
|
2020-06-08 20:10:53 +02:00
|
|
|
cmp al, 0FFh ;Compare if it's greater than 240
|
|
|
|
je putmine ;Put a mine here
|
2020-06-07 17:47:54 +02:00
|
|
|
continuecreateminefield:
|
2020-06-07 18:36:43 +02:00
|
|
|
add bx, 02h
|
2020-06-07 17:47:54 +02:00
|
|
|
inc dx
|
|
|
|
cmp dx, COLUMNS * LINES ; Check we have done the whole map
|
2020-06-07 18:36:43 +02:00
|
|
|
jl cmfloop
|
2020-06-09 11:35:45 +02:00
|
|
|
cmp byte [minecount], MAXMINES ; Check we've put all mines!
|
2020-06-07 18:36:43 +02:00
|
|
|
jl createminefield
|
2020-06-07 17:47:54 +02:00
|
|
|
finishcreateminefield:
|
|
|
|
ret ; All is ok
|
|
|
|
putmine:
|
2020-06-09 11:35:45 +02:00
|
|
|
cmp byte [minecount], MAXMINES
|
2020-06-07 18:36:43 +02:00
|
|
|
jge finishcreateminefield
|
2020-06-08 20:23:12 +02:00
|
|
|
cmp word [ds:bx], 00109h ;Check memory for placed mine
|
2020-06-07 17:47:54 +02:00
|
|
|
je continuecreateminefield
|
|
|
|
inc byte [minecount]
|
2020-06-08 20:23:12 +02:00
|
|
|
mov word [ds:bx], 00109h ;Place mine
|
2020-06-07 17:47:54 +02:00
|
|
|
jmp continuecreateminefield
|
2020-06-07 19:24:20 +02:00
|
|
|
|
|
|
|
;This routine returns in DX the value of the cell pointed by CX (Y coord) and
|
|
|
|
;AX (X coord)
|
|
|
|
;Mangles AX, BX, CX and DX
|
|
|
|
peektable:
|
|
|
|
mov dx, 0 ;In case we return prematurely, we return nothing
|
|
|
|
cmp ax, COLUMNS ;If we are out of bounds, return
|
|
|
|
jge peekend
|
|
|
|
cmp cx, LINES
|
|
|
|
jge peekend
|
|
|
|
push ax ;Calculate offset
|
|
|
|
mov ax, cx
|
|
|
|
mov cx, COLUMNS
|
|
|
|
mul cx
|
2020-06-08 00:07:37 +02:00
|
|
|
mov cx, ax
|
2020-06-07 19:24:20 +02:00
|
|
|
pop ax
|
2020-06-08 00:07:37 +02:00
|
|
|
add ax, cx
|
|
|
|
mov cx, 2
|
|
|
|
mul cx
|
|
|
|
mov bx, map
|
2020-06-07 19:24:20 +02:00
|
|
|
add bx, ax
|
|
|
|
mov dx, word [ds:bx] ;Read
|
|
|
|
peekend:
|
|
|
|
ret
|
2020-06-08 00:07:37 +02:00
|
|
|
|
|
|
|
calcnumber:
|
|
|
|
push ax
|
|
|
|
push cx
|
2020-06-08 20:10:53 +02:00
|
|
|
call peektable
|
2020-06-08 00:07:37 +02:00
|
|
|
pop cx
|
2020-06-08 20:23:12 +02:00
|
|
|
cmp dx, 00109h
|
2020-06-08 00:07:37 +02:00
|
|
|
jne calcend
|
2020-06-08 20:10:53 +02:00
|
|
|
mov al, byte [tempnumber]
|
|
|
|
inc al
|
|
|
|
mov byte [tempnumber], al
|
2020-06-08 00:07:37 +02:00
|
|
|
calcend:
|
2020-06-08 20:10:53 +02:00
|
|
|
pop ax
|
2020-06-08 00:07:37 +02:00
|
|
|
ret
|
|
|
|
|
2020-06-09 11:21:09 +02:00
|
|
|
; We don't check Y bounds as we have surrounded the field array
|
|
|
|
; with padding zeroes, rendering this calculation correct if CX
|
|
|
|
; is below or beyond the limits
|
2020-06-08 00:07:37 +02:00
|
|
|
checksurroundings:
|
|
|
|
mov byte [tempnumber], 0
|
|
|
|
push ax
|
|
|
|
push cx
|
2020-06-09 11:21:09 +02:00
|
|
|
sub cx, 1
|
2020-06-08 23:13:39 +02:00
|
|
|
test ax, ax
|
|
|
|
jz axiszerofirstrow
|
2020-06-08 00:07:37 +02:00
|
|
|
sub ax, 1
|
|
|
|
call calcnumber
|
|
|
|
add ax, 1
|
2020-06-08 23:13:39 +02:00
|
|
|
axiszerofirstrow:
|
2020-06-08 00:07:37 +02:00
|
|
|
call calcnumber
|
|
|
|
add ax, 1
|
2020-06-08 23:13:39 +02:00
|
|
|
cmp ax, COLUMNS
|
|
|
|
je axoutboundsfirstrow
|
2020-06-08 00:07:37 +02:00
|
|
|
call calcnumber
|
2020-06-08 23:13:39 +02:00
|
|
|
axoutboundsfirstrow:
|
2020-06-08 00:07:37 +02:00
|
|
|
pop cx
|
|
|
|
pop ax
|
|
|
|
push ax
|
|
|
|
push cx
|
2020-06-08 23:13:39 +02:00
|
|
|
test ax, ax
|
|
|
|
jz axiszerosecondrow
|
2020-06-08 00:07:37 +02:00
|
|
|
sub ax, 1
|
|
|
|
call calcnumber
|
2020-06-08 23:13:39 +02:00
|
|
|
inc ax
|
|
|
|
axiszerosecondrow:
|
|
|
|
inc ax
|
|
|
|
cmp ax, COLUMNS
|
|
|
|
je axoutboundssecondrow
|
2020-06-08 00:07:37 +02:00
|
|
|
call calcnumber
|
2020-06-08 23:13:39 +02:00
|
|
|
axoutboundssecondrow:
|
2020-06-08 00:07:37 +02:00
|
|
|
pop cx
|
|
|
|
pop ax
|
|
|
|
push ax
|
|
|
|
push cx
|
|
|
|
add cx, 1
|
2020-06-08 23:13:39 +02:00
|
|
|
test ax, ax
|
|
|
|
jz axiszerothirdrow
|
2020-06-08 00:07:37 +02:00
|
|
|
sub ax, 1
|
|
|
|
call calcnumber
|
|
|
|
add ax, 1
|
2020-06-09 11:21:09 +02:00
|
|
|
axiszerothirdrow:
|
2020-06-08 00:07:37 +02:00
|
|
|
call calcnumber
|
|
|
|
add ax, 1
|
2020-06-08 23:13:39 +02:00
|
|
|
cmp ax, COLUMNS
|
|
|
|
je axoutboundsthirdrow
|
2020-06-08 00:07:37 +02:00
|
|
|
call calcnumber
|
2020-06-08 23:13:39 +02:00
|
|
|
axoutboundsthirdrow:
|
2020-06-08 00:07:37 +02:00
|
|
|
pop cx
|
|
|
|
mov bx, map
|
|
|
|
mov ax, cx
|
|
|
|
mov dx, COLUMNS
|
|
|
|
mul dx
|
|
|
|
mov dx, ax
|
|
|
|
pop ax
|
|
|
|
push ax
|
|
|
|
add dx, ax
|
|
|
|
mov ax, dx
|
|
|
|
mov dx, 2
|
|
|
|
mul dx
|
|
|
|
add bx, ax
|
|
|
|
pop ax
|
2020-06-08 20:23:12 +02:00
|
|
|
mov dx, 00100h
|
2020-06-08 00:07:37 +02:00
|
|
|
mov dl, byte [tempnumber]
|
|
|
|
mov word [ds:bx], dx
|
|
|
|
ret
|
2020-06-07 14:10:33 +02:00
|
|
|
|
2020-06-07 17:47:54 +02:00
|
|
|
;This routine checks the map and puts numbers down given the
|
2020-06-07 19:24:20 +02:00
|
|
|
;amount of mines around
|
2020-06-08 00:07:37 +02:00
|
|
|
calculateminenumbers:
|
|
|
|
mov ax, 0
|
|
|
|
mov cx, 0
|
|
|
|
cmnloop:
|
|
|
|
push ax
|
|
|
|
push cx
|
|
|
|
call peektable
|
|
|
|
pop cx
|
|
|
|
pop ax
|
2020-06-08 20:23:12 +02:00
|
|
|
cmp dx, 00109h
|
2020-06-08 00:07:37 +02:00
|
|
|
je cmncontinue
|
|
|
|
call checksurroundings
|
|
|
|
cmncontinue:
|
|
|
|
inc ax
|
|
|
|
cmp ax, COLUMNS
|
|
|
|
jl cmnloop
|
2020-06-08 20:10:53 +02:00
|
|
|
mov ax, 0
|
2020-06-08 00:07:37 +02:00
|
|
|
inc cx
|
|
|
|
cmp cx, LINES
|
|
|
|
jl cmnloop
|
|
|
|
ret
|
2020-06-06 13:17:39 +02:00
|
|
|
|
|
|
|
mainloop:
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;This is where you do your mega-amazing tiny program.
|
|
|
|
;Write 8-bit values to A000:0000 to draw some pixels.
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
2020-06-07 14:10:33 +02:00
|
|
|
;Check for user input or wanting to leave by pressing ESC
|
|
|
|
in al,60h ;read whatever is at keyboard port; looking for ESC which is #1
|
2020-06-08 22:16:22 +02:00
|
|
|
cmp al,48h
|
|
|
|
je upkey
|
|
|
|
cmp al,4bh
|
|
|
|
je leftkey
|
|
|
|
cmp al,4dh
|
|
|
|
je rightkey
|
|
|
|
cmp al,50h
|
|
|
|
je downkey
|
|
|
|
cmp al,39h
|
|
|
|
je space
|
|
|
|
cmp al,38h
|
|
|
|
je lalt
|
|
|
|
mov word [lastkeypressed], 0h ;Reset the current key as it is not one we are checking
|
2020-06-07 14:10:33 +02:00
|
|
|
dec al ;if ESC, AL now 0
|
|
|
|
jnz mainloop ;fall through if 0, jump otherwise
|
2020-06-06 13:47:22 +02:00
|
|
|
|
|
|
|
exit:
|
2020-06-06 13:17:39 +02:00
|
|
|
mov al,03 ;AX=0000 due to mainloop exit condition
|
|
|
|
int 10h ;Switch back to text mode as a convenience
|
2020-06-06 13:47:22 +02:00
|
|
|
mov ah,4Ch ;Function to exit, now we are an EXE, do it correctly
|
|
|
|
mov al,00 ;Exit code as 0, everything went well
|
|
|
|
int 21h
|
2020-06-06 13:17:39 +02:00
|
|
|
|
2020-06-08 22:44:37 +02:00
|
|
|
gameover:
|
2020-06-09 11:37:28 +02:00
|
|
|
call drawfield
|
2020-06-09 11:35:45 +02:00
|
|
|
mov ax, 0
|
|
|
|
mov ah, 02Ch ;Get current system time
|
|
|
|
int 021h
|
|
|
|
mov bh, dh ;Get current seconds
|
|
|
|
waitloop:
|
|
|
|
mov ah, 02Ch
|
|
|
|
int 021h
|
|
|
|
sub dh, bh ;Get seconds elapsed
|
|
|
|
cmp dh, 2
|
|
|
|
jl waitloop
|
2020-06-08 22:44:37 +02:00
|
|
|
mov ah, 0
|
|
|
|
mov al,03 ;AX=0000 due to mainloop exit condition
|
|
|
|
int 10h ;Switch back to text mode as a convenience
|
|
|
|
mov dx, gameoverstr
|
|
|
|
mov ah, 09h
|
|
|
|
int 21h
|
|
|
|
mov ah,4Ch ;Function to exit, now we are an EXE, do it correctly
|
|
|
|
mov al,00 ;Exit code as 0, everything went well
|
|
|
|
int 21h
|
|
|
|
|
2020-06-08 22:16:22 +02:00
|
|
|
redraw:
|
|
|
|
call drawfield
|
|
|
|
jmp mainloop
|
|
|
|
|
|
|
|
leftkey:
|
2020-06-06 13:17:39 +02:00
|
|
|
cmp ax, [lastkeypressed]
|
|
|
|
je mainloop
|
|
|
|
mov [lastkeypressed], ax
|
2020-06-08 22:16:22 +02:00
|
|
|
mov ax, [cursorx]
|
|
|
|
dec ax
|
2020-06-06 13:17:39 +02:00
|
|
|
|
2020-06-08 22:16:22 +02:00
|
|
|
updatelateralmovement:
|
|
|
|
cmp ax, COLUMNS - 1
|
|
|
|
jg redraw
|
|
|
|
cmp ax, 0
|
|
|
|
jl redraw
|
|
|
|
mov [cursorx], ax
|
|
|
|
jmp redraw
|
|
|
|
|
|
|
|
rightkey:
|
2020-06-06 13:17:39 +02:00
|
|
|
cmp ax, [lastkeypressed]
|
|
|
|
je mainloop
|
|
|
|
mov [lastkeypressed], ax
|
2020-06-08 22:16:22 +02:00
|
|
|
mov ax, [cursorx]
|
|
|
|
inc ax
|
|
|
|
jmp updatelateralmovement
|
2020-06-06 13:17:39 +02:00
|
|
|
|
2020-06-08 22:16:22 +02:00
|
|
|
upkey:
|
2020-06-06 13:17:39 +02:00
|
|
|
cmp ax, [lastkeypressed]
|
|
|
|
je mainloop
|
|
|
|
mov [lastkeypressed], ax
|
2020-06-08 22:16:22 +02:00
|
|
|
mov cx, [cursory]
|
|
|
|
dec cx
|
|
|
|
|
|
|
|
updateverticalmovement:
|
|
|
|
cmp cx, LINES - 1
|
|
|
|
jg redraw
|
|
|
|
cmp cx, 0
|
|
|
|
jl redraw
|
|
|
|
mov [cursory], cx
|
|
|
|
jmp redraw
|
2020-06-06 13:17:39 +02:00
|
|
|
|
|
|
|
downkey:
|
|
|
|
cmp ax, [lastkeypressed]
|
|
|
|
je mainloop
|
|
|
|
mov [lastkeypressed], ax
|
2020-06-08 22:16:22 +02:00
|
|
|
mov cx, [cursory]
|
|
|
|
inc cx
|
|
|
|
jmp updateverticalmovement
|
2020-06-06 13:17:39 +02:00
|
|
|
|
|
|
|
space:
|
|
|
|
cmp ax, [lastkeypressed]
|
|
|
|
je mainloop
|
|
|
|
mov [lastkeypressed], ax
|
2020-06-08 22:16:22 +02:00
|
|
|
mov ax, [cursorx]
|
|
|
|
mov cx, [cursory]
|
|
|
|
call uncover
|
2020-06-08 22:44:37 +02:00
|
|
|
mov ax, [cursorx]
|
|
|
|
mov cx, [cursory]
|
|
|
|
call peektable
|
|
|
|
cmp dx, 00009h
|
|
|
|
je gameover
|
2020-06-08 22:16:22 +02:00
|
|
|
jmp redraw
|
2020-06-06 13:17:39 +02:00
|
|
|
|
|
|
|
lalt:
|
|
|
|
cmp ax, [lastkeypressed]
|
|
|
|
je mainloop
|
|
|
|
mov [lastkeypressed], ax
|
2020-06-08 22:21:36 +02:00
|
|
|
mov ax, [cursorx]
|
|
|
|
mov cx, [cursory]
|
|
|
|
call setflag
|
|
|
|
jmp redraw
|
2020-06-06 13:17:39 +02:00
|
|
|
|
2020-06-08 22:21:36 +02:00
|
|
|
getoffset:
|
2020-06-08 22:16:22 +02:00
|
|
|
cmp ax, COLUMNS ;If we are out of bounds, return
|
|
|
|
jl checky
|
|
|
|
ret
|
|
|
|
checky:
|
|
|
|
cmp cx, LINES
|
2020-06-08 22:21:36 +02:00
|
|
|
jl inbounds
|
2020-06-08 22:16:22 +02:00
|
|
|
ret
|
2020-06-08 22:21:36 +02:00
|
|
|
inbounds:
|
2020-06-08 22:16:22 +02:00
|
|
|
push ax ;Calculate offset
|
|
|
|
mov ax, cx
|
|
|
|
mov cx, COLUMNS
|
|
|
|
mul cx
|
|
|
|
mov cx, ax
|
|
|
|
pop ax
|
|
|
|
add ax, cx
|
|
|
|
mov cx, 2
|
|
|
|
mul cx
|
|
|
|
mov bx, map
|
|
|
|
add bx, ax
|
2020-06-08 22:21:36 +02:00
|
|
|
ret
|
|
|
|
|
|
|
|
uncover:
|
2020-06-09 14:07:38 +02:00
|
|
|
push ax ;Save coordinates
|
|
|
|
push cx
|
2020-06-08 22:21:36 +02:00
|
|
|
call getoffset
|
2020-06-09 14:07:38 +02:00
|
|
|
pop cx ;Recover them
|
|
|
|
pop ax
|
2020-06-08 22:16:22 +02:00
|
|
|
mov dx, word [ds:bx] ;Read
|
2020-06-09 14:07:38 +02:00
|
|
|
cmp dh, 00h ;Already uncovered
|
|
|
|
je terminateuncover
|
2020-06-08 22:16:22 +02:00
|
|
|
mov dh, 00h ;Set upperbit as 0
|
|
|
|
mov word [ds:bx], dx
|
2020-06-09 14:07:38 +02:00
|
|
|
cmp dx, 00000h ;If the cell is empty
|
|
|
|
je uncoveraround
|
|
|
|
terminateuncover:
|
|
|
|
ret
|
|
|
|
|
|
|
|
uncoveraround:
|
|
|
|
push ax
|
|
|
|
push cx
|
|
|
|
sub cx, 1
|
|
|
|
test ax, ax
|
|
|
|
jz unaxiszerofirstrow
|
|
|
|
sub ax, 1
|
|
|
|
call uncover
|
|
|
|
add ax, 1
|
|
|
|
unaxiszerofirstrow:
|
|
|
|
call uncover
|
|
|
|
add ax, 1
|
|
|
|
cmp ax, COLUMNS
|
|
|
|
je unaxoutboundsfirstrow
|
|
|
|
call uncover
|
|
|
|
unaxoutboundsfirstrow:
|
|
|
|
pop cx
|
|
|
|
pop ax
|
|
|
|
push ax
|
|
|
|
push cx
|
|
|
|
test ax, ax
|
|
|
|
jz unaxiszerosecondrow
|
|
|
|
sub ax, 1
|
|
|
|
call uncover
|
|
|
|
inc ax
|
|
|
|
unaxiszerosecondrow:
|
|
|
|
inc ax
|
|
|
|
cmp ax, COLUMNS
|
|
|
|
je unaxoutboundssecondrow
|
|
|
|
call uncover
|
|
|
|
unaxoutboundssecondrow:
|
|
|
|
pop cx
|
|
|
|
pop ax
|
|
|
|
push ax
|
|
|
|
push cx
|
|
|
|
add cx, 1
|
|
|
|
test ax, ax
|
|
|
|
jz unaxiszerothirdrow
|
|
|
|
sub ax, 1
|
|
|
|
call uncover
|
|
|
|
add ax, 1
|
|
|
|
unaxiszerothirdrow:
|
|
|
|
call uncover
|
|
|
|
add ax, 1
|
|
|
|
cmp ax, COLUMNS
|
|
|
|
je unaxoutboundsthirdrow
|
|
|
|
call uncover
|
|
|
|
unaxoutboundsthirdrow:
|
|
|
|
pop cx
|
|
|
|
pop ax
|
2020-06-08 22:16:22 +02:00
|
|
|
ret
|
|
|
|
|
2020-06-08 22:21:36 +02:00
|
|
|
setflag:
|
|
|
|
call getoffset
|
|
|
|
mov dx, word [ds:bx] ;Read
|
|
|
|
mov dh, 02h ;Set upperbit as 0
|
|
|
|
mov word [ds:bx], dx
|
|
|
|
ret
|
2020-06-08 22:16:22 +02:00
|
|
|
|
2020-06-06 13:47:22 +02:00
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
2020-06-06 13:17:39 +02:00
|
|
|
;Data segment
|
2020-06-06 13:47:22 +02:00
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
2020-06-06 13:17:39 +02:00
|
|
|
|
2020-06-07 14:10:33 +02:00
|
|
|
segment DataSeg
|
|
|
|
use16
|
|
|
|
|
2020-06-08 20:10:53 +02:00
|
|
|
lastkeypressed: dw 0
|
2020-06-07 17:47:54 +02:00
|
|
|
seed: dw 0
|
|
|
|
minecount: db 0
|
2020-06-08 00:07:37 +02:00
|
|
|
tempnumber: db 0
|
2020-06-08 22:16:22 +02:00
|
|
|
cursorx: dw 0
|
|
|
|
cursory: dw 0
|
2020-06-08 22:44:37 +02:00
|
|
|
gameoverstr: db "Game over!$"
|
|
|
|
youwinstr: db "You win!$"
|
2020-06-07 14:10:33 +02:00
|
|
|
;Game map. First 8 bytes are for the cell status
|
|
|
|
;the last 8 bytes are for the cell contents.
|
|
|
|
;
|
|
|
|
;Cell status: 0 covered, 1 uncovered, 2 flagged
|
|
|
|
;Cell content: 0 empty, 1-8 number, 9 mine
|
2020-06-08 23:13:39 +02:00
|
|
|
paddmapbf: dw COLUMNS dup 00h
|
2020-06-07 18:36:43 +02:00
|
|
|
map: dw COLUMNS * LINES dup 00h
|
2020-06-08 23:13:39 +02:00
|
|
|
paddmapaft: dw COLUMNS dup 00h
|
2020-06-07 14:10:33 +02:00
|
|
|
|
|
|
|
covercell: db 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh
|
|
|
|
db 0fh, 17h, 17h, 17h, 17h, 17h, 17h, 14h
|
|
|
|
db 0fh, 17h, 17h, 17h, 17h, 17h, 17h, 14h
|
|
|
|
db 0fh, 17h, 17h, 17h, 17h, 17h, 17h, 14h
|
|
|
|
db 0fh, 17h, 17h, 17h, 17h, 17h, 17h, 14h
|
|
|
|
db 0fh, 17h, 17h, 17h, 17h, 17h, 17h, 14h
|
|
|
|
db 0fh, 17h, 17h, 17h, 17h, 17h, 17h, 14h
|
|
|
|
db 14h, 14h, 14h, 14h, 14h, 14h, 14h, 14h
|
2020-06-07 17:47:54 +02:00
|
|
|
|
|
|
|
emptycell: db 14h, 14h, 14h, 14h, 14h, 14h, 14h, 14h
|
|
|
|
db 14h, 17h, 17h, 17h, 17h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 17h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 17h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 17h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 17h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 17h, 17h, 17h, 0fh
|
|
|
|
db 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh
|
|
|
|
|
|
|
|
minebmp: db 14h, 14h, 14h, 14h, 14h, 14h, 14h, 14h
|
|
|
|
db 14h, 10h, 17h, 10h, 17h, 17h, 10h, 0fh
|
|
|
|
db 14h, 17h, 10h, 10h, 10h, 10h, 17h, 0fh
|
|
|
|
db 14h, 17h, 10h, 10h, 0fh, 10h, 10h, 0fh
|
|
|
|
db 14h, 10h, 10h, 10h, 10h, 10h, 17h, 0fh
|
|
|
|
db 14h, 17h, 10h, 10h, 10h, 10h, 17h, 0fh
|
|
|
|
db 14h, 10h, 17h, 17h, 10h, 17h, 10h, 0fh
|
|
|
|
db 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh
|
|
|
|
|
|
|
|
flagbmp: db 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh
|
|
|
|
db 0fh, 17h, 17h, 04h, 10h, 17h, 17h, 14h
|
|
|
|
db 0fh, 17h, 04h, 04h, 10h, 17h, 17h, 14h
|
|
|
|
db 0fh, 04h, 04h, 04h, 10h, 17h, 17h, 14h
|
|
|
|
db 0fh, 17h, 17h, 17h, 10h, 17h, 17h, 14h
|
|
|
|
db 0fh, 17h, 17h, 17h, 10h, 17h, 17h, 14h
|
|
|
|
db 0fh, 17h, 10h, 10h, 10h, 10h, 10h, 14h
|
|
|
|
db 14h, 14h, 14h, 14h, 14h, 14h, 14h, 14h
|
2020-06-07 19:24:20 +02:00
|
|
|
|
|
|
|
numone: db 14h, 14h, 14h, 14h, 14h, 14h, 14h, 14h
|
|
|
|
db 14h, 17h, 17h, 17h, 01h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 01h, 01h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 01h, 17h, 01h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 01h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 01h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 01h, 01h, 01h, 01h, 01h, 0fh
|
|
|
|
db 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh
|
|
|
|
|
|
|
|
numtwo: db 14h, 14h, 14h, 14h, 14h, 14h, 14h, 14h
|
|
|
|
db 14h, 17h, 17h, 02h, 02h, 02h, 17h, 0fh
|
|
|
|
db 14h, 17h, 02h, 17h, 17h, 17h, 02h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 17h, 17h, 02h, 0fh
|
|
|
|
db 14h, 17h, 17h, 02h, 02h, 02h, 17h, 0fh
|
|
|
|
db 14h, 17h, 02h, 17h, 17h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 02h, 02h, 02h, 02h, 02h, 0fh
|
|
|
|
db 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh
|
|
|
|
|
|
|
|
numthree: db 14h, 14h, 14h, 14h, 14h, 14h, 14h, 14h
|
|
|
|
db 14h, 17h, 17h, 04h, 04h, 04h, 17h, 0fh
|
|
|
|
db 14h, 17h, 04h, 17h, 17h, 17h, 04h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 17h, 17h, 04h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 04h, 04h, 17h, 0fh
|
|
|
|
db 14h, 17h, 04h, 17h, 17h, 17h, 04h, 0fh
|
|
|
|
db 14h, 17h, 17h, 04h, 04h, 04h, 17h, 0fh
|
|
|
|
db 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh
|
|
|
|
|
|
|
|
numfour: db 14h, 14h, 14h, 14h, 14h, 14h, 14h, 14h
|
|
|
|
db 14h, 17h, 17h, 17h, 05h, 05h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 05h, 17h, 05h, 17h, 0fh
|
|
|
|
db 14h, 17h, 05h, 17h, 17h, 05h, 17h, 0fh
|
|
|
|
db 14h, 17h, 05h, 05h, 05h, 05h, 05h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 17h, 05h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 05h, 05h, 05h, 0fh
|
|
|
|
db 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh
|
|
|
|
|
|
|
|
numfive: db 14h, 14h, 14h, 14h, 14h, 14h, 14h, 14h
|
|
|
|
db 14h, 17h, 06h, 06h, 06h, 06h, 06h, 0fh
|
|
|
|
db 14h, 17h, 06h, 17h, 17h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 06h, 17h, 17h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 06h, 06h, 06h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 17h, 17h, 06h, 0fh
|
|
|
|
db 14h, 17h, 06h, 06h, 06h, 06h, 17h, 0fh
|
|
|
|
db 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh
|
|
|
|
|
|
|
|
numsix: db 14h, 14h, 14h, 14h, 14h, 14h, 14h, 14h
|
|
|
|
db 14h, 17h, 17h, 17h, 2bh, 2bh, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 2bh, 17h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 2bh, 17h, 17h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 2bh, 2bh, 2bh, 2bh, 17h, 0fh
|
|
|
|
db 14h, 17h, 2bh, 17h, 17h, 17h, 2bh, 0fh
|
|
|
|
db 14h, 17h, 17h, 2bh, 2bh, 2bh, 17h, 0fh
|
|
|
|
db 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh
|
|
|
|
|
|
|
|
numseven: db 14h, 14h, 14h, 14h, 14h, 14h, 14h, 14h
|
|
|
|
db 14h, 17h, 35h, 35h, 35h, 35h, 35h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 17h, 17h, 35h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 17h, 35h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 35h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 35h, 17h, 17h, 0fh
|
|
|
|
db 14h, 17h, 17h, 17h, 35h, 17h, 17h, 0fh
|
|
|
|
db 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh
|
|
|
|
|
|
|
|
numeight: db 14h, 14h, 14h, 14h, 14h, 14h, 14h, 14h
|
|
|
|
db 14h, 17h, 17h, 40h, 40h, 40h, 17h, 0fh
|
|
|
|
db 14h, 17h, 40h, 17h, 17h, 17h, 40h, 0fh
|
|
|
|
db 14h, 17h, 17h, 40h, 40h, 40h, 17h, 0fh
|
|
|
|
db 14h, 17h, 40h, 17h, 17h, 17h, 40h, 0fh
|
|
|
|
db 14h, 17h, 40h, 17h, 17h, 17h, 40h, 0fh
|
|
|
|
db 14h, 17h, 17h, 40h, 40h, 40h, 17h, 0fh
|
|
|
|
db 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh, 0fh
|
2020-06-08 22:16:22 +02:00
|
|
|
|
|
|
|
cursorbmp: db 2ah, 2ah, 2ah, 2ah, 2ah, 2ah, 2ah, 2ah
|
|
|
|
db 2ah, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 2ah
|
|
|
|
db 2ah, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 2ah
|
|
|
|
db 2ah, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 2ah
|
|
|
|
db 2ah, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 2ah
|
|
|
|
db 2ah, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 2ah
|
|
|
|
db 2ah, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 2ah
|
|
|
|
db 2ah, 2ah, 2ah, 2ah, 2ah, 2ah, 2ah, 2ah
|