worm 0.91.0524: further link improvements
[wormy.git] / worm.z80
index d5b88d118fd333243bd3847e680083471f60ded9..22e6fec05c517897bfb9482deec68ed6210d3bc1 100644 (file)
--- a/worm.z80
+++ b/worm.z80
@@ -1,7 +1,7 @@
 ; Title                      : Worm
 ; Title                      : Worm
-; Version                    : 89%
-; Release Date               : april 2000???
-; Filename                   : worm.86p (4kb)
+; Version                    : 91%
+; Release Date               : may 2000
+; Filename                   : worm.86p (5kb)
 ; Author(s)                  : Shiar
 ; Email Address              : shiar@mailroom.com
 ; ICQ UIN                    : #43840958
 ; Author(s)                  : Shiar
 ; Email Address              : shiar@mailroom.com
 ; ICQ UIN                    : #43840958
 ;----------- TO-DO -----------
 ;-----------------------------
 
 ;----------- TO-DO -----------
 ;-----------------------------
 
-; 89% = DONE
+; 91% = DONE
 
 
-;  3% * linkplay
-;  1% * titlescreen
+;  2% * fix deaths linkplay and transmit game/level data
 ;  2% * make linkplay available for all gametypes (not just deathmatch)
 ;  2% * make linkplay available for all gametypes (not just deathmatch)
-;     * game types:
-;  1%   * ctf: take enemy flag (right-bottom) and return to your flag (left-top)
-;  1%   * domination?: take control points by running over them and hold them
+;  1% * fix pea XOR problem in ctf (+dom?)
+;     * fix wormstop
+;  1% * domination?: take control points by running over them and hold them
+;     * customizable keys
 ;     * complete readme (+custom level info)
 ;  2% * ... (pollish, &&&)
 
 ;     * complete readme (+custom level info)
 ;  2% * ... (pollish, &&&)
 
 ;-----------------------------
 ;-----------------------------
 
 ;-----------------------------
 ;-----------------------------
 
+#define buffer      ;use display buffer (otherwise write directly to screen)
+#define readymask   ;"grays" out the field before starting a level
+
+;#define readytext  ;displays "prepare" before level starts
+;#define invincible ;worms cannot die =)
+
 #define cal call
 #define psh push
 #define dnz djnz
 #define cal call
 #define psh push
 #define dnz djnz
@@ -68,34 +74,47 @@ _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
 _mm_ldir           = $52ED ;24bit ldir
 _RAM_PAGE_1        = $47E3 ;set $8000+ to page 1
 _RAM_PAGE_7        = $47F3
-_PTEMP_END         = $D29A
+_PTEMP_END         = $D29A ;end of VAT
 _load_ram_ahl      = $462F ;ahl->page+hl
 _writeb_inc_ahl    = $5567 ;ld (ahl),c
 _load_ram_ahl      = $462F ;ahl->page+hl
 _writeb_inc_ahl    = $5567 ;ld (ahl),c
+_jforce            = $409C ;TI-OS stack restored
+_EXLP              = $4493 ;swap (hl),(de) b times
 
 ;-----------------------------
 ;------- data  storage -------
 ;-----------------------------
 
 
 ;-----------------------------
 ;------- data  storage -------
 ;-----------------------------
 
-leveldata   = $EA00 ;size< $400
-ScrBuffer   = $8100 ;size=$2000 (32x256)
-         ;->mod$800
-templevels  = $BC00 ;size= 3*$10
-DispBuffer  = $BC00 ;size= $390 (16x57)
-SinCosTable = $B500 ;size= $100  (4x64)
-
-worm1 = $B400
-worm2 = $B41E
-worm3 = $B43C
-worm4 = $B45A
-ball1 = $B478
-
-resbit  = 2   ;and%11111011
-worm1p = $B000   ;%10110000 -$B3FF
-worm2p = $B800   ;%10111000 -$BBFF
-worm3p = $F000   ;%11110000 -$F3FF
-worm4p = $A800   ;$E800=%11101000 ;$D748+$1000+
-
-WormVersion = 088
+;--- permanent
+
+ScrBuffer   = $8820 ;-A7FF (20*FF=1FE0)
+worm2p      = $A800 ;-ABFF (400)      %10101O00
+worm1       = $AC00 ;-AC1D (31d)
+worm2       = $AC1F ;-AC3B (1F)
+worm3       = $AC3E ;-AC59 (1F)
+worm4       = $AC5D ;-AC77 (1F)
+balls       = $AC7C ;-ACFF (3x43d)
+SinCosTable = $AD00 ;-AE00 (4x40)
+        ;free $AE01 ;-AFFF (1FF)
+worm1p      = $B000 ;-B7FF (800)      %1011O000
+worm3p      = $B800 ;-BBFF (400)      %10111O00
+        ;free $BF91 ;-BFFF (6F)
+
+     ;program $D748 ;-E7FF (106D+4A)
+        ;free $E800 ;-EFFF (800)
+worm4p      = $F000 ;-F3FF (400)      %11110O00
+leveldata   = $F400 ;-FA70 (<=671)
+
+peaspos = $AE01
+
+;--- temporary
+
+templevels  = $BC00 ;(3*strings) @init
+namelength  = $BC00 ;(1)         @menu
+#ifdef buffer
+DispBuffer  = $BC00 ;(10x57d)    @game
+#else
+DispBuffer  = $FC70
+#endif
 
 ;-----------------------------
 ;------- program start -------
 
 ;-----------------------------
 ;------- program start -------
@@ -103,6 +122,8 @@ WormVersion = 088
 
 .org _asm_exec_ram
 
 
 .org _asm_exec_ram
 
+WormVersion = 091
+
 start:
   nop
   jp Start
 start:
   nop
   jp Start
@@ -111,7 +132,7 @@ start:
   .dw WormIcon
 
 WormMsg:
   .dw WormIcon
 
 WormMsg:
-  .db "WORM by SHIAR -- pre-beta 89%",0
+  .db "WORM by SHIAR -- pre-beta 91%",0
 WormIcon:
   .db 9,2
   .db %10010110,%01101111
 WormIcon:
   .db 9,2
   .db %10010110,%01101111
@@ -124,20 +145,19 @@ WormIcon:
   .db %11101111,%00001111
   .db %11000011,%10000000
 
   .db %11101111,%00001111
   .db %11000011,%10000000
 
-levelhead  = '8'
-levelhead2 = '9' ;worm levels header = "89"
+levelhead  = 'w'
+levelhead2 = 91 ;worm levels header = "91"
 
 Start:
   ld  (SpSave),sp
   cal _runindicoff
   cal _flushallmenus
 
 Start:
   ld  (SpSave),sp
   cal _runindicoff
   cal _flushallmenus
-  cal _clrLCD
 
   cal _RAM_PAGE_7
   ld  hl,$BFFF ;VAT start
   ld  bc,templevels
 searchloop:
 
   cal _RAM_PAGE_7
   ld  hl,$BFFF ;VAT start
   ld  bc,templevels
 searchloop:
-  ld  de,(_PTEMP_END+1)
+  ld  de,(_PTEMP_END+1) ;VAT end
   or  a ;nc
   sbc hl,de ;hl<de?
   jr  c,searchcomplete
   or  a ;nc
   sbc hl,de ;hl<de?
   jr  c,searchcomplete
@@ -147,6 +167,7 @@ searchloop:
   cp  $0C ;string
   jr  z,stringfound
 searchnext:
   cp  $0C ;string
   jr  z,stringfound
 searchnext:
+ cal _RAM_PAGE_7
   pop hl
   dec hl ;5x
   dec hl
   pop hl
   dec hl ;5x
   dec hl
@@ -188,7 +209,6 @@ stringfound:
  ld a,l
  ld (bc),a
  inc bc
  ld a,l
  ld (bc),a
  inc bc
- cal _RAM_PAGE_7
  jr searchnext
 
 loadgametype:
  jr searchnext
 
 loadgametype:
@@ -222,13 +242,17 @@ searchcomplete:
   or  a
   sbc hl,bc
   pop hl
   or  a
   sbc hl,bc
   pop hl
