wormy 0.97.103
[wormy.git] / wormy.z80
index edb70567e7d1f53e739135f999a81bf4f9f31cfa..26d374f60d594d24140cb4a24a9707a40bc56e4b 100644 (file)
--- a/wormy.z80
+++ b/wormy.z80
@@ -1,46 +1,76 @@
-; Title                      : Wormy
-; Version                    : 95%
-; Release Date               : summer 2001
-; Filename                   : wormy.86p (5kb)
-; Author(s)                  : Shiar
-; 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)
-; Other games by author(s)   : Nemesis beta
-; Additional Credits to      : Matthew Shepcar (wrote original Peaworm, end'98)
-;                              Jonah Cohen (helped writing worm)
+;   ����                                                        ����
+;  ����                                                         �����
+; ���                                                            ����     ����
+;���      �����          ��������       �����     ����  ����      ���     �����
+;���     �������       �����������     �������   �������������     ��    ��� ���
+;��     ���   ���     �����    ����   ����  ��� ���  ����  ���     ���  ���� ���
+;��     ��     ��     ��  �      ��� ����      ���  ������  ���    ���  ���   ��
+;��     ��     ��     �� ��      ��� ���       ��� ���� ��� ���    ��� ����   ��
+;��     ���   ���     �� ��       �� ���       �������   ��� ��     �������   ��
+;��     ���   ���    ��� ��       �� ��        �� ���    ��� ���     �����   ���
+;���     ��� ���     ��� ��       �� ���       �� ����  ���� ���             ���
+;���      �����     ���  ���     ��� ���       ��  ��������  ���            ���
+; ���      ���      ���  ���     ��� ���       ���  ������   ���            ���
+;  ����  �������  ����    ���   ���  ����      ���            �����       ����
+;   �������� ��������     ���������   ���      ���             ���������������
+;    �����     �����       �������     ��       ���              �����������
+;
+; Version                  : 97% (0.97.13)
+; Release Date             : UUHHhhh... soon?!?
+; Author(s)                : Shiar
+; 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)
+; Other games by author(s) : Nemesis beta
+; Additional Credits to    : Matthew Shepcar (wrote original Peaworm, end'98)
+;                            Jonah Cohen (helped writing worm)
+; Files                    : wormy.z80 (80898 bytes) 1234
 
 ;-----------------------------
 ;----------- TO-DO -----------
 ;-----------------------------
 
-; 95% = DONE
+; 97% = DONE
 
-;    [* internal levels         ]
-;    [  * check levels/gametype ]
-;    [  * enough hiscore saves! ]
-;    [* complete readme         ]
-;  1% * misc (pollish, bugs, &&&)
+;  1% * misc (bugs, &&&, pollish, &&, &)
+;     * score >9 dispay
+;     * mem at worm #4 (still 12 bytes or so.. or more? or less?)
+;     * look at init-z in line routine again
 ;   * LINK
-;     * fix first packet loss
-;  1% * transmit game/level data
-;  1% * 1/3 worms over link
-;;;1% * get g/o signal (l&l) working
-;;;1% * send new peas' positions
+;  1% * fix transmit game/level data (?)
+;     * >Somehow do a lot of testing with 2 calcs< *sigh*
 
 ;100% = bugs fixed + levels done
 
+;      arrow to offscreen peas
+;      multiple peas in sp level
+;>110%:        sound, startpos (?)
+;>120%:        coop (DON'T COUNT ON IT)
+
 ;-----------------------------
 ;-----------------------------
-;---------  W O R M  ---------
+;-------  W O R M Y  ---------
 ;-----------------------------
 ;-----------------------------
 
+;NOTES:
+;* Use for LEARNING practises ONLY!
+;   Don't ever release altered code w/o permission!
+;* Code was originally by Scabby (Matthew Shepcar),
+;   a few lines by Jonah Cohen,
+;    and everything else by me - Shiar (Mischa Poslawsky).
+;* Although I've commented quite some stuff, I can't guarantee
+;   everybody will understand it. This is probably not the best source
+;    to learn z80 from. w00t the Shyer Way (tm).
+;* Don't scroll down if you get scared easily.
+
 #define buffer      ;use display buffer (otherwise write directly to screen)
 #define readymask   ;"greys" out the field before starting a level
 #define coolzgfx    ;nice graphics for game over screen
+multpeas
 
+;#define intlevels  ;internal levels
 ;#define readytext  ;displays "prepare" before level starts
 ;#define invincible ;worms cannot die =)
 ;#define optdie     ;in race games worms don't die when they run into each other
@@ -51,7 +81,6 @@
 
 #include "asm86.h"
 #include "ti86asm.inc"
-
 _SHRACC            = $4383 ;4x srl a
 _SHLACC            = $438B ;4x sll a
 _divHLby10         = $4044 ;hl=hl/10
@@ -98,71 +127,80 @@ worm3       = $AC3E ;-AC59 (1F)
 worm4       = $AC5D ;-AC77 (1F)
 balls       = $AC7C ;-ACFF (3x43d)
 SinCosTable = $AD00 ;-AE00 (4*40)
-        ;free $AE01 ;-AFFF (1FF)
+turn10      = $AE01 ;-AE01 (1) (counter)
+peaspos     = $AE02 ;-AE05 (4+) (peas)
+;free       = $AE06 ;-AFFF (1FA)
 worm1p      = $B000 ;-B7FF (800)      %1011O000
 worm3p      = $B800 ;-BBFF (400)      %10111O00
-        ;free $BF91 ;-BFFF (6F)
-     ;program $D748 ;-EFFF (186D+4A)
+;free       = $BF91 ;-BFFF (6F)
+;program    = $D748 ;-EFFF (186D+4A)           ;6327
 worm4p      = $F000 ;-F3FF (400)      %11110O00
 leveldata   = $F400 ;-FA70 (<=671)
+       ;can you believe i actually left $269 bytes of memory unused?!?
 
-turn10      = $AE01 ;      (1) (counter)
-peaspos     = $AE02 ;-AE05 (4) (peas)
-
-;MEM|8---9---A---B---C---D---E---F---|
-;   |..[------]||[]|......[-----]|[].|
-;   |   SCREEN 2* 13      PRGM   4LV |
+;MEM|8---9---A---B---C---D---E---F---| ;there's something wrong
+;   |..[------]||[]|......[-----]|[].| ;if you still understand
+;   |   SCREEN 2* 13      PRGM   4LV | ;after looking at this
 
 ;--- temporary
 
 namelength  = $BC00 ;(1)         @menu
+datalink    = $BC00 ;(8)        @init
 #ifdef buffer
 DispBuffer  = $BC00 ;(10x57d)    @game
 #else
 DispBuffer  = $FC70
 #endif
+lefttotalb  = $AFFF
 
 ;-----------------------------
 ;------- program start -------
 ;-----------------------------
 
-.org _asm_exec_ram
+ .org %1101011101001000
 
-wormVhost   = 093
-wormVclient = 193
-
-start:
-  nop
-  jp Start
-  .db 1
-  nop
-  .dw WormTxt
-  .dw WormIcon
-
-WormTxt:
-  .db "WORMY by SHIAR -- beta 95%",0
+start:         ;turn back NOW!
+  nop      ;and so it begins...
+  jp  Start
+  ld  bc,$5242
+  rst 10h
+ .dw  WormIcon
+  ld  d,a
+  ld  c,a
+  ld  d,d
+  ld  c,l
+  ld  e,c
+  jr  nz,$+100
+  ld  a,c
+  jr  nz,$+$55
+  ld  c,b
+ .dw  16713
+ .db  %1010010
+  jr  nz,$+47
+  dec l
+ .db  " 97% .13",0
 WormIcon:
 .db 8,2
 .db %00000000,%00111100
 .db %00000000,%01010010
 .db %00000000,%01100001
 .db %01100011,%10011001
 .db %10010100,%01101001
 .db %10011001,%00011001
 .db %01000010,%11000001
 .db %00111100,%00111110
.db  8,2
.db  %00000000,%00111100
.db  %00000000,%01010010
.db  %00000000,%01100001
.db  %01100011,%10011001
.db  %10010100,%01101001
.db  %10011001,%00011001
.db  %01000010,%11000001
.db  %00111100,%00111110
 
 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:
@@ -188,7 +226,7 @@ Start:
   ldir
   inc a   ;ld a,$D4
   ld  i,a
-  im  2
+  im  2 ;...it *does* work ;)
 
   cal _RAM_PAGE_7
   ld  hl,$BFFF ;VAT start
@@ -243,7 +281,7 @@ stringfound:
   inc ix
 _searchnext:
   cal _RAM_PAGE_7
-  jr searchnext
+  jr  searchnext
 
 loadgametype:
   psh de
@@ -265,8 +303,16 @@ searchcomplete:
   ld  a,255
   ld  (ix),a ;end mark
 
+#ifdef intlevels
   ld  ix,templevels-6
-levelselectmenu:
+#else
+  ld  ix,templevels-3
+#endif
+  cp  (ix+3) ;1st=255
+  jp  z,ExitNoStats ;->no lvls
+  cp  (ix+6) ;2nd=255
+  jr  z,loadlevel1 ;->1 lvl
+levelselectmenu: ;load next page
   psh ix ;offset
   ld  a,-2
   ld  (availevels),a
@@ -283,7 +329,9 @@ levelselectmenu:
   ld  hl,$0601 ;x=1
   ld  (_penCol),hl
 dispnextlevel:
-  ld  a,(ix+3)
+  ld  de,3
+  add ix,de
+  ld  a,(ix)
   ld  b,a
   inc a ;cp 255
   jr  z,__levselect
@@ -296,8 +344,6 @@ displevel:
   ld  (hl),a ;y+6
   cp  49 ;bottom of screen
   jr  nc,_levselect
-  ld  de,3
-  add ix,de
   ld  hl,availevels
   inc (hl)
   ld  a,b ;(ix+0)
@@ -307,8 +353,14 @@ displevel:
   cal _vputs
   jr  dispnextlevel
 
+loadlevel1:
+  psh ix
+  pop hl
+  ld  b,-2
+  jr  loadlevel
+
 readylevelfile: ;selected level at ahl
-; ld  hl,templevels-3
+; ld  hl,templevels-3/0
   ld  a,b
   add a,3 ;sellev+3 (#0==-3)
   ld  e,a
@@ -370,7 +422,11 @@ levdescclearloop:
   cal _vputs
   jr  levselectmenu+1
 __levselect:
+#ifdef intlevels
   ld  ix,templevels-6 ;reset 2 1st page
+#else
+  ld  ix,templevels-3
+#endif
 _levselect:
   ld  b,-2 ;level selected
   jr  levselect
@@ -403,12 +459,12 @@ loadlevel:
   cal _Get_Word_ahl
   ld  (leveldataSize),de
 
-  ld  d,8 ;counter
+  ld  d,9 ;counter
   ld  bc,datalevels
   cal loadgametype
   ld  (hilvlposa),a ;singleplayer levels
   ld  (hilvlposhl),hl
-  ld  d,4
+  ld  d,5
   cal loadgametype
 
   cal _SET_ABS_SRC_ADDR ;levelsstart
@@ -447,11 +503,11 @@ setdeflevels:
 ;----- build trig tables -----
 ;-----------------------------
 
-  ld  hl,TrigPrecalc
-  ld  de,SinCosTable
-  psh de
-  ld  bc,65
-  ldir
+  ld  hl,TrigPrecalc ;I believe this
+  ld  de,SinCosTable  ;is one of the few
+  psh de              ;pieces of original
+  ld  bc,65            ;Peaworm code still
+  ldir                  ;left intact..
   dec hl
   ld  b,63
 MirrorSineWave:
@@ -488,11 +544,9 @@ DisplayMenu: ;---draw menu---
   ld  hl,$FC00+$3E0 ;(*,62)
   cal hr
 dispmainmenu:
-  ld  hl,Gametype
-  ld  a,(hl)
+  ld  a,(Gametype)
   dec a ;will be inced @changegame
-  and 7
-  ld  (hl),a
+  cal changedgame
   ld  hl,changegame ;dispmenusets ;mainMenu
   psh hl ;jump here after ret
   ld  hl,txtMenu
@@ -500,9 +554,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
@@ -511,13 +566,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
@@ -527,7 +584,12 @@ dispmenuloop:
 
 hr: ;draw horizontal line at hl
   ld  b,16
-  jp  menuinvloop
+; jp  menuinvloop ;shorter but not good for pausescreen
+hrloop:
+  ld  (hl),-1
+  inc hl
+  dnz hrloop
+  ret
 
 ;--- menu loop ---
 
@@ -535,7 +597,7 @@ dispoptionmenu:
   ld  hl,txtoMenu
   ld  ix,posoMenu
 ;Back|Lives|Limit|Speed|Rotation|Growth
-  cal dispmenucommon
+  cal dispmenucommon_
 
 dispomenusets:
   cal clrold
@@ -760,6 +822,17 @@ select:   ;2nd/enter
   dec a ;6th: controls
   jp  z,changekeys
   jp  LetsGetThisPartyOn ;otherwise
+
+changenrworms:
+  cal change4spOnly
+  ld  a,(hl) ;hl=nrworms
+  inc a
+  cp  5
+  jr  nc,mainMenu ;may not be >4
+changednrworms:
+  ld  (hl),a
+  jr  _dispmenusets ;mainMenu
+
 notselect
   cp  K_EXIT
   jp  z,ExitNoStats
@@ -815,15 +888,6 @@ bchangecurworm:
   jr  nz,changedcurworm ;save >0
   jr  mainMenu
 
-changenrworms:
-  cal change4spOnly
-  ld  a,(hl) ;hl=nrworms
-  inc a
-  cp  5
-  jr  nc,mainMenu ;may not be >4
-changednrworms:
-  ld  (hl),a
-  jr  _dispmenusets ;mainMenu
 changenrwormsInit:
   ld  a,(Gametype)
   cp  3
@@ -863,7 +927,12 @@ changegame:
   jr  z,changegame
   jr  dispmenusets ;mainMenu
 changedgame:
-  and 7 ;mod 8
+  cp  9
+  jr  c,changedgameok
+  sub 255-8 ;-1 -> 8
+  jr  nc,changedgameok
+  xor a ;9 -> 0
+changedgameok:
   ld  (Gametype),a
   cal getnrlevels
   xor a
@@ -1150,7 +1219,9 @@ nameentered:
   ld  (ix+8),0 ;end mark
   jp  DisplayMenu
 
-;--proc
+;-----------------------------
+;------- procs-n-stuff -------
+;-----------------------------
 
 ubergetkey:
   halt ;woo hoo
@@ -1181,7 +1252,7 @@ hlatlevel: ;d must be 0
   add a,a ;nc
   add a,e
   add a,a ;8->2bytes
-  add a,24+1 ;go to datalevels
+  add a,28+1 ;go to datalevels
   ld  e,a ;=de
   sbc hl,de ;datalevels
   cal _ldHLind ;ld hl,(hl)
@@ -1237,18 +1308,21 @@ skipballs:
 
 skipflags:
   ld  a,(Gametype)
+  cp  gamerace
+  jr  z,skiplaps
   cp  gamectf
   jr  nz,noflagstoskip
   inc hl
   inc hl
+skiplaps:
   inc hl
   inc hl
 noflagstoskip:
 
 skipobjects:
-  ld  a,(hl)
-  inc hl
-  or  a
+  xor a
+  or  (hl)
+  inc hl ;nf
   ret z ;0=end
   inc hl
   inc hl
@@ -1286,36 +1360,47 @@ LetsGetThisPartyOn:
   ld  a,$17 ;no exit
   ld  (CheckExit),a ;set exit state
 
-  cal loadgamecar
-  psh hl
-  ld  (wormbeglives),a
-  inc hl ;nrworms
-  ld  a,(hl)
-  ld  (nrworms),a
-  inc hl ;level
+setupworms:
+  ld  hl,worm1set
+  ld  de,worm1
+  ld  a,4 ;4x (all worms)
+createwormsloop:
+  ex  de,hl
+  ld  bc,died ;0008
+  add hl,bc
+; ld  b,0
+  ld  (hl),b ;died=0
   inc hl
-  ld  a,(hl)
-  ld  (customspeed),a
+  ld  (hl),b ;score=0
   inc hl
-  ld  a,(hl)
-  ld  (growspeed),a
+  ld  (hl),b ;score+1=0
   inc hl
-  ld  a,(hl)
-  ld  (turnleft),a
-  ld  (turnright),a ;more efficient
+  ld  (hl),2 ;delay=2
   inc hl
-  ld  l,(hl)
-  ld  h,0
-  cal _HLTIMES10       ;hl=10*(hl)
-  ld  (scorelimit),hl
+  ld  (hl),3 ;lives=x
+wormbeglives =$-1
+  inc hl
+  ex  de,hl  ;de=wormX+head
+  ld  bc,18
+  ldir       ;copy 18 bytes
+  dec a      ;loop
+  jr  nz,createwormsloop
 
-  pop hl ;loadgamecar
+OhMyGodItsALabel:      ;pj34r my coding skillz
+  cal loadgamecar
+  psh hl ;datatype
   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
+  jr  nc,_StartLevel
+
+;--------- link ------------
+
+wormVhost   = 095
+wormVclient = 195
 
 linkmatch:
   cal _clrWindow
@@ -1335,53 +1420,146 @@ linkmatch:
 host:
   ld  c,wormVclient
   cal Qsend
-  ld  a,$18
-  jr  multiplayer
+  jr  sethost
 client:
   ld  hl,txtReceive
   cal _puts
-  ld  a,$E6
-multiplayer:
-  ld  (SwapPos),a
-; ld  a,2
-; ld  (nrworms),a
-
-;-----------------------------
-;--------- game over ---------
-;-----------------------------
-
-GameOver:
-  ld  hl,worm1set
-  ld  de,worm1
-  ld  a,4 ;4x (all worms)
-createwormsloop:
+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 ;loadgamecar
+  pop de ;leveldata
+  psh de
+  psh hl ;loadgamecar
+  ld  b,8
+  cal sendstuff
+  ld  hl,gameCar
+  ld  b,1
+  cal sendstuff
+  ld  hl,Gametype
+  ld  b,1
+  cal sendstuff
   ex  de,hl
-  ld  bc,died ;8
-  add hl,bc
-; ld  b,0
-  ld  (hl),b ;died=0
+  ld  b,168
+  cal sendstuff
+_StartLevel:
+  jr  StartLevel
+sendstuff:
+  psh de
+sendstuffloop:
+  psh bc
+  ld  c,(hl)
   inc hl
-  ld  (hl),b ;score=0
+  cal Qsend
+  pop bc
+  dnz sendstuffloop
+  pop de
+  ret
+recvstuff:
+  psh de
+recvstuffloop:
+  psh bc
+  cal Qrecv
+  ld  (hl),c
   inc hl
-  ld  (hl),b ;score+1=0
+  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 ;loadgamecar
+  pop de ;leveldata
+  ld  hl,templevels ;&&&&&&&
+  ld  de,datalink
+  psh de
+  psh hl ;loadgamecar
+  ld  b,8
+  cal recvstuff
+  ld  hl,gameCar
+  ld  b,1
+  cal recvstuff
+  ld  hl,Gametype
+  ld  b,1
+  cal recvstuff
+  ex  de,hl
+  ld  b,168
+  cal recvstuff
+
+;-------- 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  (hl),2 ;delay=2
+  ld  a,(hl)
+  ld  (customspeed),a
   inc hl
-  ld  (hl),3 ;lives=x
-wormbeglives =$-1
+  ld  a,(hl)
+  ld  (growspeed),a
   inc hl
-  ex  de,hl  ;de=wormX+head
-  ld  bc,18
-  ldir       ;copy 18 bytes
-  dec a      ;loop
-  jr  nz,createwormsloop
+  ld  a,(hl)
+  ld  (turnleft),a
+  ld  (turnright),a ;more efficient
+  inc hl
+  ld  l,(hl)
+  ld  h,0
+  ld  a,(gameCar)
+  rla
+  ld  a,0 ;(Left)=256
+  jr  nc,setscorelimit
+  ld  a,l
+  ld  l,h
+setscorelimit:
+  ld  (customleft),a
+  cal _HLTIMES10 ;hl=10*(hl)
+  ld  (scorelimit),hl
 
-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
@@ -1393,13 +1571,30 @@ 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
   cal nz,skiplvltitle
-  ld  de,Left
-  ldi
+  ld  a,(hl)
+  and 127
+  jr  nz,setleft
+customleft =$+1
+  ld  a,0
+setleft:
+  ld  (Left),a
+  inc a
+  ld  (lefttotal),a
+  dec a
+  xor (hl) ;bit (hl),7
+  ld  bc,gameCar
+  ld  a,(bc)
+  jr  z,leftloaded
+  or  128+32
+leftloaded:
+  ld  (bc),a
+  inc de
+  inc hl
   ld  de,Speed
   ld  a,0
 customspeed =$-1
@@ -1478,8 +1673,11 @@ worminit:
   ld  (hl),a ;y2
   inc hl
   ld  (hl),a ;x2
+  inc hl
+  inc hl
+  ld  (hl),a ;growH=0
 
-  ld  bc,(worm2-worm1)-5
+  ld  bc,(worm2-worm1)-7
   add hl,bc
   pop bc ;<0
   dnz worminit
@@ -1491,6 +1689,7 @@ worminit:
 
 ;-------- draw level ---------
 
+initlevel:
   ld  a,(de)
   inc de
   sub 128
@@ -1586,8 +1785,9 @@ levelhasbeensetup:
 
   cal drawstuff
 
-;-----------------------------
+;--------- prepare -----------
 
+leveldone:
   psh hl                        ; >> levelp new
   cal forceshowstats
 
@@ -1609,7 +1809,6 @@ maskline:
   dec c
   jr  nz,maskloop
 #endif
-
 #ifdef readytext
   ld  hl,$FDE0
   ld  de,$FDE1
@@ -1624,60 +1823,15 @@ maskline:
   res 3,(iy+5)
 #endif
 
-  ld  a,0
-gameCar =$-1
-  rra ;and _datalink
-  jr  nc,initfinished ;no link
+  ld  a,(gameCar)
+  bit _bitfood,a
+  jr  nz,nofood
+;  ld  ix,worm1
+  cal NewPea
   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:
-  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:
+  rla ;bit _bitmultpeas,a
+  cal c,multnewpea
   ld  bc,(worm1+pos)
   cal DisplayField
 
@@ -1789,76 +1943,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
@@ -2164,7 +2335,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)
@@ -2179,6 +2350,8 @@ removewormloop:
   cal res4pixels
   pop hl
   inc (ix+grow)
+  jr  nz,DoesWormTailEqualsWormHead
+  inc (ix+grow+1) ;+256
 DoesWormTailEqualsWormHead:
   cal _cphlde
   jr  nz,removewormloop
@@ -2189,6 +2362,7 @@ DoesWormTailEqualsWormHead:
   ld  a,0
 beginsize =$-1
   ld  (ix+grow),a
+  ld  (ix+grow+1),0 ;high
 safewormsizedone:
 
   ;de=ix+head
@@ -2267,7 +2441,9 @@ inlink:
   ld  l,c
   ret
 
+;-----------------------------
 ;------- handle worm ---------
+;-----------------------------
 
 HandleWorm:
   xor a
@@ -2306,6 +2482,7 @@ donediddelydone:
   ld  e,(ix+pos2)
   ld  d,(ix+pos2+1)
 
+#ifdef optdie
   psh hl
   ld  hl,previouspos
   ld  (hl),c
@@ -2317,6 +2494,7 @@ donediddelydone:
   inc hl
   ld  (hl),d
   pop hl
+#endif
 
 ;-------- move worm ----------
 
@@ -2377,37 +2555,45 @@ Hitworm:
   ld  a,(gameCar)
   ld  h,a
 #ifdef optdie
-  and _datadie
-  cal z,checkhitotherworm
+; if race - originally
+  cal checkhitotherworm
   ld  a,h
 #endif
-  and _datamultpeas ;&&bit
+  and _datactfpeas ;&&bit
   jr  nz,chkctfpeas
   ld  a,h
+  and _datamultpeas ;&&bit
+  jp  nz,chkmultpeas
+  ld  a,h
   and _datafood
-  jp  z,WormDead ;no food
+  jp  nz,WormDead ;no food
 
   ld  hl,0
 PeaY =$-2
 PeaX =$-1
   cal chkpeahit
   jp  nc,WormDead
+pickpea:
   cal DrawPea ;remove pea
+  cal NewPea
+pickpea_:
   ld  a,(ix+grow)
   add a,15
 peagrowth =$-1
   ld  (ix+grow),a
-  cal NewPea
+  jr  nc,wormset2grow
+  inc (ix+grow+1)
+wormset2grow:
   ld  hl,Left
-  dec (hl)
+  dec (hl) ;dec left before display
   psh af
   ld  e,10
   cal IncScore
   pop af
   jp  nz,Drawworm ;continue
-  ld  a,(gameCar)
-  and _datafoodl
-  jp  z,Drawworm
+; ld  a,(gameCar) ;(Left)>256
+; and _datafoodl
+; jp  z,Drawworm
   ld  a,(Gametype)
   or  a
   jp  nz,Exit ;stack restored
@@ -2426,7 +2612,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)
@@ -2490,6 +2676,34 @@ hitflag: ;correct pea hit
   ld  (drawctfpea2),a ;..both flags
   jr  Drawworm
 
