worm 0.92.0907: link improvements
[wormy.git] / worm.z80
index d50545fe7c0cbfa70a623cb899249a25c3c6a54a..af6b84aa3132cacbf22cbbb1fe8682a7dde596d3 100644 (file)
--- a/worm.z80
+++ b/worm.z80
 ; Title                      : Worm
-; Version                    : 0.92
-; Release Date               : soon (I hope)
-; Filename                   : worm.86p (3404)
+; Version                    : 92%
+; Release Date               : june 2000
+; Filename                   : worm.86p (5kb)
 ; Author(s)                  : Shiar
-; Email Address              : shiar@mailroom.com
+; Email Address              : shiar0@hotmail.com
 ; ICQ UIN                    : #43840958
-; Web Page                   : www.games3.net/shiar
-; Description                : ruling multiplayer game for 86 (most like Nibbles)
-; Where to get this game     : games3.net/shiar (home of Worm)
-; Other games by author(s)   : Shiar: Nemesis beta
+; Web Page                   : www.shiar.org
+; Description                : ruling Nibbles-like game 1-4 players
+; Where to get this game     : www.shiar.org (home of Worm)
+; Other games by author(s)   : Nemesis beta
 ; Additional Credits to      : Matthew Shepcar (wrote original Peaworm, end'98)
-;                              Jonah Cohen (wrote some parts of worm)
+;                              Jonah Cohen (helped writing worm)
 
 ;-----------------------------
 ;----------- TO-DO -----------
 ;-----------------------------
 
-;       Shiar 3.III.00
+; 92% = DONE
 
-;Feel like doing something? (name indicates who's working on it)
-;  * linkplay
-;  * singleplay ending
-;  * titlescreen
-;  * make linkplay available for all gametypes (not just deathmatch)
-;  * two worms collide with heads -> both should die
-;  * 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)* sprites for picks instead of blocks
+;     * customizable keys
+;     * internal levels
+;       * check levels/gametype
+;       * enough hiscore saves!
+;     * complete readme
+;  2% * misc (pollish, bugs, &&&)
+;   * LINK
+;  2% * fix deaths linkplay and transmit game/level data
+;  2% * make linkplay available for all gametypes (not just deathmatch)
+;   * CTF
+;  1% * fix pea XOR problem in ctf (+dom?)
+;     * fix wormstop
+;  1% * domination?: take control points by running over them and hold them
 
-;1) Working on a new pickup-system allowing more than one "food" and different pickup-handling
+;100% = bugs fixed + levels done
+
+;-----------------------------
+;-----------------------------
+;---------  W O R M  ---------
+;-----------------------------
+;-----------------------------
+
+#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
 
 #include "asm86.h"
 #include "ti86asm.inc"
-#include "ti86abs.inc"
-
-_SHRACC    = $4383
-_SHLACC    = $438B
-_divHLby10 = $4044
-_divAby10  = $4DAF
-_cphlde    = $403C
-_clrWindow = $4A86
-_asapvar   = $D6FC
-_MOV4B     = $429B ;4x ld (de),(hl)
-_MOV5B     = $4297 ;5x ld (de),(hl)
-_mov9b     = $4283 ;9x ld (de),(hl)
-_ldHLind   = $4010 ;ld hl,(hl)
-_swapt_    = $45F3 ;ex_ahl_bde
-
-leveldata  = $EA00 ;size<$400
+
+_SHRACC            = $4383
+_SHLACC            = $438B
+_divHLby10         = $4044 ;hl=hl/10
+_divAby10          = $4DAF ;a=a/10
+_HLTIMES10         = $41BF ;hl=hl*10
+_cphlde            = $403C
+_clrWindow         = $4A86 ;clear screen
+_asapvar           = $D6FC ;own name (worm)
+_MOV4B             = $429B ;4x ld (de),(hl)
+_MOV5B             = $4297 ;5x ld (de),(hl)
+_mov9b             = $4283 ;9x ld (de),(hl)
+_ldHLind           = $4010 ;ld hl,(hl)
+_swapt_            = $45F3 ;ex_ahl_bde
+_Get_Word_ahl      = $521D ;ld de,(ahl)
+_Set_Word_ahl      = $5221 ;ld (ahl),de
+_INC_PTR_AHL       = $4637 ;ahl=ahl+1
+_AHL_PLUS_2_PG3    = $4C3F ;ahl=ahl+2
+_SET_ABS_SRC_ADDR  = $4647 ;set source for mm.ldir =ahl
+_LOAD_ABS_SRC_ADDR = $5209 ;ahl = mm.ldir source
+_SET_ABS_DEST_ADDR = $5285 ;set destination for mm.ldir = ahl
+_SET_MM_NUM_BYTES  = $464F ;number of bytes for mm.ldir = ahl
+_mm_ldir           = $52ED ;24bit ldir
+_RAM_PAGE_1        = $47E3 ;set $8000+ to page 1
+_RAM_PAGE_7        = $47F3
+_PTEMP_END         = $D29A ;end of VAT
+_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 -------
+;-----------------------------
+
+;--- 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
+
+namelength  = $BC00 ;(1)         @menu
+#ifdef buffer
+DispBuffer  = $BC00 ;(10x57d)    @game
+#else
+DispBuffer  = $FC70
+#endif
 
 ;-----------------------------
 ;------- program start -------
 ;-----------------------------
 
 .org _asm_exec_ram
+
+wormVhost   = 092
+wormVclient = 192
+
 start:
   nop
   jp Start
@@ -62,11 +134,13 @@ start:
   .dw WormMsg
   .dw WormIcon
 
+WormMsg:
+  .db "WORM by SHIAR -- alpha 92%",0
 WormIcon:
   .db 9,2
-  .db %10010111,%01101111
+  .db %10010110,%01101111
   .db %10110101,%01001011
-  .db %11110111,%01001001
+  .db %01110011,%01001001
   .db %00000011,%10000000
   .db %00000001,%11100000
   .db %00111000,%11111000
@@ -74,48 +148,220 @@ WormIcon:
   .db %11101111,%00001111
   .db %11000011,%10000000
 
-levelfile:
-  .db 7,"wormlvl"
+levelhead  = 'w'
+levelhead2 = 92 ;worm levels header = "92"
+
+int_handler:
+  ex af,af'
+  in a,($03)
+  bit 3,a
+  jp z,$0039
+  res 0,a
+  out ($03),a
+  jp $0039
+int_end:
 
 Start:
   ld  (SpSave),sp
-  call _runindicoff
-  call _flushallmenus
-  call _clrLCD
+  cal _runindicoff
+  cal _flushallmenus
 
-  ld  hl,levelfile-1
-  rst 20h ;_ABS_MOV10TOOP1
-  rst 10h ;_FINDSYM
-  ret c ;not found
-  ex  de,hl
-  ld  a,b ;call _ex_ahl_bde
-  call _SET_ABS_SRC_ADDR
+  im  1
+  ld  a,$D4
+  ld  h,a
+  ld  l,0     ;ld hl,$D400
+  ld  d,a
+  ld  e,1     ;ld de,$D401
+  ld  b,e
+  ld  c,l     ;ld bc,$0100
+  dec a       ;ld a,$D3
+  ld  (hl),a
+  ldir
+  ld  hl,int_handler
+  ld  d,a
+  ld  e,a     ;ld de,$D3D3
+  ld  bc,int_end-int_handler
+  ldir
+  inc a       ;ld a,$D4
+  ld  i,a
+  im  2
+
+  cal _RAM_PAGE_7
+  ld  hl,$BFFF ;VAT start
+  ld  bc,templevels
+searchloop:
+  ld  de,(_PTEMP_END+1) ;VAT end
+  or  a ;nc
+  sbc hl,de ;hl<de?
+  jr  c,searchcomplete
+  add hl,de
+  psh hl
+  ld  a,(hl)
+  cp  $0C ;string
+  jr  z,stringfound
+searchnext:
+ cal _RAM_PAGE_7
+  pop hl
+  dec hl ;5x
+  dec hl
+  dec hl
+  dec hl
+  dec hl
+ psh bc
+  ld  b,(hl) ;name size
+  inc b
+skipname:
+  dec hl
+  dnz skipname
+ pop bc
+  jr  searchloop
 
-  xor a
-  ld  hl,leveldata ;datalevels
-  call _SET_ABS_DEST_ADDR
- xor a
-  ld  hl,2
-  call _SET_MM_NUM_BYTES
-  call _mm_ldir
+stringfound:
+  dec hl
+  ld  e,(hl)
+  dec hl
+  ld  d,(hl)
+  dec hl
+  ld  a,(hl)
+  ex  de,hl ;ld ahl,(hl)
+  cal _AHL_PLUS_2_PG3 ;string id
+  cal _Get_Word_ahl ;ld de,(ahl)
+ cal _RAM_PAGE_1
+ ld (bc),a
+  ld  a,levelhead
+  cp  e
+  jr  nz,searchnext ;not worm
+  ld  a,levelhead2
+  cp  d
+  jr  nz,searchnext
+
+ inc bc
+ ld a,h
+ ld (bc),a
+ inc bc
+ ld a,l
+ ld (bc),a
+ inc bc
+ jr searchnext
+
+loadgametype:
+  psh de
+  inc bc
+  inc bc
+  cal _Get_Word_ahl ;ld de,(ahl++)
+  psh af
+  ld  a,d
+  or  e
+  jr  z,defaultlevels
+  ld  a,e ;set new level
+  ld  (bc),a
+  inc bc
+  ld  a,d
+  ld  (bc),a
+  dec bc
+defaultlevels:
+  pop af
+  pop de ;counter
+  dec d ;8x
+  jr  nz,loadgametype
+  ret
 
+searchcomplete:
+  cal _RAM_PAGE_1
+  ld  a,255
+  ld  (bc),a ;end mark
+  ld  hl,templevels-3
+dispnextlevel:
+  cal _RAM_PAGE_1
+  psh hl
+  cal _clrWindow
+  ld  a,2
+  ld  (_curRow),a
+  ld  hl,txtLevsel
+  cal _puts ;"< Select levels: >"
+  ld  hl,$0004
+  ld  (_curRow),hl
+  pop hl
+  ld  a,(hl)
+  cp  255 ;&&
+  jr  nz,displevel
+  ld  hl,templevels-3
+  ld  a,(hl)
+displevel:
+  inc hl
+  ld  d,(hl)
+  inc hl
+  ld  e,(hl)
+  inc hl  ;ade=(hl)
+  psh hl  ;HL
+  ld  c,a
+  ld  h,d
+  ld  l,e ;cde=ahl=(hl)
+  cal _load_ram_ahl ;hl=ahl
+  ld  b,(hl) ;b=title size
+  psh bc
+  cal _putps ;destr=abchl
+  pop bc  ;cde=hl
+  pop hl  ;HL
+levselect:
+  halt
+  psh hl
+  psh de
+  psh bc
+  cal GET_KEY
+  pop bc
+  pop de
+  pop hl
+  cp  K_RIGHT
+  jr  z,dispnextlevel
+  sub K_SECOND
+  jr  z,loadlevel
+  dec a ;K_EXIT
+  ret z
+  cp  K_ENTER-K_EXIT+256
+  jr  nz,levselect
+
+loadlevel:
+  ld  a,c
+  or  a ;levelfile on page 0 (=internal)
+  jr  z,levelloaded
+
+  ex  de,hl ;ahl=cde
+  inc b ;b=titlesize+1
+skiptitle:
+  cal _INC_PTR_AHL
+  dnz skiptitle
+
+  cal _Get_Word_ahl
+  ld  (leveldataSize),de
+  ld  d,8 ;counter
+  ld  bc,datalevels-2
+  cal loadgametype
+  ld  (hilvlposa),a
+  ld  (hilvlposhl),hl
+  ld  d,4
+  cal loadgametype
+
+  cal _SET_ABS_SRC_ADDR ;levelsstart
   xor a