-  jp  z,levelloaded ;no ext files
+  jp  z,_clrWindow ;no ext files: exit
 dispnextlevel:
   cal _RAM_PAGE_1
   psh hl
   cal _clrWindow
 dispnextlevel:
   cal _RAM_PAGE_1
   psh hl
   cal _clrWindow
-  ld  a,4
+  ld  a,2
   ld  (_curRow),a
   ld  (_curRow),a
+  ld  hl,txtLevsel
+  cal _puts ;"< Select levels: >"
+  ld  hl,$0004
+  ld  (_curRow),hl
   pop hl
   ld  a,(hl)
   cp  255
   pop hl
   ld  a,(hl)
   cp  255
@@ -342,17 +366,32 @@ NegativeSineWave:
   ld  (curlevel),a
 DisplayMenu:
   cal _clrWindow
   ld  (curlevel),a
 DisplayMenu:
   cal _clrWindow
-  ld  hl,txtWelcome
-  cal _puts
+  ld  de,$FC42 ;(10,2)
+  ld  hl,wtPicture
+  ld  a,16 ;height
+disptitleloop:
+  ld  bc,8 ;width
+  ldir
+  ex  de,hl
+  ld  bc,8 ;next line
+  add hl,bc
+  ex  de,hl
+  dec a
+  jr  nz,disptitleloop
+
+  ld  hl,txtMenu
+  ld  de,$0D5A
+  ld  (_penCol),de
+  cal _vputs ;by Shiar
   ld  de,$0207
   ld  (_curRow),de
   cal _puts ;---
   dec e ;$0206
   ld  (_curRow),de
   ld  de,$0207
   ld  (_curRow),de
   cal _puts ;---
   dec e ;$0206
   ld  (_curRow),de
-  cal _puts ;Level
+  cal _puts ;Level <00>
   dec e ;$0205
   ld  (_curRow),de
   dec e ;$0205
   ld  (_curRow),de
-  cal _puts ;Worms: 2
+  cal _puts ;Worms <2>
   dec e ;$0204
   ld  (_curRow),de
   ld  hl,(CURtxtGame)
   dec e ;$0204
   ld  (_curRow),de
   ld  hl,(CURtxtGame)
@@ -372,6 +411,8 @@ select:
 notselect
   cp  K_EXIT
   jp  z,ExitNoStats
 notselect
   cp  K_EXIT
   jp  z,ExitNoStats
+  cp  K_LEFT
+  jr  z,selleft
   cp  K_RIGHT
   ld  a,b
   jr  nz,mainMenu
   cp  K_RIGHT
   ld  a,b
   jr  nz,mainMenu
@@ -389,18 +430,32 @@ changelevel:
   ld  hl,nrlevels
   add hl,de
   ld  d,(hl) ;max level for sel.game
   ld  hl,nrlevels
   add hl,de
   ld  d,(hl) ;max level for sel.game
+curlevel =$+1
   ld  a,1
   ld  a,1
-curlevel =$-1
   inc a
   cp  d
   jr  c,changedlevel
   inc a
   cp  d
   jr  c,changedlevel
-  ld  a,1
+  ld  a,d
 changedlevel:
   ld  (curlevel),a
 changedlevel:
   ld  (curlevel),a
-dispcurlevel:
-  ld  hl,$0806
+_dispcurlevel:
+  ld  hl,$0906
   ld  (_curRow),hl
   cal showA
   ld  (_curRow),hl
   cal showA
+_mainMenu:
+  jr  mainMenu
+
+selleft:
+  ld  a,b
+  dec a
+  jr  z,bchangenrworms
+  dec a
+  jr  nz,mainMenu
+
+bchangelevel:
+  ld  a,(curlevel)
+  dec a
+  jr  nz,changedlevel
   jr  mainMenu
 
 changegame:
   jr  mainMenu
 
 changegame:
@@ -422,33 +477,42 @@ okilydokily:
   cal _puts
   ld  (NEXTtxtGame),hl
 howmanyworms:
   cal _puts
   ld  (NEXTtxtGame),hl
 howmanyworms:
+  ld  hl,nrworms
   ld  a,(Gametype)
   cp  2
   ld  a,(Gametype)
   cp  2
-  ld  a,1
-  jr  c,oneworm
-nrworms =$+1
-  ld  a,2
-oneworm:
-  jr  dispnrworms ;jr mainMenu
+  ld  (hl),1
+  jr  c,dispnrworms
+  inc (hl) ;2
+  jr  dispnrworms ;mainMenu
 
 changenrworms:
   ld  a,(Gametype)
 
 changenrworms:
   ld  a,(Gametype)
-  cp  2
-  jr  c,mainMenu ;type 0/1
+  cp  2 ;&&
+  jr  c,_mainMenu ;type 0/1
   ld  hl,nrworms
   ld  a,(hl)
   inc a
   cp  5
   ld  hl,nrworms
   ld  a,(hl)
   inc a
   cp  5
-  jr  c,changednrworms
-  ld  a,1
+  jr  nc,dispcurlevel
 changednrworms:
   ld  (hl),a
 dispnrworms:
 changednrworms:
   ld  (hl),a
 dispnrworms:
+  ld  a,(hl) ;hl=nrworms
   ld  hl,$0905
   ld  (_curRow),hl
   ld  hl,$0905
   ld  (_curRow),hl
-  cal showA
+  add a,'0'
+  cal _putc
+dispcurlevel
   ld  a,(curlevel)
   ld  a,(curlevel)
-  jr  dispcurlevel ;mainMenu
+  jr  _dispcurlevel ;mainMenu
+
+bchangenrworms:
+  ld  hl,nrworms
+  ld  a,(hl)
+  dec a
+  cp  2 ;2-4
+  jr  nc,changednrworms
+  jr  dispcurlevel
 
 menucall:
   psh bc
 
 menucall:
   psh bc
@@ -496,21 +560,31 @@ menudraw:
 
 changeworms:
   cal _clrWindow
 
 changeworms:
   cal _clrWindow
+  ld  hl,txtName
+  cal _puts ;"Enter name player "
   ld  a,(Gametype)
   cp  2
   ld  a,1
   jr  c,wormnrname
   ld  a,(Gametype)
   cp  2
   ld  a,1
   jr  c,wormnrname
-  ld  a,(nrworms)
+nrworms =$+1
+  ld  a,1
 wormnrname:
 wormnrname:
+  add a,'0'
+  cal _putc
+  sub '0'
+
+  ld  d,a  ;1x
   add a,a  ;2x
   ld  e,a
   add a,a  ;4x
   add a,a  ;8x
   add a,a ;16x
   add a,e ;18x
   add a,a  ;2x
   ld  e,a
   add a,a  ;4x
   add a,a  ;8x
   add a,a ;16x
   add a,e ;18x
+  add a,d ;19x
   ld  e,a
   ld  e,a
-  ld  d,0
-  ld  ix,worm1name-18
+  ld  d,0 ;de=a
+
+  ld  ix,worm1name-19
   add ix,de
   ld  a,maxnamelength
   cal entername
   add ix,de
   ld  a,maxnamelength
   cal entername
@@ -518,6 +592,9 @@ wormnrname:
   jp  DisplayMenu
 
 entername:
   jp  DisplayMenu
 
 entername:
+  ld  h,1
+  ld  l,h ;)
+  ld  (_curRow),hl
   ld  (namelength),a
 enternameloop:
   ld  a,'_'
   ld  (namelength),a
 enternameloop:
   ld  a,'_'
@@ -578,16 +655,14 @@ waitnokeypressed:
   jr  nz,waitnokeypressed
   ret
 
   jr  nz,waitnokeypressed
   ret
 
-namelength:
-  .db 0
 chartable:
 chartable:
-  .db 0,"!<>^",0,0,0,0
-  .db 0,"xtoje0",0      ;enter..clear
-  .db " wsnid9",0       ;(-)..custom
-  .db "zvrmhc8",0       ;dot..del
-  .db "yuqlgb7*"        ;0..xvar
-  .db 0,"-pkfa6'"       ;on..alpha
-  .db "54321.",0,0      ;F5..more
+  .db 0,".<>!",0,0,0,0  ;down,L,R,up
+  .db 0,"XTOJE0",0      ;enter..clear
+  .db " WSNID9",0       ;(-)..custom
+  .db "ZVRMHC8",0       ;dot..del
+  .db "YUQLGB7#"        ;0..xvar
+  .db $D9,"-PKFA6'"     ;on..alpha
+  .db "54321*",0,$D0    ;F5..more
 
 ;--proc
 
 
 ;--proc
 
@@ -618,6 +693,17 @@ skipworms:
 skipballs:
   inc hl
   dnz skipballs
 skipballs:
   inc hl
   dnz skipballs
+
+skipflags:
+  ld  a,(Gametype)
+  cp  gamectf
+  jr  nz,noflagstoskip
+  inc hl
+  inc hl
+  inc hl
+  inc hl
+noflagstoskip:
+
   cal skiplines ;lines
 skiplines: ;boxes
   ld  a,(hl) ;lines/boxes
   cal skiplines ;lines
 skiplines: ;boxes
   ld  a,(hl) ;lines/boxes
@@ -625,6 +711,7 @@ skiplines: ;boxes
   add a,a
   inc a
   ld  b,a ;4x(hl)+1
   add a,a
   inc a
   ld  b,a ;4x(hl)+1
+
 skiplb
   inc hl
   dnz skiplb
 skiplb
   inc hl
   dnz skiplb
@@ -684,28 +771,68 @@ linkmatch:
   cal _clrWindow
   ld  a,WormVersion
   cal send
   cal _clrWindow
   ld  a,WormVersion
   cal send
-  jr  c,client ;2nd
+  jr  nc,client ;2nd
 
 host:
   ld  hl,txtWaiting
   cal _puts
   cal receive
   cp  WormVersion
 
 host:
   ld  hl,txtWaiting
   cal _puts
   cal receive
   cp  WormVersion
-  jp  nz,LinkBreak
+;  jp  nz,linkiniterror
   cal send
   cal send
+ jr c,linkiniterror
 
 
-  ld  hl,SwapPos
-  ld  (hl),$f6
+;  cal sendname
+;  cal receivename
+
+  ld  a,$18
   jr  multiplayer
 
   jr  multiplayer
 
+linkiniterror:
+  pop hl
+  jp  DisplayMenu
+
+sendname:
+  ld  hl,worm1+name
+  ld  b,maxnamelength
+sendnameloop:
+  ld  a,(hl)
+  inc hl
+  psh bc
+  psh hl
+  cal send
+  pop hl
+  pop bc
+;  dnz sendnameloop
+  ret
+receivename:
+  ld  hl,worm2+name
+  ld  b,maxnamelength
+recvnameloop:
+  psh bc
+  psh hl
+  cal receive
+  pop hl
+  pop bc
+  ld  (hl),a
+  inc hl
+;  dnz recvnameloop
+  ret
+
 client:
   ld  hl,txtReceive
   cal _puts
 client:
   ld  hl,txtReceive
   cal _puts
-  cal receive
+  cal Qreceive
+  jp  c,linkiniterror
   cp  WormVersion
   cp  WormVersion
-  jp  nz,LinkBreak
+;  jp  nz,linkiniterror
 
 
+;  cal receivename
+;  cal sendname
+
+  ld  a,$f6
 multiplayer:
 multiplayer:
+  ld  (SwapPos),a
   ld  a,2
   ld  (nrworms),a
 
   ld  a,2
   ld  (nrworms),a
 
@@ -715,42 +842,33 @@ multiplayer:
 
 GameOver:
   cal _clrLCD
 
 GameOver:
   cal _clrLCD
-  ld  hl,0
-  ld  (worm1+died),hl
-;+died=0 \ +score1=0
-  ld  (worm2+died),hl
-  ld  (worm3+died),hl
-  ld  (worm4+died),hl
-  inc h
-  ld  (worm1+score+1),hl
-;+score2=0 \ +delay=1
-  ld  (worm2+score+1),hl
-  ld  (worm3+score+1),hl
-  ld  (worm4+score+1),hl
-  ld  hl,worm1set+4
-  ld  de,worm1+lives
-;&&&>*
-  cal _MOV5B ;9xld(de),(hl)
-  cal _mov9b
-  ld  hl,worm2set+4
-  ld  de,worm2+lives
-  cal _MOV5B
-  cal _mov9b
-  ld  hl,worm3set+4
-  ld  de,worm3+lives
-  cal _MOV5B
-  cal _mov9b
-  ld  hl,worm4set+4
-  ld  de,worm4+lives
-  cal _MOV5B
-  cal _mov9b
+  ld  hl,worm1set
+  ld  de,worm1
+  ld  a,4 ;4x (all worms)
+createwormsloop:
+  ex  de,hl
+  ld  bc,died
+  add hl,bc
+  ld  (hl),0 ;died=0
+  inc hl
+  ld  (hl),0 ;score=0
+  inc hl
+  ld  (hl),0 ;score+1=0
+  inc hl
+  ld  (hl),2 ;delay=2
+  inc hl
+  ex  de,hl  ;de=wormX+head
+  ld  bc,19
+  ldir       ;copy 19 bytes
+  dec a      ;loop
+  jr  nz,createwormsloop
 
   ld  a,(Gametype)
   cp  1 ;=peaworm
   jr  nz,worminitdone
 
   ld  a,(Gametype)
   cp  1 ;=peaworm
   jr  nz,worminitdone
-  ld  (worm1+lives),a ;&&&<*
+  ld  (worm1+lives),a
 worminitdone:
 worminitdone:
-  pop hl
+  pop hl ;begin of current level
 
 StartLevel:
   ld  de,Left
 
 StartLevel:
   ld  de,Left
@@ -759,10 +877,7 @@ StartLevel:
   jp  nz,nextlevel
 
   psh hl
   jp  nz,nextlevel
 
   psh hl
-  ld  b,150
-waitsomemore:
-  halt
-  dnz waitsomemore
+  cal releasekeys
   cal _clrWindow
   pop hl
 ;show end msg or smtn
   cal _clrWindow
   pop hl
 ;show end msg or smtn
@@ -811,35 +926,14 @@ setsprite:
   add a,c
   ld  c,a
   ld  b,0
   add a,c
   ld  c,a
   ld  b,0
-  ld  de,ball1
+  ld  de,balls
   ldir
 toobad_noballs:
 
   ldir
 toobad_noballs:
 
-#ifdef 0
-  ld  a,(gameCar)
-  and _datahunt
-  jr  z,nohunter
-  ld  a,huntersize
-  ld  (worm2+grow),a
-nohunter:
-#endif
-
   ex  de,hl
   ex  de,hl
+#ifndef invincible
   ld  (thislevel),de
   ld  (thislevel),de
-  psh de
-  ld  hl,worm1set
-  ld  de,worm1+head
-  cal _MOV4B
-  ld  hl,worm2set
-  ld  de,worm2+head
-  cal _MOV4B
-  ld  hl,worm3set
-  ld  de,worm3+head
-  cal _MOV4B
-  ld  hl,worm4set
-  ld  de,worm4+head
-  cal _MOV4B
-  pop de
+#endif
 
   ld  hl,worm1
   ld  a,(gameCar)
 
   ld  hl,worm1
   ld  a,(gameCar)
@@ -939,9 +1033,21 @@ NoVertShift:
   ld  c,64
   ldir
 
   ld  c,64
   ldir
 
-;-draw lines-
 
   pop hl                         ; << levelp
 
   pop hl                         ; << levelp
+  ld  a,(Gametype)
+  cp  gamectf
+  jr  nz,noctf
+  ld  de,peaspos
+  ld  bc,4
+  ldir
+  psh hl
+  cal DrawAllPeas
+  pop hl
+noctf:
+
+;-draw lines-
+
   ld  a,(hl)
   inc hl
   or  a
   ld  a,(hl)
   inc hl
   or  a
