X-Git-Url: http://git.shiar.net/wormy.git/blobdiff_plain/0e077b916a6dd54a2d1140fdcfea5c783e4961cd..711d2428b9a29f7c412e208f87f109b9671424a3:/wormy.z80 diff --git a/wormy.z80 b/wormy.z80 index 447f511..b7db1ce 100644 --- a/wormy.z80 +++ b/wormy.z80 @@ -40,8 +40,9 @@ ;----------------------------- #define buffer ;use display buffer (otherwise write directly to screen) -#define readymask ;"grays" out the field before starting a level +#define readymask ;"greys" out the field before starting a level ;#define hlines ;horizontal-line routine for more speed drawing boxes + ;(doesn't work properly) ;#define readytext ;displays "prepare" before level starts ;#define invincible ;worms cannot die =) @@ -53,12 +54,12 @@ #include "asm86.h" #include "ti86asm.inc" -_SHRACC = $4383 -_SHLACC = $438B +_SHRACC = $4383 ;4x srl a +_SHLACC = $438B ;4x sll a _divHLby10 = $4044 ;hl=hl/10 _divAby10 = $4DAF ;a=a/10 _HLTIMES10 = $41BF ;hl=hl*10 -_cphlde = $403C +_cphlde = $403C ;cp hl,de _clrWindow = $4A86 ;clear screen _asapvar = $D6FC ;own name (worm) _MOV4B = $429B ;4x ld (de),(hl) @@ -76,7 +77,7 @@ _SET_ABS_DEST_ADDR = $5285 ;set destination for mm.ldir = ahl _SET_MM_NUM_BYTES = $464F ;number of bytes for mm.ldir = ahl _mm_ldir = $52ED ;24bit ldir _RAM_PAGE_1 = $47E3 ;set $8000+ to page 1 -_RAM_PAGE_7 = $47F3 +_RAM_PAGE_7 = $47F3 ;"""" 7 _PTEMP_END = $D29A ;end of VAT _load_ram_ahl = $462F ;ahl->page+hl _writeb_inc_ahl = $5567 ;ld (ahl),c @@ -136,7 +137,7 @@ start: .dw WormIcon WormTxt: - .db "WORMY by SHIAR -- alpha 93%",0 + .db "WORMY by SHIAR -- beta 93%",0 WormIcon: .db 9,2 .db %10010110,%01101111 @@ -412,12 +413,10 @@ levelloaded: ld hl,datasingle+3 ld b,8 + ld de,8 setdeflevels: ld (hl),1 ;def=level#1 - inc hl - inc hl - inc hl - inc hl + add hl,de ;next dnz setdeflevels ;----------------------------- @@ -452,14 +451,37 @@ NegativeSineWave: ;----------------------------- DisplayMenu: ;---draw menu--- + cal linkok cal _clrWindow ld de,$FC40 ;(0,4) ld hl,wtPicture ld bc,16*16 ldir - + ld hl,$FC00+$160 + cal hr + ld hl,$FC00+$3E0 + cal hr +dispmainmenu: + ld hl,dispmenusets ;mainMenu + psh hl ;jump here after ret ld hl,txtMenu ld ix,posMenu +;Mode|Level|Limit|Worms|worm #|controls +; jr dispmenucommon ;cal + +dispmenucommon: + ld de,$FD80 ;begin pos + ld b,36*16/3 + xor a +clroldmenuloop: + ld (de),a + inc de + ld (de),a + inc de + ld (de),a + inc de + dnz clroldmenuloop + ld b,6 dispmenuloop: ld d,(ix) @@ -467,14 +489,236 @@ dispmenuloop: ld e,(ix) inc ix ld (_penCol),de - cal _vputs ;Mode \ Level \ Limit \ Worms \ worm # \ controls + cal _vputs dnz dispmenuloop +; ld b,0 ;b=menu# + ret - ld b,0 ;b=menu# - jr _dispmenusets ;mainMenu +hr: ;draw horizontal line at hl + ld b,16 +hrloop: + ld (hl),-1 + inc hl + dnz hrloop + ret ;--- menu loop --- +dispoptionmenu: + ld hl,txtoMenu + ld ix,posoMenu +;Back|Lives|Limit|Speed|Rotation|Growth + cal dispmenucommon + +dispomenusets: + cal clrold + + ld hl,$1E3E + ld (_penCol),hl + cal loadgamecar + psh hl + cal cshowA ;lives + + ld hl,$2A3E + ld (_penCol),hl + pop hl ;loadgamecar + inc hl \ inc hl \ inc hl + psh hl + ld a,(hl) ;(Speed) + inc a ;1..99 + jr nz,dispspeed + ld hl,txtDef + cal _vputs + jr dispspeeddone +dispspeed: + cal cshowA +dispspeeddone: + + ld hl,$363E + ld (_penCol),hl + pop hl ;loadgamecar + inc hl + psh hl + ld a,(hl) ;(growth) + inc a ;-1=None; 0..98->1..99 + cal cshowA + + ld hl,$303E + ld (_penCol),hl + pop hl ;loadgamecar + inc hl + psh hl + ld a,(hl) + cp 8 + jr nz,dispturn + ld hl,txtDef + cal _vputs + jr dispturndone +dispturn: + cal cshowA ;turn speed +dispturndone: + + ld hl,$243E + ld (_penCol),hl + pop hl ;loadgamecar + inc hl + ld a,(hl) ;(scorelimit) + or a + psh af + cal cshowA ;limit + pop af ;a==0? + jr z,optionMenu ;do not display 0 behind 'None' + ld a,'0' + cal _vputmap ;x10 + +optionMenu: + cal menupos + cal menucall + jr nz,notoselect +oselect: + cal menupos + ld a,b + or a ;1st item? + jp z,dispmainmenu ;mainMenu + jr optionMenu +notoselect + cp K_EXIT + jp z,dispmainmenu + psh af + cal menupos + cal loadgamecar + inc hl + pop af + cp K_LEFT + jr z,seloleft + cp K_RIGHT + ld a,b + jr nz,optionMenu + +seloright: + dec a + jr z,changelives + dec a + jr z,changelimit + dec a + jr z,changespeed + dec a + jr z,changeturn + dec a + jr z,changegrowth + +seloleft: + ld a,b + dec a + jr z,bchangelives + dec a + jr z,bchangelimit + dec a + jr z,bchangespeed + dec a + jr z,bchangeturn + dec a + jr z,bchangegrowth +_optionMenu: + jr optionMenu + +changelives: + cal loadgamecar ;a=(hl) + inc a + cp 100 + jr nc,optionMenu ;>99 +changedlives: + ld (hl),a +_dispomenusets: + jp dispomenusets ;optionMenu +bchangelives: + cal loadgamecar + sub 1 ;dec does not set cf + jr c,optionMenu ;<0 + jr changedlives + +changelimit: + cal changelimitInit + inc a + cp 100 + jr nc,optionMenu ;>99 +changedlimit: + ld (hl),a + jr _dispomenusets ;optionMenu +bchangelimit: + cal changelimitInit + sub 1 ;dec does not set cf + jr c,optionMenu ;<0 + jr changedlimit +changelimitInit: + cal loadgamecar + ld de,6 + add hl,de + ld a,(hl) ;(scorelimit) + ret + +changespeed: + cal changespeedInit + inc a + cp 99 + jr nc,_optionMenu ;>98 +changedspeed: + dec hl ;(Speed) + ld (hl),a + jr _dispomenusets ;optionMenu +bchangespeed: + cal changespeedInit + dec a + cp -2 +__optionMenu: ;w/ zf + jr z,_optionMenu ;<-1 + jr changedspeed +changespeedInit: + cal loadgamecar + ld de,3 + add hl,de + ld a,(hl) ;(Speed) + inc hl ;=saves 2 bytes :P + ret + +changeturn: + cal changespeedInit + inc hl ;(turnspeed) + ld a,(hl) + inc a + cp 26 + jr nc,_optionMenu ;>25 +changedturn: + ld (hl),a + jr _dispomenusets ;optionMenu +bchangeturn: + cal changespeedInit + inc hl + ld a,(hl) + dec a + cp 3 + jr c,_optionMenu ;<3 + jr changedturn + +changegrowth: + cal changespeedInit + ld a,(hl) + inc a + cp 99 + jr nc,_optionMenu ;>98 +changedgrowth: + ld (hl),a + jr _dispomenusets ;optionMenu +bchangegrowth: + cal changespeedInit + ld a,(hl) + dec a + cp -2 + jr z,__optionMenu ;<-1 + jr changedgrowth + +;--- + mainMenu: cal menupos cal menucall @@ -482,11 +726,13 @@ mainMenu: select: ;2nd/enter cal menupos ld a,b - sub 4 ;4th item? + dec a ;2nd item: level + jp z,dispoptionmenu + sub 3 ;5th item: wormname jp z,changeworms - dec a ;5th? + dec a ;6th: controls jp z,changekeys - jp LetsGetThisPartyOn ;1/2/3/5 + jp LetsGetThisPartyOn ;otherwise notselect cp K_EXIT jp z,ExitNoStats @@ -507,7 +753,7 @@ selright: dec a jp z,changelevel ;&&&jr?? dec a - jr z,changelives +; jr z,changelives dec a jr z,changenrworms ; dec a @@ -530,7 +776,7 @@ selleft: dec a jr z,bchangelevel dec a - jr z,bchangelives +; jr z,bchangelives dec a jr z,bchangenrworms ; dec a @@ -576,29 +822,6 @@ bchangegame: dec a jr changedgame -changelives: - cal changelivesInit - inc a - cp 100 - jr nc,_mainMenu ;&& _? -changedlives: - ld (hl),a - jr dispmenusets ;mainMenu -bchangelives: - cal changelivesInit - dec a - jr z,_mainMenu - jr changedlives -changelivesInit: - cal loadgamecar ;c=(gameCar) -;a=(hl)=(Gametype+1)=(wormbeglives) - ld a,(Gametype) ;&&& - cp 3 - ld a,(hl) - ret nc ;change lives - pop hl ;restore stack - jr _mainMenu ;singleplayer (no limit) - changelevel: inc hl ;hl=loadgamecar+2 psh hl @@ -649,20 +872,7 @@ changekeys: ;---display current settings--- dispmenusets: - ld hl,$FD97 ;begin pos - ld de,7 ;bytes to add - ld a,35 ;nr of lines -clroldsettings: - ld c,9 ;bytes to clear -clroldsetsloop: - ld (hl),d ;=0 - inc hl - dec c - jr nz,clroldsetsloop - add hl,de - dec a - jr nz,clroldsettings - + cal clrold ld de,$183E ld (_penCol),de ld d,0 @@ -677,30 +887,24 @@ clroldsetsloop: ld (CURtxtGame),hl ;save for g/o cal _vputs ;Singleplayer - cal loadgamecar - psh hl - ld hl,$243E - ld (_penCol),hl - cal cshowA ;liveslimit - sub '0' ;original A - ld l,a - ld a,c - and _datascore - ld a,' ' - jr z,limitok - ld a,'0' -limitok: - cal _vputmap ;x10 - ld hl,$2A3E ;worms ld (_penCol),hl - pop hl ;cal loadgamecar + cal loadgamecar inc hl psh hl ld a,(hl) add a,'0' cal _vputmap + ld hl,$243E + ld (_penCol),hl + rr c ;(gameCar) + ld hl,txtYes + jr c,displink + ld hl,txtNo +displink: + cal _vputs + ld hl,$1E3E ;level ld (_penCol),hl pop hl ;loadgamecar; hl++ @@ -722,8 +926,8 @@ curworm =$-1 cal _vputs ld hl,$363E ;controls ld (_penCol),hl -; ld hl,txtMenu -; cal _vputs + ld hl,txtMenu6 + cal _vputs jp mainMenu ;--- handle menukeys --- @@ -889,6 +1093,22 @@ chartable: ;--proc +clrold: + ld hl,$FD97 ;begin pos + ld de,7 ;bytes to add + ld a,35 ;nr of lines +clroldsettings: + ld c,9 ;bytes to clear +clroldsetsloop: + ld (hl),d ;=0 + inc hl + dec c + jr nz,clroldsetsloop + add hl,de + dec a + jr nz,clroldsettings + ret + skiplevel: ;@hl - destr:ab - alter:hl inc hl inc hl @@ -948,6 +1168,7 @@ loadgamecar: ld a,(Gametype) add a,a add a,a + add a,a ;8 bytes per mode ld e,a ld d,0 add hl,de @@ -968,30 +1189,39 @@ LetsGetThisPartyOn: ld (CheckExit),a ;set exit state cal loadgamecar - ld b,a ;psh a + psh hl + ld (wormbeglives),a inc hl ;nrworms ld a,(hl) ld (nrworms),a - ld l,b ;pop a - ld h,0 ;hl=a - cal _HLTIMES10 ;hl=10*(hl) - ld (scorelimit),hl ;set limit + inc hl ;level + inc hl + ld a,(hl) + ld (customspeed),a + inc hl + ld a,(hl) + ld (growspeed),a + inc hl + ld a,(hl) + ld (turnleft),a + ld (turnright),a ;more efficient + inc hl + ld l,(hl) + ld h,0 + cal _HLTIMES10 ;hl=10*(hl) + ld (scorelimit),hl - cal loadgamecar ;nc + pop hl ;loadgamecar psh hl - ld a,(Gametype) ;4bytes -> 3bytes - add a,a ;3->2bytes + ld a,(Gametype) ;8bytes -> 7bytes + ld e,a + add a,a ;nc + add a,e + add a,a ;8->2bytes add a,24+1 ;go to datalevels ld e,a ;=de sbc hl,de ;datalevels - ld a,c ;(gameCar) - and _datascore - jr nz,scorelimitset - dec a ;ld a,$FF ;=no_limit - ld (scorelimit),a -scorelimitset: - cal _ldHLind ;ld hl,(hl) pop de ;de=loadgamecar inc de \ inc de @@ -1006,7 +1236,7 @@ skiplevelloop: levelsskipped: psh hl ;1st level - ld a,c + ld a,(gameCar) and _datalink jr z,GameOver @@ -1021,22 +1251,23 @@ linkmatch: cp wormVclient jr z,client cp wormVhost - jr nz,linkiniterror + jr z,host + pop hl ;error + jp DisplayMenu ;return to menu + host: ld c,wormVclient cal Qsend ld a,$18 jr multiplayer - -linkiniterror: - pop hl - jp DisplayMenu - client: ld hl,txtReceive cal _puts ld a,$E6 multiplayer: +; cal linkok + ld a,D0LD1L + out (7),a ld (SwapPos),a ld a,2 ld (nrworms),a @@ -1046,8 +1277,6 @@ multiplayer: ;----------------------------- GameOver: - ld a,%11000000 - out (7),a ;link normal cal _clrLCD ld hl,worm1set ld de,worm1 @@ -1056,11 +1285,12 @@ createwormsloop: ex de,hl ld bc,died add hl,bc - ld (hl),0 ;died=0 + ld b,0 + ld (hl),b ;died=0 inc hl - ld (hl),0 ;score=0 + ld (hl),b ;score=0 inc hl - ld (hl),0 ;score+1=0 + ld (hl),b ;score+1=0 inc hl ld (hl),2 ;delay=2 inc hl @@ -1074,16 +1304,15 @@ wormbeglives =$-1 jr nz,createwormsloop pop hl ;begin of current level - StartLevel: ld de,Left ld a,(hl) inc a ;=255? jp nz,nextlevel + psh hl ld hl,Level dec (hl) ;curlevel-- (not beyond last lvl) - psh hl cal releasekeys cal _clrWindow pop hl @@ -1094,6 +1323,13 @@ StartLevel: jp (hl) ;go there ("call") nextlevel: ldi + ld a,0 +customspeed =$-1 + inc a ;$FF=def + jr z,defspeed + dec a + ld (hl),a ;store new speed +defspeed: ld de,Speed ldi ld de,peagrowth @@ -1151,24 +1387,23 @@ toobad_noballs: jr z,worminit ld b,4 worminit: - psh bc ; >> 1 + psh bc ;>1 ex de,hl - ldi ;d + ldi ;d ld a,SinCosTable/256 ld (de),a inc de - ldi ;y - ldi ;x + ldi ;y + ldi ;x ex de,hl - xor a - ld (hl),a ;y2 + ld (hl),a ;y2 inc hl - ld (hl),a ;x2 + ld (hl),a ;x2 ld bc,(worm2-worm1)-5 add hl,bc - pop bc ; << 0k + pop bc ;<0 dnz worminit ;-------- draw level --------- @@ -1197,7 +1432,7 @@ setfieldy: add hl,hl add hl,hl add hl,hl - add hl,hl + add hl,hl ;32=scr.width ex de,hl ld hl,ScrBuffer @@ -1315,15 +1550,41 @@ gameCar =$-1 and _datalink jr z,initfinished ;no link xor a - ld (Speed),a ;max.speed SwapPos: ;$18 xx -> $E6 xx ; jr xx -> and xx jr sethost setclient: - ld (worm1+left),a ;worm 1 via link + ld (worm1+left),a ;worm 1... + ld (worm3+left),a ;and worm 3 via link + cal Crecv + ld a,c + ld (worm2+name+0),a + cal Crecv + ld a,c + ld (worm2+name+1),a + cal Crecv + ld a,c + ld (worm2+name+2),a + cal Crecv + ld a,c + ld (worm2+name+3),a + cal Crecv + ld a,c + ld (worm2+name+4),a jr initfinished sethost: - ld (worm2+left),a ;worm 2 via link + ld (worm2+left),a ;worm 2+4.. + ld (worm4+left),a ;..over link + ld c,'T' + cal Qsend + ld c,'e' + cal Qsend + ld c,'s' + cal Qsend + ld c,'t' + cal Qsend + ld c,0 + cal Qsend initfinished: ld b,startdelay @@ -1337,8 +1598,13 @@ ReadyDelay: ;----------------------------- GameLoop: - ld bc,(worm1+pos) - cal DisplayField + ld bc,(worm1+pos) ;camera worm #1 + ld a,(worm1+left) + or a ;if #1 not over link + jr nz,showfield + ld bc,(worm2+pos) ;otherwise view from #2 +showfield: + cal DisplayField ;display piece of level ld a,1 flashtime =$-1 @@ -1366,7 +1632,18 @@ Delay: jr nz,Delay NoDelay: - ld (handledworm),a ;=0 + ld (handledworm),a ;reset + + ld hl,turn + ld a,(hl) + inc a ;-1 + jr z,nextturnok + dec (hl) + dec a ;0 (now <0) + jr nz,nextturnok +growspeed =$+1 + ld (hl),$FF +nextturnok: ld a,0 nrballs =$-1 @@ -1428,10 +1705,13 @@ handledworm =$-2 inc hl ld (ix+heading),a ld a,(hl) - ld (ix+pos),a + ld (ix+pos),a ;y inc hl ld a,(hl) - ld (ix+pos+1),a + ld (ix+pos+1),a ;x + xor a + ld (ix+pos2),a ;y2 + ld (ix+pos2+1),a ;x2 inc (ix+died) dec (ix+lives) @@ -1440,9 +1720,23 @@ handledworm =$-2 cal DecScore pop af ret nz ;HandleWorm done - ld a,(gameCar) - and _datalivel - ret z + ld a,(wormbeglives) + or a ;0=no live limit + ret z ;don't end game + ld a,(Gametype) + cp gametron + jr nz,anyworm ;if not Tron, quit at any worm's death + ld a,(nrworms) + ld b,a ;# of worms + ld hl,worm1+lives-(worm2-worm1) + ld de,worm2-worm1 + xor a ;check for 0 lives +checklives: + add hl,de ;next worm + cp (hl) ;lives==0? + ret nz ;any >0: don't exit + dnz checklives +anyworm: ld a,$A7 ;exit@end of turn ld (CheckExit),a ;set exit state ret ;finish turn @@ -1451,8 +1745,8 @@ handledworm =$-2 Exit: ld sp,0 ;pop all SpSave = $-2 - ld a,D0HD1H - out (7),a + ld a,D0LD1L + out (7),a ;both wires low = game over signal cal _clrWindow ld hl,txtGO cal _puts @@ -1550,8 +1844,7 @@ hilevelcheckdone: ld a,(gameCar) and _datasingl - - jr z,hiscorecheckdone + jr z,hiscorecheckdone ;no SP checkhiscore: cal loadhiscoreposinahl cal _Get_Word_ahl ;de=old_hi @@ -1607,6 +1900,7 @@ waitkey: ;8Snaky @ 00 04820 ExitNoStats: + cal linkok ld hl,_asapvar rst 20h ;_ABS_MOV10TOOP1 rst 10h ;_FINDSYM @@ -1630,36 +1924,30 @@ ExitNoStats: jp _clrWindow loadhiscoreposinahl: - ld a,(Level) - ld b,a - - ld h,0 ;hl= - ld a,(nrlevels+1) ;# peaworm lvls - add a,a - ld l,a - + ld h,0 ld a,(Gametype) - dec a - ld c,a - dec a ;z=(Gametype)=2 - jr z,tronhi - ld l,h ;hl=0 -tronhi: - - xor a ;ahl=0(+x) - psh bc + cp 2 + ld l,h ;hl=0 for peaworm and singleplayer + jr nz,hi_ + ld a,(nrlevels+1) + ld l,a ;skip peaworm slots for tron mode +hi_: + or a ;Singleplayer? + ld b,0 ;offset 0 for SP + jr z,hi__ + ld a,(Level) + ld b,a ;levels to skip (including 1 for singleplayer) +addlevelposition: + inc hl ;add one word per level + dnz addlevelposition +hi__: + add hl,hl ;one WORD per hiscore + xor a ;ahl=0(+hl) ld bc,defhiscrpos hiscrposhl =$-2 add hl,bc - pop bc - adc a,0 -hiscrposa =$-1 ;ahl=saveloc - - inc c - ret z ;(Gametype)=0 -addlevelposition: - cal _AHL_PLUS_2_PG3 - dnz addlevelposition +hiscrposa =$+1 + adc a,0 ;ahl=saveloc ret ;----------------------------- @@ -1718,10 +2006,6 @@ respawndue: saverespawncounter: ld (ix+delay),a jr inputcall -; ld a,(ix+input) -; or a -; jr z,inlink -; ret chkkey: ;key=a dec a @@ -1752,6 +2036,7 @@ inkeys: ;use jp not call! jr nc,notright ld a,l add a,8 +turnright =$-1 ld l,a notright: ld a,(ix+right) @@ -1759,6 +2044,7 @@ notright: ret nc ld a,l sub 8 +turnleft =$-1 ld l,a ret inputcall: @@ -1770,24 +2056,33 @@ inputcall: and _datalink ret z ;no link ld c,l ;send our keys - psh hl - cal Qsend ;Csend - pop hl - ret + jp Qsend inlink: - psh hl cal Qrecv ;Crecv - pop hl ld l,c ret ;------- handle worm --------- HandleWorm: + xor a + cp (ix+lives) + jr nz,alive + ld a,(wormbeglives) + or a + ret nz ;live limit +alive: ld a,(ix+delay) dec a jp nz,respawncheck + xor a + cp 0 +turn =$-1 + jr nz,nogrow + inc (ix+grow) +nogrow: + ld a,(Gametype) cp gametron jr nz,notron @@ -2086,14 +2381,13 @@ Drawworm: ld b,(ix+pos+1) ld a,(Gametype) - ld d,a cp gamerace cal z,checkhitlapline cal set4pixels dec c - ld a,d - cp gametron + ld a,(growspeed) + or a ;0=tron ret z ;keep tail in "Tron" ld l,(ix+head) @@ -2339,9 +2633,9 @@ scorecommon: ld (ix+score),l ld de,0 scorelimit =$-2 - inc e - jr z,showstats ;de=$FF??=no limit - dec e + ld a,d + or e + jr z,showstats ;de=0=no limit cal _cphlde jp nc,Exit @@ -2375,19 +2669,18 @@ showstatloop: ret showstat: - ld a,(gameCar) - and _datascore - jr z,showlives + ld a,(Gametype) + cp gametron + jr z,showscore + ld a,(wormbeglives) + or a ;0=death limit + jr nz,showlives showscore: ld h,(ix+score+1) ld l,(ix+score) cal _D_HL_DECI jr __vputs showlives: - ld a,(Gametype) - cp gametron - jr z,showscore - ld a,(ix+lives) add a,'0' __vputmap: @@ -2456,6 +2749,11 @@ showA: jp _putc cshowA: + or a + jr nz,cshowavalue + ld hl,txtNone + jp _vputs +cshowavalue: ld l,a ld h,0 cal _divHLby10 @@ -3068,174 +3366,59 @@ circledraw: ;destr:de -;**** link routines **** -;these are identical in concept to the routines used in ZTetris, ZPong, and probably -;every other link game out there. However, these are commented :) -losses: .dw 0 -Csend: - ld b,32 -csendwait: - nop - dnz csendwait - cal Qsend - jr c,Csend - ret -Qsend: -send: -;inputs: c=byte to send, both wires must be high by default -;outputs: b=8-number of bits sent, both wires high, goes to game over on certain conditions -;destroys: af,bc,de - in a,(7) - and %00000011 - jr z,killlink ;if both lines low, get out of here (game over signal) - ld b,8 ;sending 8 bits -sendloop: - ld de,$8000 ;error timer - rl c ;force high bit into carry - ld a,%11010100 ;lower the red wire by default (sending 0) ($d4) - jr nc,selected ;if high bit was 0, use above value - ld a,%11101000 ;if 1, lower the white wire instead ($e8) -selected: - out (7),a ;put it out the link port -waitconfirm: - call linktimer - in a,(7) ;see what the wires are doing - and %00000011 ;check lower 2 bits - jr nz,waitconfirm ;if both bits 0, data was received ok (both wires low) - ld a,%11000000 - out (7),a ;give the ok to raise both wires (one will be done automatically) ($c0) -waitconfirm2: - call linktimer - in a,(7) - and %00000011 - cp 3 - jr nz,waitconfirm2 ;wait for other calc to raise the other wire - djnz sendloop ;continue sending - xor a ;reset c; ld a,0 - ld (losses),a ;reset number of losses - ret - - -Crecv: - cal receive - jr c,Crecv - ret -Qrecv: -receive: -;inputs: both wires must be high by default -;outputs: c=byte received, b=8-number of bits received, both wires high -; goes to game over on certain conditions -;destroys: af,bc,de - in a,(7) - and %00000011 - jr z,killlink ;game over signal applies to receiving too - ld b,8 ;receiving 8 bits -receiveloop: - ld de,$8000 ;error timer -waitreceive: - call linktimer - in a,(7) - and %11 - cp 3 ;if bits 0 and 1 set, both wires are high - jr z,waitreceive ;wait for one of the wires to go low - rra ;check red wire status - rl c ;if set, red is high (thus white is low), so put the correct bit into c - rra ;now check white wire (since the flags are destroyed) - ld a,%11010100 ;$d4 - jr nc,selected2 ;if white is low, lower red and vice versa - ld a,%11101000 ;$e8 -selected2: - out (7),a ;so now both wires are low -waitreceive2: - call linktimer - in a,(7) - and %11 - jr z,waitreceive2 ;wait for the wire we didn't lower to go high again (the other will remain low) - ld a,%11000000 ;$c0 - out (7),a ;raise both wires since the other calc will have given the ok sign - djnz receiveloop ;if not done, wait for next bit - xor a ;reset c - ld (losses),a ;reset number of losses - ret - -linktimer: ;leave if we have to wait too long (and return an error) - dec de - ld a,d - or e ;see if de is 0 - ret nz ;if not, keep going as usual - ;otherwise we have to deal with a link failure - ld a,%11000000 ;$c0 - out (7),a ;reset link status (both high) - ld a,(losses) ;see how many consecutive losses we have - inc a - ld (losses),a ;add this loss to it - pop de ;fix the stack to leave the link routine (de is ok to destroy) - cp 20 ;see if this is the 20th consecutive failure - ret c ;if not, keep playing - ;otherwise, all is probably lost... - -killlink2: - jr linkend -killlink: -linkend: - jp z,Exit - - - - - - - - - -#ifdef 0 + + + ;----------------------------- ;----------- link ------------ ;----------------------------- -timeout = $800 +linkok: + ld a,D0HD1H + out (7),a ;raise both wires = link ok + ret -checklink: - dec de +timeout = $8000 +lossout = 20 + +checklink: ;load wires in A and check for timeout + dec de ;decrease timer ld a,d or e - jr z,linkerror - - ld a,$BF - out (1),a - in a,(1) - bit 6,a - jp z,Exit - + jr nz,linkfine ;ok if de>0 +;de==0 = timeout + cal linkok + ld a,0 ;losses so far +linklosses =$-1 + inc a ;and this is another one + ld (linklosses),a + pop de ;return from link + cp lossout ;quit if too many errors + ret c ;otherwise just continue +linkerr: + jp Exit +linkfine: in a,(7) and %11 ret -linkerror: - scf - ld a,%11 - pop hl - ret - ;-------------- ;---- SEND ---- ;-------------- -Csend: ;--- send 8 bits in A --- destr:abcdehl --- - ld c,a -Csendloop: +Csend: + ld b,32 +csendwait: + nop + dnz csendwait cal Qsend - ret nc ;NC = all ok - ld a,D0HD1H - out (7),a ;both high - jr Csendloop ;CF = error + jr c,Csend + ret -Qsend: ;--- try to send 8 bits in C; CF=error --- destr:abcdehl --- - ld de,timeout - cal checklink - cp %11 ;are they? - scf - ret nz ;nope, wait +Qsend: ;try to send 8 bits in C; CF=error --- destr:abcde + in a,(7) + and %11 ;both wires low = exit signal + jr z,linkerr ;error otherwise ld b,8 ;bits to send sendloop: ld de,timeout @@ -3254,9 +3437,10 @@ sendfinish: cal checklink cp %11 ;both raised (by other calc) jr nz,sendfinish - nop \ nop +; nop \ nop dnz sendloop ;repeat for all bits xor a ;nc... + ld (linklosses),a ;reset number of losses ret ;=ok ;-------------- @@ -3266,17 +3450,12 @@ sendfinish: Crecv: ;--- receive 8 bits into A/C --- destr:abcdehl --- cal Qrecv ret nc ;return if all went ok - ld a,D0HD1H - out (7),a ;raise both on error jr Crecv ;and try again -Qrecv: ;--- receive 8 bits into A/C; CF=error --- destr:abcdehl --- - ld de,timeout - cal checklink - jp z,Exit ;both low = error, quit - cp %11 - scf - ret z ;both high = nothing yet, wait +Qrecv: ;--- receive 8 bits into A/C; CF=error --- destr:abcde --- + in a,(7) + and %11 + jr z,linkerr ;both low = error, quit ld b,8 ;bits to receive recvloop: ld de,timeout @@ -3299,9 +3478,9 @@ recvwaitack: recvfinish: dnz recvloop ;repeat for all bits xor a ;nc=no error - ld a,c ;result in a + ld (linklosses),a ;reset number of losses ret -#endif + ;----------------------------- ;---------- levels ----------- @@ -3354,36 +3533,43 @@ LevelDefC: ;ctf wdPicture = 16 wtPicture: -.db %01001010,%00101001,%00000111,%10000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01110000,%00000000,%00000000,%00000000,%01000000,%00000000 -.db %10001010,%10101000,%10001111,%10000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111000,%00000000,%00000000,%00000000,%10100100,%01000000 -.db %10101010,%10101010,%10011100,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00011100,%00001110,%00000000,%00000000,%10101010,%10100000 -.db %01010001,%01000101,%00011000,%00011111,%00000000,%01111111,%11000000,%00111100,%00011110,%01111000,%00001100,%00011111,%00000000,%00000000,%11001001,%10100000 -.db %00000000,%00000000,%00111000,%00111111,%10000000,%11111111,%11100000,%11111110,%00111111,%11111100,%00001100,%00111011,%10000000,%00000011,%10001000,%00100000 -.db %01101010,%10010011,%00110000,%01110001,%11000001,%11000000,%01110001,%11100110,%01110011,%11001110,%00001100,%00110001,%10000000,%00000000,%10010000,%00100000 -.db %10001010,%00101010,%10110000,%01100000,%11000001,%10000000,%00111001,%10000000,%01100111,%11100110,%00001110,%01110001,%10000000,%00000000,%01100000,%01000000 -.db %11101110,%10111011,%00110000,%01100000,%11000001,%10110000,%00011011,%10000000,%11101110,%01110111,%00001110,%01110001,%10000011,%11100000,%00000011,%10000000 -.db %00101010,%10101010,%10110000,%01110001,%11000001,%10110000,%00011011,%00000000,%11001100,%00110011,%00000111,%11100001,%10001100,%00011000,%00010000,%00000000 -.db %11001010,%10101010,%10110000,%00110001,%10000001,%10110000,%00011011,%00000000,%11001100,%00110011,%00000011,%11000011,%10010000,%00000100,%00100011,%00001100 -.db %00000000,%00000000,%00111000,%00111011,%10000011,%10110000,%00011011,%00000000,%11001110,%01110011,%00000000,%00000011,%00010011,%00000100,%00100100,%10010010 -.db %00111001,%11000111,%00011000,%00011111,%00000011,%00110000,%00011011,%00000000,%11000111,%11100011,%10000000,%00000011,%00001100,%10000100,%00101000,%10010100 -.db %01100101,%00101000,%00011100,%00001110,%00000111,%00111000,%00111011,%10000000,%11000011,%11000001,%10000000,%00000111,%00000000,%01001110,%00101000,%10011000 -.db %01001101,%11001011,%00001110,%00111111,%10001110,%00011100,%01110001,%10000000,%11100000,%00000001,%11100000,%00001110,%00000000,%01010101,%00101000,%10011000 -.db %00111001,%01100111,%00000111,%11111011,%11111100,%00001111,%11100001,%11000000,%01100000,%00000000,%11111111,%11111100,%00000000,%10010101,%00100110,%00010100 -.db %00000000,%00000000,%00000011,%11100000,%11111000,%00000111,%11000000,%11000000,%01100000,%00000000,%00111111,%11111000,%11111111,%00001000,%11000001,%11100011 +.db %00000000,%00000000,%00000111,%10000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01110000,%00000000,%00000000,%00000000,%00000000,%00000000 +.db %00000000,%00000000,%00001111,%10000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111000,%00000000,%00000000,%00000110,%01111011,%00100000 +.db %00000000,%00000000,%00011100,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00011100,%00001110,%00000000,%00001001,%00010011,%01000000 +.db %00000000,%00000000,%00011000,%00011111,%00000000,%01111111,%11000000,%00111100,%00011110,%01111000,%00001100,%00011111,%00000000,%10100111,%00110000,%10000000 +.db %00000000,%00000000,%00111000,%00111111,%10000000,%11111111,%11100000,%11111110,%00111111,%11111100,%00001100,%00111011,%00000000,%10100001,%00001001,%01100000 +.db %00000000,%00000000,%00110000,%01110001,%11000001,%11000000,%01110001,%11100110,%01110011,%11001110,%00001100,%00110001,%10000000,%01001110,%01110010,%01100000 +.db %00000000,%00000000,%00110000,%01100000,%11000001,%10000000,%00111001,%10000000,%01100111,%11100110,%00001110,%01110001,%10000000,%00000000,%00000000,%00000000 +.db %00000000,%00000000,%00110000,%01100000,%11000001,%10110000,%00011011,%10000000,%11101110,%01110111,%00001110,%01110001,%10000000,%00000000,%00000000,%00000000 +.db %00000000,%00000000,%00110000,%01110001,%11000001,%10110000,%00011011,%00000000,%11001100,%00110011,%00000111,%11100001,%10000000,%00000000,%00000000,%00000000 +.db %00000000,%00000000,%00110000,%00110001,%10000001,%10110000,%00011011,%00000000,%11001100,%00110011,%00000011,%11000011,%10000000,%00000000,%00000000,%00000000 +.db %00000000,%00000000,%00111000,%00111011,%10000011,%10110000,%00011011,%00000000,%11001110,%01110011,%00000000,%00000011,%00110101,%01001001,%10000000,%00000000 +.db %00000000,%00000000,%00011000,%00011111,%00000011,%00110000,%00011011,%00000000,%11000111,%11100011,%10000000,%00000011,%01000101,%00010101,%01000011,%01100011 +.db %00000000,%00000000,%00011100,%00001110,%00000111,%00111000,%00111011,%10000000,%11000011,%11000001,%10000000,%00000111,%01100101,%01010101,%01000101,%01010100 +.db %00000000,%00000000,%00001110,%00111111,%10001110,%00011100,%01110001,%10000000,%11100000,%00000001,%11100000,%00001110,%00110111,%01011101,%10010101,%01100101 +.db %00000000,%00000000,%00000111,%11111011,%11111100,%00001111,%11100001,%11000000,%01100000,%00000000,%11111111,%11111100,%00010101,%01010101,%01000101,%01010101 +.db %00000000,%00000000,%00000011,%11100000,%11111000,%00000111,%11000000,%11000000,%01100000,%00000000,%00111111,%11111000,%01100101,%01010101,%01000110,%01010011 txtMenu: .db "Mode",0 ;1st menu item .db "Level",0 ;2nd - .db "Limit",0 ;... + .db "Link",0 ;... .db "Worms",0 .db "worm #",0 - .db "controls",0 -posMenu: .dw $$2418,$231E,$2524,$1F2A,$1730,$1936 +txtMenu6: .db "controls",0 +posMenu: .dw $2418,$231E,$2824,$1F2A,$1730,$1936 +txtoMenu: .db "Back",0 ;1st menu item + .db "Lives",0 ;2nd + .db "Limit",0 ;... + .db "Speed",0 + .db "Rotation",0 + .db "Growth",0 +posoMenu: .dw $2618,$251E,$2524,$222A,$1A30,$1C36 txtGame: .db "Singleplayer",0 txtGame1: .db "Peaworm",0 txtGame2: .db "Tron",0 txtGame3: .db "Deathmatch",0 txtGame4: .db "Foodmatch",0 -txtGame5: .db "LinkMatch",0 +txtGame5: .db "Timematch",0 txtGame6: .db "Race",0 txtGame7: .db "CTF",0 ; .db "Domination",0 ;8 @@ -3395,9 +3581,13 @@ posGame: .db 0,txtGame1-txtGame .db txtGame6-txtGame .db txtGame7-txtGame -txtKeyleft: .db "Left",0 -txtKeyright:.db " | Right",0 -txtLevsel: .db $CF," Select levels: ",5,0 +txtNone: .db "None",0 +txtDef: .db "Default",0 +txtYes: .db "Yes",0 +txtNo: .db "No",0 +txtKeyleft: .db ":left",0 +txtKeyright:.db "/right",0 +txtLevsel: .db $CF," Select levels ",5,0 txtEName: .db "Enter name player ",0 txtWaiting: .db "Waiting...",0 txtReceive: .db "Receiving..." ;,0 @@ -3424,17 +3614,16 @@ txtReady: .db "Prepare!",0 txtposReady = 7 txtGO: .db 5,5,5,5,5," GAME OVER ",$CF,$CF,$CF,$CF,$CF,0 -_datalink = %00000001 ;linkplay -_datalivel = %00000010 ;lives=0 limit -_datafoodl = %00000100 ;left=0 limit -_datanextl = %00001000 ;next level if left=0 -_datasingl = %00001000 ;singleplayer=1 - ;1=hiscore+keep_length -_datafood = %00010000 ;food present -_datadie = %01000000 ;worm dies on impact -_datascore = %10000000 ;score>=100 limit -_datamultpeas = %00100000 -_datasp = %01011110 +_datalink = %0000001 ;linkplay + +_datafoodl = %0000010 ;left=0 limit +_datanextl = %0000100 ;next level if left=0 +_datasingl = %0000100 ;singleplayer=1 (=hiscore+keep_length) +_datamultpeas = %0001000 ;multiple peas=1 +_datatime = %0010000 ;time incs score +_datafood = %0100000 ;food present +_datadie = %1000000 ;worm dies on impact +_datasp = %1100110 datalevels: .dw LevelDef, LevelDefM .dw LevelDefT,LevelDefM @@ -3442,26 +3631,30 @@ datalevels: .dw LevelDef, LevelDefM .dw LevelDefM,LevelDefC nrlevels: .db 1,3,1,3,3,3,3,1 ;=defaults -savestart: - -gamesingle = 0 -datasingle: .db %01011110,3,1,1 ;3 lives (