-  ld  hl,datalevels
-  call _SET_ABS_DEST_ADDR
- xor a
-  ld  hl,16
-  call _SET_MM_NUM_BYTES
-  call _mm_ldir
-
- xor a
   ld  hl,leveldata
-  call _SET_ABS_DEST_ADDR
- xor a
-  ld  hl,400
-  call _SET_MM_NUM_BYTES
-  call _mm_ldir
+  cal _SET_ABS_DEST_ADDR ;store in mem.
+  ld  hl,0
+leveldataSize =$-2
+  cal _SET_MM_NUM_BYTES
+  cal _mm_ldir
 
- call _RAM_PAGE_1
+  cal _LOAD_ABS_SRC_ADDR ;->ahl
+  ld  (hiscrposa),a
+  ld  (hiscrposhl),hl
+  cal _RAM_PAGE_1
+
+  ld  hl,leveldata
+  ld  de,defsprsize
+  ldi ;(de),(hl)\inc hl
+  ld  (defsprite),hl
+levelloaded:
+  cal _RAM_PAGE_1
 
   res 2,(iy+13) ;appAutoScroll
   ld  a,r
@@ -127,7 +373,7 @@ Start:
 
   ld  hl,TrigPrecalc
   ld  de,SinCosTable
-  push de                        ; >> 1
+  psh de                        ; >> 1
   ld  bc,65
   ldir
   dec hl
@@ -137,7 +383,7 @@ MirrorSineWave:
   ld  a,(hl)
   ld  (de),a
   inc de
-  djnz MirrorSineWave
+  dnz MirrorSineWave
   pop hl                         ; << 0k
   ld  b,128+64
 NegativeSineWave:
@@ -146,85 +392,121 @@ NegativeSineWave:
   ld  (de),a
   inc hl
   inc de
-  djnz NegativeSineWave
+  dnz NegativeSineWave
 
 ;-----------------------------
 ;---------- menu -------------
 ;-----------------------------
 
+  ld  a,1
+  ld  (curlevel),a
+
+;--- draw menu ---
+
 DisplayMenu:
-  ld  a,2
-  ld  (nrworms),a
-gomainMenu:
-  call _clrWindow
-  ld  hl,txtWelcome
-  call _puts
-  ld  de,$0205
+  cal _clrWindow
+  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
-  call _puts ;txtOptions
+  cal _puts ;Level <00>
+  dec e ;$0206
+  ld  (_curRow),de
+  cal _puts ;Limit <00>
+  dec e ;$0205
+  ld  (_curRow),de
+  cal _puts ;Worms <2>
   dec e ;$0204
   ld  (_curRow),de
   ld  hl,(CURtxtGame)
-  call _puts
+  cal _puts ;Singleplayer
 
   xor a
+  cal menudraw
+  jr  howmanyworms
+
+;--- menu loop ---
+
 mainMenu:
-  call menucall
+  cal menucall
   jr  nz,notselect
-select:
+select:   ;2nd/enter
   ld  a,b
-  or  a
-  jr  nz,gooptionsMenu
-  jp  LetsGetThisPartyOn
+  dec a   ;2nd item
+  jp  z,changeworms
+  jp  LetsGetThisPartyOn ;1/3/4
 notselect
   cp  K_EXIT
   jp  z,ExitNoStats
+  cp  K_LEFT
+  jr  z,selleft
   cp  K_RIGHT
   ld  a,b
   jr  nz,mainMenu
-  or  a
-  jr  z,Variation
 
-gooptionsMenu:
-  call _clrWindow
-  ld  hl,txtWelcome
-  call _puts
-  ld  hl,txtLevel
-  ld  de,$0205
-  ld  (_curRow),de
-  call _puts ;txtLevel
-  dec e ;$0204
-  ld  (_curRow),de
-  call _puts ;txtWorms
-  ld  a,(nrworms)
-  add a,'0'
-  call _putc
-  xor a
-optionsMenu:
-  call menucall
-  jr  nz,notopselect
-opselect:
-  ld  a,b
+selright:
   or  a
-  jr  nz,changelevel
-changeworms:
-  ld  hl,nrworms
-  inc (hl)
-  ld  a,4
-  cp  (hl)
-  jr  nc,gooptionsMenu
-  ld  (hl),2
-  jr  gooptionsMenu
+  jr  z,changegame
+  dec a
+  jr  z,changenrworms
+  dec a
+  jp  z,changelives
+
 changelevel:
-  jr  optionsMenu
+  ld  hl,Gametype
+  ld  d,0
+  ld  e,(hl)
+  ld  hl,nrlevels
+  add hl,de
+  ld  d,(hl) ;max level for sel.game
+curlevel =$+1
+  ld  a,1
+  inc a
+  cp  d
+  jr  c,changedlevel
+  ld  a,d
+changedlevel:
+  ld  (curlevel),a
+_dispcurlevel:
+  ld  hl,$0807
+  ld  (_curRow),hl
+  cal showA
+  jp  displives ;mainMenu
 
-notopselect:
-  cp  K_EXIT
-  jr  z,gomainMenu
+selleft:
   ld  a,b
-  jr  optionsMenu
+  dec a
+  jr  z,bchangenrworms
+  dec a
+  jp  z,bchangelives
+  dec a
+  jr  nz,mainMenu
+
+bchangelevel:
+  ld  a,(curlevel)
+  dec a
+  jr  nz,changedlevel
+_mainMenu:
+  jr  mainMenu
 
-Variation:
+changegame:
+  ld  a,1
+  ld  (curlevel),a
   ld  a,0
 Gametype =$-1
   ld  hl,txtGame2
@@ -238,121 +520,382 @@ okilydokily:
   ld  de,$0204
   ld  (_curRow),de
   ld  (CURtxtGame),hl
-  call _puts
+  cal _puts
   ld  (NEXTtxtGame),hl
-  ld  a,b
-  jp  mainMenu
+howmanyworms:
+  ld  hl,nrworms
+  ld  a,(Gametype)
+  cp  2
+  ld  (hl),1
+  jr  c,dispnrworms
+  inc (hl) ;2
+  jr  dispnrworms ;mainMenu
 
-menucall:
-  push af
-  ld  hl,$0004
+changenrworms:
+  ld  a,(Gametype)
+  cp  2 ;&&
+  jr  c,_mainMenu ;type 0/1
+
+  ld  hl,nrworms
+  ld  a,(hl)
+  inc a
+  cp  5
+  jr  nc,dispcurlevel
+changednrworms:
+  ld  (hl),a
+dispnrworms:
+  ld  a,(hl) ;hl=nrworms
+  ld  hl,$0805
   ld  (_curRow),hl
-  ld  a,' '
-  call _putc
-  ld  hl,$0005
+  add a,'0'
+  cal _putc
+dispcurlevel:
+  ld  a,(curlevel)
+  jr  _dispcurlevel ;mainMenu
+
+bchangenrworms:
+  ld  hl,nrworms
+  ld  a,(hl)
+  dec a ;1-3
+  jr  nz,changednrworms
+  jr  dispcurlevel
+
+
+changelives:
+  cal changelivesInit
+  inc a
+  cp  100
+  jr  nc,displives
+changedlives:
+  ld  (hl),a
+displives:
+  cal loadgamecar
+  ld  hl,$0806
   ld  (_curRow),hl
-  call _putc
-  pop af
-  push af
-  ld  h,0
-  add a,4
+  cal showA ;liveslimit
+  sub '0' ;original A
   ld  l,a
-  ld  (_curRow),hl
-  ld  a,'*'
-  call _putc
-  pop af
-  ld  b,a
-menukeys:
+  ld  a,c
+  and _datascore
+  ld  a,' '
+  jr  z,limitok
+  ld  a,'0'
+limitok:
+  cal _putc ;x10
+  jp  mainMenu
+bchangelives:
+  cal changelivesInit
+  dec a
+  jr  z,displives
+  jr  changedlives
+
+changelivesInit:
+  cal loadgamecar  ;c=(gameCar)
+;a=(hl)=(Gametype+1)=(wormbeglives)
+  ld  a,(Gametype) ;&&&
+  cp  3
+  ld  a,(hl)
+  ret nc           ;change lives
+  pop hl           ;restore stack
+  jr  displives
+
+;--- handle menukeys ---
+
+menucall:
+  psh bc
+menuwaitkey:
   halt \ halt
-  call GET_KEY
+  cal GET_KEY
   or  a
-  jr  z,menukeys
+  jr  z,menuwaitkey
+  pop bc ;pop a as b
   cp  K_UP
-  jr  nz,notup
-updown:
-  ld  a,b
-  xor 1
-  ld  b,a
-  inc a ;nz
-  ret
-notup:
+  cal z,menuup
   cp  K_DOWN
-  jr  z,updown
+  cal z,menudown
   cp  K_ENTER
   ret z
   cp  K_SECOND
   ret ;z=select
+menupos:
+  ld  a,b
+  add a,4
+  ld  h,0
+  ld  l,a
+  ld  (_curRow),hl
+  ret
+menuclr:
+  cal menupos
+  ld  a,' '
+  jp  _putc
+menudown:
+  cal menuclr
+  inc b
+  jr  menuupdown
+menuup:
+  cal menuclr
+  dec b
+menuupdown:
+  ld  a,b
+  and %11 ;4=0;-1=3
+menudraw:
+  ld  b,a
+  cal menupos
+  ld  a,'*'
+  jp  _putc ;a=K_STO
 
-;-----------------------------
-;-------- start game ---------
-;-----------------------------
+;--- change name ---
+; of worm#(nrworms)
+;or #1 if Gametype<2
 