@@ -998,6 +1104,27 @@ noboxes:
 nofood:
   ld  bc,(worm1+pos)
   cal DisplayField
 nofood:
   ld  bc,(worm1+pos)
   cal DisplayField
+
+#ifdef readymask
+  ld  hl,$FC70
+  ld  d,%10101010
+  ld  c,56
+maskloop:
+  ld  a,d
+  xor %11111111
+  ld  d,a
+  ld  b,$10
+maskline:
+  ld  a,(hl)
+  or  d
+  ld  (hl),a
+  inc hl
+  dnz maskline
+  dec c
+  jr  nz,maskloop
+#endif
+
+#ifdef readytext
   ld  hl,$FDE0
   ld  de,$FDE1
   ld  (hl),%11111111
   ld  hl,$FDE0
   ld  de,$FDE1
   ld  (hl),%11111111
@@ -1009,36 +1136,38 @@ nofood:
   ld  hl,txtReady
   cal _puts
   res 3,(iy+5)
   ld  hl,txtReady
   cal _puts
   res 3,(iy+5)
+#endif
 
   ld  a,0
 gameCar =$-1
   and _datalink
 
   ld  a,0
 gameCar =$-1
   and _datalink
-  jr  z,SwapPos ;no link
+  jr  z,initfinished ;no link
+
   xor a
   xor a
-  ld  (worm2+input),a
+  ld  (worm2+input),a ;worm 2 via link
   ld  (worm2+left),a
   ld  (worm2+left),a
-  ld  (Speed),a
-
+  ld  (Speed),a ;max.speed
 SwapPos: ;$18 xx -> $F6 xx
 SwapPos: ;$18 xx -> $F6 xx
+         ; jr xx ->  or xx
   jr  initfinished
   inc a
   jr  initfinished
   inc a
-  ld  (worm2+left),a
-  ld  hl,(worm1+pos)
-  ld  de,(worm2+pos)
-  ld  (worm2+pos),hl
-  ld  (worm1+pos),de
-  ld  a,(worm1+heading)
-  ld  b,a
-  ld  a,(worm2+heading)
-  ld  (worm1+heading),a
-  ld  a,b
-  ld  (worm2+heading),a
+  ld  (worm2+left),a ;1
+  ld  hl,worm1
+  ld  de,worm2
+  ld  b,4 ;+heading +pos
+  cal _EXLP ;swap positions
+;&&& over link
+  ld  hl,worm1+name
+  ld  de,worm2+name
+  ld  b,maxnamelength
+  cal _EXLP ;swap positions
 initfinished:
 
 initfinished:
 
-  ld  b,0
+  ld  b,startdelay
 ReadyDelay:
   halt
   dnz ReadyDelay
 ReadyDelay:
   halt
   dnz ReadyDelay
+  cal releasekeys
 
 ;-----------------------------
 ;----------- LOOP ------------
 
 ;-----------------------------
 ;----------- LOOP ------------
@@ -1074,7 +1203,10 @@ Delay:
   jr  nz,Delay
 NoDelay:
 
   jr  nz,Delay
 NoDelay:
 
-  cal handlethoseneatlittleballs
+  ld  a,0
+nrballs =$-1
+  or  a
+  cal nz,handlethoseneatlittleballs
 
   ld  ix,worm1
   ld  a,(nrworms)
 
   ld  ix,worm1
   ld  a,(nrworms)
@@ -1110,10 +1242,12 @@ CheckExit:
   jr  Exit
 
 WormDead:
   jr  Exit
 
 WormDead:
+#ifdef invincible
+  jp  stopworm
+#else
   ld  a,2
   ld  (flashtime),a
   ld  a,2
   ld  (flashtime),a
-  ld  a,respawndelay
-  ld  (ix+delay),a
+  ld  (ix+delay),respawndelay
 
 thislevel =$+1
   ld  de,0
 
 thislevel =$+1
   ld  de,0
@@ -1139,10 +1273,13 @@ thislevel =$+1
   ld  a,$A7 ;exit@end of turn
   ld  (CheckExit),a ;set exit state
   ret ;finish turn
   ld  a,$A7 ;exit@end of turn
   ld  (CheckExit),a ;set exit state
   ret ;finish turn
+#endif
 
 Exit:
   ld  sp,0 ;pop all
 SpSave = $-2
 
 Exit:
   ld  sp,0 ;pop all
 SpSave = $-2
+  ld  a,D0HD1H
+  out (7),a
   cal _clrWindow
   ld  hl,txtGO
   cal _puts
   cal _clrWindow
   ld  hl,txtGO
   cal _puts
@@ -1170,13 +1307,13 @@ displayWormStats:
   ld  bc,input-died
   add hl,bc ;+input
   xor a
   ld  bc,input-died
   add hl,bc ;+input
   xor a
-  cp  (hl)
+  cp  (hl)  ;input=0 = link
   jr  nz,NoLinkIndic
   jr  nz,NoLinkIndic
-  ld  b,7
+  ld  b,7 ;{DOWN}
   inc hl ;+left
   cp  (hl)
   jr  z,hostLinkIndic
   inc hl ;+left
   cp  (hl)
   jr  z,hostLinkIndic
-  dec b
+  dec b   ;{UP}
 hostLinkIndic:
   ld  a,8
   ld  (_curCol),a
 hostLinkIndic:
   ld  a,8
   ld  (_curCol),a
@@ -1196,9 +1333,9 @@ NoLinkIndic:
   ld  a,13
   ld  (_curCol),a
   ld  a,(hl) ;worm+died
   ld  a,13
   ld  (_curCol),a
   ld  a,(hl) ;worm+died
-  psh hl
   cal showA
   pop hl
   cal showA
   pop hl
+  psh hl
 
   ld  a,16
   ld  (_curCol),a
 
   ld  a,16
   ld  (_curCol),a
@@ -1218,7 +1355,6 @@ NoLinkIndic:
 checkhilevel:
   ld  hl,nrlevels
   ld  a,(Level)
 checkhilevel:
   ld  hl,nrlevels
   ld  a,(Level)
-  inc a
   cp  (hl)
   jr  c,hilevelcheckdone
   ld  (hl),a    ;save local
   cp  (hl)
   jr  c,hilevelcheckdone
   ld  (hl),a    ;save local
@@ -1265,13 +1401,16 @@ NotNewHigh: ;de=current hiscore
   cal showHL
 hiscorecheckdone:
 
   cal showHL
 hiscorecheckdone:
 
+  cal releasekeys
 waitkey:
   halt
   halt
   cal GET_KEY
   cp  K_ENTER
   jp  z,DisplayMenu
 waitkey:
   halt
   halt
   cal GET_KEY
   cp  K_ENTER
   jp  z,DisplayMenu
-;  cp  K_EXIT
+  cp  K_SECOND
+  jp  z,DisplayMenu
+  cp  K_EXIT
   jr  nz,waitkey
 
 ;x123456789012345678901
   jr  nz,waitkey
 
 ;x123456789012345678901
@@ -1301,11 +1440,14 @@ ExitNoStats:
   cal _SET_MM_NUM_BYTES
   cal _mm_ldir
 
   cal _SET_MM_NUM_BYTES
   cal _mm_ldir
 
+  cal releasekeys
   res 4,(iy+9)
   set 2,(iy+13)
   jp  _clrWindow
 
 loadhiscoreposinahl:
   res 4,(iy+9)
   set 2,(iy+13)
   jp  _clrWindow
 
 loadhiscoreposinahl:
+  ld  a,(Level)
+  ld  b,a
   ld  a,(Gametype)
   or  a
 externalhiscoresavepos:
   ld  a,(Gametype)
   or  a
 externalhiscoresavepos:
@@ -1314,63 +1456,19 @@ hiscrposa =$-1
   ld  hl,0
 hiscrposhl =$-2
   ret z ;(Gametype)=0
   ld  hl,0
 hiscrposhl =$-2
   ret z ;(Gametype)=0
