wormedit 0.5.1C20
[wormy.git] / wormy.z80
index e0bb2b21affa566f98efa39a2fd6ba19de19d30a..22fc9186eee1171cdf216892eebe266110189862 100644 (file)
--- a/wormy.z80
+++ b/wormy.z80
@@ -1,10 +1,9 @@
 ; Title                      : Wormy
-; Version                    : 95%
-; Release Date               : summer 2001
+; Version                    : 96% (0.96.C14)
+; Release Date               : UUHHhhh... soon?!?
 ; Filename                   : wormy.86p (5kb)
 ; Author(s)                  : Shiar
-; Email Address              : shiar0@hotmail.com
-; ICQ UIN                    : #43840958
+; Email Address              : wormy@shiar.org
 ; Web Page                   : www.shiar.org
 ; Description                : ruling Nibbles-like game 1-4 players
 ; Where to get this game     : www.shiar.org (home of Wormy)
 ;----------- TO-DO -----------
 ;-----------------------------
 
-; 95% = DONE
+; 96% = DONE
 
 ;    [* internal levels         ]
 ;    [  * check levels/gametype ]
 ;    [  * enough hiscore saves! ]
 ;    [* complete readme         ]
 ;  1% * misc (pollish, bugs, &&&)
+;  1% * long length save (level#6)
+;     * mem at worm #4
 ;   * LINK
-;     * fix first packet loss
 ;  1% * transmit game/level data
-;;;1% * get g/o signal (l&l) working
-;  2% * send new peas' positions
+;      Xfirst packet loss?? or vti onlyXXXXX
+;      X1/3 worms over linkXXXX
+;      Xsend new peas' positionsXXXXX
 
 ;100% = bugs fixed + levels done
 
+; MAYBE: sound
+; NO:   coop
+
 ;-----------------------------
 ;-----------------------------
-;---------  W O R M  ---------
+;-------  W O R M Y  ---------
 ;-----------------------------
 ;-----------------------------
 
@@ -48,7 +52,6 @@
 #define cal call
 #define psh push
 #define dnz djnz
-;#define halt nop
 
 #include "asm86.h"
 #include "ti86asm.inc"
@@ -117,6 +120,7 @@ peaspos     = $AE02 ;-AE05 (4) (peas)
 ;--- temporary
 
 namelength  = $BC00 ;(1)         @menu
+datalink    = $BC00 ;(8)        @init
 #ifdef buffer
 DispBuffer  = $BC00 ;(10x57d)    @game
 #else
@@ -129,18 +133,19 @@ DispBuffer  = $FC70
 
 .org _asm_exec_ram
 
-wormVhost   = 093
-wormVclient = 193
+wormVhost   = 095
+wormVclient = 195
 
 start:
   nop
-  jp Start
-  .dw 1
+  jp  Start
+  .db 1
+  nop
   .dw WormTxt
   .dw WormIcon
 
 WormTxt:
-  .db "WORMY by SHIAR -- beta 95%",0
+  .db "WORMY by SHIAR -- 96% C14",0
 WormIcon:
   .db 8,2
   .db %00000000,%00111100
@@ -156,13 +161,13 @@ levelhead  = 'w'
 levelhead2 = 95 ;wormy levels header = "95"
 
 int_handler:
-  ex af,af'
-  in a,($03)
+  ex  af,af'
+  in  a,($03)
   bit 3,a
-  jp z,$0039
+  jp  z,$0039
   res 0,a
   out ($03),a
-  jp $0039
+  jp  $0039
 int_end:
 
 Start:
@@ -276,113 +281,129 @@ levelselectmenu:
   ld  hl,txtLevsel
   cal _vputs ;"< SELECT LEVELS >"
   ld  hl,$FC00+(2*16)
-  cal hr
-  ld  hl,$FC00+(10*16)
-  cal hr
+  ld  b,16*9
+  cal menuinvloop
   ld  hl,$FC00+(56*16)
   cal hr
-  ld  hl,$0C01 ;x=1
+  ld  hl,$0601 ;x=1
   ld  (_penCol),hl
 dispnextlevel:
-  ld  de,3
-  add ix,de
-  ld  a,(ix)
+  ld  a,(ix+3)
+  ld  b,a
   inc a ;cp 255
   jr  z,__levselect
-  dec a
 displevel:
-  ld  h,(ix+1)
-  ld  l,(ix+2) ;ahl=(ix)
-  cal _load_ram_ahl ;hl=ahl
-  ld  b,(hl) ;b=title size
-  cal _vputs
   ld  hl,_penCol
   ld  (hl),$01 ;x=1
   inc hl
   ld  a,(hl)
   add a,6
   ld  (hl),a ;y+6
-  ld  hl,availevels
-  inc (hl)
   cp  49 ;bottom of screen
   jr  nc,_levselect
+  ld  de,3
+  add ix,de
+  ld  hl,availevels
+  inc (hl)
+  ld  a,b ;(ix+0)
+  ld  h,(ix+1)
+  ld  l,(ix+2) ;ahl=(ix)
+  cal _load_ram_ahl ;hl=ahl
+  cal _vputs
   jr  dispnextlevel
 
+readylevelfile: ;selected level at ahl
+; ld  hl,templevels-3
+  ld  a,b
+  add a,3 ;sellev+3 (#0==-3)
+  ld  e,a
+  add a,a ;*2
+  add a,e ;*3
+  ld  e,a
+  ld  d,0 ;de=sellev*3
+  add hl,de
+  ld  a,(hl) ;ade=(hl)
+  inc hl
+  ld  d,(hl)
+  inc hl
+  ld  e,(hl)
+  ex  de,hl ;ahl=ade
+skiptitle:
+  ld  d,a ;psh ahl
+  psh hl
+  cal _GETB_AHL ;ld a,(ahl)
+  pop hl
+  or  a
+  ld  a,d ;pop ahl
+  psh af
+  cal _INC_PTR_AHL ;ahl++
+  pop af ;cp 0
+  jr  nz,skiptitle ;goto #0-terminator
+  ret
+
 levup:
   cal menupos
   dec b ;up
   ld  a,b
   cp  -3
-  jr  nz,levselected
+  jr  nz,levselect
   inc b ;undo
-  jr  levselected
+  jr  levselect
 levdown:
   cal menupos
   inc b ;down
   ld  a,b
   cp  -2
 availevels =$-1
-  jr  nz,levselected
+  jr  nz,levselect
   dec b ;back up
-levselected:
-  jp  menupos
-
+levselect:
+  cal menupos
+  ld  hl,$3900
+  ld  (_penCol),hl
+  pop hl
+  psh hl
+  cal readylevelfile
+  cal _load_ram_ahl ;hl=ahl
+  ld  de,$FFA0 ;desc.text
+  xor a
+levdescclearloop:
+  ld (de),a ;empty
+  inc de
+  cp  d ;de>$FFFF (offscreen)
+  jr  nz,levdescclearloop
+  cal _vputs
+  jr  levselectmenu+1
 __levselect:
   ld  ix,templevels-6 ;reset 2 1st page
 _levselect:
   ld  b,-2 ;level selected
-  cal menupos
-  pop hl
-levselect:
+  jr  levselect
+levselectmenu:
   psh hl
   psh bc
   cal ubergetkey
   pop bc ;GET_KEY destr. b
-  cp  K_UP
-  cal z,levup
-  dec a ;K_DOWN
-  cal z,levdown
-  cp  K_SECOND-1
-  jr  z,loadlevel
+  dec a ;cp K_DOWN
+  jr  z,levdown
+  sub K_UP-1
+  jr  z,levup
   pop hl
-  cp  K_RIGHT-1
+  inc a ;cp K_RIGHT
   jp  z,levelselectmenu
-  cp  K_EXIT-1
+  cp  K_ENTER-K_RIGHT
+  jr  z,loadlevel
+  sub K_EXIT-K_RIGHT
   jp  z,ExitNoStats
-  cp  K_ENTER-1
-  jr  nz,levselect
+  inc a ;cp K_SECOND
+  jr  nz,levselectmenu
 ; jr  z,loadlevel
 
 loadlevel:
-; ld  hl,templevels-3
-  ld  a,b
-  add a,3 ;sellev+3 (#0==-3)
-  ld  e,a
-  add a,a ;*2
-  add a,e ;*3
-  ld  e,a
-  ld  d,0 ;de=sellev*3
-  add hl,de
-  ld  a,(hl) ;ade=(hl)
+  cal readylevelfile
   or  a ;levelfile on page 0 (=internal)
   jr  z,levelloaded
-
-  inc hl
-  ld  d,(hl)
-  inc hl
-  ld  e,(hl)
-  ex  de,hl ;ahl=ade
-skiptitle:
-  ld  b,a ;psh ahl
-  psh hl
-  cal _GETB_AHL ;ld a,(ahl)
-  pop hl
-  or  a
-  ld  a,b ;pop ahl
-  psh af
-  cal _INC_PTR_AHL ;ahl++
-  pop af ;cp 0
-  jr  nz,skiptitle ;goto #0-terminator
+  cal skiptitle ;skip description
 
   cal _Get_Word_ahl
   ld  (leveldataSize),de
@@ -484,9 +505,10 @@ dispmainmenu:
 ;Mode|Level|Limit|Worms|worm #|controls
 ; jr  dispmenucommon ;cal
 
+dispmenucommon_:
+  ld  b,36*16/4
 dispmenucommon:
   ld  de,$FD80 ;begin pos
-  ld  b,36*16/3
   xor a
 clroldmenuloop:
   ld  (de),a
@@ -495,13 +517,15 @@ clroldmenuloop:
   inc de
   ld  (de),a
   inc de
+  ld  (de),a
+  inc de
   dnz clroldmenuloop
 
-  ld  b,6
+  ld  b,(ix)
 dispmenuloop:
-  ld  d,(ix)
+  ld  d,(ix+1)
   inc ix
-  ld  e,(ix)
+  ld  e,(ix+1)
   inc ix
   ld  (_penCol),de
   cal _vputs
@@ -509,9 +533,17 @@ dispmenuloop:
 ; ld  b,0 ;b=menu#
   ret
 
-hr: ;draw horizontal line at hl
+;hr: ;draw horizontal line at hl
+;  ld  b,16
+;  jp  menuinvloop
+
+hr:
   ld  b,16
-  jp  menuinvloop
+hrloop:
+  ld  (hl),-1
+  inc hl
+  dnz hrloop
+  ret
 
 ;--- menu loop ---
 
@@ -519,7 +551,7 @@ dispoptionmenu:
   ld  hl,txtoMenu
   ld  ix,posoMenu
 ;Back|Lives|Limit|Speed|Rotation|Growth
-  cal dispmenucommon
+  cal dispmenucommon_
 
 dispomenusets:
   cal clrold
@@ -1134,7 +1166,9 @@ nameentered:
   ld  (ix+8),0 ;end mark
   jp  DisplayMenu
 
-;--proc
+;-----------------------------
+;------- procs-n-stuff -------
+;-----------------------------
 
 ubergetkey:
   halt ;woo hoo
@@ -1230,9 +1264,9 @@ skipflags:
 noflagstoskip:
 
 skipobjects:
-  ld  a,(hl)
-  inc hl
-  or  a
+  xor a
+  or  (hl)
+  inc hl ;nf
   ret z ;0=end
   inc hl
   inc hl
@@ -1272,34 +1306,15 @@ LetsGetThisPartyOn:
 
   cal loadgamecar
   psh hl
-  ld  (wormbeglives),a
-  inc hl ;nrworms
-  ld  a,(hl)
-  ld  (nrworms),a
-  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
-
-  pop hl ;loadgamecar
   cal hlatlevel
-
-  psh hl  ;1st level
-  ld  a,(gameCar)
+  ex  (sp),hl ;pop \ psh leveldata
+  psh hl ;psh loadgamecar
+  ld  a,0
+gameCar =$-1
   rra ;and _datalink
-  jr  nc,GameOver
+  jp  nc,StartLevel ;&&&jr
+
+;--------- link ------------
 
 linkmatch:
   cal _clrWindow
@@ -1319,25 +1334,120 @@ linkmatch:
 host:
   ld  c,wormVclient
   cal Qsend
-  ld  a,$18
-  jr  multiplayer
+  jr  sethost
 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
+setclient:
+ ;name/keys: wormy#1 = link    = 0  + link (name1)
+ ;                 2 = worm #1 = #1 + local(name1)
+ ;                 3 = link    = 0  + link (name2)
+ ;                 4 = worm #2 = #2 + local(name2)
+  ld  de,worm2+left
+  ld  hl,worm1+left
+  ldi ;keys worm#2 = worm#1
+  ldi ;+right
+  ld  de,worm4+left
+  ldi ;keys worm#4 = worm#2
+  ldi
+  xor a
+  ld  (worm1+left),a ;worm 1...
+  ld  (worm3+left),a ;and worm 3 via link
+  ld  hl,worm1+name
+  ld  b,9
+  cal recvstuff
+  ld  hl,worm2+name
+  ld  b,9
+  cal sendstuff
+  pop hl
+  pop de
+  psh de
+  psh hl
+  ld  b,168
+  cal sendstuff
+  ex  de,hl
+  ld  b,8
+  cal sendstuff
+  jr  StartLevel
+sendstuff:
+  psh de
+sendstuffloop:
+  psh bc
+  ld  c,(hl)
+  inc hl
+  cal Qsend
+  pop bc
+  dnz sendstuffloop
+  pop de
+  ret
+recvstuff:
+  psh de
+recvstuffloop:
+  psh bc
+  cal Qrecv
+  ld  (hl),c
+  inc hl
+  pop bc
+  dnz recvstuffloop
+  pop de
+  ret
+sethost:
+ ;name/keys: wormy#1 = worm #1 = ok
+ ;                 2 = link    = 0  + link (name1)
+ ;                 3 = worm #2 = #2 + local(name2)
+ ;                 4 = link    = 0  + link (name2)
+  ld  de,worm3+left
+  ld  hl,worm2+left
+  ldi ;keys worm#3 = worm#2
+  ldi ;+right
+  xor a
+  ld  (worm2+left),a ;worm 2+4..
+  ld  (worm4+left),a ;..over link
+  ld  hl,worm1+name
+  ld  b,9
+  cal sendstuff
+  ld  hl,worm2+name
+  ld  b,9
+  cal recvstuff
+  pop hl
+  pop de
+  ld  hl,templevels
+  ld  de,datalink
+  psh de
+  psh hl
+  ld  b,168
+  cal recvstuff
+  ex  de,hl
+  ld  b,8
+  cal recvstuff
 
-;-----------------------------
-;--------- game over ---------
-;-----------------------------
+;-------- load level ---------
+
+StartLevel:
+  pop hl ;loadgamecar
+  ld  a,(hl)
+  ld  (wormbeglives),a
+  inc hl ;nrworms
+  ld  a,(hl)
+  ld  (nrworms),a
+  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
 
-GameOver:
+setupworms:
   ld  hl,worm1set
   ld  de,worm1
   ld  a,4 ;4x (all worms)
@@ -1363,12 +1473,12 @@ wormbeglives =$-1
   dec a      ;loop
   jr  nz,createwormsloop
 
-StartLevel:
+Nextlevel:
   cal _clrWindow
   pop hl ;begin of current level
   ld  a,(hl)
   inc a ;=255?
-  jp  nz,nextlevel
+  jp  nz,donextlevel
 
   psh hl
   ld  hl,Level
@@ -1380,7 +1490,7 @@ StartLevel:
   psh bc   ;where to go afterwards
   inc hl   ;location of ending-code
   jp  (hl) ;go there ("call")
-nextlevel:
+donextlevel:
   ld  a,(Gametype)
   or  a ;gamesingle
   psh af
@@ -1478,6 +1588,7 @@ worminit:
 
 ;-------- draw level ---------
 
+initlevel:
   ld  a,(de)
   inc de
   sub 128
@@ -1573,17 +1684,11 @@ levelhasbeensetup:
 
   cal drawstuff
 
-;-----------------------------
+;--------- prepare -----------
 
+leveldone:
   psh hl                        ; >> levelp new
   cal forceshowstats
-  ld  a,(gameCar)
-  and _datafood
-  jr  z,nofood
-  cal NewPea
-nofood:
-  ld  bc,(worm1+pos)
-  cal DisplayField
 
 #ifdef readymask
   ld  hl,$FC70
@@ -1603,7 +1708,6 @@ maskline:
   dec c
   jr  nz,maskloop
 #endif
-
 #ifdef readytext
   ld  hl,$FDE0
   ld  de,$FDE1
@@ -1618,56 +1722,14 @@ maskline:
   res 3,(iy+5)
 #endif
 
-  ld  a,0
-gameCar =$-1
-  rra ;and _datalink
-  jr  nc,initfinished ;no link
-  xor a
-SwapPos: ;$18 xx -> $E6 xx
-         ; jr xx -> and xx
-  jr  sethost
-setclient:
-  ld  (worm1+left),a ;worm 1...
-  ld  (worm3+left),a ;and worm 3 via link
-  ld  hl,worm1+name
-  ld  b,9
-  cal recvstuff
-  ld  hl,worm2+name
-  ld  b,9
-  cal sendstuff
-  jr  initfinished
-sendstuff:
-  psh bc
-  ld  c,(hl)
-  inc hl
-  psh hl
-  cal Qsend
-  pop hl
-  pop bc
-  dnz sendstuff
-  ret
-recvstuff:
-  psh bc
-  psh hl
-  cal Qrecv
-  pop hl
-  ld  (hl),c
-  inc hl
-  pop bc
-  dnz recvstuff
-  ret
-sethost:
- halt
- dnz sethost
-  ld  (worm2+left),a ;worm 2+4..
-  ld  (worm4+left),a ;..over link
-  ld  hl,worm1+name
-  ld  b,9
-  cal sendstuff
-  ld  hl,worm2+name
-  ld  b,9
-  cal recvstuff
-initfinished:
+  ld  a,(gameCar)
+  and _datafood
+  jr  z,nofood
+  ld  ix,worm1
+  cal NewPea
+nofood:
+  ld  bc,(worm1+pos)
+  cal DisplayField
 
   ld  b,startdelay
 ReadyDelay:
@@ -1777,76 +1839,93 @@ HandleKeys:
   out (1),a
   in  a,(1)
   rla ;MORE?
-  jr  c,CheckExit
-  ld  bc,$0103
-  out (c),b
-  halt ;pause/off
-  ld  b,11
-  out (c),b
-
+  jr  nc,disppausemenu
 CheckExit:
   rla  ;=$17 (c=EXIT-key)
       ;or$A7 (c=0)
   jp  c,GameLoop
-  jr  Exit
+  jp  Exit ;jr?
 
-WormDead:
-#ifdef invincible
-  jp  stopworm
-#else
-  ld  a,2
-  ld  (flashtime),a
-  ld  (ix+delay),respawndelay
+;------- pause menu -------
 
-thislevel =$+1
-  ld  hl,0
-  ld  de,0
-handledworm =$-2
-  add hl,de
-  add hl,de
-  add hl,de
-  ld  a,(hl)
-  inc hl
-  ld  (ix+heading),a
-  ld  a,(hl)
-  ld  (ix+pos),a ;y
-  inc hl
-  ld  a,(hl)
-  ld  (ix+pos+1),a ;x
-  xor a
-  ld  (ix+pos2),a ;y2
-  ld  (ix+pos2+1),a ;x2
+disppausemenu:
+  ld  hl,txtpMenu
+  ld  ix,pospMenu
+;Resume|Turn Off|Contrast|Exit||
+  ld  b,25*16/4
+  cal dispmenucommon
+  ld  hl,$FC00+$170 ;(*,23)
+  cal hr
+  ld  hl,$FC00+$310 ;(*,49)
+  cal hr
+  cal menupos
 
-  inc (ix+died)
-  dec (ix+lives)
+pauseMenu:
+  psh bc
+pmenuwaitkey:
+  cal ubergetkey
+  or  a
+  jr  z,pmenuwaitkey
+  pop bc ;GET_KEY
+  ld  d,b ;c=new b
+  cp  K_UP
+  jr  nz,pmenunotup
+  dec d
+pmenunotup:
+  cp  K_DOWN
+  jr  nz,pmenunotdown
+  inc d
+pmenunotdown:
   psh af
-  ld  de,10
-  ld  a,(Gametype)
-  cp  gamectf ;ctf no death penalty
-  cal nz,DecScore
+  cal menupos
+  ld  a,d ;new pos
+  and 3 ;0-3
+  ld  b,a
+  cal menupos
   pop af
-  ret nz ;HandleWorm done
-  ld  a,(wormbeglives)
-  or  a ;0=no live limit
-  ret z ;don't end game
-  ld  a,(gameCar)
-  and _datatime
-  jr  z,anyworm ;quit at any worm's death
-  ld  a,(nrworms) ;timematch: all worms must've died
-  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
-#endif
+  cp  K_ENTER
+  jr  z,pselect
+  cp  K_SECOND
+  jr  nz,notpselect
+pselect:
+  ld  a,b
+  or  a ;1: continue
+  jr  z,donepausing
+  dec a ;2: off
+  jr  z,turnoff
+  dec a ;3: contrast
+  jr  z,pauseMenu
+  jr  Exit ;4: exit
+notpselect
+  cp  K_EXIT
+  jr  z,donepausing
+  ld  hl,CONTRAST
+  sub K_LEFT
+  jr  z,contrastdown
+  dec a ;K_RIGHT
+  jr  nz,pauseMenu
+contrastup:
+  inc (hl)
+  jr  setcontrast
+contrastdown:
+  dec (hl)
+setcontrast:
+  ld  a,(hl)
+  out (2),a
+  jr  pauseMenu
+
+turnoff:
+  ld  bc,$0103
+  out (c),b
+  halt ;pause/off
+  ld  b,11
+  out (c),b
+  ld  b,1
+  jr  pauseMenu
+
+donepausing:
+  cal releasekeys
+  jp  GameLoop
 
 Exit:
   cal releasekeys
@@ -2152,7 +2231,7 @@ respawncheck:
   jr  nz,unnamedlabel
   cal saverespawncounter
 removeworm:
-  ld  h,(ix+tail+1)
+  ld  h,(ix+tail+1) ;&
   ld  l,(ix+tail)
   ld  d,(ix+head+1)
   ld  e,(ix+head)
@@ -2255,7 +2334,9 @@ inlink:
   ld  l,c
   ret
 
+;-----------------------------
 ;------- handle worm ---------
+;-----------------------------
 
 HandleWorm:
   xor a
@@ -2414,7 +2495,7 @@ peagrowth =$-1
   pop hl                         ; << call
   pop hl                         ; << call
   ld  (ix+delay),2
-  jp  StartLevel
+  jp  Nextlevel
 
 chkpeahit: ;bc=ownpos;hl=peapos (destr:ad)
   ld  a,(sprsize)
@@ -2743,6 +2824,64 @@ Seed =$+1
   add a,2
   ret
 
+WormDead:
+#ifdef invincible
+  jp  stopworm
+#else
+  ld  a,2
+  ld  (flashtime),a
+  ld  (ix+delay),respawndelay
+
+thislevel =$+1
+  ld  hl,0
+  ld  de,0
+handledworm =$-2
+  add hl,de
+  add hl,de
+  add hl,de
+  ld  a,(hl)
+  inc hl
+  ld  (ix+heading),a
+  ld  a,(hl)
+  ld  (ix+pos),a ;y
+  inc hl
+  ld  a,(hl)
+  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)
+  psh af
+  ld  de,10
+  ld  a,(Gametype)
+  cp  gamectf ;ctf no death penalty
+  cal nz,DecScore
+  pop af
+  ret nz ;HandleWorm done
+  ld  a,(wormbeglives)
+  or  a ;0=no live limit
+  ret z ;don't end game
+  ld  a,(gameCar)
+  and _datatime
+  jr  z,anyworm ;quit at any worm's death
+  ld  a,(nrworms) ;timematch: all worms must've died
+  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
+#endif
+
 CheckPea: ;@hl; destr:abcde
   ld  c,l
   ld  a,(sprsize)
@@ -2779,6 +2918,24 @@ tryDrawPea: ;hl=peapos;bc=dopea
   jr  z,DrawPea
   ret
 
+sendnewpeaoverlink:
+  ld  a,(gameCar)
+  rra ;and _datalink
+  ret nc ;no link
+  ld  a,(ix+left)
+  or  a
+  jr  z,receivenewpeaoverlink
+  ld  c,l ;send pea's pos
+  cal Qsend
+  ld  c,h
+  jp  Qsend ;&&&possible jr
+receivenewpeaoverlink:
+  cal Qrecv ;Crecv
+  ld  l,c
+  cal Qrecv ;Crecv
+  ld  h,c
+  ret
+
 NewPea:
   ld  a,(FieldWidth)
   add a,127-4
@@ -2788,9 +2945,10 @@ NewPea:
   add a,56-4
   cal randompos
   ld  l,a
-  ld  (PeaY),hl
   cal CheckPea
   jr  nz,NewPea
+  cal sendnewpeaoverlink
+  ld  (PeaY),hl
 DrawPea: ;hl=(PeaY)
   ld  b,h
   ld  c,l
@@ -2838,9 +2996,12 @@ nextbitok:
 
 ;----------- score -----------
 
-timematchscore: ;piece of crap checking whether you've already won in timematch
+timematchscore:
+  ;piece of crap checking whether you've already won in timematch
   ld  a,(nrworms)
   ld  b,a ;# of worms
+  dec a
+  ret z ;singleplayer
   ld  hl,worm1+lives
   ld  de,worm2-worm1
   ld  a,(handledworm)
@@ -3588,24 +3749,35 @@ line4sm:
   dnz LineLoopSteep
   jr  DoneLine
 
+;..and last but not least..:
 ;-----------------------------
 ;----------- link ------------
 ;-----------------------------
 
+timeout = $8000
+lossout = 20
+
 linkok:
   ld  a,D0HD1H
-  out (7),a    ;raise both wires = link ok
+  out (7),a            ;raise both wires = link ok
   ret
 
-timeout = $8000
-lossout = 20
-
 checklink:             ;load wires in A and check for timeout
   dec de               ;decrease timer
   ld  a,d
   or  e
-  jr  nz,linkfine      ;ok if de>0
-;de==0 = timeout
+  jr  z,linktimeout    ;timeout if de==0
+linktest:
+  ld  a,$BF
+  out (1),a            ;select keys
+  in  a,(1)            ;input
+  bit 6,a              ;exit key
+  jp  z,Exit           ;break!
+linkfine:
+  in  a,(7)
+  and %11
+  ret
+linktimeout: ;de==0
   cal linkok
   ld a,0               ;losses so far
 linklosses =$-1
@@ -3616,27 +3788,13 @@ linklosses =$-1
   ret c                ;otherwise just continue
 linkerr:
   jp  Exit
-linkfine:
-  in  a,(7)
-  and %11
-  ret
 
 ;---- SEND ----
 
-Csend:
-  ld  b,32
-csendwait:
-  nop
-  dnz csendwait
-  cal Qsend
-  jr  c,Csend
-  ret
-
-Qsend:         ;try to send 8 bits in C; CF=error --- destr:abcde
+Qsend:         ;--- try to send 8 bits in C; CF=error --- destr:abcde ---
   nop \ nop
-  in  a,(7)
-  and %11              ;both wires low = exit signal
-  jr  z,linkerr        ;error otherwise
+  cal linkfine
+  jr  z,linkerr                ;both wires low = exit signal
   ld  b,8              ;bits to send
 sendloop:
   ld  de,timeout
@@ -3649,8 +3807,7 @@ sendbit:
 sendwaitack:
   cal checklink                ;other calc must lower other wire
   jr  nz,sendwaitack
-  ld  a,D0HD1H         ;raise one, ok to raise other
-  out (7),a
+  cal linkok           ;raise one, ok to raise other (out (7),D0HD1H)
 sendfinish:
   cal checklink
   cp  %11              ;both raised (by other calc)
@@ -3663,22 +3820,22 @@ sendfinish:
 
 ;---- RECV ----
 
-Crecv:         ;--- receive 8 bits into A/C --- destr:abcdehl ---
+Crecv:         ;--- receive 8 bits into A/C --- destr:abCde ---
   cal Qrecv
   ret nc               ;return if all went ok
   jr  Crecv            ;and try again
 
-Qrecv:         ;--- receive 8 bits into A/C; CF=error --- destr:abcde ---
-  in  a,(7)
-  and %11
+Qrecv:         ;--- receive 8 bits into A/C; CF=error --- destr:abCde ---
+  cal linkfine
   jr  z,linkerr        ;both low = error, quit
   ld  b,8              ;bits to receive
 recvloop:
-  ld  de,timeout
+;  ld  de,timeout
 recvwait:
-  cal checklink
+  cal linktest ;checklink
   cp  %11
   jr  z,recvwait       ;both high = nothing sent (yet)
+  ld  de,timeout
   rra                  ;received bit in cf
   ld  a,D0LD1H
   jr  c,received       ;lower white wire as well
@@ -3689,8 +3846,7 @@ received:
 recvwaitack:
   cal checklink
   jr  z,recvwaitack    ;same wire will be raised again by other calc
-  ld  a,D0HD1H
-  out (7),a            ;raise both
+  cal linkok           ;raise both
 recvfinish:
   dnz recvloop         ;repeat for all bits
   xor a                        ;nc=no error
@@ -3702,6 +3858,7 @@ recvfinish:
 ;---------- levels -----------
 ;-----------------------------
 
+;&&&&& 99%
 LevelDef:
   .db 5,4,15,15,0,0    ;peas,speed,growth,begin_size,sprite,balls
   .db 0,2,63           ;start d, y, x
@@ -3762,7 +3919,7 @@ LevelDefC: ;ctf
 ;---------- data -------------
 ;-----------------------------
 
-wtPicture:
+wtPicture: ;title
 .db %00011110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000001,%11000000,%00000000,%00000000,%00000001,%10000000,%00000000,%00001111,%10000000
 .db %00111110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000001,%11100000,%00000000,%00000011,%11000010,%01000011,%10011100,%00110000,%01100000
 .db %01110000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01110000,%00111000,%00001100,%00110001,%00110100,%01100011,%01000000,%00010000
@@ -3780,7 +3937,7 @@ wtPicture:
 .db %00011111,%11101111,%11110000,%00111111,%10000111,%00000001,%10000000,%00000011,%11111111,%11110000,%00111110,%00011110,%00010111,%01011101,%10010101,%01100101
 .db %00001111,%10000011,%11100000,%00011111,%00000011,%00000001,%10000000,%00000000,%11111111,%11100000,%00000000,%00000000,%11100101,%01010101,%01000110,%01010011
 
-wtWormy:
+wtWormy: ;g/o
 .db %00000110,%00111000,%00000000,%00111100,%00001111,%10001110,%00111100,%01111000,%00001100,%11011000,%11100011,%10000000,%00000000,%11111100,%00111000,%00000000
 .db %00011001,%01000110,%11100000,%11000010,%00011100,%11011111,%01111110,%11111000,%00011110,%11011101,%11110111,%11000000,%00111111,%00000011,%01000110,%11100000
 .db %00100000,%10000011,%00010001,%00110010,%00011000,%00010011,%01101010,%11000000,%00111011,%01001101,%10000110,%01000000,%11000000,%00000000,%10000001,%00010000
@@ -3796,8 +3953,8 @@ txtMenu:  .db "Mode",0  ;1st menu item
          .db "Link",0  ;...
          .db "Worms",0
          .db "worm #",0
-         .db 0
-posMenu:  .dw $2418,$231E,$2824,$1F2A,$1730,$1936
+posMenu:  .db 5
+         .dw $2418,$231E,$2824,$1F2A,$1730
 txtMenuR: .db "controls",0
 txtoMenu: .db "Back",0  ;1st menu item
          .db "Lives",0 ;2nd
@@ -3805,7 +3962,14 @@ txtoMenu: .db "Back",0  ;1st menu item
          .db "Speed",0
          .db "Rotation",0
          .db "Growth",0
-posoMenu: .dw $2618,$251E,$2524,$222A,$1A30,$1C36
+posoMenu: .db 6
+         .dw $2618,$251E,$2524,$222A,$1A30,$1C36
+txtpMenu: .db "Resume",0  ;1st menu item
+         .db "Turn Off",0 ;2nd
+         .db "Contrast",$CF,5,0  ;...
+         .db "Exit",0
+pospMenu: .db 4
+         .dw $3418,$331E,$2F24,$3A2A
 txtGame:  .db "Singleplayer",0
 txtGame1: .db "Peaworm",0
 txtGame2: .db "Tron",0
@@ -3866,7 +4030,7 @@ datalevels: .dw LevelDef, LevelDefM
             .dw LevelDefT,LevelDefM
             .dw LevelDefM,LevelDefM
             .dw LevelDefR,LevelDefC
-nrlevels:   .db 1,3,1,3,3,3,3,1     ;=defaults
+nrlevels:   .db 0,3,1,3,3,3,3,1     ;=defaults
 
 _datalink      = %0000001 ;linkplay
 _datafoodl     = %0000010 ;left=0 limit
@@ -3940,7 +4104,7 @@ head     = 13  ;4B (head=tail)
 tail     = 15  ;also@next level
 storepos = 17
 reserv   = 18  ;loop (race:lap|ctf:pea)
-input    = 19
+input    = 19 ;---currently unused afaik---
 left     = 20
 right    = 21
 name     = 22
@@ -3950,6 +4114,7 @@ startdelay    = 30
 respawndelay  = 30
 maxnamelength = 8+1
 
+;bla space (reserved for internal levels)
 .db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
 .db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
 .db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
@@ -3988,7 +4153,9 @@ defspriteimg:     .db %01100000
                .db %01100000
 
 deflevels:
-  .db "Internal Levels" ;,0
+  .db "Internal Levels",0
+  .db "by SHIAR -- still t"
+  .db "o be added...." ;,0
 
   .db 0,deflevels/256,deflevels&255
 templevels: