title GOBBLE for SOL name ('GOBBLE') ; DASMed version of the SOL game GOBBLE - Original version ; Race the clock to pick up as many pieces as you can ; Game starts at 0x0000 .phase 0000h esc equ 1bh _NL equ 0feh _EOT equ 0ffh _man equ 07h ; Symbol of player _bush equ 0ch+MSB _dand equ '*' ; Symbol of dandylion _dandv equ _dand+MSB _blnk equ ' '+MSB MSB equ 10000000b NOMSB equ 01111111b _inc equ 25 lcc00 equ 0cc00h VDMRAM equ lcc00 maxrow equ 16 ; Max rows maxcol equ 64 ; Max columns ; vidspc equ maxcol*maxrow ; VidTop equ VDMRAM+vidspc ; End of video ram - xD000 lc000 equ 0c000h ; Warmstart l0580 equ 0580h dandc equ 500 $DANDC macro db '500' endm DELVAL equ 0ffffh ; Max value for delay xy.bc macro x,y ld bc,lcc00+y*maxcol+x endm xy.hl macro x,y ld hl,lcc00+y*maxcol+x endm nop jp l0094 ; Start the game ; l0004: dw 0 ; Score l0006: dw 0 ; Hi score ; ; Get random value into Accu and reg C ; l0008: ld hl,(l0037) ; Fetch pointer ld a,l sub LOW l0037-1 ; Test list scanned jp z,l001c ; Yeap ld a,(hl) ; Get byte inc hl add a,(hl) ; Combine it dec hl ld (hl),a ; Save it ld c,a ; Get value inc hl l0018: ld (l0037),hl ; Store pointer ret l001c: ld a,(l0028) ; Get first entry add a,(hl) ; Add it ld (hl),a ; Bring it back ld c,a ; Get value ld hl,l0028 ; Init pointer jp l0018 ; Reset it ; l0028: db 0feh,013h,095h,062h,087h,0a7h,0b2h db 0a3h,00ch,0f4h,0e6h,0ddh,04ch,001h db 058h l0037: dw l0028 ; ; Clear video memory ; l0039: xy.hl 0,0 ; Init memory pointer l003c: ld (hl),' ' ; Blank memory inc hl ld a,h cp HIGH VidTop jp nz,l003c ret ; ; Output string ^DE to video memory ^BC ; l0046: ld h,b ; Copy memory address ld l,c ld a,(de) ; Get character sub _EOT ; Test empty string ret z ; Yeap ld a,(de) ; Get start column add a,l ; Position video memory jp nc,l0052 inc h ; Fix row l0052: ld l,a l0053: inc de ld a,(de) ; Get character sub _NL ; Test new line jp nz,l0066 ; Nope inc de ld a,c add a,maxcol ; Advance columns jp nc,l0062 inc b ; Next row l0062: ld c,a jp l0046 ; Output next l0066: ld a,(de) ; Get character ld (hl),a ; Put to screen inc hl jp l0053 ; ; Increment ASCII ^HL by value in DE ; l006c: ld a,e ; Get value or d ; Test zero ret z ; Yeap, done dec de ; Count down ld c,l ; Save column l0071: inc (hl) ; Increment digit ld a,(hl) ; Get digit and NOMSB ; Strip off attribute cp '9'+1 ; Test overflow jp z,l007e ; Yeap ld l,c ; Reset column jp l006c ; Go on with increment l007e: ld a,(hl) ; Get back digit sub 10 ; Fix it ld (hl),a ; Bring it back dec l ; Position to previous digit jp l0071 ; Increment this one ; ; Get character - Z set no character there ; l0086: in a,(0fah) ; Get state of keyboard cpl and 1 ; Test key pressed ret z ; Nope in a,(0fch) ; Get key cp esc ; Test abort jp z,lc000 ; Yeap ret ; ; #################### ; ### Start GOBBLE ### ; #################### ; l0094: sub a out (0feh),a ; Clear VDM port call l0039 ; Clear video memory xy.bc 0,0 ; Init video address ld de,l02f7 call l0046 ; Tell the rules l00a3: call l06bc ; Get acception jp z,l00a3 ; Not yet cp ' ' ; Test real acception jp nz,l00a3 ld hl,0 ld (l0006),hl ; Init hi score ; ; Start next field ; l00b4: ld hl,0 ld (l0004),hl ; Clear score call l02b8 ; Init game board xy.bc 0,0 ; Init video address ld de,l0628 call l0046 ; Init score line xy.bc 0,15 ; Position video memory ld de,l067f call l0046 ; Tell waiting for key to be pressed xy.hl 0,0 ; Set left side call l0104 ; Blank left vertical line xy.hl maxcol-1,0 call l0104 ; Blank right vertical line xy.hl 0,0 call l0115 ; Hilite first line xy.hl 0,15 ; Position video memory call l0115 ; Hilite last line ld hl,(l0006) ; Get hi score ex de,hl xy.hl 55,0 ; Position video memory call l006c ; Increment ASCII by score value ld a,_man ; Init player ld (lcc00+7*maxcol+32),a l00f6: call l0086 ; Get character jp z,l00f6 ; Nothing here sub a ld (l0103),a ; Init bush count jp l013d ; l0103: db 0 ; Bush count ; ; Blank vertical line ; l0104: ld (hl),_blnk ld a,l add a,maxcol ; Advance line ld l,a jp nc,l0104 inc h ld a,h cp HIGH VidTop ; Test end jp nz,l0104 ret ; ; Hilite one line ; l0115: ld b,maxcol ; Set count l0117: ld a,(hl) ; Get character or MSB ; Set hilite ld (hl),a inc hl dec b jp nz,l0117 ret ; ; Blank last line ; l0121: xy.hl 0,15 ; Set video memory l0124: ld (hl),_blnk inc hl jp l06b0 ; l012a: dw 0 ; Dandylion count l012c: dw 0 ; Current dandylions l012e: dw lcc00+7*maxcol+32 ; ; Fill screen with dandylions ; l0130: xy.hl 0,1 ; Init line l0133: ld (hl),_dandv ; Fill it inc hl ld a,h cp HIGH VidTop ; Test end jp nz,l0133 ret ; ; Real game play ; l013d: call l0130 ; Fill screen with dandylions ld hl,0 ld (l012c),hl ; Clear current dandylions ld hl,l0580 ld (l012a),hl ; Init dandylion count xy.hl 32,7 ld (l012e),hl ; Set player position ld (hl),_man ; Set player xy.hl 0,0 call l0104 ; Blank left vertical line xy.hl maxcol-1,0 call l0104 ; Blank right vertical line call l0121 ; Blank last line ld a,(l0103) ; Get bush count add a,_inc ; Increment it ld (l0103),a ld b,a ; Get it l016c: call l0008 ; Get random value xy.hl 0,0 ; Init video memory l0172: sub maxcol ; Test random jp c,l017b inc h ; Point to next row jp l0172 l017b: ex de,hl call l06b7 ; Get random value ld l,a ; Set as column pointer ld a,(hl) ; Get piece cp _dandv ; Test dandylion jp nz,l016c ; Nope, try next ld (hl),_bush ; Overwrite it by bush dec b ; Test all bushes set jp nz,l016c ; Nope jp l06d2 ; Init direction ; ; Direction table ; l018f: db 0 ; Current direction l0190: db maxcol-1 ; 1: Down left db maxcol ; 2: Down db maxcol+1 ; 3: Down right db 2*maxcol+1 ; 4: Left db 0 ; 5: No move db 1 ; 6: Right db -(maxcol-1) ; 7: Up left db -(maxcol) ; 8: Up db -(maxcol+1) ; 9: Up right ; ; Entered with clock count in reg B ; l0199: ld c,255 ; Set more count l019b: call l0086 ; Get character jp z,l01b9 ; Nothing here cp '1' ; Veriy 1..9 jp c,l01b9 cp '9'+1 jp nc,l01b9 sub '0' ; Make digit 1..9 ld hl,l0190-1 ; Init pointer l01b0: inc hl ; Position to direction dec a jp nz,l01b0 ld a,(hl) ; Get direction ld (l018f),a ; Save it l01b9: dec c jp l06c8 ; Test clock remaining l01bd: ld a,(l018f) ; Get direction or a ; Test any jp z,l01f9 ; Nope ld hl,(l012e) ; Get player position ld c,a and MSB ; Test up direction jp nz,l01d7 ; Yeap ld a,l add a,c ; Add direction ld l,a jp nc,l01e2 inc h jp l01e2 l01d7: ld a,c and NOMSB ; Strip off bit ld c,a ld a,l sub c ; Do up direction ld l,a jp nc,l01e2 dec h l01e2: ld a,(hl) ; Get piece cp _dandv ; Test dandylion jp z,l0227 ; Yeap cp ' ' ; Test empty place jp nz,l01f9 ; Nope ; ; Move player ; l01ed: ex de,hl ld hl,(l012e) ; Get player position ld (hl),' ' ; Clear it ex de,hl ; Get back current position ld (hl),_man ; Set player ld (l012e),hl ; Set new player position ; ; No direction selected ; l01f9: ld hl,(l012a) ; Get dandylion count dec hl ; Count down ld (l012a),hl ld a,h or l ; Test still any remaining jp nz,l06c3 ; Yeap, reset counter ld hl,(l012c) ; Get current dandylions ex de,hl ld hl,(l0004) ; Get score ld a,l add a,e ; Add dandylions ld l,a ld a,h adc a,d ld h,a ld (l0004),hl ; Set new score ld a,d cp HIGH dandc ; Test next field jp c,l0268 ; Yeap jp nz,l0262 ld a,e cp LOW dandc jp c,l0268 jp l0262 ; ; Found dandylion ; l0227: ld (l023b),hl ; Save current dandylion position ld hl,(l012c) ; Get current dandylions inc hl ; Update it ld (l012c),hl xy.hl 18,0 ld de,1 call l006c ; Increment ASCII by one l023b equ $+1 ld hl,$-$ jp l01ed ; Go on ; ; Preset game board ; l0240: call l0130 ; Fill screen with dandylions xy.hl 0,15 ; Point to last line call l003c ; Blank last line ret ; ; Mark remaining dandylions ; l024a: xy.hl 0,0 ; Init video memory l024d: ld a,(hl) cp _dandv ; Test dandylion jp nz,l0255 ; Nope ld (hl),_dand ; Mark normal l0255: inc hl ld a,h cp HIGH VidTop ; Test memory scanned jp nz,l024d ; Not yet ld hl,DELVAL jp l02bf ; Then erase game board ; ; This field done ; l0262: call l024a ; Mark remaining dandylions jp l013d ; Next game ; ; Enter next field ; l0268: call l024a ; Mark remaining dandylions call l0039 ; Clear video memory xy.bc 0,1 ; Set video memory ld de,l065c call l0046 ; Init eat line of dandylions ld hl,(l0004) ; Get score ex de,hl xy.hl 19,1 call l006c ; Increment ASCII by score ld hl,(l0004) ; Get score ex de,hl ld hl,(l0006) ; Get hi score ld a,l sub e ; Test max of it ld a,h sbc a,d jp nc,l029c ; Nope xy.bc 0,4 ex de,hl ld (l0006),hl ; Set hi score ld de,l069a call l0046 ; Tell new hi score l029c: xy.bc 0,7 ld de,l057e call l0046 ; Tell rating, ask for more l02a5: call l0086 ; Get character jp z,l02a5 ; Nothing here cp 'N' ; Test no more jp z,lc000 ; Exit if so cp 'Y' ; Test more jp nz,l02a5 jp l00b4 ; Restart ; ; Init game board ; l02b8: call l0039 ; Clear video memory call l0240 ; Preset game board ret ; ; Erase game board ; l02bf: dec hl ; Delay a bit ld a,h or l jp nz,l02bf xy.hl 0,0 ; Init video memory l02c8: ld a,(hl) ; Get board entry cp _dand ; Test dandylion jp nz,l02d0 ; Nope ld (hl),' ' ; Clear it l02d0: inc hl ld a,h cp HIGH VidTop ; Test all scanned jp z,l02ed ; Yeap ld a,l ; Get position l02d8: or a ; Test boundary jp z,l02e4 ; Yeap sub maxcol jp c,l02c8 ; Test within line jp l02d8 l02e4: ld a,DELVAL l02e6: dec a ; Short delay jp nz,l02e6 jp l02c8 l02ed: ld hl,DELVAL l02f0: dec hl ; Final delay ld a,h or l jp nz,l02f0 ret ; l02f7: db 27 db 'GOBBLE ''EM' db _NL db 0 db _NL db 25 db 'BY RAY G WHITE' db _NL db 0 db _NL db 2 db 'The object of this game is to move your man (',_man,') around the' db _NL db 0 db 'screen eating all the dandylions (',_dandv,') while avoiding the' db _NL db 15 db 'bushes (',_bush,'). You may move your man according to' db _NL db 0 db '7 8 9 the grid shown to the left by pressing the' db _NL db 2 db '\ ! / appropriate key for each direction. You only have' db _NL db 0 db '4 - 5 - 6 a limited time to eat the dandylions before they' db _NL db 2 db '/ ! \ dry up and blow away. However, each time you eat' db _NL db 0 db '1 2 3 ' $DANDC db ' or more dandylions in a single field you' db _NL db 15 db 'will have enough energy to walk to the next field' db _NL db 0 db 'to eat some more. Otherwise you will die of starvation.' db _NL db 0 db _NL db 19 db '*PRESS SPACE TO CONTINUE*' db _NL db _EOT l057e: db 0 db 'RATINGS: 0000-0999: WEED WHIP' db _NL db 14 db '1000-2499: SCYTHE' db _NL db 14 db '2500-4999: MOWER' db _NL db 14 db '5000-9999: HARVESTER' db _NL db 14 db '10000+ : SUPER HARVESTER' db _NL db 0 db _NL db 0 db 'ANOTHER GAME? (Y OR N)' db _NL db _EOT l0628: db 7 db 'SCORE: 00000 HIGH SCORE: 00000' db _NL db _EOT l065c: db 0 db 'YOU HAVE EATEN 00000 DANDYLIONS.' db _NL db _EOT l067f: db 20 db '*PRESS ANY KEY TO START*' db _NL db _EOT ; ; Hilite version of ' NEW HIGH SCORE! ' ; l069a: db 8 db 0a0h,0ceh,0c5h,0d7h,0a0h,0c8h,0c9h db 0c7h,0c8h,0a0h,0d3h,0c3h,0cfh,0d2h db 0c5h,0a1h,0a0h db _NL db _EOT,_EOT,_EOT ; ; ### PATCH AREA ### ; ; Routine l0121 cont'd ; l06b0: ld a,h cp HIGH VidTop ; Test end jp nz,l0124 ; Nope ret ; ; Get random value ; l06b7: call l0008 ; Get random value ex de,hl ret ; ; Init random and wait for key pressed ; l06bc: call l0008 ; Get random value call l0086 ; Get character ret ; ; Init count and play the game ; l06c3: ld b,5 jp l0199 ; ; Routine l01b9 cont'd ; l06c8: jp nz,l019b ; Still more tries dec b ; Test total end jp nz,l0199 ; Nope jp l01bd ; ; Clear direction and start the game ; l06d2: sub a ld (l018f),a ; Clear direction jp l06c3 ; Then go ; l06d9:: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0 l06f4:: .dephase end