-  cal _INC_PTR_AHL
+addlevelposition:
+  cal _AHL_PLUS_2_PG3
+  dnz addlevelposition
   ret
 
 ;-----------------------------
 ;----------- worm ------------
 ;-----------------------------
 
   ret
 
 ;-----------------------------
 ;----------- worm ------------
 ;-----------------------------
 
-inlink:
-  ld  a,0
-sendbyte =$-1
-  ld  b,(ix+left)
-  dec b
-  jr  z,receivefirst
-  cal send
-  cal receive
-  ld  l,a
-  ret
-receivefirst:
-  psh af
-  cal receive
-  ld   l,a
-  pop  af
-  psh hl
-  cal send
-  pop  hl
-  ret
-
-inkeys: ;use jp not call!
-  out (1),a ;nop\nop
-  in  a,(1)
-  ld  b,a
-  and (ix+right)
-  jr  z,notright
-  ld  a,l
-  add a,8
-  ld  l,a
-notright:
-  ld  a,b
-  and (ix+left)
-  ret z
-  ld  a,l
-  sub 8
-  ld  l,a
-  ret
-
-chkinput:
-  ld  bc,donediddelydone
-  psh bc ;ret-dest.
-inputcall:
-  ld  a,(ix+input)
-  or  a
-  jr  nz,inkeys
-  jr  inlink
-
 respawncheck:
   cp  respawndelay-1
   jr  nz,unnamedlabel
 respawncheck:
   cp  respawndelay-1
   jr  nz,unnamedlabel
+  cal saverespawncounter
 removeworm:
   ld  h,(ix+tail+1)
   ld  l,(ix+tail)
 removeworm:
   ld  h,(ix+tail+1)
   ld  l,(ix+tail)
@@ -1382,7 +1480,7 @@ removewormloop:
   inc hl
   ld  b,(hl)
   inc hl
   inc hl
   ld  b,(hl)
   inc hl
-  res resbit,h
+  cal resbit
   psh hl
   cal res4pixels
   pop hl
   psh hl
   cal res4pixels
   pop hl
@@ -1401,7 +1499,8 @@ safewormsizedone:
 
   ;de=ix+head
   ld  (ix+tail+1),d
 
   ;de=ix+head
   ld  (ix+tail+1),d
-  ld  (ix+tail),e
+  ld  (ix+tail),e ;head=tail/size=0
+  ret
 
 unnamedlabel:
   cp  1
 
 unnamedlabel:
   cp  1
@@ -1410,11 +1509,65 @@ unnamedlabel:
 respawndue:
   ld  l,a
   cal inputcall
 respawndue:
   ld  l,a
   cal inputcall
+  ld  (sendbyte),a
   ld  a,h ;previous
   cp  l   ;changed?
   ret z
   ld  a,h ;previous
   cp  l   ;changed?
   ret z
+  ld  (ix+delay),a ;=0
+  ret
 saverespawncounter:
 saverespawncounter:
-  ld  (ix+delay),h
+  ld  (ix+delay),a
+  jr  inputcall
+;  ld  a,(ix+input)
+;  or  a
+;  jr  z,inlink
+;  ret
+
+inkeys: ;use jp not call!
+  out (1),a ;nop\nop
+  in  a,(1)
+  ld  b,a
+  and (ix+right)
+  jr  z,notright
+  ld  a,l
+  add a,8
+  ld  l,a
+notright:
+  ld  a,b
+  and (ix+left)
+  ret z
+  ld  a,l
+  sub 8
+  ld  l,a
+  ret
+
+inputcall:
+  ld  a,(ix+input)
+  or  a
+  jr  nz,inkeys
+
+inlink:
+  ld  a,0
+sendbyte =$-1
+  ld  b,(ix+left)
+  dec b
+  jr  z,receivefirst
+  psh hl
+  cal send
+  cal receive
+  pop hl
+  ld  l,a
+  ret
+receivefirst:
+  psh af
+  psh hl
+  cal receive
+  pop hl
+  ld  l,a
+  pop af
+  psh hl
+  cal send
+  pop hl
   ret
 
 ;------- handle worm ---------
   ret
 
 ;------- handle worm ---------
@@ -1422,10 +1575,10 @@ saverespawncounter:
 HandleWorm:
   ld  a,(ix+delay)
   dec a
 HandleWorm:
   ld  a,(ix+delay)
   dec a
-  jr  nz,respawncheck
+  jp  nz,respawncheck
 
   ld  l,(ix+heading)
 
   ld  l,(ix+heading)
-  jr  chkinput
+  cal inputcall
 donediddelydone:
   ld  a,l
   ld  (sendbyte),a
 donediddelydone:
   ld  a,l
   ld  (sendbyte),a
@@ -1437,6 +1590,18 @@ donediddelydone:
   ld  e,(ix+pos2)
   ld  d,(ix+pos2+1)
 
   ld  e,(ix+pos2)
   ld  d,(ix+pos2+1)
 
+  psh hl
+  ld  hl,previouspos
+  ld  (hl),c
+  inc hl
+  ld  (hl),b
+  inc hl
+  inc hl
+  ld  (hl),e
+  inc hl
+  ld  (hl),d
+  pop hl
+
 ;-------- move worm ----------
 
 Wormmove:
 ;-------- move worm ----------
 
 Wormmove:
@@ -1495,27 +1660,19 @@ GotFour:
 Hitworm:
   ld  a,(gameCar)
   ld  h,a
 Hitworm:
   ld  a,(gameCar)
   ld  h,a
-  and _datafood
-  jp  z,WormDead
+  and _datadie
+  cal z,checkhitotherworm
+  ld  a,h
+  and _datamultpeas ;&&bit
+  jr  nz,multiple_peas
   ld  a,h
   ld  a,h
-  and _datahunt
-  cal nz,checkhitotherworm
+  and _datafood
+  jp  z,WormDead ;no food
 
   ld  hl,0
 PeaY =$-2
 PeaX =$-1
 
   ld  hl,0
 PeaY =$-2
 PeaX =$-1
-  ld  a,(sprsize)
-  inc a
-  ld  d,a
-  ld  a,b
-  sub h
-  inc a
-  cp  d ;=(sprsize)+1
-  jp  nc,WormDead
-  ld  a,c
-  sub l
-  inc a
-  cp  d
+  cal chkpeahit
   jp  nc,WormDead
   cal DrawPea ;remove pea
   ld  a,(ix+grow)
   jp  nc,WormDead
   cal DrawPea ;remove pea
   ld  a,(ix+grow)
@@ -1529,10 +1686,10 @@ peagrowth =$-1
   ld  de,10
   cal IncScore
   pop af
   ld  de,10
   cal IncScore
   pop af
-  jr  nz,still_alive_not_dead
+  jp  nz,Drawworm ;continue
   ld  a,(gameCar)
   and _datafoodl
   ld  a,(gameCar)
   and _datafoodl
-  jr  z,still_alive_not_dead
+  jp  z,Drawworm
   ld  a,(Gametype)
   or  a
   jp  nz,Exit ;stack restored
   ld  a,(Gametype)
   or  a
   jp  nz,Exit ;stack restored
@@ -1547,20 +1704,95 @@ peagrowth =$-1
   cal _HLTIMES10
   ex  de,hl
   cal IncScore ;score+(40*level)
   cal _HLTIMES10
   ex  de,hl
   cal IncScore ;score+(40*level)
+  cal removeworm
   pop hl                         ; << call
   pop hl                         ; << call
   pop hl                         ; << levelp new
   pop hl                         ; << call
   pop hl                         ; << call
   pop hl                         ; << levelp new
+  ld  (ix+delay),2
   jp  StartLevel
 
   jp  StartLevel
 