-LetsGetThisPartyOn:
-  ld  hl,gamesdata
+changeworms:
+  cal _clrWindow
+  ld  hl,txtName
+  cal _puts ;"Enter name player "
+  ld  a,(Gametype)
+  cp  2
+  ld  a,1
+  jr  c,wormnrname
+nrworms =$+1
+  ld  a,1
+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,d ;19x
+  ld  e,a
+  ld  d,0 ;de=a
+
+  ld  ix,worm1name-19
+  add ix,de
+  ld  a,maxnamelength
+  cal entername
+  ld  (ix),0
+  jp  DisplayMenu
+
+entername:
+  ld  h,1
+  ld  l,h ;)
+  ld  (_curRow),hl
+  ld  (namelength),a
+enternameloop:
+  ld  a,'_'
+  cal _putc
+  ld  hl,_curCol
+  dec (hl)
+nokeypressed:
+  halt
+  cal GET_KEY
+  or  a
+  jr  z,nokeypressed
+
+  cp  K_DEL
+  jr  nz,continue
+backspace:
+  ld  hl,namelength
+  ld  a,(hl)
+  cp  maxnamelength
+  jr  nc,nokeypressed
+  inc (hl)
+
+  dec ix
+  ld  a,' '
+  ld  (ix),a
+  cal _putc
+  ld  hl,_curCol
+  dec (hl)
+  dec (hl)
+  jr  enternameloop
+continue:
+  cp  K_ENTER
+  ret z
+  cp  K_EXIT
+  ret z
+
+  ld  hl,namelength
+  dec (hl)
+  ret z
+
+  ld  hl,chartable
+  ld  e,a
+  ld  d,0
+  add hl,de
+  ld  a,(hl)
+  or  a
+  jr  z,nokeypressed
+
+  ld  (ix),a
+  cal _putc
+  inc ix
+  cal releasekeys
+  jr  enternameloop
+
+
+chartable:
+  .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
+
+skiplevel: ;@hl - destr:ab - alter:hl
+  inc hl
+  inc hl
+  inc hl
+  inc hl ;skip 4
+  ld  b,(hl) ;spritesize
+  inc b
+skipsprite:
+  inc hl
+  dnz skipsprite
+  ld  b,(hl) ;balls
+  inc b
+  inc b ;skip 6
+  ld  a,c
+  cp  _datasp
+  jr  z,skipworms
+  inc b ;multiplayer lvl
+  inc b
+  inc b ;skip other 3 worms (9 bytes)
+skipworms:
+  ld  a,b
+  add a,a
+  add a,b
+  ld  b,a ;3x(balls+2)
+skipballs:
+  inc hl
+  dnz skipballs
+
+skipflags:
   ld  a,(Gametype)
+  cp  gamectf
+  jr  nz,noflagstoskip
+  inc hl
+  inc hl
+  inc hl
+  inc hl
+noflagstoskip:
+
+skipobjects:
+  ld  a,(hl)
+  inc hl
+  or  a
+  ret z ;0=end
+  inc hl
+  inc hl
+  inc hl
+  inc hl
+  jr  skipobjects
+
+loadgamecar:
+;in:    (Gametype)
+;out:   Gametype+1=hl
+;build: c=(gameCar)=(hl-1)
+;       a=(wormbeglives)=(hl)
+;destr: acdehl
+  ld  hl,datasingle
+  ld  a,(Gametype)
+  add a,a
   ld  e,a
   ld  d,0
   add hl,de
   ld  a,(hl)
   ld  (gameCar),a
+  ld  c,a
+  inc hl
+  ld  a,(hl)
+  ld  (wormbeglives),a
+  ret
 
-  add hl,de
-  ld  e,8 ;=de
-  add hl,de
+;-----------------------------
+;-------- start game ---------
+;-----------------------------
 
-  ld  d,a ;push af
+LetsGetThisPartyOn:
+  ld  a,$17 ;no exit
+  ld  (CheckExit),a ;set exit state
+
+  cal loadgamecar
+  ld  l,a
+  ld  h,0             ;hl=a
+  cal _HLTIMES10      ;hl=10*(hl)
+  ld  (scorelimit),hl ;set limit
+
+  cal loadgamecar ;nc
+  ld  e,24+1 ;=de
+  sbc hl,de ;datalevels
+
+  ld  a,c ;(gameCar)
   and _datasingl
   jr  z,notsingle
   ld  a,1
   ld  (nrworms),a
-  ld  a,d
-  and _datafoodl
-  jr  nz,notsingle
-  ld  a,1
-  ld  (worm1+lives),a
 notsingle:
-  ld  a,d
-  push af ;&&&b?
-
+  ld  a,c
   and _datascore
-  ld  de,$FF64 ;virt.infinate
-  jr  z,setscorelimit
-  ld  d,0 ;de=100
-setscorelimit:
-  ld  (scorelimit),de
+  jr  nz,scorelimitset
+  dec a ;ld a,$FF ;=no_limit
+  ld  (scorelimit),a
+scorelimitset:
 
-  call _ldHLind ;ld hl,(hl)
-  pop af
-  push hl
+  cal _ldHLind ;ld hl,(hl)
+  ld  a,(curlevel)
+  ld  (Level),a
+  ld  d,a ;begin level
+skiplevelloop:
+  dec d ;levels to skip
+  jr  z,levelsskipped
+  cal skiplevel
+  jr  skiplevelloop
+levelsskipped:
+
+  psh hl  ;1st level
+  ld  a,c
   and _datalink
   jr  z,GameOver
 
 linkmatch:
-  call _clrWindow
-  ld  a,WormVersion
-  call send
-  jr  c,client ;2nd
+  cal _clrWindow
+  ld  c,wormVhost
+  cal Qsend
+  ld  hl,txtWaiting
+  cal _puts
+  cal Crecv
+;  ld  a,c
+  cp  wormVclient
+  jr  z,client
+  cp  wormVhost
+  jr  nz,linkiniterror
 
 host:
-  ld  hl,txtWaiting
-  call _puts
-  call receive
-  cp  WormVersion
-  jp  nz,LinkBreak
-  call send
-
-  ld  hl,SwapPos
-  ld  (hl),$f6
+  ld  c,wormVclient
+  cal Qsend
+  ld  a,$18
   jr  multiplayer
 
+linkiniterror:
+  pop hl
+  jp  DisplayMenu
+
 client:
   ld  hl,txtReceive
-  call _puts
-  call receive
-  cp  WormVersion
-  jp  nz,LinkBreak
+  cal _puts
 
+  ld  a,$f6
 multiplayer:
+  ld  (SwapPos),a
   ld  a,2
   ld  (nrworms),a
 
@@ -361,44 +904,54 @@ multiplayer:
 ;-----------------------------
 
 GameOver:
-  call _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  a,l
-  ld  (Level),a
-  ld  hl,worm1set+4
-  ld  de,worm1+lives
-  call _MOV5B ;9xld(de),(hl)
-  call _mov9b
-  ld  hl,worm2set+4
-  ld  de,worm2+lives
-  call _MOV5B
-  call _mov9b
-  ld  hl,worm3set+4
-  ld  de,worm3+lives
-  call _MOV5B
-  call _mov9b
-  ld  hl,worm4set+4
-  ld  de,worm4+lives
-  call _MOV5B
-  call _mov9b
-  pop hl
+  cal _clrLCD
+  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
+  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 ;begin of current level
 
 StartLevel:
   ld  de,Left
+  ld  a,(hl)
+  inc a ;=255?
+  jp  nz,nextlevel
+
+  psh hl
+  cal releasekeys
+  cal _clrWindow
+  pop hl
+;show end msg or smtn
+  ld  bc,Exit
+  psh bc   ;where to go afterwards
+  inc hl   ;location of ending-code
+  jp  (hl) ;go there ("call")
+nextlevel:
   ldi
   ld  de,Speed
   ldi
+  ld  de,peagrowth
+  ldi
   ld  a,(hl)
   ld  (worm1+grow),a
   ld  (worm2+grow),a
@@ -407,50 +960,52 @@ StartLevel:
   ld  (beginsize),a
   inc hl
 
+  ld  a,(hl)
+  inc hl
+  or  a
+  jr  z,defaultsprite
+  ld  d,h
+  ld  e,l ;ld de,hl
+  ld  c,a
+  ld  b,0 ;bc=sprite size
+  add hl,bc ;hl=behind sprite
+  jr  setsprite
+defaultsprite:
+  ld  a,defspritesz
+defsprsize =$-1
+defsprite  =$+1
+  ld  de,defspriteimg
+setsprite: ;de=@sprite ;a=sprsize
+  ld  (sprsize),a
+  ld  (spritepos),de
+
   ld  a,(hl)
   inc hl
   ld  (nrballs),a
   or  a
   jr  z,toobad_noballs
-  ld  de,ballpos
-  ldi
-  ldi
+  ld  c,a
+  add a,a
+  add a,c
+  ld  c,a
+  ld  b,0
+  ld  de,balls
+  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
+#ifndef invincible
   ld  (thislevel),de
-  push de
-  ld  hl,worm1set
-  ld  de,worm1+head
-  call _MOV4B
-  ld  hl,worm2set
-  ld  de,worm2+head
-  call _MOV4B
-  ld  hl,worm3set
-  ld  de,worm3+head
-  call _MOV4B
-  ld  hl,worm4set
-  ld  de,worm4+head
-  call _MOV4B
-  pop de
+#endif
 
   ld  hl,worm1
   ld  a,(gameCar)
-  and _datanextl
+  cp  _datasp
   ld  b,1
-  jr  nz,worminit
+  jr  z,worminit
   ld  b,4
 worminit:
-  push bc                        ; >> 1
+  psh bc                        ; >> 1
   ex  de,hl
   ldi          ;d
   ld  a,SinCosTable/256
@@ -468,7 +1023,7 @@ worminit:
   ld  bc,(worm2-worm1)-5
   add hl,bc
   pop bc                         ; << 0k
-  djnz worminit
+  dnz worminit
 
 ;-------- draw level ---------
 
@@ -481,7 +1036,7 @@ worminit:
   sub 57
   ld  (FieldHeight),a
   add a,57-5
-  push de                        ; >> levelp
+  psh de                        ; >> levelp
   ld  l,a
   ld  h,0
   add hl,hl
@@ -492,8 +1047,8 @@ worminit:
   ex  de,hl
 
   ld  hl,ScrBuffer
-  push hl                        ; >> 1
-  push de                        ; >> 2
+  psh hl                        ; >> 1
+  psh de                        ; >> 2
   ld  de,ScrBuffer+1
   ld  bc,63
   ld  (hl),%11111111
@@ -505,12 +1060,12 @@ worminit:
 ClearLine:
   ld  (hl),c
   inc hl
-  djnz ClearLine
-  push hl                        ; >> 3
+  dnz ClearLine
+  psh hl                        ; >> 3
 
   ld  a,(FieldWidth)
   add a,126
-  push af                        ; >> 4
+  psh af                        ; >> 4
   and %11111000
   rra
   rra
@@ -527,7 +1082,7 @@ ClearLine:
 VertShift:
   rra
   rr  c
-  djnz VertShift
+  dnz VertShift
 NoVertShift:
   ld  (hl),a
   inc hl
@@ -541,66 +1096,53 @@ NoVertShift:
   ld  c,64
   ldir
 
-;-draw lines-
 
   pop hl                         ; << levelp
-  ld  a,(hl)
-  inc hl
-  or  a
-  jr  z,NoLines
-DrawLines:
-  push af                        ; >> 1
-  call loaddrawdata
-  push hl                        ; >> 2
-  ld  l,(hl)
-  ld  h,a
-  call Line
-  inc d
-  inc h
-  call Line
-  inc e
-  inc l
-  call Line
-  dec d
-  dec h
-  call Line
-  pop hl                         ; << 1
-  inc hl
-  pop af                         ; << 0k
-  dec a
-  jr  nz,DrawLines
-NoLines:
-
-  ld  a,(hl)
-  inc hl
-  or  a
-  jr  z,noboxes
-drawboxes:
-  push af
-  call loaddrawdata
-  push hl
-  ld  l,(hl)
-  ld  h,a
-  call drawbox
+  ld  a,(Gametype)
+  cp  gamectf
+  jr  nz,noctf
+  ld  de,peaspos
+  ld  bc,4
+  ldir
+  psh hl
+  cal DrawAllPeas
   pop hl