+chkmultpeas:
+  ld  de,peaspos-1
+  ld  hl,lefttotalb
+lefttotal =$+1
+  ld  (hl),0
+chkmultpealoop:
+  ex  de,hl
+  inc hl
+  ld  e,(hl)
+  inc hl
+  ld  d,(hl)
+  ex  de,hl
+  psh de
+  cal chkpeahit
+  pop de
+  jr  c,pickmultpea
+  ld  hl,lefttotalb
+  dec (hl)
+  jr  nz,chkmultpealoop
+  jp  WormDead
+pickmultpea:
+  ld  a,247
+  ld  (de),a
+  dec de
+  ld  (de),a
+  cal DrawPea
+  jp  pickpea_
+
 ;-----------------------------
 
 nextotherwormbit:
@@ -2539,37 +2753,6 @@ checklap:
   pop bc
   ret
 
-#ifdef optdie
-checkhitotherworm:
- .db  $dd,$7d ;ld a,lx
-  cp  worm2&255
- psh ix
- jr nz,chkworm2 ; ret nz
-  ld  ix,worm1
- 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
-#endif
-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:
@@ -2596,10 +2779,14 @@ Drawworm:
   ld  (ix+head),l
   ld  (ix+head+1),h
 
-  ld  a,(ix+grow)
-  dec a
+  ld  l,(ix+grow)
+  ld  h,(ix+grow+1)
+  dec hl
+  ld  a,h
+  or  l
   jr  z,removetail