+chkpeahit: ;hl=peapos
+  ld  a,(sprsize)
+  inc a
+  ld  d,a
+  ld  a,b
+  sub h
+  inc a
+  cp  d ;=(sprsize)+1
+  ret nc ;nc=no pea
+  ld  a,c
+  sub l
+  inc a
+  cp  d
+  ret ;c=pea
+
+flagcaptured:
+  psh hl
+  ld  de,30
+  cal IncScore
+  pop hl
+sillylabel:
+  cal WormDead
+DrawAllPeas:
+  ld  hl,(peaspos)
+  cal DrawPea
+  ld  hl,(peaspos+2)
+  jp  DrawPea
+
+multiple_peas:
+  ld  hl,(peaspos) ;1st pea
+  psh hl
+  ld  a,(ix+reserv)
+  ld  e,a ;push a
+  and %01
+  jr  nz,sel_ownpea
+  ld  hl,(peaspos+2) ;2nd pea
+sel_ownpea:
+  cal chkpeahit
+  pop hl ;(peapos) 1st pea
+  jp  c,stopworm ;own pea hit
+
+  ld  a,e ;peek a (that x86 asm for pop\push ;)
+  and %01
+  jr  z,sel_otherpea
+  ld  hl,(peaspos+2) ;2nd pea
+sel_otherpea:
+  cal chkpeahit
+  jp  c,hitflag
+
+;no peas hit
+  ld  a,e
+  cal flagtoken
+  jp  z,WormDead
+  ld  b,a ;%10
+  srl b   ;%01
+  add a,b ;%11
+  ld  (ix+reserv),a
+  cal DrawPea ;restore own flag
+  jr  sillylabel ;inv both\die
+
+hitflag: ;correct pea hit
+  ld  a,e ;pop a
+  xor %01 ;0=1;1=0
+  ld  (ix+reserv),a
+  cal flagtoken
+  psh af ;safe z-flag
+  cal DrawPea ;remove
+  pop af
+  jr  z,flagcaptured
+  jr  stopworm
+
+flagtoken:
+  and %01 ;current
+  add a,a ;<< for cp
+  ld  b,a ;in b
+  ld  a,e
+  and %10 ;own
+  cp  b   ;same?
+  ret ;Z=yes: no flag taken
+
 ;-----------------------------
 
 ;-----------------------------
 
-checkhitotherworm:
-  .db $dd,$7d ;ld a,lx
-  cp  worm2&255
-  ret nz
-ThisIsJustASillyUselessLabel:
-  ld  hl,(worm1+tail)
-  ld  de,(worm1+head)
 nextotherwormbit:
   ld  a,c
   sub (hl)
 nextotherwormbit:
   ld  a,c
   sub (hl)
@@ -1572,13 +1804,14 @@ nextotherwormbit:
   sub (hl)
   inc a
   cp  4
   sub (hl)
   inc a
   cp  4
-  jr  c,otherwormHIT ;yes
+  ret c ;nz ;yes
 nothit1:
   inc hl
 nothit1:
   inc hl
-  res resbit,h
+  cal resbit
+ChkWorm:
   cal _cphlde
   jr  nz,nextotherwormbit
   cal _cphlde
   jr  nz,nextotherwormbit
-  ret
+  ret ;z
 
 checkhitlapline:
   ld  a,63
 
 checkhitlapline:
   ld  a,63
@@ -1601,29 +1834,44 @@ nolap:
   ld  (ix+reserv),a
   ret
 
   ld  (ix+reserv),a
   ret
 
-otherwormHIT:
-  psh ix
-  ld  de,10
-  cal IncScore
+checkhitotherworm:
+ .db  $dd,$7d ;ld a,lx
+  cp  worm2&255
+ psh ix
+ jr nz,chkworm2 ; ret nz
   ld  ix,worm1
   ld  ix,worm1
-  cal WormDead
-  pop ix
-  pop bc
-still_alive_not_dead:
+ jr chkworm
+chkworm2:
+ ld ix,worm2
+
+chkworm:
+ ld h,(ix+tail+1)
+ ld l,(ix+tail)
+ ld e,(ix+head)
+ ld d,(ix+head+1)
+  cal ChkWorm
+ pop ix
+  ret z ;not hit
+  pop bc ;call
+stopworm:
+  ld  bc,0
+previouspos =$-2
+  ld  de,0
+  ld  (ix+pos),c
+  ld  (ix+pos+1),b
+  ld  (ix+pos2),e
+  ld  (ix+pos2+1),d
+  ret
 
 ;-------- draw worm ----------
 
 Drawworm:
 
 ;-------- draw worm ----------
 
 Drawworm:
-  ld  a,(gameCar)
-  and _datahunt
-  cal nz,HuntingTimeScore
-
   ld  c,(ix+pos)
   ld  b,(ix+pos+1)
 
   ld  c,(ix+pos)
   ld  b,(ix+pos+1)
 
-  ld  a,(gameCar)
-  and _datalaps
-  cal nz,checkhitlapline
+  ld  a,(Gametype)
+  cp  gamerace
+  cal z,checkhitlapline
 
   ld  l,(ix+head)
   ld  h,(ix+head+1)
 
   ld  l,(ix+head)
   ld  h,(ix+head+1)
@@ -1631,7 +1879,7 @@ Drawworm:
   inc hl
   ld  (hl),b
   inc hl
   inc hl
   ld  (hl),b
   inc hl
-  res resbit,h
+  cal resbit
   ld  (ix+head),l
   ld  (ix+head+1),h
 
   ld  (ix+head),l
   ld  (ix+head+1),h
 
@@ -1650,7 +1898,7 @@ removetail:
   inc hl
   ld  b,(hl)
   inc hl
   inc hl
   ld  b,(hl)
   inc hl
-  res resbit,h
+  cal resbit
   ld  (ix+tail),l
   ld  (ix+tail+1),h
 
   ld  (ix+tail),l
   ld  (ix+tail+1),h
 
@@ -1673,13 +1921,8 @@ ResPixel:
 ;-----------------------------
 
 handlethoseneatlittleballs:
 ;-----------------------------
 
 handlethoseneatlittleballs:
-  ld  a,0
-nrballs =$-1
-  or  a
-  ret z
-
-  ld  hl,ball1
-  ld  b,a
+  ld  hl,balls
+  ld  b,a ;a=(nrballs)
 handleballs
   psh bc
   psh hl
 handleballs
   psh bc
   psh hl
@@ -1772,6 +2015,22 @@ checkballhit:
 ;----------- procs -----------
 ;-----------------------------
 
 ;----------- procs -----------
 ;-----------------------------
 
+releasekeys:
+  halt
+  ld  a,%10000000    ;all key-masks
+  out (1),a
+  in  a,(1)
+  inc a              ;cp %11111111 (no keys pressed)
+  jr  nz,releasekeys ;keep waitin
+  cal GET_KEY        ;clear buffer
+  ret
+
+resbit:
+  ld  a,h
+  and (ix+storepos)
+  ld  h,a
+  ret
+
 randompos:
   ld  b,a
 Random: ;(2..b+2)
 randompos:
   ld  b,a
 Random: ;(2..b+2)
@@ -1823,8 +2082,7 @@ DrawPea: ;hl=(PeaY)
   ld  c,l
   ld  de,peasprite
 spritepos =$-2
   ld  c,l
   ld  de,peasprite
 spritepos =$-2
-  cal PutSprite ;||-ed
-  ret
+  jp  PutSprite ;||-ed
 
 ;----------- score -----------
 
 
 ;----------- score -----------
 
@@ -1838,14 +2096,6 @@ divideagain: ;3x
   pop hl
   ret
 
   pop hl
   ret
 
-HuntingTimeScore:
-  .db $dd,$7d ;ld a,lx
-  cp  worm2&255
-  ret z ;=worm#2
-  dec (ix+reserv)
-  ret nz
-  ld  hl,10
-
 IncScore:
   ld  h,(ix+score+1)
   ld  l,(ix+score)
 IncScore:
   ld  h,(ix+score+1)
   ld  l,(ix+score)
@@ -2029,10 +2279,10 @@ NotMaxYScroll:
   jr  nc,NotMinXScroll
   xor a
 NotMinXScroll:
   jr  nc,NotMinXScroll
   xor a
 NotMinXScroll:
-  cp 128
+  cp  128
 FieldWidth = $-1
 FieldWidth = $-1