-  inc hl
-  pop af
-  dec a
-  jr  nz,drawboxes
-noboxes:
+noctf:
+
+  cal drawstuff
 
 ;-----------------------------
 
-  push hl                        ; >> levelp new
-  call showstats
+  psh hl                        ; >> levelp new
+  cal showstats
   ld  a,(gameCar)
   and _datafood
   jr  z,nofood
-  call NewPea
-  call DrawPea
+  cal NewPea
 nofood:
   ld  bc,(worm1+pos)
-  call DisplayField
+  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
@@ -610,38 +1152,40 @@ nofood:
   ld  (_curRow),hl
   set 3,(iy+5)
   ld  hl,txtReady
-  call _puts
+  cal _puts
   res 3,(iy+5)
+#endif
 
   ld  a,0
 gameCar =$-1
   and _datalink
-  jr  z,SwapPos ;no link
+  jr  z,initfinished ;no link
+
   xor a
-  ld  (worm2+input),a
+  ld  (worm2+input),a ;worm 2 via link
   ld  (worm2+left),a
-  ld  (Speed),a
-
+  ld  (Speed),a ;max.speed
 SwapPos: ;$18 xx -> $F6 xx
+         ; jr xx ->  or xx
   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:
 
-  ld  b,0
+  ld  b,startdelay
 ReadyDelay:
   halt
-  djnz ReadyDelay
+  dnz ReadyDelay
+  cal releasekeys
 
 ;-----------------------------
 ;----------- LOOP ------------
@@ -649,7 +1193,7 @@ ReadyDelay:
 
 GameLoop:
   ld  bc,(worm1+pos)
-  call DisplayField
+  cal DisplayField
 
   ld  a,1
 flashtime =$-1
@@ -677,18 +1221,21 @@ Delay:
   jr  nz,Delay
 NoDelay:
 
-  call handlethatneatlittleball
+  ld  a,0
+nrballs =$-1
+  or  a
+  cal nz,handlethoseneatlittleballs
 
   ld  ix,worm1
   ld  a,(nrworms)
   ld  b,a
 handleworms:
-  push bc
-  call HandleWorm
+  psh bc
+  cal HandleWorm
   ld  bc,worm2-worm1
   add ix,bc
   pop bc
-  djnz handleworms
+  dnz handleworms
 
 ;-----------------------------
 ;---------- keys -------------
@@ -698,55 +1245,27 @@ HandleKeys:
   ld  a,%10111111
   out (1),a
   in  a,(1)
-  rla
-  jr  c,NotPaused
+  rla ;MORE?
+  jr  c,CheckExit
   ld  bc,$0103
   out (c),b
-  halt
+  halt ;pause/off
   ld  b,11
   out (c),b
 
-NotPaused:
-  rla
+CheckExit:
+  rla  ;=$17 (c=EXIT-key)
+      ;or$A7 (c=0)
   jp  c,GameLoop
-  jr  Exit ;&&
+  jr  Exit
 
 WormDead:
+#ifdef invincible
+  jp  stopworm
+#else
   ld  a,2
   ld  (flashtime),a
-
-  ld  h,(ix+tail+1)
-  ld  l,(ix+tail)
-  ld  d,(ix+head+1)
-  ld  e,(ix+head)
-  jr  DoesWormTailEqualsWormHead ;chk4 size=0
-removewormloop:
-  ld  c,(hl)
-  inc hl
-  ld  b,(hl)
-  inc hl
-  res resbit,h
-  push hl
-  call res4pixels
-  pop hl
-  inc (ix+grow)
-DoesWormTailEqualsWormHead:
-  call _cphlde
-  jr  nz,removewormloop
-
-  ld  a,(gameCar)
-  and _datasingl
-  jr  nz,safewormsizedone
-  ld  a,0
-beginsize =$-1
-  ld  (ix+grow),a
-safewormsizedone:
-
-  ;de=ix+head
-  ld  (ix+tail+1),d
-  ld  (ix+tail),e
-  ld  a,50
-  ld  (ix+delay),a
+  ld  (ix+delay),respawndelay
 
 thislevel =$+1
   ld  de,0
@@ -761,57 +1280,63 @@ thislevel =$+1
 
   inc (ix+died)
   dec (ix+lives)
-  push af
+  psh af
   ld  de,10
-  call DecScore
+  cal DecScore
   pop af
   ret nz ;HandleWorm done
   ld  a,(gameCar)
   and _datalivel
   ret z
+  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
-  call _clrWindow
+  ld  a,D0HD1H
+  out (7),a
+  cal _clrWindow
   ld  hl,txtGO
-  call _puts
+  cal _puts
   ld  hl,txtGame
 CURtxtGame =$-2
-  call _puts
+  cal _puts
   ld  de,0002
   ld  (_curRow),de
-  call showLevel
+  cal showLevel
   ld  de,$0B03
   ld  (_curRow),de
   ld  hl,txtDied
-  call _puts
-  call _puts ;txtScore
+  cal _puts
+  cal _puts ;txtScore
   xor a
   ld  (_curCol),a
 
-  ld  b,2
-nrworms =$-1
+  ld  a,(nrworms)
+  ld  b,a
   ld  hl,worm1+died
 displayWormStats:
-  push bc
-  push hl
+  psh bc
+  psh hl
 
   ld  bc,input-died
   add hl,bc ;+input
   xor a
-  cp  (hl)
+  cp  (hl)  ;input=0 = link
   jr  nz,NoLinkIndic
-  ld  b,7
+  ld  b,7 ;{DOWN}
   inc hl ;+left
   cp  (hl)
   jr  z,hostLinkIndic
-  dec b
+  dec b   ;{UP}
 hostLinkIndic:
   ld  a,8
   ld  (_curCol),a
   ld  a,b
-  call _putc
+  cal _putc
   xor a
   ld  (_curCol),a
   dec hl
@@ -819,61 +1344,92 @@ NoLinkIndic:
   inc hl
   inc hl
   inc hl ;+name
-  call _puts
+  cal _puts
 
   pop hl
-  push hl
+  psh hl
   ld  a,13
   ld  (_curCol),a
   ld  a,(hl) ;worm+died
-  push hl
-  call showA
+  cal showA
   pop hl
+  psh hl
 
   ld  a,16
   ld  (_curCol),a
   inc hl ;worm+score
-  call _ldHLind ;ld hl,(hl)
-  call showHL ;worm+score
+  cal _ldHLind ;ld hl,(hl)
+  cal showHL ;worm+score
 
   pop hl
   ld  bc,worm2-worm1
   add hl,bc
   pop bc
-  djnz displayWormStats
+  dnz displayWormStats
+
+  ld  a,(Gametype)
+  or  a ;singleplayer (0) only
+  jr  nz,hilevelcheckdone
+checkhilevel:
+  ld  hl,nrlevels
+  ld  a,(Level)
+  cp  (hl)
+  jr  c,hilevelcheckdone
+  ld  (hl),a    ;save local
+  ld  c,a
+  ld  a,0
+hilvlposa =$-1
+  ld  hl,nrlevels
+hilvlposhl =$-2 ;save external
+  cal _writeb_inc_ahl ;ld (ahl),c
+hilevelcheckdone:
 
   ld  a,(gameCar)
   and _datasingl
+
   jr  z,hiscorecheckdone
 checkhiscore:
-  ld  de,(worm1+score)
-HiScore =$+1
-  ld  hl,0
-  ld  a,d
-  cp  h
-  jr  c,NotNewHigh
-  ld  a,e
-  cp  l
-  jr  c,NotNewHigh
-  ld  (HiScore),de
-  ex  de,hl ;disp.new hiscore
-NotNewHigh:
-  ex  de,hl ;push
+  cal loadhiscoreposinahl
+  cal _Get_Word_ahl ;de=old_hi
+ psh de
+ cal _RAM_PAGE_1 ;&&
+ pop de
+  ld  hl,(worm1+score)
+
+  ld  a,h           ;New
+  cp  d             ;Old
+  jr  c,NotNewHigh  ;New<Old
+  jr  nz,newhigh    ;New>Old
+
+  ld  a,e           ;old
+  cp  l             ;new
+  jr  nc,NotNewHigh ;new<old
+
+newhigh:            ;New>=Old
+  ex  de,hl
+  cal loadhiscoreposinahl
+  cal _Set_Word_ahl ;de->(ahl)
+ cal _RAM_PAGE_1
+
+NotNewHigh: ;de=current hiscore
   ld  hl,$0807
   ld  (_curRow),hl
   ld  hl,txthiscore
-  call _puts
+  cal _puts
   ex  de,hl ;pop
-  call showHL
+  cal showHL
 hiscorecheckdone:
 
+  cal releasekeys
 waitkey:
   halt
   halt
-  call GET_KEY
+  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
@@ -890,51 +1446,122 @@ ExitNoStats:
   ld  hl,_asapvar
   rst 20h ;_ABS_MOV10TOOP1
   rst 10h ;_FINDSYM
-  call _swapt_ ;_ex_ahl_bde
-  ld  de,4
+  ld  hl,savestart-_asm_exec_ram+4
+  xor a
   add hl,de
-  adc a,0
-  call _SET_ABS_DEST_ADDR
+  adc a,b ;ahl=bde+4
+  cal _SET_ABS_DEST_ADDR
 
   xor a
-  ld  hl,start
-  call _SET_ABS_SRC_ADDR
-  ld  hl,end-start
-  call _SET_MM_NUM_BYTES
-  call _mm_ldir
-
-;  xor a
-;  ld  (_asapvar+1),a
+  ld  hl,savestart
+  cal _SET_ABS_SRC_ADDR
+  ld  hl,saveend-savestart
+  cal _SET_MM_NUM_BYTES
+  cal _mm_ldir
+
+  cal releasekeys
   res 4,(iy+9)
   set 2,(iy+13)
+  im  1 ;remove keyfix
   jp  _clrWindow
 
+loadhiscoreposinahl:
+  ld  a,(Level)
+  ld  b,a
+
+  ld  h,0            ;hl=
+  ld  a,(nrlevels+1) ;# peaworm lvls
+  add a,a
+  ld  l,a
+
+  ld  a,(Gametype)
+  dec a
+  ld  c,a
+  dec a              ;z=(Gametype)=2
+  jr  z,tronhi
+  ld  l,h            ;hl=0
+tronhi:
+
+  xor a              ;ahl=0(+x)
+  psh bc
+  ld  bc,defhiscrpos
+hiscrposhl =$-2
+  add hl,bc
+  pop bc
+  adc a,0
+hiscrposa =$-1       ;ahl=saveloc
+
+  inc c
+  ret z              ;(Gametype)=0
+addlevelposition:
+  cal _AHL_PLUS_2_PG3
+  dnz addlevelposition
+  ret
+
 ;-----------------------------
 ;----------- worm ------------
 ;-----------------------------
 
-inlink:
+respawncheck:
+  cp  respawndelay-1
+  jr  nz,unnamedlabel
+  cal saverespawncounter
+removeworm:
+  ld  h,(ix+tail+1)
+  ld  l,(ix+tail)
+  ld  d,(ix+head+1)
+  ld  e,(ix+head)
+  jr  DoesWormTailEqualsWormHead ;chk4 size=0
+removewormloop:
+  ld  c,(hl)
+  inc hl
+  ld  b,(hl)
+  inc hl
+  cal resbit
+  psh hl
+  cal res4pixels
+  pop hl
+  inc (ix+grow)
+DoesWormTailEqualsWormHead:
+  cal _cphlde
+  jr  nz,removewormloop
+
+  ld  a,(gameCar)
+  and _datasingl
+  jr  nz,safewormsizedone
   ld  a,0
-sendbyte =$-1
-  ld  b,(ix+left)
-  dec b
-  jr  z,receivefirst
-  call send
-  call receive
-  ld  l,a
+beginsize =$-1
+  ld  (ix+grow),a
+safewormsizedone:
+
+  ;de=ix+head
+  ld  (ix+tail+1),d
+  ld  (ix+tail),e ;head=tail/size=0
   ret
-receivefirst:
-  push af
-  call receive
-  ld   l,a
-  pop  af
-  push hl
-  call send
-  pop  hl
+
+unnamedlabel:
+  cp  1
+  ld  h,a
+  jr  nz,saverespawncounter
+respawndue:
+  ld  l,a
+  cal inputcall
+  ld  (sendbyte),a
+  ld  a,h ;previous
+  cp  l   ;changed?
+  ret z
+  ld  (ix+delay),a ;=0
   ret
+saverespawncounter:
+  ld  (ix+delay),a
+  jr  inputcall
+;  ld  a,(ix+input)
+;  or  a
+;  jr  z,inlink
+;  ret
 
 inkeys: ;use jp not call!
-  out (1),a
+  out (1),a ;nop\nop
   in  a,(1)
   ld  b,a
   and (ix+right)
@@ -945,23 +1572,57 @@ inkeys: ;use jp not call!
 notright:
   ld  a,b
   and (ix+left)
-  jr  z,donediddelydone
+  ret z
   ld  a,l
   sub 8
   ld  l,a
-  jr  donediddelydone
+  ret
+
+inputcall:
+  ld  a,(ix+input)
+  or  a
+  jr  nz,inkeys
+
+inlink:
+  ld  b,(ix+left)
+  dec b
+  jr  z,receivefirst
+  psh hl
+  ld  c,0
+sendbyte =$-1
+  cal Csend
+  cal Crecv
+  pop hl
+  ld  l,c
+  ret
+receivefirst:
+  psh hl
+  cal Crecv
+  pop hl
+  ld  l,c
+  psh hl
+  ld  a,(sendbyte)
+  ld  c,a
+  cal Csend
+  pop hl
+  ret
 
 ;------- handle worm ---------
 
 HandleWorm:
-  dec (ix+delay)
-  ret nz
-  inc (ix+delay)
+  ld  a,(ix+delay)
+  dec a
+  jp  nz,respawncheck
+
+  ld  a,(Gametype)
+  cp  gametron
+  jr  nz,notron
+  ld  de,1
+  cal IncScore
+notron:
+
   ld  l,(ix+heading)
-  ld  a,(ix+input)
-  or  a
-  jr  nz,inkeys
-  call inlink
+  cal inputcall
 donediddelydone:
   ld  a,l
   ld  (sendbyte),a
@@ -973,10 +1634,22 @@ donediddelydone:
   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:
-  push bc                        ; >> pos
+  psh bc                        ; >> pos
   ld  a,(hl)
   add a,a
   add a,d
@@ -1022,7 +1695,7 @@ notmoveY: ;bc=newpos
   xor 3
   ld  d,a
 GotFour:
-  call chk4pixels
+  cal chk4pixels
   rl  d
   jp  nc,Drawworm
 
@@ -1031,62 +1704,139 @@ GotFour:
 Hitworm:
   ld  a,(gameCar)
   ld  h,a
-  and _datafood
-  jp  z,WormDead
+  and _datadie
+  cal z,checkhitotherworm
   ld  a,h
-  and _datahunt
-  call nz,checkhitotherworm
+  and _datamultpeas ;&&bit
+  jr  nz,multiple_peas
+  ld  a,h
+  and _datafood
+  jp  z,WormDead ;no food
 
   ld  hl,0
 PeaY =$-2
 PeaX =$-1
-  ld  a,b
-  sub h
-  inc a
-  cp  4
-  jp  nc,WormDead
-  ld  a,c
-  sub l
-  inc a
-  cp  4
+  cal chkpeahit
   jp  nc,WormDead
-  call DrawPea
+  cal DrawPea ;remove pea
   ld  a,(ix+grow)
   add a,15
+peagrowth =$-1
   ld  (ix+grow),a
-  call NewPea
+  cal NewPea
   ld  hl,Left
   dec (hl)
-  push af
+  psh af
   ld  de,10
-  call IncScore
+  cal IncScore
   pop af
-  jr  nz,still_alive_not_dead
+  jp  nz,Drawworm ;continue
   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  hl,Level
   ld  a,(hl)
   inc (hl)
+  ld  l,a ;hl=Level
+  ld  h,0
+  add hl,hl
+  add hl,hl
+  cal _HLTIMES10
+  ex  de,hl
+  cal IncScore ;score+(40*level)
+  cal removeworm
   pop hl                         ; << call
   pop hl                         ; << call
   pop hl                         ; << levelp new
-  cp  NUM_LEVELS
-  jp  z,Exit
-  ld  a,(gameCar)
-  and _datanextl
-  jp  nz,StartLevel
-  jp  Exit
+  ld  (ix+delay),2
+  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)
@@ -1098,13 +1848,14 @@ nextotherwormbit:
   sub (hl)
   inc a
   cp  4
-  jr  c,otherwormHIT ;yes
+  ret c ;nz ;yes
 nothit1:
   inc hl
-  res resbit,h
-  call _cphlde
+  cal resbit
+ChkWorm:
+  cal _cphlde
   jr  nz,nextotherwormbit
-  ret
+  ret ;z
 
 checkhitlapline:
   ld  a,63
@@ -1118,38 +1869,60 @@ nextlaphalf:
   jr  nz,nolap
   cp  (ix+reserv)
   jr  z,nolap
-  push bc
+  psh bc
   ld  de,20
-  call IncScore
+  cal IncScore
   pop bc
   xor a
 nolap:
   ld  (ix+reserv),a
   ret
 
-otherwormHIT:
-  push ix
-  ld  de,10
-  call IncScore
+checkhitotherworm:
+ .db  $dd,$7d ;ld a,lx
+  cp  worm2&255
+ psh ix
+ jr nz,chkworm2 ; ret nz
   ld  ix,worm1
-  call 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:
-  ld  a,(gameCar)
-  and _datahunt
-  call nz,HuntingTimeScore
-
   ld  c,(ix+pos)
   ld  b,(ix+pos+1)
 
-  ld  a,(gameCar)
-  and _datalaps
-  call nz,checkhitlapline
+  ld  a,(Gametype)
+  ld  d,a
+  cp  gamerace
+  cal z,checkhitlapline
+
+  cal set4pixels
+  dec c
+  ld  a,d
+  cp  gametron
+  ret z ;keep tail in "Tron"
 
   ld  l,(ix+head)
   ld  h,(ix+head+1)
@@ -1157,12 +1930,10 @@ Drawworm:
   inc hl
   ld  (hl),b
   inc hl
-  res resbit,h
+  cal resbit
   ld  (ix+head),l
   ld  (ix+head+1),h
 
-  call set4pixels
-
   ld  a,(ix+grow)
   dec a
   jr  z,removetail
@@ -1176,19 +1947,19 @@ removetail:
   inc hl
   ld  b,(hl)
   inc hl
-  res resbit,h
+  cal resbit
   ld  (ix+tail),l
   ld  (ix+tail+1),h
 
 res4pixels:
-  call ResPixel
+  cal ResPixel
   inc b
-  call ResPixel
+  cal ResPixel
   inc c
-  call ResPixel
+  cal ResPixel
   dec b
 ResPixel:
-  call FindPixel
+  cal FindPixel
   cpl
   and (hl)
   ld  (hl),a
@@ -1198,35 +1969,81 @@ ResPixel:
 ;---------- ball -------------
 ;-----------------------------
 
-handlethatneatlittleball:
-  ld  a,0
-nrballs =$-1
-  or  a
-  ret z
-ballpos =$+1
-  ld  bc,$0503
-  call res4pixels
+handlethoseneatlittleballs:
+  ld  hl,balls
+  ld  b,a ;a=(nrballs)
+handleballs
+  psh bc
+  psh hl
+  ld  c,(hl)
+  inc hl
+  ld  b,(hl)
+  inc hl
+  ld  d,(hl)
+  cal handleball
+  dec c
+  pop hl
+  ld  (hl),c
+  inc hl
+  ld  (hl),b
+  inc hl
+  ld  (hl),d
+  inc hl
+  pop bc
+  dnz handleballs
+  ret
+
+handleball:
+  cal res4pixels
   dec c
-  ld  e,b
+
 ballxmove:
-  inc b ;=%000100 dec=%000101
-  call checkballhit
-  jr  z,ballxdone
-  ld  b,e
-  ld  hl,ballxmove
-  call letsmovetheotherway
-ballxdone:
-  ld  e,c
+  bit 0,d ;1=L; 0=R
+  jr  z,ballright
+ballleft:
+  dec b
+  cal checkballhit
+  jr  z,ballymove
+  inc b ;undo
+  res 0,d ;go right
+  jr  ballymove
+ballright:
+  inc b
+  cal checkballhit
+  jr  z,ballymove
+  dec b ;back
+  set 0,d ;>left
+
 ballymove:
-  inc c ;=%001100 dec=%001101
-  call checkballhit
+  bit 1,d ;1=up; 0=down
+  jr  z,balldown
+ballup:
+  dec c
+  cal checkballhit
   jr  z,balldone
-  ld  c,e
-  ld  hl,ballymove
-  call letsmovetheotherway
+  inc c
+  res 1,d ;go down
+  jr  balldone
+balldown:
+  inc c
+  cal checkballhit
+  jr  z,balldone
+  dec c
+  set 1,d ;up
 balldone:
-  ld  (ballpos),bc
-  jp  set4pixels
+
+set4pixels: ;@(b,c)
+  cal SetPixel
+  inc b
+  cal SetPixel
+  inc c
+  cal SetPixel
+  dec b
+SetPixel: ;at bc
+  cal FindPixel
+  or  (hl)
+  ld  (hl),a
+  ret
 
 letsmovetheotherway:
   ld  a,1
@@ -1235,180 +2052,129 @@ letsmovetheotherway:
   ret
 
 checkballhit:
+  psh de
   ld  d,0
-  call chk4pixels
+  cal chk4pixels
   xor a
   cp  d
+  pop de
   ret
 
 ;-----------------------------
 ;----------- procs -----------
 ;-----------------------------
 
-NewPea:
-;random routine
-  ld hl,0
-  ld de,12345
-Seed =$-2
-  ld a,7921&255
-  ld bc,$1000+(7921/256)
-domult16:
-  add hl,hl
-  rla
-  rl  c
-  jr  nc,noadd16
-  add hl,de
-noadd16:
-  djnz domult16
-  inc hl
-  ld  (Seed),hl ;seed=(seed*7921+1)\65536
-
-  ld  a,(FieldWidth)
-  add a,123
-  cp  h
-  jr  c,NewPea
-  inc h
-  inc h
-  ld a,(FieldHeight)
-  add a,51
-  cp  l
-  jr  c,NewPea
-  inc l
-  inc l
-  ld  (PeaY),hl
-  ld  d,2 ;don't draw
-  push hl
-  call CheckPea
-  pop hl
-  dec d
-  jr  z,NewPea
-
-DrawPea: ;hl=(PeaY)
-  ld  d,0 ;draw
-CheckPea:
-  ld  b,h
-  ld  c,l
-  call PeaPixel
-  inc c
-  call PeaPixel
-  inc b
-  call PeaPixel
-  dec c
-PeaPixel:
-  push de
-  call FindPixel
-  pop de
-  ld  e,a ;>>
-  ld  a,d
-  or  a
-  ld  a,e ;<<
-  jr  z,DrawPeaPixel ;d=0:draw
-  and (hl) ;pixel?
-  ret z
-  ld  d,1 ;d=1:yes 2:no
-  ret
-DrawPeaPixel:
-  xor (hl) ;change pixel
-  ld  (hl),a
+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
 
-;-------- pixelprocs ---------
-
-set4pixels:
-  call SetPixel
-  inc b
-  call SetPixel
-  inc c
-  call SetPixel
-  dec b
-SetPixel: ;at bc
-  call FindPixel
-  or  (hl)
-  ld  (hl),a
+resbit:
+  ld  a,h
+  and (ix+storepos)
+  ld  h,a
   ret
 
-chk4pixels: ;&&
-  call CheckPixel
-  inc b
-  call CheckPixel
-  inc c
-  call CheckPixel
-  dec b
-  call CheckPixel
-  dec c
-  ret
-CheckPixel: ;at bc in d
-  call FindPixel
-  and (hl)
-  ret z
-  dec d
+randompos:
+  ld  b,a
+Random: ;(2..b+2)
+  ld  a,r
+Seed =$+1
+  add a,0
+  ld  (Seed),a
+  and %01111110
+  cp  b
+  jr  nc,Random
+  add a,2
   ret
 
-;CLEM's FIND_PIXEL (131+? cycles; 28+4 bytes)
-;                (b,c) to hl:a; destroyes: -)
-
-FindPixel:
-  ld  h,0
-  ld  l,c    ;hl=y
-  add hl,hl
-  add hl,hl
-  ld  a,b    ;a=x
-  rra
-  add hl,hl
-  rra
-  add hl,hl
-  add hl,hl  ;hl=32*y
-  rra        ;a=x/8
-  or  l
+NewPea:
+  ld  a,(FieldWidth)
+  add a,127-4
+  cal randompos
+  ld  h,a
+  ld  a,(FieldHeight)
+  add a,56-4
+  cal randompos
   ld  l,a
-  ld  a,b
-  and 7
-  cpl
-  rlca
-  rlca
-  rlca
-  ld  (FP_Bit),a
-  xor a
-FP_Bit =$+1
-  set 0,a
+  ld  (PeaY),hl
 
-  push de
-  ld  de,ScrBuffer
-  add hl,de
-  pop de
-  ret
+CheckPea:
+  ld  c,l
+  ld  a,(sprsize)
+  ld  e,a
+chkloopy:
+  ld  b,h
+  ld  a,(sprsize)
+  ld  d,a
+chkloopx:
+  psh hl
+  cal FindPixel
+  and (hl)
+  pop hl
+  jr  nz,NewPea ;pixel found
+  inc b
+  dec d
+  jr  nz,chkloopx
+  inc c
+  dec e
+  jr  nz,chkloopy
+;all ok; empty space
+
+DrawPea: ;hl=(PeaY)
+  ld  b,h
+  ld  c,l
+  ld  de,0
+spritepos =$-2
+  jp  PutSprite ;||-ed
 
 ;----------- score -----------
 
-HuntingTimeScore:
-  .db $dd,$7d ;ld a,lx
-  cp  worm2&255
-  ret z ;=worm#2
-  dec (ix+reserv)
-  ret nz
-  ld  de,10
+_divHLby1000:
+  psh hl
+  ld  b,3
+divideagain: ;3x
+  cal _divHLby10
+  dnz divideagain
+  ld  a,l ;a=hl/1000
+  pop hl
+  ret
 
 IncScore:
   ld  h,(ix+score+1)
   ld  l,(ix+score)
+  cal _divHLby1000
+  ld  c,a
   add hl,de
+  cal _divHLby1000
+  cp  c
+  jr  z,scorecommon ;hl/1000 not increased
+  inc (ix+lives)
   jr  scorecommon
 DecScore: ;&&&
   ld  h,(ix+score+1)
   ld  l,(ix+score)
   or  a
   sbc hl,de
-  ret c
+  jr  c,showstats ;<0=0
 scorecommon:
   ld  (ix+score+1),h
   ld  (ix+score),l
   ld  de,0
 scorelimit =$-2
-  call _cphlde
+  inc e
+  jr  z,showstats ;de=$FF??=no limit
+  dec e
+  cal _cphlde
   jp  nc,Exit
 
 showstats:
-  push ix
+  psh ix
   ld  h,0
   ld  l,h
   ld  (_penCol),hl
@@ -1419,8 +2185,8 @@ showstats:
   and _datanextl
   jr  nz,showstatsS
 showstatloop:
-  push bc
-  call showstat
+  psh bc
+  cal showstat
   ld  de,worm2-worm1
   add ix,de
   ld  hl,_penCol
@@ -1428,52 +2194,57 @@ showstatloop:
   add a,10
   ld  (hl),a
   pop bc
-  djnz showstatloop
+  dnz showstatloop
   pop ix
   ret
 
 showstat:
   ld  a,(gameCar)
-  and _datalivel
-  jr  nz,showlives
+  and _datascore
+  jr  z,showlives
 showscore:
   ld  h,(ix+score+1)
   ld  l,(ix+score)
-  call _D_HL_DECI
+  cal _D_HL_DECI
   jr __vputs
 showlives:
+  ld  a,(Gametype)
+  cp  gametron
+  jr  z,showscore
+
   ld  a,(ix+lives)
   add a,'0'
 __vputmap:
-  push ix
-  call _vputmap
+  psh ix
+  cal _vputmap
   pop ix
   ret
 
 showstatsS:
   ld  hl,txtLevel
-  call __vputs
-  ld  a,(Level)
+  cal __vputs
+  ld  a,0
+Level =$-1
   cp  10
   jr  c,tilllevel9
   ld  l,a
   ld  h,0
-  call _divHLby10
-  push af
+  cal _divHLby10
+  psh af
   ld  a,l
   add a,'0'
-  call __vputmap
+  cal __vputmap
   pop af
 tilllevel9:
   add a,'0'
-  call __vputmap
+  cal __vputmap
 
   ld  a,98
   ld  (_penCol),a
-  call showscore
+  cal showscore
   ld  a,123
   ld  (_penCol),a
-  call showlives
+  cal showlives
   ld  a,(gameCar)
   and _datafoodl
   pop ix
@@ -1483,52 +2254,53 @@ showleft:
   ld  (_penCol),a
   ld  a,0
 Left =$-1
-  push af
-  call _divAby10
+  ld  l,a
+  ld  h,0
+  cal _divHLby10
+  psh af
+  ld  a,l
   add a,'0'
-  call __vputmap
+  cal __vputmap
   pop af
   add a,'0'
-  call __vputmap
+  cal __vputmap
+
   ld  hl,txtLeft
 __vputs:
-  push ix
-  call _vputs
+  psh ix
+  cal _vputs
   pop ix
   ret
 
 showLevel:
   ld  hl,txtLevel
-  call _puts
+  cal _puts
   ld  a,(Level)
 showA:
-  cp  10
-  jr  c,LevelBelowTen
   ld  l,a
   ld  h,0
-  call _divHLby10
-  push af
+  cal _divHLby10
+  psh af
   ld  a,l
   add a,'0'
-  call _putc
+  cal _putc
   pop af
-LevelBelowTen:
   add a,'0'
   jp  _putc
 
 showHL:
-  call _D_HL_DECI
+  cal _D_HL_DECI
   jp  _puts
 
 _D_HL_DECI:
   ld  de,savestr+4
   ld  b,5
 ldhld:
-  call _divHLby10
+  cal _divHLby10
   add a,'0'
   ld  (de),a
   dec de
-  djnz ldhld
+  dnz ldhld
   ld  hl,savestr
   ret
 savestr:
@@ -1554,8 +2326,8 @@ NotMaxYScroll:
   add hl,hl
   add hl,hl
   add hl,hl
-  push bc                        ; >> 1
-  push de                        ; >> 2
+  psh bc                        ; >> 1
+  psh de                        ; >> 2
   ld  de,ScrBuffer
   add hl,de
   ld  a,b
@@ -1563,12 +2335,12 @@ NotMaxYScroll:
   jr  nc,NotMinXScroll
   xor a
 NotMinXScroll:
-  cp 128
+  cp  128
 FieldWidth = $-1
-  jr c,NotMaxXScroll
-  ld a,(FieldWidth)
+  jr  c,NotMaxXScroll
+  ld  a,(FieldWidth)
 NotMaxXScroll:
-  push af                        ; >> 3
+  psh af                        ; >> 3
   and %11111000
   rra
   rra
@@ -1578,21 +2350,21 @@ NotMaxXScroll:
   ld  de,DispBuffer
   pop af                         ; << 2
   and %00000111
-  push af                        ; >> 3
+  psh af                        ; >> 3
   cp  6
   jr  c,CopyScreen
   inc c
 CopyScreen:
   add hl,bc
-  ld b,57
+  ld  b,57
 CopyScreenLoop:
-  push bc                        ; >> 4
-  ld bc,16
+  psh bc                        ; >> 4
+  ld  bc,16
   ldir
-  ld c,16
+  ld  c,16
   add hl,bc
   pop bc                         ; << 3
-  djnz CopyScreenLoop
+  dnz CopyScreenLoop
   pop af                         ; << 2
   ld  c,$b7 ;or a
 Bit0:
@@ -1602,155 +2374,157 @@ Bit0:
   jr  AfterShiftDelay
 Bit1:
   dec a
-  jr nz,Bit2
-  call ShiftRight1
-  jr AfterShiftDelay
+  jr  nz,Bit2
+  cal ShiftRight1
+  jr  AfterShiftDelay
 Bit2:
   dec a
-  jr nz,Bit3
-  ld a,2
-  call ShiftRight
-  jr AfterShiftDelay
+  jr  nz,Bit3
+  ld  a,2
+  cal ShiftRight
+  jr  AfterShiftDelay
 Bit3:
   dec a
-  jr nz,Bit4
-  call Chunk
-  call ShiftLeft1
-  jr AfterShift
+  jr  nz,Bit4
+  cal Chunk
+  cal ShiftLeft1
+  jr  AfterShift
 Bit4:
   dec a
-  jr nz,Bit5
-  call Chunk
-  jr AfterShiftDelay
+  jr  nz,Bit5
+  cal Chunk
+  jr  AfterShiftDelay
 Bit5:
   dec a
-  jr nz,Bit6
-  call Chunk
-  call ShiftRight1
-  jr AfterShift
+  jr  nz,Bit6
+  cal Chunk
+  cal ShiftRight1
+  jr  AfterShift
 Bit6:
   dec a