-  ld  (ix+grow),a
+  ld  (ix+grow),l
+  ld  (ix+grow+1),h
   ret
 
 removetail:
@@ -2612,6 +2799,13 @@ removetail:
   cal resbit
   ld  (ix+tail),l
   ld  (ix+tail+1),h
+  psh hl
+  cal res4pixels
+  pop hl
+  ld  c,(hl)
+  inc hl
+  ld  b,(hl)
+  jr  set4pixels
 
 res4pixels:
   cal ResPixel
@@ -2755,6 +2949,95 @@ Seed =$+1
   add a,2
   ret
 
+WormDead:
+#ifdef invincible
+  jp  stopworm
+#endif
+  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
+
+#ifdef optdie
+checkhitotherworm:
+ .db  $dd,$7d ;ld a,lx
+  cp  worm2&255
+ psh ix
+ jr nz,chkworm2 ; ret nz
+  ld  ix,worm1
+ 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
+#endif
+
 CheckPea: ;@hl; destr:abcde
   ld  c,l
   ld  a,(sprsize)
@@ -2791,22 +3074,20 @@ 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
+multnewpea:
+  ld  de,peaspos
+  ld  a,(Left)
+  ld  b,a
+multpealoop:
+  psh bc
+  psh de
+  cal NewPea
+  pop de
+  ld  hl,PeaY
+  ldi
+  ldi
+  pop bc
+  dnz multpealoop
   ret
 
 NewPea:
@@ -2869,7 +3150,8 @@ 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
@@ -2884,7 +3166,7 @@ chktimematchover:
   jr  z,nneexxtt ;yourself
   cp  (hl)
   ret nz ;someone else still alive
-  dec hl ;+delay
+  dec hl ;+del0ay
   dec hl ;+score+1
   ld  a,(hl)
   cp  (ix+score+1)
@@ -3121,9 +3403,9 @@ savestr:
 
 ;-----------------------------
 
-DisplayField:
-  ld  a,c
-  sub 29
+DisplayField:  ;all done by Jonah Cohen iirc. (-scrolling is scary-)
+  ld  a,c      ;not the fastest routine outthere, but it does get the job done.
+  sub 29       ;if something doesn't work, I probably _did_ alter it ;)
   jr  nc,NotMinYScroll
   xor a
 NotMinYScroll:
@@ -3392,7 +3674,7 @@ FindPixel: ;(b,c) to hl:a
 FP_Bit =$+1
   set 0,a
 
-  psh de ;&&&
+  psh de ;&&& C`MON! THIS IS UGLY! *hit myself*
   ld  de,ScrBuffer
   add hl,de
   pop de
@@ -3430,6 +3712,12 @@ drawsmtn:
 ; dec a ;4 = circle
 ; jp  z,drawcircle
 
+;IMHO, one weery nice routine. Oh lemme be proud just *once*.
+;Not perfect since it uses a screwy lineroutine to draw stuff
+;but, just _look_ at it. Ain't it grand? Z80 at its best.
+;Nice comments, also. So here we go: Shiar's Circle Routine:
+;(using the Bresenham method)
+
 drawcircle: ;(d,e),h   ;de=x,y; h=z
   ld  c,h              ;c=yy=z
   ld  a,h
@@ -3493,7 +3781,7 @@ circledraw:               ;destr:de
   ld  b,c
   ld  c,a              ;ex b,c
   pop hl
-  ret
+  ret                  ;thats it
 
 drawbox: ;(d,e)-(h,l)
   ld  b,l ;Delta-y
@@ -3517,159 +3805,141 @@ drawfatline:
   dec h
 ; jp  drawline
 
-;LINE (d,e)-(h,l)
-;destroyes a
+;A lot like Scabby's line routine in Wonderworm (dunno whether he wrote it
+;himself tho.) I did make a few optimizations and commented the thing.
+;A nice routine (also Bresenham), but for Wormy not perfect since really
+;large lines (>128 pixels in length or something) won't be flawless.
 
 drawline: ;(d,e)-(h,l)
   psh bc  ;destr: a
   psh hl
   psh de
-  ld  a,d
-  cp  h
-  jr  c,lineOrdered
-  ex  de,hl
-lineOrdered:
+  ld  a,d              ;a=d=x
+  cp  h                        ;h=xx
+  jr  c,lineXincs      ;if x>xx
+  ex  de,hl            ;make x<xx
+lineXincs:             ;deltax=|deltax|
   ld  b,d
-  ld  c,e
-  psh hl
-  psh bc
-  cal FindPixel
-  pop bc
-  pop de
-connectedLine:
-  psh hl
-  ld  h,c
-  ld  c,a
-  ld  a,d
-  sub b
-  ld  b,a
-  ld  a,e
-  jr  nz,LineNotPoint
-  cp  h
-  jr  nz,LineNotPoint
-  pop hl
-  jr  DoneLine
-LineNotPoint:
-  sub h
-  ld  de,32
-  jr  nc,LinePositiveY
-  neg
-  ld  de,-32
-LinePositiveY:
-  cp  b
-  jr  nc,SteepLine
-  add a,a
-  ld  (line2sm+1),a
+  ld  c,e              ;bc=x,y
+  psh hl               ;hl=xx,yy
+  cal FindPixel                ;  (ahl=x+y)
+  ex  (sp),hl          ;       :hl>
+  ld  c,a              ;c=mask (always)
+  ld  a,h              ;a=xx
+  sub b                        ;xx-x
+  ld  b,a              ;b=deltax (always>0)
+  ld  a,l              ;a=yy
+  jr  nz,lineexists    ;deltax!=0
+  cp  e                        ;yy==y
+  jr  nz,lineexists    ;deltay!=0
+  pop hl               ;       :<hl
+  jr  DoneLine         ;line is 1 pixel
+lineexists:
+  sub e                        ;a=deltay
+  ld  de,32            ;go down (def)
+  jr  nc,lineYincs     ;cf = deltay<0
+  neg                  ;a=|deltay|
+  ld  de,-32           ;go up
+lineYincs:             ;lets assume y incs as well
+  cp  b                
+  jr  nc,SteepLine     ;deltay<deltax?
+  ld  (line2sm+1),a    ;a=deltay
   ld  h,a
   xor a
   sub b
-  add a,a
-  ld  (line1sm+1),a
-  ld  a,h
-  sub b
-  pop hl
-LineLoopGentle:
-  psh af
+  ld  (line1sm+1),a    ;a=-deltax
+  rra
+  add a,h              ;a=deltay-deltax/2
+  pop hl               ;       :<hl
+
+linedrawxloop:
+  psh af               ;init z=dy-dx
   ld  a,(hl)
-  or  c
+  or  c                        ;|c:hl
   ld  (hl),a
   rrc c
   jr  nc,$+3
-  inc hl
+  inc hl               ;(x++,y)
   pop af
-  jp  m,line2sm
+  jp  m,line2sm                ;z<0
 line1sm:
-  add a,0
-  add hl,de
+  add a,0              ;z-=deltax
+  add hl,de            ;(x,y++)
 line2sm:
-  add a,0
-  dnz LineLoopGentle
+  add a,0              ;z+=deltay
+  dnz linedrawxloop    ;|deltax| times
+
 DoneLine:
   ld  a,(hl)
-  or  c
-  ld  (hl),a
+  or  c                        ;|c:hl
+  ld  (hl),a           ;draw end
   pop de
   pop hl
   pop bc
   ret
+
 SteepLine:
-  ld  h,a
-  neg
-  add a,a
+  ld  h,a              ;h=deltay
+  neg                  ;a=-deltay
   ld  (line3sm+1),a
   ld  a,b
-  add a,a
-  ld  (line4sm+1),a
-  sub h
-  ld  b,h
-  pop hl
-LineLoopSteep:
-  psh af
+  ld  (line4sm+1),a    ;a=deltax
+  sub h                        ;a=deltax-deltay
+  ld  b,h              ;b=deltay
+  pop hl               ;       :<hl
+linedrawyloop:
+  psh af               ;init z=2(dx-dy)
   ld  a,(hl)
-  or  c
+  or  c                        ;|c:hl
   ld  (hl),a
-  add hl,de
+  add hl,de            ;(x,y++)
   pop af
-  jp  m,line4sm
+  jp  m,line4sm                ;z<0
 line3sm:
-  add a,0
+  add a,0              ;z-=deltay
   rrc c
   jr  nc,$+3
-  inc hl
+  inc hl               ;(x++,y)
 line4sm:
-  add a,0
-  dnz LineLoopSteep
+  add a,0              ;z+=deltax
+  dnz linedrawyloop    ;|deltay| times
   jr  DoneLine
 
+
+;--- foo ---
+;wild insert
+receivenewpeaoverlink:
+  cal Qrecv ;Crecv
+  ld  l,c
+  cal Qrecv ;Crecv
+  ld  h,c
+  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
+; jr  Qsend ;that's why it's here
+
+;..and last but not least..:
 ;-----------------------------
 ;----------- link ------------
 ;-----------------------------
 
-linkok:
-  ld  a,D0HD1H
-  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
-  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
-
 ;---- 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
@@ -3695,22 +3965,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
@@ -3728,6 +3998,41 @@ recvfinish:
   ld (linklosses),a    ;reset number of losses
   ret
 
+;---- COMMON ----
+
+linkok:
+  ld  a,D0HD1H
+  out (7),a            ;raise both wires = link ok
+  ret
+
+checklink:             ;load wires in A and check for timeout
+  dec de               ;decrease timer
+  ld  a,d
+  or  e
+  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
+  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
+
+#ifdef intlevels
 
 ;-----------------------------
 ;---------- levels -----------
@@ -3744,13 +4049,13 @@ LevelDef:
 
 LevelDefM:
   .db "Empty Arena",0
-  .db 8,4,15,15,0,0
+  .db 5,4,15,15,0,0
   .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
   .db 128,57
   .db 0
 
   .db "Fast Fun :))",0
-  .db 8,0,18,12,5
+  .db 8+128,0,18,12,5
   .db %1110000,%10001000,%10001000,%10001000,%1110000,0
   .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
   .db 128,57
@@ -3789,11 +4094,13 @@ LevelDefC: ;ctf
   .db 27,8,27,116
   .db 0
 
+#endif
+
 ;-----------------------------
 ;---------- 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
@@ -3811,7 +4118,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
@@ -3827,8 +4134,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
@@ -3836,15 +4143,23 @@ 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
 txtGame3: .db "Deathmatch",0
 txtGame4: .db "Foodmatch",0
-txtGame5: .db "Timematch",0
-txtGame6: .db "Race",0
-txtGame7: .db "CTF" ;,0
+txtGame5: .db "Multifoodmatch",0
+txtGame6: .db "Timematch",0
+txtGame7: .db "Race",0
+txtGame8: .db "CTF" ;,0
 
 posGame:  .db 0
          .db txtGame1-txtGame
@@ -3854,6 +4169,7 @@ posGame:  .db 0
          .db txtGame5-txtGame
          .db txtGame6-txtGame
          .db txtGame7-txtGame
+         .db txtGame8-txtGame
 
 txtNone:   .db "None",0
 txtDef:    .db "Default",0
@@ -3893,45 +4209,54 @@ txtposReady = 7
 txtGO:     .db 5,5,5,5,5," GAME OVER ",$CF,$CF,$CF,$CF,$CF,0
 #endif
 
+#ifdef intlevels
 datalevels: .dw LevelDef, LevelDefM
             .dw LevelDefT,LevelDefM
-            .dw LevelDefM,LevelDefM
+            .dw LevelDefM,LevelDefM,LevelDefM
             .dw LevelDefR,LevelDefC
-nrlevels:   .db 1,3,1,3,3,3,3,1     ;=defaults
-
-_datalink      = %0000001 ;linkplay
-_datafoodl     = %0000010 ;left=0 limit
-_datasingl     = %0000100 ;singleplayer=1 (=hiscore+keep_length+nextlevel)
-_datamultpeas  = %0001000 ;multiple peas=1
-_datatime      = %0010000 ;time incs score (timematch)
-_datafood      = %0100000 ;food present
-_datadie       = %1000000 ;worm dies on impact
-;reserved       %10000000 ;for future use
-
-savestart:        ;     �game info (see above)
-                  ;     | �lives (0=unlimited)
-                  ;     | | �nrworms (can be altered by user)
-                  ;     | | | �level (reset to 1 at startup)
-                  ;     | | | |  �speed/delay (-1=def)
-                  ;     | | | |  |  �grow speed (-1=none; 0=continuous)
-                  ;     | | | |  |  |  �turn speed (8=def)
-                  ;     | | | |  |  |  |  �score limit (0=none)
-gamesingle   =  0 ;used | | | |  |  |  |  |
-datasingle: .db  %1100110,3,1,1,-1,-1, 8, 0 ;Singleplayer (SP; 3 lives)
+nrlevels:   .db 2,3,1,3,3,3,3,3,1,0     ;=defaults
+#else
+datalevels: .dw 0,0,0,0,0,0,0,0,0
+nrlevels:   .dw 0,0,0,0,0
+#endif
+
+_datalink      = %00000001 ;linkplay
+_datafoodl     = %00000010 ;left=0 limit
+_datasingl     = %00000100 ;singleplayer=1 (=hiscore+keep_length+nextlevel)
+_datactfpeas   = %00001000 ;ctf peas=1
+_datatime      = %00010000 ;time incs score (timematch)
+_datafood      = %00100000 ;food present=0
+_bitfood       = 5
+_datamultpeas  = %10000000 ;multiple peas=1 (no _datafood)
+_bitmultpeas   = 7
+;reserved        %01000000 ;for future use
+
+savestart:        ;      �game info (see above)
+                  ;      | �lives (0=unlimited)
+                  ;      | | �nrworms (can be altered by user)
+                  ;      | | | �level (reset to 1 at startup)
+                  ;      | | | |  �speed/delay (-1=def)
+                  ;      | | | |  |  �grow speed (-1=none; 0=continuous)
+                  ;      | | | |  |  |  �turn speed (8=def)
+                  ;      | | | |  |  |  |  �score limit (0=none)
+gamesingle   =  0 ;      | | | |  |  |  |  |
+datasingle: .db  %01000110,3,1,1,-1,-1, 8, 0 ;Singleplayer (SP; 3 lives)
 gamepeas     =  1
-datapeas:   .db  %1100100,1,1,1,-1,-1, 8, 0 ;Peaworm (SP; 1 live)
+datapeas:   .db  %01000100,1,1,1,-1,-1, 8, 0 ;Peaworm (SP; 1 live)
 gametron     =  2
-datatron:   .db  %1010100,1,1,1,-1, 0, 8, 0 ;Tron (SP; 1 live, cont.growth)
-gamedeathm   =  3 ;used
-datadeathm: .db  %1000000,3,2,1,-1,49, 8, 0 ;Deathmatch (3 lives, 50 growth)
+datatron:   .db  %01110100,1,1,1,-1, 0, 8, 0 ;Tron (SP; 1 live, cont.growth)
+gamedeathm   =  3
+datadeathm: .db  %01100000,3,2,1,-1,49, 8, 0 ;Deathmatch (3 lives, 50 growth)
 gamefoodm    =  4
-datafoodm:  .db  %1100000,0,2,1,-1,-1, 8,10 ;Foodmatch (100 score)
-gametimem    =  5
-datatimem:  .db  %1010000,1,2,1,-1, 0, 8, 0 ;Timematch (tron, 100 score)
-gamerace     =  6 ;used
-datarace:   .db  %0000000,0,2,1,-1,-1, 8,10 ;Race (100 score, no collision)
-gamectf      =  7 ;used
-datactf:    .db  %1001000,0,4,1,-1,-1, 8,10 ;CTF (100 score)
+datafoodm:  .db  %01000000,0,2,1,-1,-1, 8,10 ;Foodmatch (100 score)
+gamemfoodm   =  5
+datamfoodm: .db  %11100010,0,2,1,-1,-1, 8,10 ;MuchFoodmatch (10 peas))
+gametimem    =  6
+datatimem:  .db  %01110000,1,2,1,-1, 0, 8, 0 ;Timematch (tron, 100 score)
+gamerace     =  7
+datarace:   .db  %01100000,0,2,1,-1,-1, 8,10 ;Race (100 score)
+gamectf      =  8
+datactf:    .db  %01001000,0,4,1,-1,-1, 8,10 ;CTF (100 score)
 
 worm1set:  .dw worm1p,worm1p
            .db %11110111,1,-01,K_RIGHT,K_LEFT
@@ -3947,11 +4272,13 @@ worm4set:  .dw worm4p,worm4p
 worm4name: .db "JIM     ",0
 
 defhiscrpos:
+#ifdef intlevels
   .db 0,0,"SHI"
   .db 0,0,"SHI"
   .db 0,0,"SHI"
   .db 0,0,"SHI"
   .db 0,0,"SHI"
+#endif
 
 Gametype:  .db 0 ;last gamemode
 
@@ -3971,7 +4298,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
@@ -3981,49 +4308,19 @@ startdelay    = 30
 respawndelay  = 30
 maxnamelength = 8+1
 
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
-.db "   wormy@shiar.org",0
-
 defspritesz = 4
 defspriteimg:  .db %01100000
                .db %11110000
                .db %11110000
                .db %01100000
 
+#ifdef intlevels
 deflevels:
   .db "Internal Levels",0
-  .db "by SHIAR -- still t"
-  .db "o be added...." ;,0
+  .db "by Shiar" ;,0
 
   .db 0,deflevels/256,deflevels&255
+#endif
 templevels:
 
 ;-----------------------------