-  jr c,NotMaxXScroll
-  ld a,(FieldWidth)
+  jr  c,NotMaxXScroll
+  ld  a,(FieldWidth)
 NotMaxXScroll:
   psh af                        ; >> 3
   and %11111000
 NotMaxXScroll:
   psh af                        ; >> 3
   and %11111000
@@ -2050,7 +2300,7 @@ NotMaxXScroll:
   inc c
 CopyScreen:
   add hl,bc
   inc c
 CopyScreen:
   add hl,bc
-  ld b,57
+  ld  b,57
 CopyScreenLoop:
   psh bc                        ; >> 4
   ld  bc,16
 CopyScreenLoop:
   psh bc                        ; >> 4
   ld  bc,16
@@ -2105,10 +2355,12 @@ Bit7:
 AfterShiftDelay:
   halt
 AfterShift:
 AfterShiftDelay:
   halt
 AfterShift:
+#ifdef buffer
   ld  hl,DispBuffer
   ld  de,$fc00+$70
   ld  bc,1024-$70
   ldir
   ld  hl,DispBuffer
   ld  de,$fc00+$70
   ld  bc,1024-$70
   ldir
+#endif
   pop de                         ; << 1
   pop bc                         ; << 0k
   ret
   pop de                         ; << 1
   pop bc                         ; << 0k
   ret
@@ -2448,12 +2700,68 @@ boxloop:
 
 TIMEOUT = $1000
 
 
 TIMEOUT = $1000
 
-receive:
-  cal GET_KEY
-  cp  K_EXIT
-  jp  z,LinkBreak
+checklink:
+  pop hl
+  dec de
+  ld  a,d
+  or  e
+  jr  z,LinkFailed
+
+  ld  a,$BF
+  out (1),a
+; nop \ nop
+  in  a,(1)
+  psh af
+  ld  a,%11111111
+  out (1),a
+  pop af
+  bit 6,a
+  jp  z,Exit
+
   in  a,(7)
   and %11
   in  a,(7)
   and %11
+  jp  (hl)
+
+;--------------
+;---- SEND ---- 8 bits in a
+;-------------- destr:bcdehl
+send:
+  ld  c,a
+  ld  b,8+1        ;bits to send
+  jr  checksend
+sendloop:
+  rr  c            ;bit to send (in cf)
+  ld  a,D0LD1H     ;0: lower white
+  jr  nc,sendbit
+  ld  a,D0HD1L     ;1: lower red
+sendbit:
+  out (7),a        ;lower one (send bit)
+  ld  de,TIMEOUT
+waitacksend:
+  cal checklink    ;other calc must lower other whire
+  jr  nz,waitacksend
+checksend:
+  ld  a,D0HD1H     ;ok to raise both
+  out (7),a
+  ld  de,TIMEOUT
+finishsend:
+  cal checklink
+  cp  %11          ;both raised (by other calc)
+  jr  nz,finishsend
+  dnz sendloop     ;repeat for all bits
+ .db  $F6 ;or NN   ;nc
+LinkFailed:
+  scf              ;c=error
+  ret
+
+;--------------
+;---- RECV ---- 8 bits to a
+;-------------- destr:bcdehl
+receive:
+ halt ;&&&
+  ld  de,TIMEOUT
+  cal checklink
+  jr  z,receive
   cp  %11
   jr  z,receive
   cal Qreceive
   cp  %11
   jr  z,receive
   cal Qreceive
@@ -2461,104 +2769,39 @@ receive:
   ret
 
 Qreceive:
   ret
 
 Qreceive:
-  ld  b,8
-  jr  ReceiveCont
+  ld  b,8          ;bits to receive
 receiveloop:
   ld  de,TIMEOUT
 WaitRecBit:
 receiveloop:
   ld  de,TIMEOUT
 WaitRecBit:
-  cal CheckLink
-  jr  z,LinkFailed
+  cal checklink
+  jr  z,LinkFailed ;both low = error
   cp  %11
   cp  %11
-  jr  z,WaitRecBit
-ReceiveCont:
-  sub 2
-  ld  a,2
+  jr  z,WaitRecBit ;both on = nothing sent
+recvbit:
+  rra              ;received bit in cf
+  ld  a,%10
   ld  d,D0LD1H
   ld  d,D0LD1H
-  jr  c,ReceiveLow
-  rra
-  ld  d,D0HD1L
-ReceiveLow:
-  rr c
-  ld (AckBit),a
-  ld a,d
-  out (7),a
+  jr  c,savebit    ;lower white as well
+  rra ;ld a,%01
+  ld  d,D0HD1L     ;lower red
+savebit:
+  rr  c            ;save bit
+  ld  (AckBit),a
+  ld  a,d
+  out (7),a        ;lower other (both low)
   ld  de,TIMEOUT
   ld  de,TIMEOUT
-WaitAckRec:
-  cal CheckLink
+waitackrecv:
+  cal checklink
+;  jr  z,waitackrecv ;wait for one to go high
   cp  0
 AckBit =$-1
   cp  0
 AckBit =$-1
-  jr  nz,WaitAckRec
-  ld  a,D0HD1H
-  out (7),a
-  ld  d,4
-WaitReadyRec:
-  dec d
-  jr  z,ReadyRec
-  in  a,(7)
-  cp  %11
-  jr  nz,WaitReadyRec
-ReadyRec:
-  dnz receiveloop
-  jr  LinkSuccess
-
-send:
-  ld  b,9
-  ld  c,a
-  jr  SendAcked
-SendBits:
-  rr  c
-  ld  a,D0LD1H
-  jr  nc,SendLow
-  ld  a,D0HD1L
-SendLow:
-  out (7),a
-  ld  de,TIMEOUT
-WaitAckSend:
-  cal CheckLink
-  jr  nz,WaitAckSend
-SendAcked:
+  jr  nz,waitackrecv
   ld  a,D0HD1H
   ld  a,D0HD1H
-  out (7),a
-  ld  de,TIMEOUT
-WaitReadySend:
-  cal CheckLink
-  cp  %11
-  jr  nz,WaitReadySend
-  dnz SendBits
-LinkSuccess:
-  ld  a,c ;pop a
-  ret
-
-LinkFailed:
-  scf
-  ld a,c
+  out (7),a        ;raise both
+  dnz receiveloop  ;repeat for all bits
+  or  a            ;nc
+  ld  a,c          ;a=byte received
   ret
   ret
-LinkBreak:
-  ld  a,D0HD1H
-  out (7),a
-  jp  Exit
-
-CheckLink:
-  pop hl
-  dec de
-  ld a,d
-  or e
-  jr z,LinkFailed
-
-  ld  a,$BF
-  out (1),a
-  nop \ nop
-  in  a,(1)
-  psh af
-  ld  a,%11111111
-  out (1),a
-  pop af
-  bit 6,a
-
-  in  a,(7)
-  and %11
-  jp  (hl)
-
 
 ;-----------------------------
 ;---------- levels -----------
 
 ;-----------------------------
 ;---------- levels -----------
@@ -2583,6 +2826,41 @@ LevelDefM:
 ;---------- data -------------
 ;-----------------------------
 
 ;---------- data -------------
 ;-----------------------------
 