-  jr nz,Bit7
-  ld a,2
-  call ShiftLeft
-  jr AfterShift
+  jr  nz,Bit7
+  ld  a,2
+  cal ShiftLeft
+  jr  AfterShift
 Bit7:
-  call ShiftLeft
+  cal ShiftLeft
 AfterShiftDelay:
   halt
 AfterShift:
-  ld hl,DispBuffer
-  ld de,$fc00+$70
-  ld bc,1024-$70
+#ifdef buffer
+  ld  hl,DispBuffer
+  ld  de,$fc00+$70
+  ld  bc,1024-$70
   ldir
+#endif
   pop de                         ; << 1
   pop bc                         ; << 0k
   ret
 
 ShiftRight1:
-  ld a,1
+  ld  a,1
 ShiftRight:
-  ld (ShiftRightCounter),a
-  ld a,c
-  ld (ShiftRightChunk),a
-  ld c,16
+  ld  (ShiftRightCounter),a
+  ld  a,c
+  ld  (ShiftRightChunk),a
+  ld  c,16
   add hl,bc
-  ld b,57
+  ld  b,57
 ShiftRightLoop:
-  push bc
-  ld bc,-32
+  psh bc
+  ld  bc,-32
   add hl,bc
-  ex de,hl
-  ld a,(de)
+  ex  de,hl
+  ld  a,(de)
 ShiftRightChunk:
-  or a
-  call c,_SHLACC
-  ld c,0
+  or  a
+  cal c,_SHLACC
+  ld  c,0
 ShiftRightCounter = $-1
 ShiftRowsLeft:
-  push hl
+  psh hl
   rla
-  ld b,16
+  ld  b,16
 ShiftRowLeft:
   dec hl
-  rl (hl)
-  djnz ShiftRowLeft
+  rl  (hl)
+  dnz ShiftRowLeft
   pop hl
   dec c
-  jr nz,ShiftRowsLeft
-  ld bc,-16
+  jr  nz,ShiftRowsLeft
+  ld  bc,-16
   add hl,bc
-  ex de,hl
+  ex  de,hl
   pop bc
-  djnz ShiftRightLoop
+  dnz ShiftRightLoop
   ret
 
 ShiftLeft1:
-  ld a,1
+  ld  a,1
 ShiftLeft:
-  ld (ShiftLeftCounter),a
-  ld a,c
-  ld (ShiftLeftChunk),a
+  ld  (ShiftLeftCounter),a
+  ld  a,c
+  ld  (ShiftLeftChunk),a
   rla
-  jr nc,ShiftLeftSameByte
+  jr  nc,ShiftLeftSameByte
   dec hl
 ShiftLeftSameByte:
-  ex de,hl
-  ld bc,-16
+  ex  de,hl
+  ld  bc,-16
   add hl,bc
 NewSprite:
-  ex de,hl
-  ld b,57
+  ex  de,hl
+  ld  b,57
 ShiftLeftLoop:
-  push bc                        ; >> 1
-  ld bc,-32
+  psh bc                        ; >> 1
+  ld  bc,-32
   add hl,bc
-  ex de,hl
-  ld a,(de)
+  ex  de,hl
+  ld  a,(de)
 ShiftLeftChunk:
-  or a
-  call c,_SHRACC
-  ld c,0
+  or  a
+  cal c,_SHRACC
+  ld  c,0
 ShiftLeftCounter = $-1
 ShiftRowsRight:
-  push hl                        ; >> 2
+  psh hl                        ; >> 2
   rra
-  ld b,16
+  ld  b,16
 ShiftRowRight:
-  rr (hl)
+  rr  (hl)
   inc hl
-  djnz ShiftRowRight
+  dnz ShiftRowRight
   pop hl                         ; << 1
   dec c
-  jr nz,ShiftRowsRight
-  ld bc,-16
+  jr  nz,ShiftRowsRight
+  ld  bc,-16
   add hl,bc
-  ex de,hl
+  ex  de,hl
   pop bc                         ; << 0k
-  djnz ShiftLeftLoop
+  dnz ShiftLeftLoop
   ret
 
 Chunk:
-  push hl                        ; >> 1
-  push de                        ; >> 2
+  psh hl                        ; >> 1
+  psh de                        ; >> 2
   ld  c,16
   add hl,bc
   ld  b,57
 ChunkScreen:
-  push bc                        ; >> 3
+  psh bc                        ; >> 3
   ld  bc,-32
   add hl,bc
   ex  de,hl
   ld  a,(de)
-  call _SHRACC
+  cal _SHRACC
   ld  b,16
 ChunkRow:
   dec hl
   rld
-  djnz ChunkRow
+  dnz ChunkRow
   ex  de,hl
   pop bc                         ; << 2
-  djnz ChunkScreen
+  dnz ChunkScreen
   pop de                         ; << 1
   pop hl                         ; << 0k
   ld  c,$37 ;scf
@@ -1758,32 +2532,172 @@ ChunkRow:
 
 ;----------- draw ------------
 
-loaddrawdata:
+;--- pixel ---
+
+chk4pixels: ;&&
+  cal CheckPixel
+  inc b
+  cal CheckPixel
+  inc c
+  cal CheckPixel
+  dec b
+  cal CheckPixel
+  dec c
+  ret
+CheckPixel: ;at bc in d
+  cal FindPixel
+  and (hl)
+  ret z
+  dec d
+  ret
+
+;CLEM's FIND_PIXEL (131+? cycles; 28+4 bytes)
+;(b,c) to hl:a; "destroyes" ahl
+
+FindPixel: ;(b,c) to hl:a
+  ld  h,0
+  ld  l,c    ;hl=y
+  add hl,hl
+  add hl,hl
+  ld  a,b    ;a=x
+  rra
+  add hl,hl
+  rra
+  add hl,hl
+  add hl,hl  ;hl=32*y
+  rra        ;a=x/8
+  or  l
+  ld  l,a
+  ld  a,b
+  and 7
+  cpl
+  rlca
+  rlca
+  rlca
+  ld  (FP_Bit),a
+  xor a
+FP_Bit =$+1
+  set 0,a
+
+  psh de ;&&&
+  ld  de,ScrBuffer
+  add hl,de
+  pop de
+  ret
+
+;--- sprite ---
+
+PutSprite:  ;||@(b,c)
+  ;by SHIAR  only ix saved
+  cal FindPixel
+putspr:
+  ld  (beginbit),a
+  ld  a,0
+sprsize =$-1
+  ld  b,a ;rows
+sprloopy:
+  psh bc ;rows
+  psh hl
+  ld  a,(de)
+  ld  c,a
+  inc de
+  ld  a,(sprsize)
+  ld  b,a ;width
+beginbit =$+1
+  ld  a,1
+sprloopx:
+  sla c ;draw?
+  jr  nc,sprnodraw
+  psh af
+  xor (hl)
+  ld  (hl),a
+  pop af
+sprnodraw:
+  rrca ;next bit
+  jp  nc,nextbitok
+  inc hl ;next byte
+nextbitok:
+  dnz sprloopx
+
+  pop hl
+  ld  bc,32 ;next line
+  add hl,bc
+  pop bc
+  dnz sprloopy
+  ret
+
+;--- objects ---
+
+drawstuff:
+  ld  a,(hl)
+  inc hl
+  or  a ;0 =
+  ret z ;no more
+
   ld  d,(hl)
   inc hl
   ld  e,(hl)
   inc hl
-  ld  a,(hl)
+  ld  b,(hl)
+  inc hl
+  psh hl
+  ld  l,(hl)
+  ld  h,b
+
+  dec a ;1 = line
+  cal z,drawline
+  dec a ;2 = fatline
+  cal z,drawfatline
+  dec a ;3 = box
+  cal z,drawbox
+
+  pop hl
   inc hl
+  jr  drawstuff
+
+drawbox: ;(d,e)-(h,l)
+  ld  b,l ;Delta-y
+  ld  l,e
+boxloop:
+  cal drawline
+  inc l
+  inc e
+  dnz boxloop
   ret
 
-Line: ;draw line from de to hl (d<h)
-  push hl
-  push de
-  ld a,d
-  cp h
-  jr c,lineOrdered
-  ex de,hl
+drawfatline:
+  cal drawline
+  inc d
+  inc h
+  cal drawline
+  inc e
+  inc l
+  cal drawline
+  dec d
+  dec h
+  jp  drawline
+
+;LINE (d,e)-(h,l)
+;destroyes a
+
+drawline:
+  psh bc
+  psh hl
+  psh de
+  ld  a,d
+  cp  h
+  jr  c,lineOrdered
+  ex  de,hl
 lineOrdered:
   ld  b,d
   ld  c,e
-  push hl
-  push bc
-  call FindPixel
+  psh hl
+  psh bc
+  cal FindPixel
   pop bc
   pop de
 connectedLine:
-  push hl
+  psh hl
   ld  h,c
   ld  c,a
   ld  a,d
@@ -1815,7 +2729,7 @@ LinePositiveY:
   sub b
   pop hl
 LineLoopGentle:
-  push af
+  psh af
   ld  a,(hl)
   or  c
   ld  (hl),a
@@ -1829,13 +2743,14 @@ line1sm:
   add hl,de
 line2sm:
   add a,0
-  djnz LineLoopGentle
+  dnz LineLoopGentle
 DoneLine:
   ld  a,(hl)
   or  c
   ld  (hl),a
   pop de
   pop hl
+  pop bc
   ret
 SteepLine:
   ld  h,a
@@ -1849,7 +2764,7 @@ SteepLine:
   ld  b,h
   pop hl
 LineLoopSteep:
-  push af
+  psh af
   ld  a,(hl)
   or  c
   ld  (hl),a
@@ -1863,181 +2778,194 @@ line3sm:
   inc hl
 line4sm:
   add a,0
-  djnz LineLoopSteep
+  dnz LineLoopSteep
   jr  DoneLine
 
-drawbox:
- ld  b,h
- ld  c,l
- call FindPixel
-;  ld  b,a
-;makefirstbyte:
-;  or  b
-;  rr  b
-;  jr  nc,makefirstbyte
-;  or  (hl) ;()
-;  ld  (hl),a
-
-  ld  b,e ;yloop
-boxloopy:
-  push bc ;yloop
-  ld  b,d ;xloop
-boxloopx:
-  ld  a,%11111111
-  ld  (hl),a
-  inc hl
-  djnz boxloopx
-
-  ld  b,0
-  ld  a,16
-  sub d
-  ld  c,a
-  add hl,bc
-  pop bc ;yloop
-  djnz boxloopy
-  ret
-
 ;-----------------------------
 ;----------- link ------------
 ;-----------------------------
 
-TIMEOUT = $1000
+timeout = $800
+
+checklink:
+  dec de
+  ld  a,d
+  or  e
+  jr  z,linkerror
+
+  ld  a,$BF
+  out (1),a
+  in  a,(1)
+  bit 6,a
+  jp  z,Exit
 
-receive:
-  call GET_KEY
-  cp  K_EXIT
-  jp  z,LinkBreak
   in  a,(7)
   and %11
-  cp  %11
-  jr  z,receive
-  call Qreceive
-  jr  c,receive
   ret
 
