;This program uses the mouse to play a tile game on the screen ;Written by Dan Gookin, whotta guy ;05/10/1986 @ 21:53:26 ;06/17/1988 @ 21:00:00 Updated CODE segment TILE proc far assume cs:CODE Org 100h ;set up equates cr equ 0dh ;carriage return lf equ 0ah ;line feed eof equ 1ah ;^Z, end of file,line ;define any macros; Mouse macro x mov ax,x int 33h endm Dosfc macro x mov ah,x int 21h endm Retrace macro local R1 push dx ;save regs push ax mov dx,3dah ;video input register R1: in al,dx ;retrace check and al,1 ;if al = 1, ok dec al ;if al = 0, in retrace jnz R1 pop ax ;restore regs pop dx endm ;---------------------------------------; Entry: jmp Start ;jump over crap db eof ;stop a list cold Screen: ;36 x 11 db 11 ;bp+0 = rows db 36 ;bp+1 = columns dw 184 ;bp+2 = position on screen dw $+2 ;location db "ÖNÄNÂNÄNÄNÄNÄNÄNÄNÄNÄNÄNÄNÄNÄNÄNÄN¿N" ;bp+4 db "ºNþN³N N pMpopupspepTpiplpepsp p N³N" db "ÌNÍNÏNÍNËNÍNÍNÍNËNÍNÍNÍNËNÍNÍNÍN»N³N" db "ºN N1N NºN N2N NºN N3N NºN N4N NºN³N" db "ÌNÍNÍNÍNÎNÍNÍNÍNÎNÍNÍNÍNÎNÍNÍNÍN¹N³N" db "ºN N5N NºN N6N NºN N7N NºN N8N NºN³N" db "ÌNÍNÍNÍNÎNÍNÍNÍNÎNÍNÍNÍNÎNÍNÍNÍN¹N³N" db "ºN N9N NºN NAN NºN NBN NºN NCN NºN³N" db "ÌNÍNÍNÍNÎNÍNÍNÍNÎNÍNÍNÍNÎNÍNÍNÍN¹N³N" db "ºN NDN NºN NEN NºN NFN NºN N N NºN³N" db "ÈNÍNÍNÍNÊNÍNÍNÍNÊNÍNÍNÍNÊNÍNÍNÍN¼N³N" Help: ;76 x 9 db 9 db 76 dw 1328 dw $+2 db "ÉpÍpËpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍp" db "ÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍp»p" db "ºpþtºp / / /W/r/i/t/t/e/n/ /B/y/ /D/a/" db "n/ /G/o/o/k/i/n/ / /(/c/)/1/9/9/0/ /ºp" db "ÇpÄpÐpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp" db "ÄpÂpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp¶p" db "ºp /L!e!t!t!e!r!s! ! ! ! ! ! ! ! ! / /" db " /³p /þ$ /C/h/e/a/t/ / / / / / / / /ºp" db "ºp /Z/ /t/o/ /L/ /L/e/t/t/e/r/s/ / / /" db " /³p /þ$ /S/c/r/a/m/b/l/e/!/ / / / /ºp" db "ºp /P/o/k/e/r/d/e/c/i/m/a/l/ / / / / /" db " /³p /þ$ /R/e/s/e/t/ /T/i/l/e/s/ / /ºp" db "ºp /M/y/s/t/e/r/y/ /S/y/m/b/o/l/s/ / /" db " /ÆpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍp¹p" db "ºp /M/o/u/s/e/t/i/l/e/s/ /F/u/n/!/ / /" db " /³p / /S/c/o/r/e/:/ / /9/9/9/" Splace: db "9/ / /ºp" db "ÈpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍp" db "ÍpÏpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍpÍp¼p" ;keeps track of rnd values: array db 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0h ;tile map, shows tiles on screen: tiles db 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0h ;character tables; letter db "ABCDEFGHIJKLMNO",0h backw db "ZYXWVUTSRQPONML",0h poker db 0ach,0abh,"A23456789TJQK",0h myst db 128,146,155,156,157,158,169,170 db 206,219,241,247,249,251,254,0h idon db "MousetilES fUn!",0 nomouse db "-- Mouse driver not installed --",cr,lf,"$" S_MODE dw 0000h ;screen mode SAVE1 dw 0000h ;cursor position storage TMOVES dw 0000h ;total moves CTYPE db 01h ;character type ;1 = anglo letters ;2 = backwards letters ;3 = poker ;4 = myst ;5 = Mousetiles fun ;---------------------------------------; Start: Mouse 0 ;Mousefunction call 0 inc ax ;test for software there jz ok1 ;if zero, everything ok ;no mouse present, display error and exit mov dx,offset nomouse ;"Mouse driver not..." Dosfc 09h ;Function call 9 - display$ int 20h ;generic bail to dos ;Mouse installed, display screen, show mouse cursor ok1: int 11h ;get equipment list and al,30h ;check for mono display cmp al,30h ;if mono mov ax,0b800h ;for color jnz color ;goto color mov ax,0b000h ;mono address color: mov es,ax ;point extra segement at... mov s_mode,ax mov bh,0 ;current screen page mov ah,3 ;get cursor position int 10h ;bios video interrupt mov bx,offset SAVE1 mov word ptr [bx],dx ;save starting location ;draw the screen mov bp,offset Screen call Dscreen ;draw the screen call Zipup ;do noise cmp s_mode,0b800h ;are we talking color? jnz bandw_1 mov bx,1 ;select hardware cursor mov cx,1 ;start scan line mov dx,5 ;end scan line (CGA) Mouse 10 ;Set text cursor jmp update_1 bandw_1: mov bx,1 mov cx,1 mov dx,10 ;end scan line (MONO) Mouse 10 update_1: mov cx,160 ;horz/col position mov dx,56 ;vert/row position Mouse 4 ;set cursor position Mouse 1 ;show cursor Restart: ;entry point of restart mov bx,offset TMOVES ;reset moves mov word ptr [bx],0h ; to zero call Eggs ;scramble tiles on screen ;play the game Main: call Sloop ;get data cmp cx,020dh ;row 2, col 13 = go away jz Exit cmp ch,2 ;if second row, could be help jnz M01 cmp cl,10h jl Main cmp cl,1bh jg Main call Hquest ;get help jmp Main M01: cmp cl,13 ;check bounds far left jl Main cmp cl,27 ;far right jg Main cmp ch,4 ;top jl Main cmp ch,10 ;bottom jg Main call Play ;play the game jmp Main ;continue else Exit: cmp s_mode,0b800h ;are we talking color? jnz bandw_2 mov bx,1 ;select hardware cursor mov cx,6 ;start scan line mov dx,7 ;end scan line (CGA) jmp update_2 bandw_2: mov bx,1 mov cx,12 ;default for MONO mov dx,13 update_2: Mouse 10 ;Set text cursor mov bx,offset SAVE1 mov dx,word ptr [bx] ;starting location add bx,2 mov cx,word ptr [bx] mov bh,0 ;current screen page mov ah,2 ;set cursor position int 10h ;bios video interrupt mov bp,offset Screen call Dscreen ;replace old screen call Zipdn ;end sound push ds pop es Mouse 2 ;hide cursor mov ax,4c00h ;(proper) int 21h ;exit TILE endp ;------------------------------------------; ;scramble the array, place tiles on screen ; ;------------------------------------------; Eggs proc near call Build ;structure the array mov di,offset tiles ;build tile pattern on screen mov bl,10h ;loop count mov ah,0 ;get the time of day int 1ah ;time of day BIOS call rnd: add dx,9248h ;reseed the rnd value mov cl,3 ;rotation value ror dx,cl mov al,dl ;sto value in al and al,0fh ;adjust value to inc al ; 1 to 16 mov si,offset array-1 ;point si at array buffer mov ch,0 mov cl,al ;get looping count E01: inc si ;put a dot '.' in value's loop E01 ; position in array. cmp byte ptr [si],2eh ;Is a '.' already there? jz rnd ;if so, fetch another value and al,0fh ;make rnd# from 0 to fh mov [di],al ;place rnd# into tile grid inc di ;point at next tile mov byte ptr [si],2eh ;mark array as used dec bl ;test for end of loop jnz rnd call Build ;restructure array for matching ;Get character type: call GCT ;get char, put on screen Eggs endp ;---------------------------------------; ; Build the array, fill w/10h...1h ; ;---------------------------------------; Build proc near mov bx,offset array ;build array mov cx,10h mov al,0 Eloop: and al,0fh ;from 0-fh mov [byte ptr bx],al ;fill array w/15-0 inc bx inc al loop Eloop ret Build endp ;---------------------------------------; ; Put tiles on screen based on ; ; pattern in array tiles. ; ;---------------------------------------; GCT proc near mov al,byte ptr [CTYPE] ;point at char table value mov bx,offset tiles ;first choice - 10h E02: add bx,10h ;point bx at correct value dec al jnz E02 ;loop until match found mov di,bx ;point di at the table ;put the characters on the screen: ;put tile [di] on screen mov si,offset tiles ;get rnd values into si mov cx,10h ;all tiles mov al,0 Put1: push cx ;save count mov bx,di ;set location into bx dec bx ;for loop mov cl,[si] mov ch,0 ;looping value inc cl ;for loop P01: inc bx ;point to proper char for cell loop P01 mov dl,[bx] ;dl = char mov dh,al ;get tile# into dh call Chrtile ;put dl @ dh inc si ;point to next tile inc al pop cx loop Put1 ret GCT endp ;--- Chrtile proc near ;put tile dl on screen dh mov bx,668 ;offset inc dh ;for z flag test CH0: mov cx,4 ;four column positions CH1: dec dh ;are we at right column? jz Found ;if so, go! add bx,8 ;else, add to next column loop CH1 add bx,288 ;skip two rows jmp CH0 Found: Retrace ;no FUZZ! mov es:[bx],dl ;put tile on screen ret Chrtile endp ;---------------------------------------; ; Display help request ; ;---------------------------------------; Hquest proc near call Calc ;figure the score mov bp,offset Help call Dscreen ;display helpwindow call Zipup ;sound Eeek! Hq0: call Sloop ;just return on mouse press cmp cx,919h ;is an exit? jz Hexit ;leave this box cmp ch,11 ;top jl Hq0 cmp ch,15 ;bottom jg Hq0 cmp cl,46 ;if < col 46 jl Hless ; check left side cmp cl,60 ;if < col 59 jl Hover ; do right side jmp Hq0 ;otherwise, ignore Hless: cmp cl,26 ;far left jl Hq0 ;loop back if less cmp cl,42 ;far right jg Hq0 ;all the way! sub ch,10 ;get new column # into cl mov al,ch ;get new pattern into al call Hilite ;hilight it jmp Hq0 ;don't exit on tile call Hover: sub ch,10 ;make cl > 0, = 1 dec ch ;check for cheat jnz Gsco ;if not, scramble call Dscreen ;erase screen call Docht ;Cheat and exit call Zipdn ;noise ret ;get out of here Gsco: ;scramble the tiles dec ch Jnz Hreset call Dscreen call Eggs ;Reset and Scramble call Zipdn ret Hreset: dec ch jnz Hq0 ;don't leave yet call Dscreen ;close help window call Zipdn ;sound sub sp,2 ;get this address off stack jmp Restart ;reset from day 1 Hexit: ;just leave call Dscreen call Zipdn ;erase screen ret Hquest endp ;--- Hilite proc near ;highlight tile pattern on screen mov bx,offset CTYPE ;get current pattern mov ah,[bx] ; into ah push ax ;save values sub ah,al ;test for the same pop ax jnz notsam ;they're not the same ret ;return if the same place notsam: mov [bx],al ;Update new pattern mov bx,1813 ;lowlight current pattern HL0: dec ah ;old pattern in ah jz HL01 add bx,160 jmp HL0 ;loop 'till found HL01: mov cx,15 ;lenght of pattern to fill HL1: Retrace mov byte ptr es:[bx],2fh ;lowlight pattern add bx,2 loop HL1 ;now, highlight the new pattern mov bx,1813 ;highlight current pattern HL2: dec al ;new pattern in al jz HL02 add bx,160 jmp HL2 ;loop 'till found HL02: mov cx,15 ;lenght of pattern to fill HL3: Retrace mov byte ptr es:[bx],21h ;turn on highlight add bx,2 loop HL3 ;for whole row ret Hilite endp ;---------------------------------------; ; This procedure plays the tile game ; ; and moves the tiles ; ;---------------------------------------; Play proc near mov dx,040dh ;upper/left corner r4/c13 mov al,0 ;cell number Prow: cmp ch,dh ;test for first row jz fndrow ;we found the row add dh,2 ;check nex valid row add al,4 ;boost cell count cmp dh,11 ;too far jl Prow ;continue Pout0: ret ;fucking processor error fndrow: cmp cl,dl ;test for correct column jz Pover ;found it inc dl ;test middle cmp cl,dl jz Pover inc dl ;test final cmp cl,dl jz Pover ;is in this column inc al ;point to next column add dl,2 ;skip boundary and point to next cmp dl,28 jl fndrow jmp Pout0 ;leave out of bounds Pover: ;cell is in al, offset = 0 ;is blank tile next to this one? mov bx,offset tiles-1 ;set up pointers mov cl,al ;set up loop inc cl ;adjust for offset 0 mov ch,0 Pl0: inc bx loop Pl0 ;point at proper tile value mov si,bx mov di,bx ;set up pointers ;find tile cmp al,4 jl Plow ;don't look above board sub di,4 ;look down four mov ah,[di] cmp ah,15 ;test for zero jz Pcont Plow: cmp al,11 jg Phi ;don't look below board mov di,bx ;align them again add di,4 ;look up four mov ah,[di] cmp ah,15 ;test jz Pcont Phi: cmp al,0 ;test left values jz Pleft cmp al,4 jz Pleft cmp al,8 jz Pleft cmp al,12 jz Pleft mov di,bx ;align tiles dec di ;look left mov ah,[di] cmp ah,15 ;test for null jz Pcont Pleft: cmp al,3 ;test right values jz Pout ;if eliminated, go! cmp al,7 jz Pout cmp al,11 jz Pout cmp al,15 jz Pout mov di,bx ;alignmentaryous inc di ;look right mov ah,[di] cmp ah,15 jnz Pout ;leave! Pcont: ;if yes, move tile in array mov al,[si] ;swap values in array mov ah,[di] mov [si],ah mov [di],al call GCT call Tick mov bx,offset TMOVES ;increment move counter inc word ptr [bx] ;is this a win? mov si,offset array ;to compare to mov di,offset tiles mov cx,10h ;all of them Pwin: mov al,[si] mov ah,[di] cmp al,ah ;all must match jnz Pout ;leave if not inc si inc di ;point to next loop Pwin call Popeye ;if win, play song Pout: ret Play endp ;---------------------------------------; ; Main Scan Loop ; ; CL = column, CH = row ; ; returns iff button down ; ;---------------------------------------; Sloop proc near mov ah,1 ;read keyboard status int 16h jz Sloop_0 ;no key waiting mov ah,0 ;read the key int 16h cmp ah,1 ;is it ESC? ; ; add routines to use arrow keys here ; jnz Sloop_0 ;keep going mov cx,020dh ;row 2, col 13 = go away ret ;force an exit Sloop_0: Mouse 3 ;get location, button xchg cx,ax ;change for multiplication ror ax,cl ror dx,cl ;divide row/column by 8 xchg cx,ax ;replace cx mov ch,dl ;update vertical location and bl,3 ;if al=0 zr flag set, else button jz Sloop ;jump if button not down ret Sloop endp ;---------------------------------------; ; Display/Erase tile on screen ; ;---------------------------------------; Dscreen proc near mov cl,[bp+0] ;number of rows mov ch,0 mov si,[bp+4] ;spare memory mov di,[bp+2] ;place on screen Row1: push cx ;save row count mov cl,[bp+1] ;number of columns Col1: ;ch already 0 mov al,[si] push ax ;RETRACE CHECK mov dx,3dah ;video input register in al,dx ;retrace check and al,1 ;if al = 1, ok dec al ;if al = 0, in retrace jnz $-5 ;R1 pop ax ;restore reg mov ah,es:[di] mov [si],ah push ax ;RETRACE CHECK in al,dx ;retrace check (dx saved) and al,1 ;if al = 1, ok dec al ;if al = 0, in retrace jnz $-5 ;R1 pop ax ;restore reg mov es:[di],al inc si inc di loop Col1 mov ah,[bp+1] ;length of window mov al,160 ;length of screen sub al,ah mov ah,0 ;cbw not valid for > 128 add di,ax ;offset of next row pop cx ;get row count back loop Row1 ;do all eleven rows ret Dscreen endp ;---------------------------------------; ; Calculate score and update memory ; ;---------------------------------------; Calc proc near mov bx,word ptr [TMOVES] ;get total moves mov si,offset Buff ;storage buffer mov di,offset t10 Calc0: xor al,al ;zero decimal value mov cx,word ptr [di] ;get power of ten Calc1: or al,al ;clear carry bit sub bx,cx jb Calc2 ;jump if less inc al ;boost decimal value jmp Calc1 Calc2: add al,30h ;make al decimal add bx,cx mov byte ptr [si],al ;update count inc si ;next digit add di,2 ;next value cmp cl,1 ;if cl=1 then end jnz Calc0 mov bx,offset Buff ;pad spaces mov cx,4 Cspc: mov al,[bx] cmp al,'0' ;is it a zer0? jnz Cs0 ;if not, go on... mov byte ptr [bx],' ' ;if so, put a space there inc bx loop Cspc Cs0: mov bx,offset Splace ;update score in box mov si,offset Buff+4 mov cx,5 ;five digits Calc3: mov al,[si] ;get number mov [bx],al ;update sub bx,2 ;backspacing dec si ;back to start loop Calc3 ret t10: dw 10000 dw 1000 dw 100 dw 10 dw 1 Buff: db "00000" Calc endp ;---------------------------------------; ; Cheat you somobtch ; ;---------------------------------------; Docht proc near mov bx,offset tiles ;update tile pattern mov al,0 ;start with one mov cx,14 ;All but last one Doch0: mov [bx],al ;build new array inc al inc bx loop Doch0 mov byte ptr [bx],15 ;almost there inc bx mov byte ptr [bx],14 ;last two switched call GCT ret Docht endp ;---------------------------------------; ; Sound generation routines ; ;---------------------------------------; Zipup proc near mov bx,104h ;produces zipping up sound mov al,4ch D0: xor al,2 out 61h,al mov cx,bx ;Pause mov ah,0 ;read BIOS clock int 1ah ;BIOS read tick counter add dx,3 mov bx,dx ;save here D1: ;this will key the song to mov ah,0 ;the timer--not the CPU int 1ah cmp dx,bx ;are they equal? jnz D1 ;continue here dec bx jnz D0 ret Zipup endp Zipdn proc near ;produces zipping down sound mov bx,10h mov al,4ch D2: xor al,2 out 61h,al mov cx,bx ;Pause mov ah,0 ;read BIOS clock int 1ah ;BIOS read tick counter add dx,3 mov bx,dx ;save here D3: ;this will key the song to mov ah,0 ;the timer--not the CPU int 1ah cmp dx,bx ;are they equal? jnz D3 ;continue here inc bx cmp bx,140h jle D2 ret Zipdn endp Tick proc near ;produces light ticking noise mov bx,0 mov al,4ch D4: xor al,2 out 61h,al mov cx,28h ;Pause mov ah,0 ;read BIOS clock int 1ah ;BIOS read tick counter add dx,1 mov bx,dx ;save here D5: ;this will key the song to mov ah,0 ;the timer--not the CPU int 1ah cmp dx,bx ;are they equal? jnz D5 ;continue here inc bx cmp bx,3fh jnz D4 ret Tick endp Popeye proc near mov si,offset Polay Phere: mov al,[si] inc si cmp al,128 jz Pexit cmp al,255 jnz Poyer PPoz: mov cx,4000h loop $ jmp Phere Pexit: ret Poyer: shl al,1 cbw mov bx,ax mov ax,0 mov dx,12h div word ptr ds:[Ptbl+bx] mov bx,ax ; mov al,0b6h out 43h,al mov ax,bx out 42h,al mov al,ah out 42h,al in al,61h or al,3 out 61h,al ;Pause mov ah,0 ;read BIOS clock int 1ah ;BIOS read tick counter add dx,2 mov bx,dx ;save here MDM_1: ;this will key the song to mov ah,0 ;the timer--not the CPU int 1ah cmp dx,bx ;are they equal? jnz MDM_1 ;continue here in al,61h and al,0fch out 61h,al jmp Phere Ptbl: dw 262 ;C 0 dw 330 ;E 1 dw 349 ;F 2 dw 392 ;G 3 dw 440 ;A 4 dw 494 ;B 5 dw 523 ;C5 6 dw 131 ;C6 7 Polay: db 255 ;initial delay db 1,3,3,3,2,1,3,255 db 3,4,1,4,6,4,3,255 db 3,4,2,4,6,5,4,3,4,3,1,0 db 1,3,3,3,4,5,6,255,7,7,128 Popeye endp ;---------------------------------------; CODE ends end Entry