+wtPicture:
+.db %00011110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
+.db %00111110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
+.db %01110000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
+.db %01100000,%01111100,%00000001,%11111111,%00000000,%11110000,%01111001,%11100000
+.db %11100000,%11111110,%00000011,%11111111,%10000011,%11111000,%11111111,%11110000
+.db %11000001,%11000111,%00000111,%00000001,%11000111,%10011001,%11001111,%00111000
+.db %11000001,%10000011,%00000110,%00000000,%11100110,%00000001,%10011111,%10011000
+.db %11000001,%10000011,%00000110,%11000000,%01101110,%00000011,%10111001,%11011100
+.db %11000001,%11000111,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100
+.db %11000000,%11000110,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100
+.db %11100000,%11101110,%00001110,%11000000,%01101100,%00000011,%00111001,%11001100
+.db %01100000,%01111100,%00001100,%11000000,%01101100,%00000011,%00011111,%10001100
+.db %01110000,%00111000,%00011100,%11100000,%11101110,%00000011,%00001111,%00001100
+.db %00111000,%11111110,%00111000,%01110001,%11000110,%00000011,%10000000,%00011100
+.db %00011111,%11101111,%11110000,%00111111,%10000111,%00000001,%10000000,%00011000
+.db %00001111,%10000011,%11100000,%00011111,%00000011,%00000001,%10000000,%00011000
+
+txtMenu:    .db "by Shiar",0
+            .db "Have fun!",0 ;4th menu item
+            .db "Level ",$CF,"??",5,0 ;3rd
+            .db "Worms ",$CF,"?",5,0  ;2nd
+txtGame:    .db "Singleplayer",0  ;0 (1st)
+txtGame2:   .db "Peaworm     ",0  ;1 (next 1st)
+            .db "Deathmatch",0    ;2
+            .db "Foodmatch ",0    ;3
+            .db "LinkMatch",0     ;4
+            .db "Race     ",0     ;5
+            .db "CTF ",0          ;6
+            .db "Domination",0    ;7
+txtLevsel:  .db $CF," Select levels: ",5,0
+txtName:    .db "Enter name player ",0
+txtWaiting: .db "Waiting...",0
+txtReceive: .db "Receiving..." ;,0
+
 TrigPrecalc:
 .db   0,  3,  6,  9, 12, 15, 18, 21
 .db  24, 27, 30, 33, 36, 39, 42, 45
 TrigPrecalc:
 .db   0,  3,  6,  9, 12, 15, 18, 21
 .db  24, 27, 30, 33, 36, 39, 42, 45
@@ -2594,23 +2872,6 @@ TrigPrecalc:
 .db 124,125,125,126,126,126,126,126
 .db 127
 
 .db 124,125,125,126,126,126,126,126
 .db 127
 
-txtWelcome: .db "Welcome to Worm!! ",
-            .db "by Shiar",0
-            .db "Have fun!",0 ;4th menu item
-            .db "Level 00",0 ;3rd
-            .db "Worms: 0",0 ;2nd
-txtGame:    .db "Singleplayer",0  ;0 (1st)
-txtGame2:   .db "Peaworm     ",0  ;1
-            .db "Deathmatch",0    ;2
-            .db "Foodmatch ",0    ;3
-            .db "LinkMatch",0     ;4 (>options)
-            .db "Hunting  ",0     ;5
-            .db "Race   ",0       ;6
-            .db "CTF ",0          ;7
-            .db "Domination",0    ;(>=8)
-txtWaiting: .db "Waiting...",0
-txtReceive: .db "Receiving...",0
-
 txtLevel:  .db "Level ",0
 txtWorms:  .db "Worms: 0",0 ;follows txtLevel
 txtDied:   .db "Died ",0
 txtLevel:  .db "Level ",0
 txtWorms:  .db "Worms: 0",0 ;follows txtLevel
 txtDied:   .db "Died ",0
@@ -2623,45 +2884,53 @@ txtGO:     .db "----- GAME OVER -----",0
 
 gamesdata:
 
 
 gamesdata:
 
-_datalink  = %00000001
-_datalivel = %00000010 ;ix+lives=0 limit
+_datalink  = %00000001 ;linkplay
+_datalivel = %00000010 ;lives=0 limit
 _datafoodl = %00000100 ;left=0 limit
 _datanextl = %00001000 ;next level if left=0
 _datasingl = %00001000 ;singleplayer=1
 _datafood  = %00010000 ;food present
 _datafoodl = %00000100 ;left=0 limit
 _datanextl = %00001000 ;next level if left=0
 _datasingl = %00001000 ;singleplayer=1
 _datafood  = %00010000 ;food present
-_datahunt  = %00100000
-_datalaps  = %01000000 ;give lap score
+_________  = %00100000 ;
+_datadie   = %01000000 ;worm dies on impact
 _datascore = %10000000 ;score>=100 limit
 _datascore = %10000000 ;score>=100 limit
+_datamultpeas = %00100000
+
+gamesingle   =  0
+datasingle: .db %01011110
+gamepeas     =  1
+datapeas:   .db %01011010
+gamedeathm   =  2
+datadeathm: .db %01000010
+gamefoodm    =  3
+datafoodm:  .db %11010000
+gamelinkm    =  4
+datalinkm:  .db %01000011
+gamerace     =  5
+datarace:   .db %10000000
+gamectf      =  6
+datactf:    .db %11100000
+gamedomin    =  7
+datadomin:  .db %01000000 ;==(8 modes)
 
 
-datasingle: .db %00011110
-datapeas:   .db %00011010
-datadeathm: .db %00000010
-datafoodm:  .db %10010000
-datalinkm:  .db %00000011
-datahuntin: .db %10100000
-datarace:   .db %11000000
-datactf:    .db %00000000 ;==(8 modes)
-;datadomin:  .db %00000000
 datalevels: .dw LevelDef, LevelDef
             .dw LevelDefM,LevelDefM
             .dw LevelDefM,LevelDefM
             .dw LevelDefM,LevelDefM
 datalevels: .dw LevelDef, LevelDef
             .dw LevelDefM,LevelDefM
             .dw LevelDefM,LevelDefM
             .dw LevelDefM,LevelDefM
-nrlevels:   .db 1,1,1,1,1,1,1,1
+nrlevels:   .db 2,2,2,2,2,2,2,2
 
 worm1set:  .dw worm1p,worm1p
 
 worm1set:  .dw worm1p,worm1p
-           .db 3,0,%01111110,%10,%100 ;< >
-worm1name: .db "Left    ",0
+           .db %11110111,3,%00,%01111110,%10,%100 ;< >
+worm1name: .db "worm #01",0
 worm2set:  .dw worm2p,worm2p
 worm2set:  .dw worm2p,worm2p
-           .db 3,0,%00111111,%10000,%1000 ;f1 f2
-worm2name: .db "Right   ",0
+           .db %11111011,3,%11,%00111111,%10000,%1000 ;f1 f2
+worm2name: .db "worm #02",0
 worm3set:  .dw worm3p,worm3p
 worm3set:  .dw worm3p,worm3p
-           .db 3,0,%01011111,%10,%100 ;sto ,
-worm3name: .db "Top     ",0
+           .db %11111011,3,0,%01011111,%10,%100 ;sto ,
+worm3name: .db "worm #03",0
 worm4set:  .dw worm4p,worm4p
 worm4set:  .dw worm4p,worm4p
-           .db 3,0,%01111101,%10,%1 ;enter +
-worm4name: .db "Bottom  ",0
+           .db %11111011,3,0,%01111101,%10,%1 ;enter +
+worm4name: .db "worm #04",0
 
 
-hipeaworm: .dw 0
 end:
 
 defsprsize   = 4
 end:
 
 defsprsize   = 4
@@ -2679,21 +2948,23 @@ grow     = 6   ;level
 died     = 8   ;game
 score    = 9   ;game
 delay    = 11  ;game
 died     = 8   ;game
 score    = 9   ;game
 delay    = 11  ;game
-
-head     = 12  ;level
-tail     = 14  ;level
-lives    = 16  ;game
-reserv   = 17  ;loop
+               ;19B @game
+head     = 12  ;4B (head=tail)
+tail     = 14  ;also@next level
+storepos = 16
+lives    = 17
+reserv   = 18  ;loop
  ;race:lap
  ;race:lap
- ;hunt:time
-input    = 18  ;&
-left     = 19  ;&
-right    = 20  ;&
-name     = 21  ;game
-wormsize = 30
-
-respawndelay  = 40
-maxnamelength = 9
+ ;ctf:pea
+input    = 19
+left     = 20
+right    = 21
+name     = 22
+wormsize = 31
+
+startdelay    = 30
+respawndelay  = 30
+maxnamelength = 8+1
 
 ;-----------------------------
 ;----------- end -------------
 
 ;-----------------------------
 ;----------- end -------------