-Qreceive:
-  ld  b,8
-  jr  ReceiveCont
-receiveloop:
-  ld  de,TIMEOUT
-WaitRecBit:
-  call CheckLink
-  jr  z,LinkFailed
-  cp  %11
-  jr  z,WaitRecBit
-ReceiveCont:
-        sub 2
-        ld  a,2
-        ld  d,D0LD1H
-        jr  c,ReceiveLow
-        rra
-        ld  d,D0HD1L
-ReceiveLow:
-        rr c
-        ld (AckBit),a
-        ld a,d
-        out (7),a
-        ld  de,TIMEOUT
-WaitAckRec:
-        call CheckLink
-        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:
-        djnz receiveloop
-        jr  LinkSuccess
-
-send:
-  ld  b,9
+linkerror:
+  scf
+  ld  a,%11
+  pop hl
+  ret
+
+;--------------
+;---- SEND ----
+;--------------
+
+Csend:         ;--- send 8 bits in A --- destr:abcdehl ---
   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:
-  call CheckLink
-  jr  nz,WaitAckSend
-SendAcked:
+Csendloop:
+  cal Qsend
+  ret nc               ;NC = all ok
   ld  a,D0HD1H
-  out (7),a
-  ld  de,TIMEOUT
-WaitReadySend:
-  call CheckLink
-  cp  %11
-  jr  nz,WaitReadySend
-  djnz SendBits
-LinkSuccess:
-  ld  a,c ;pop a
-  ret
+  out (7),a            ;both high
+  jr  Csendloop        ;CF = error
 
-LinkFailed:
+Qsend:         ;--- try to send 8 bits in C; CF=error --- destr:abcdehl ---
+  ld  de,timeout
+  cal checklink
+  cp  %11              ;are they?
   scf
-  ld a,c
-  ret
-LinkBreak:
-  ld  a,D0HD1H
+  ret nz               ;nope, wait
+  ld  b,8              ;bits to send
+sendloop:
+  ld  de,timeout
+  rl  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)
+sendwaitack:
+  cal checklink                ;other calc must lower other wire
+  jr  nz,sendwaitack
+  ld  a,D0HD1H         ;raise one, ok to raise other
   out (7),a
-  jp  Exit
-
-CheckLink:
-  pop hl
-  dec de
-  ld a,d
-  or e
-  jr z,LinkFailed
-
-  ld  a,$BF
-  out (1),a
+sendfinish:
+  cal checklink
+  cp  %11              ;both raised (by other calc)
+  jr  nz,sendfinish
   nop \ nop
-  in  a,(1)
-  push af
-  ld  a,%11111111
-  out (1),a
-  pop af
-  bit 6,a
+  dnz sendloop         ;repeat for all bits
+  xor a                        ;nc...
+  ret                  ;=ok
 
-  in  a,(7)
-  and %11
-  jp  (hl)
+;--------------
+;---- RECV ----
+;--------------
+
+Crecv:         ;--- receive 8 bits into A/C --- destr:abcdehl ---
+  cal Qrecv
+  ret nc               ;return if all went ok
+  ld  a,D0HD1H
+  out (7),a            ;raise both on error
+  jr  Crecv            ;and try again
 
+Qrecv:         ;--- receive 8 bits into A/C; CF=error --- destr:abcdehl ---
+  ld  de,timeout
+  cal checklink
+  jp  z,Exit           ;both low = error, quit
+  cp  %11
+  scf
+  ret z                        ;both high = nothing yet, wait
+  ld  b,8              ;bits to receive
+recvloop:
+  ld  de,timeout
+recvwait:
+  cal checklink
+  cp  %11
+  jr  z,recvwait       ;both high = nothing sent (yet)
+  rra                  ;received bit in cf
+  ld  a,D0LD1H
+  jr  c,received       ;lower white wire as well
+  ld  a,D0HD1L         ;lower red
+received:
+  rl  c                        ;save bit in c
+  out (7),a            ;both wires low
+recvwaitack:
+  cal checklink
+  jr  z,recvwaitack    ;same wire will be raised again by other calc
+  ld  a,D0HD1H
+  out (7),a            ;raise both
+recvfinish:
+  dnz recvloop         ;repeat for all bits
+  xor a                        ;nc=no error
+  ld  a,c              ;result in a
+  ret
 
 ;-----------------------------
 ;---------- levels -----------
 ;-----------------------------
 
-NUM_LEVELS = 1
-
 LevelDef:
-  .db 5,4,15,0      ;peas,speed,begin_size,balls
+  .db 5,4,15,15,0,0 ;peas,speed,growth,begin_size,sprite,balls
   .db 0,2,63        ;start d, y, x
   .db 128,57        ;field width (128-255), height (57-255)
-  .db 0,0           ;no additional lines, boxes
+  .db 0             ;no additional lines, boxes
+
+  .db 255
+   ret
 
 LevelDefM:
-  .db 8,0,15,0
+  .db 8,4,15,15,0,0
+  .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
+  .db 128,57
+  .db 0
+
+  .db 8,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
-  .db 0,0
+  .db 0
 
+LevelDefT:
+  .db 8,4,18,12,5
+  .db %1110000,%10001000,%10001000,%10001000,%1110000,0
+  .db $40,30,64,$C0,30,64, $00,30,64,$80,30,64
+  .db 128,57
+  .db 0
 
 ;-----------------------------
 ;---------- 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 "Level 00",0      ;4th menu item
+            .db "Limit 00 ",0     ;3rd
+            .db "Worms 0",0       ;2nd
+txtGame:    .db "Singleplayer",0  ;0 (1st)
+txtGame2:   .db "Peaworm     ",0  ;1 (next 1st)
+            .db "Tron      ",0    ;2
+            .db "Deathmatch",0    ;3
+            .db "Foodmatch ",0    ;4
+            .db "LinkMatch",0     ;5
+            .db "Race     ",0     ;6
+            .db "CTF         ",0  ;7
+;            .db "Domination",0    ;8
+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
@@ -2049,102 +2977,121 @@ TrigPrecalc:
 .db 124,125,125,126,126,126,126,126
 .db 127
 
-txtWelcome: .db "Welcome to Worm!! ",
-            .db "by Shiar",0
-txtOptions: .db "Options",0
-txtGame:    .db "Singleplayer",0  ;0
-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
-
-WormVersion = 092
-WormMsg:   .db "WORM by SHIAR -- test version",0
 txtLevel:  .db "Level ",0
 txtWorms:  .db "Worms: 0",0 ;follows txtLevel
 txtDied:   .db "Died ",0
-txtScore:  .db "Score",0  ;follows txtDied
-txtLeft:   .db " left",0   ;follows txtScore
+txtScore:  .db "Score",0    ;follows txtDied
+txtLeft:   .db " left",0    ;follows txtScore
 txthiscore:.db "HiScore:",0
 txtReady:  .db "Prepare!",0
 txtposReady = 7
 txtGO:     .db "----- GAME OVER -----",0
 
-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
+                       ;1=hiscore+keep_length
 _datafood  = %00010000 ;food present
-_datahunt  = %00100000
-_datalaps  = %01000000 ;give lap score
+_datadie   = %01000000 ;worm dies on impact
 _datascore = %10000000 ;score>=100 limit
+_datamultpeas = %00100000
+_datasp    = %01011110
 
-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
+datalevels: .dw LevelDef, LevelDefM
+            .dw LevelDefT,LevelDefM
             .dw LevelDefM,LevelDefM
             .dw LevelDefM,LevelDefM
-            .dw LevelDefM,LevelDefM
-
-resbit  = 2             ;and%11111011
-worm1set:  .dw $B000,$B000 ;%10110000
-           .db 3,0,%01111110,%10,%100 ;< >
-           .db "Worm #1",0
-worm2set:  .dw $B800,$B800 ;%10111000
-           .db 3,0,%00111111,%10000,%1000 ;f1 f2
-           .db "Worm #2",0
-worm3set:  .dw $F000,$F000 ;$E800=%11101000 ;$D748+$1000+
-           .db 3,0,%01011111,%10,%100 ;sto ,
-           .db "Worm #3",0
-worm4set:  .dw $A800,$A800 ;$F000=%11110000
-           .db 3,0,%01111101,%10,%1 ;enter +
-           .db "Worm #4",0
-worm1 = $B400
-worm2 = $B42A
-worm3 = $B454
-worm4 = $B47E ;-A8
-end:
-              ;set:
-heading = 0   ;level*
-pos     = 2   ;level*
-pos2    = 4   ;level
-grow    = 6   ;level
-died    = 8   ;game
-score   = 9   ;game
-delay   = 11  ;game
-
-head    = 12  ;level
-tail    = 14  ;level
-lives   = 16  ;game
-reserv  = 17  ;loop
+nrlevels:   .db 1,2,2,2,2,2,2,1     ;=defaults
+
+savestart:
+
+gamesingle   =  0
+datasingle: .db %01011110,3 ;3 lives (<must b unique)
+gamepeas     =  1
+datapeas:   .db %01011010,1 ;1 "
+gametron     =  2
+datatron:   .db %01000010,1
+gamedeathm   =  3
+datadeathm: .db %01000010,3
+gamefoodm    =  4
+datafoodm:  .db %11010000,10 ;10 score limit (=100)
+gamelinkm    =  5
+datalinkm:  .db %01000011,3
+gamerace     =  6
+datarace:   .db %10000000,10
+gamectf      =  7
+datactf:    .db %11100000,9
+;gamedomin    =  8
+;datadomin:  .db %01100000,3 ;==(8 modes)
+
+worm1set:  .dw worm1p,worm1p
+           .db %11110111,%00,%01111110,%10,%100 ;< >
+worm1name: .db "worm #01",0
+worm2set:  .dw worm2p,worm2p
+           .db %11111011,%11,%00111111,%10000,%1000 ;f1 f2
+worm2name: .db "worm #02",0
+worm3set:  .dw worm3p,worm3p
+           .db %11111011,0,%01011111,%10,%100 ;sto ,
+worm3name: .db "worm #03",0
+worm4set:  .dw worm4p,worm4p
+           .db %11111011,0,%01111101,%10,%1 ;enter +
+worm4name: .db "worm #04",0
+
+defhiscrpos:
+  .dw 0,0,0,0,0
+
+saveend:
+
+               ;set:
+heading  = 0   ;level*
+pos      = 2   ;level*
+pos2     = 4   ;level
+grow     = 6   ;level
+died     = 8   ;game
+score    = 9   ;game
+delay    = 11  ;game
+               ;19B @game
+lives    = 12
+head     = 13  ;4B (head=tail)
+tail     = 15  ;also@next level
+storepos = 17
+reserv   = 18  ;loop
  ;race:lap
- ;hunt:time
-input   = 18  ;&
-left    = 19  ;&
-right   = 20  ;&
-name    = 21  ;game
-
-Level =$+1
-DispBuffer =$+2 ;912 bytes
-
-ScrBuffer   = $8100 ;-$A2FF (32x256) mod$800=0
-SinCosTable = $B500 ;size=$100 (4x64)
+ ;ctf:pea
+input    = 19
+left     = 20
+right    = 21
+name     = 22
+wormsize = 31
+
+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 "   shiar0@hotmail.com",0
+
+defspritesz = 4
+defspriteimg: .db %01100000
+              .db %11110000
+              .db %11110000
+              .db %01100000
+
+deflevels:
+  .db 15,"Internal Levels"
+
+  .db 0,deflevels/256,deflevels&255
+templevels:
 
 ;-----------------------------
 ;----------- end -------------