case-insensitive z80 label usage
[wormy.git] / wormy.z80
index a2c919bf891d934a05bb890702fcf304ba6cc226..5bf22f79f92cf289ea5f6db04e10291ab8a664d7 100644 (file)
--- a/wormy.z80
+++ b/wormy.z80
-; Title                      : Wormy
-; Version                    : 93%
-; Release Date               : summer 2001
-; Filename                   : wormy.86p (5kb)
-; Author(s)                  : Shiar
-; Email Address              : shiar0@hotmail.com
-; ICQ UIN                    : #43840958
-; 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)
-
-;-----------------------------
-;----------- TO-DO -----------
-;-----------------------------
-
-; 93% = DONE
-
-;     * internal levels
-;       * check levels/gametype
-;       * enough hiscore saves!
-;     * complete readme
-;  1% * 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
-
-;100% = bugs fixed + levels done
-
-;-----------------------------
-;-----------------------------
-;---------  W O R M  ---------
-;-----------------------------
-;-----------------------------
-
-#define buffer      ;use display buffer (otherwise write directly to screen)
-#define readymask   ;"greys" out the field before starting a level
-;#define hlines     ;horizontal-line routine for more speed drawing boxes
-
-;#define readytext  ;displays "prepare" before level starts
-;#define invincible ;worms cannot die =)
-
-#define cal call
-#define psh push
-#define dnz djnz
+;___����________________________________________________________����____________
+;  ����                                                         �����
+; ���                                                            ����     ����
+;���      �����          ��������       �����     ����  ����      ���     �����
+;���     �������       �����������     �������   �������������     ��    ��� ���
+;��     ���   ���     �����    ����   ����  ��� ���  ����  ���     ���  ���� ���
+;��     ��     ��     ��  �      ��� ����      ���  ������  ���    ���  ���   ��
+;��     ��     ��     �� ��      ��� ���       ��� ���� ��� ���    ��� ����   ��
+;��     ���   ���     �� ��       �� ���       �������   ��� ��     �������   ��
+;��     ���   ���    ��� ��       �� ��        �� ���    ��� ���     �����   ���
+;���     ��� ���     ��� ��       �� ���       �� ����  ���� ���             ���
+;���      �����     ���  ���     ��� ���       ��  ��������  ���            ���
+; ���      ���      ���  ���     ��� ���       ���  ������   ���            ���
+;  ����  �������  ����    ���   ���  ����      ���            �����       ����
+;   �������� ��������     ���������   ���      ���             ���������������
+;    �����     �����       �������     ��       ���              �����������
+;_______________________________________________________________________________
+;
+; Version                  :                                      100% (1.00.36)
+; Release Date             :                                        2002 March 6
+; Author(s)                :                                               Shiar
+; Email Address            :                                     wormy@shiar.org
+; Web Page                 :                                       www.shiar.org
+; Description              :  perfect Nibbles game with free movement, nine game
+;                                 modes, for 1-4 players, many levels and editor
+; Where to get this game   :                                     wormy.shiar.org
+; Other games by author(s) :                                        Nemesis beta
+; Additional Credits to    : Matthew Shepcar  :   wrote original Peaworm, end'98
+;                            Jonah Cohen      :              helped writing worm
+; Files                    : wormy.txt (9283) : ed15e942a99b40e5a584c597cb13df46
+;                            wormy.z80 (100k) : 977109a7d25f3227fe817edbcc36ad9a
+;                            wormy.86g (8914) : fbff7c36687c1e7e3113c29069021718
+;_______________________________________________________________________________
+
+;--- notes ---------------------------------------------------------------------
+
+; * Game README is wormy.txt
+;  * Use for LEARNING practises ONLY!
+;   * Don't _ever_ release altered code w/o permission!
+;    * Give me credits when you use any of this stuff
+;     * I'm not responsible for any damage this might cause, yada yada...
+;      * Although I've commented & labeled quite some stuff, due to
+;         crazy optimizations and weird coding, it may be harder to
+;          understand than the average blob of code. This is probably _not_
+;           the best source to learn z80 from. w00t the Shyer Way (tm).
+;          * Email me. If you've got suggestions|patches|questions: tell me.
+;           * Don't scroll down if you get scared easily.
+
+;--- index ---------------------------------------------------------------------
+
+; * TO_DO                       :                                future features
+;  * #INCLUDE
+;   * STORAGE                   :                   permanent; temporary; layout
+;    * PROG_START               :                                  search levels
+;     * LEV_SELECT
+;      * MORE_INIT              :                                    trig tables
+;       * MAIN_MENU             :    draw menu; options menu; main menu; display
+;                                 current settings; handle menukeys; change name
+;        * MISC_PROCS
+;         * START_GAME          : link; client; set/send worms; host; load game;
+;                                                            draw level; prepare
+;          * GAME_LOOP
+;           * KEYS              :                                     pause menu
+;            * GAME_OVER        :                  who won?; display worms; quit
+;             * WORM_STUFF
+;              * WORM_ALIVE     :                           move worm; draw worm
+;               * BOUNCYBALL
+;                * WORMY_HIT    :  multifood; ctf; main; foodmatch|SP; take pea;
+;                                                                           misc
+;                 * PROCS
+;                  * SCORE
+;                   * DISPLAY
+;                    * DRAW     :        pixel; findpixel; objects; circle; box;
+;                                                                  fatline; line
+;                     * LINK!   :        multiple bytes; foo; send; recv; common
+;                      * INT_LEVELS
+;                       * DATA  :      graphics; menus; text; foo; game settings
+;                        * THAT'S_ALL
+
+;_______________________________________________________________________________
+; _______  _____       ______   _____
+;    |    |     |      |     \ |     |
+;    |    |_____| ____ |_____/ |_____|
+;_______________________________________________________________________________
+
+; 99% = PREVIOUS
+;     X [34] freeze when no space left to place pea (break after 10k tries)
+;     X [34] wow another bit of code 'reniced' (easter egg or something :)
+;     X [34] two more jp to jr
+;     X [34] highly improved randomizer (values >127 were rare)
+;     X [36] replace 'left' at the change-control prompt
+;     X [36] ED: fixed immediate exit at level preview when using enter key
+;     X [36] bouncies drawn after placing peas (causing overwrites)
+;     X [36] FIX: skip string length bytes when running from yas
+;     X [36] ED: pointer to ending message realigned
+;     X [36] LVL: end messages fixed in affected episodes
+;100% = CURRENT
+;     * scorebar last digit (at 128-3) not displayed by _vputs :(
+;     * save last played level (in levelfile prolly)
+;     * automatically start players in multiplayer games after certain time
+;     * muliplayer bonuses/powerups (shrink, lives, stun, inverse, etc.)
+;     * levels with random pixels appearing during game
+;     * no borders (move players from one side to another)
+;     * hiding levels crashes?? (ishell 2.01 rom 1.6)
+;     * use selected player on main menu as first player in singleplayer games
+
+
+;--- future features -----------------------------------------------------------
+
+;just a maybe-list; NO guarantees!
+;
+; * correct team winners
+;  * level compression
+;   * ubersized bouncies (sprites)
+;    * arrow to offscreen peas
+;     * w00t AI
+;      * sound
+;       * startpos
+;        * pause in linkplay
+;         * coop (DON'T COUNT ON IT)
+
+;_______________________________________________________________________________
+;  _/_/_____ __   _ _______        _     _ ______  _______
+; _/_/   |   | \  | |       |      |     | |     \ |______
+; / /  __|__ |  \_| |_____  |_____ |_____| |_____/ |______
+;_______________________________________________________________________________
 
 #include "asm86.h"
 #include "ti86asm.inc"
 
-_SHRACC            = $4383
-_SHLACC            = $438B
+ #define cal call
+ #define psh push
+ #define dnz djnz
+
+_SHRACC            = $4383 ;4x srl a
+_SHLACC            = $438B ;4x sll a
 _divHLby10         = $4044 ;hl=hl/10
 _divAby10          = $4DAF ;a=a/10
 _HLTIMES10         = $41BF ;hl=hl*10
-_cphlde            = $403C
+_cphlde            = $403C ;cp hl,de
 _clrWindow         = $4A86 ;clear screen
 _asapvar           = $D6FC ;own name (worm)
 _MOV4B             = $429B ;4x ld (de),(hl)
 _MOV5B             = $4297 ;5x ld (de),(hl)
 _mov9b             = $4283 ;9x ld (de),(hl)
 _ldHLind           = $4010 ;ld hl,(hl)
-_swapt_            = $45F3 ;ex_ahl_bde
+_swapt_            = $45F3 ;ex ahl,bde (doesn't work?)
 _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
+_INC_PTR_AHL       = $4637 ;inc ahl
+_AHL_PLUS_2_PG3    = $4C3F ;add 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
+_MM_LDIR_SET_SIZE  = $524D ;_SET_MM_NUM_BYTES + _mm_ldir
 _RAM_PAGE_1        = $47E3 ;set $8000+ to page 1
-_RAM_PAGE_7        = $47F3
+_RAM_PAGE_7        = $47F3 ;"""" 7
 _PTEMP_END         = $D29A ;end of VAT
 _load_ram_ahl      = $462F ;ahl->page+hl
-_writeb_inc_ahl    = $5567 ;ld (ahl),c
+_writeb_inc_ahl    = $5567 ;ld (ahl++),c
 _jforce            = $409C ;TI-OS stack restored
 _EXLP              = $4493 ;swap (hl),(de) b times
-_GETB_AHL         = $46C3 ;a=(ahl) \ hl=ahl
-
-;-----------------------------
-;------- data  storage -------
-;-----------------------------
-
-;--- permanent
-
-ScrBuffer   = $8820 ;-A7FF (20*FF=1FE0)
+_GETB_AHL          = $46C3 ;a=(ahl) \ hl=ahl
+_OP1TOOP6          = $4263
+
+ #define id2        ;yas2 level identifier - this'll add (65) bytes
+ #define buffer     ;use display buffer, otherwise write directly to screen (11)
+ #define readymask  ;"greys" out the field before starting a level (20)
+;#define readytext  ;-displays "prepare" before level starts (42)
+ #define coolzgfx   ;nice graphics for game over screen (98)
+ #define spprotect  ;options not changable for singleplayer modes
+;#define intlevels  ;-internal levels
+                    ;-to become invincible, define the magic word :D
+
+levelhead   = 'w'
+levelhead2  = 97 ;wormy levels header = "0"
+
+;_______________________________________________________________________________
+; _______ _______  _____   ______ _______  ______ _______
+; |______    |    |     | |_____/ |_____| |  ____ |______
+; ______|    |    |_____| |    \_ |     | |_____| |______
+;_______________________________________________________________________________
+
+;--- permanent -----------------------------------------------------------------
+
+ScrBuffer   = $8420 ;-A3FF (20*FF=1FE0)
+worm4p      = $A400 ;-A5FF (200)      %101001O0
+;free       = $A600 ;-A7FF (200)
 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)
+SinCosTable = $AC00 ;-AD00 (4*40)
+worm1       = $AD01 ;-AD1E (1E)
+worm2       = $AD1F ;-AD3C (1E)
+worm3       = $AD3D ;-AD5A (1E)
+worm4       = $AD5B ;-AD78 (1E)
+balls       = $AD79 ;-AE00 (<=3x2D) (bb<=45)
+turn10      = $AE01 ;-AE01 (1)     (counter)
+peaspos     = $AE02 ;-AF05 (4-104)    (peas)
+;free       = $AF06 ;-AFFF (F9)
 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)
+;buffer     = $BC00 ;-BF90 (390)
+;free       = $BF91 ;-BFFF (6F)
+;program    = $D748 ;-EFFF (186D+4A)           ;6327
+leveldata   = $F080 ;-F9FF (<=97F)
+#ifndef intlevels
+datalevels  = $FA00 ;-FA11 (12) (>=$C000)
+nrlevels    = $FA12 ;-FA1B (A)   (<$FA70)
+defspr      = $F078 ;-F07F (8)
+#endif
 
-peaspos = $AE01
+;MEM|8---9---A---B---C---D---E---F---| ;there's something wrong
+;   |..[------]||[]|......[-----]|[].| ;if you still understand    < OUTDATED <
+;   |   SCREEN 2* 13      PRGM   4LV | ;after looking at this
 
-;--- temporary
+;--- temporary -----------------------------------------------------------------
 
 namelength  = $BC00 ;(1)         @menu
+datalink    = $BC00 ;(8)        @init
 #ifdef buffer
 DispBuffer  = $BC00 ;(10x57d)    @game
 #else
 DispBuffer  = $FC70
 #endif
-
-;-----------------------------
-;------- program start -------
-;-----------------------------
-
-.org _asm_exec_ram
-
-wormVhost   = 093
-wormVclient = 193
-
-start:
+linklevel   = $AECC ;(<=134)     @game+init
+lefttotalb  = $BF91 ;(1)         @game
+drawctfpea1 = peaspos+4
+drawctfpea2 = peaspos+6
+
+;--- layout --------------------------------------------------------------------
+
+;(wormN)      offs:  set:
+heading     =   0   ;level*
+pos         =   2   ;level*
+pos2        =   4   ;level
+grow        =   6   ;level
+died        =   8   ;game:
+score       =   9
+wdelay      =   11
+lives       =   12
+head        =   13
+                    ; �15B (wormNset)
+tail        =   15  ; |also@next level
+storepos    =   17  ; |
+reserv      =   18  ; |loop (race:lap|ctf:pea)
+wleft       =   19  ; |
+wright       =   20  ; |
+name        =   21  ; |_
+
+wormsize    =   30 ;^mark^
+
+;_______________________________________________________________________________
+;  _____   ______  _____   ______       _______ _______ _______  ______ _______
+; |_____] |_____/ |     | |  ____       |______    |    |_____| |_____/    |
+; |       |    \_ |_____| |_____| _____ ______|    |    |     | |    \_    |
+;_______________________________________________________________________________
+
+ .org %1101011101001000
+
+start:         ;turn back NOW!
+  nop      ;and so it begins...
+  jp  codestart
+#ifndef id2
+  ld  bc,$5242
+  rst 10h
+ .dw  WormIcon
+#else
+  ld  (bc),a
   nop
-  jp Start
-  .dw 1
-  .dw WormTxt
-  .dw WormIcon
-
-WormTxt:
-  .db "WORMY by SHIAR -- beta 93%",0
+  ld  d,h
+  rst 10h
+ .dw  WormIcon
+ .dw  WormData
+#endif
+  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  " v1.00.36",0
 WormIcon:
-  .db 9,2
-  .db %10010110,%01101111
-  .db %10110101,%01001011
-  .db %01110011,%01001001
-  .db %00000011,%10000000
-  .db %00000001,%11100000
-  .db %00111000,%11111000
-  .db %01111110,%00111111
-  .db %11101111,%00001111
-  .db %11000011,%10000000
-
-levelhead  = 'w'
-levelhead2 = 93 ;wormy levels header = "93"
+ .db  8,2                ;Rkaydees' icon:
+ .db  %00000000,%00111100 ;      XX
+ .db  %00000000,%01010010 ;     XXX
+ .db  %00000000,%01100001 ;     XX
+ .db  %01100011,%10011001 ;     XX
+ .db  %10010100,%01101001 ;      XX
+ .db  %10011001,%00011001 ;      XX
+ .db  %01000010,%11000001 ; X   XX
+ .db  %00111100,%00111110 ;  XXXX
+#ifdef id2
+WormData:
+ .db  1
+ .dw  wormlevel
+wormlevel:
+ .db  4        ;priority
+ .db  12       ;string
+ .db  "wor"    ;description
+ .dw  yasexec  ;execution routine
+ .dw  yascomment-yasdetect
+ .dw  yasdetect-$-1    ;detection routine
+ .dw  yasicon-yascomment
+ .dw  yascomment-$-1   ;comment routine
+ .dw  yasdataend-yasicon
+ .dw  yasicon-$-1      ;icon routine
+yasexec:
+  rst 10h
+  ex  de,hl
+  ld  a,b
+  cal _AHL_PLUS_2_PG3 ;skip past length bytes
+  cal skiptitle ;title (plus size+header <- all non-0)
+; cal skiptitle ;description
+  jp  leveldataAHL-3
+yasdetect:
+  cal _AHL_PLUS_2_PG3 ;skip past length bytes
+  cal _Get_Word_ahl
+  ld  hl,levelhead+(levelhead2*256)
+  cal _cphlde
+  ret z
+  scf
+  ret
+yascomment:
+  inc hl
+  inc hl ;skip header
+  ret
+yasicon:
+  ld  hl,$F400+levelicon-yasicon
+  ld  bc,6+(256*1)
+  or  a
+  ret
+levelicon:
+ .db %00011100 ;..XXX...  ...XXX..
+ .db %00011110 ;.X...X..  ...XXXX.
+ .db %00000011 ;.X..X...  ......XX
+ .db %10000001 ;X..X..XX  X......X
+ .db %01011011 ;X..X..XX  .X.XX.XX
+ .db %01101110 ;X...XXX.  .XX.XXX.
+yasdataend:
+#endif
 
 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:
-  ld  (SpSave),sp
+;--- search levels -------------------------------------------------------------
+
+codestart:
   cal _runindicoff
   cal _flushallmenus
 
-  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  ix,templevels
@@ -202,11 +378,8 @@ searchloop:
   jr  z,stringfound
 searchnext:
   pop hl
-  dec hl ;5x
-  dec hl
-  dec hl
-  dec hl
-  dec hl
+  ld  de,-5
+  add hl,de
   ld  b,(hl) ;name size
   inc b
 skipname:
@@ -229,122 +402,98 @@ stringfound:
   cp  e
   jr  nz,_searchnext ;not worm
   ld  a,levelhead2
-  cp  d
+  cp  d ;=0
   jr  nz,_searchnext
-  inc ix ;save level's ahl
-  ld a,h
-  ld (ix),a
-  inc ix
-  ld a,l
-  ld (ix),a
-  inc ix
+  ld (ix+1),h ;save level's ahl
+  ld (ix+2),l
+  ld  de,3 ;&&&d=0
+  add ix,de
 _searchnext:
   cal _RAM_PAGE_7
-  jr searchnext
+  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:
+  inc bc
   pop af
   pop de ;counter
-  dec d ;8x
+  dec d ;9x
   jr  nz,loadgametype
   ret
 
+;_______________________________________________________________________________
+;        _______ _    _       _______ _______        _______ _______ _______
+; |      |______  \  /        |______ |______ |      |______ |          |
+; |_____ |______   \/   _____ ______| |______ |_____ |______ |_____     |
+;_______________________________________________________________________________
+
 searchcomplete:
   ld  a,255
   ld  (ix),a ;end mark
 
+#ifdef intlevels
+  ld  ix,templevels-6
+#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
   cal _clrWindow
-  ld  hl,templevels-3
-  psh hl
-  ld  hl,$0020
+  ld  hl,$0320
   ld  (_penCol),hl
   ld  hl,txtLevsel
-  cal _vputs ;"< Select levels: >"
-  ld  hl,$0601 ;x=1
+  cal _vputs ;"< SELECT LEVELS >"
+  ld  hl,$FC00+(2*16)
+  ld  b,16*9
+  cal menuinvloop
+  ld  hl,$FC00+$380 ;(*,56)
+  cal hr
+  ld  hl,$0C01 ;x=1
   ld  (_penCol),hl
-  pop hl
 dispnextlevel:
-  ld  a,(hl)
-  inc a ;cp 255
-  jr  z,_levselect
-  ld  a,(hl) ;ade=(hl)
-displevel:
-  inc hl
-  ld  d,(hl)
-  inc hl
-  ld  e,(hl)
-  inc hl
-  psh hl
-  ex  de,hl ;ahl=ade=(hl)
+  ld  de,3
+  add ix,de ;goto next
+  ld  a,(ix)
+  ld  h,(ix+1)
+  ld  l,(ix+2)
   cal _load_ram_ahl ;hl=ahl
-  ld  b,(hl) ;b=title size
   cal _vputs
+  ld  hl,availevels
+  inc (hl)
+  ld  a,(ix+3) ;next
+  inc a ;cp 255
+  jr  z,__levselect
   ld  hl,_penCol
   ld  (hl),$01 ;x=1
   inc hl
   ld  a,(hl)
   add a,6
   ld  (hl),a ;y+6
-  ld  hl,availevels
-  inc (hl)
-  pop hl
+  cp  49 ;bottom of screen
+  jr  nc,_levselect
   jr  dispnextlevel
 
-levup:
-  cal menupos
-  dec b ;up
-  ld  a,b
-  cp  -4
-  jr  nz,levselected
-  inc b ;undo
-  jr  levselected
-levdown:
-  cal menupos
-  inc b ;down
-  ld  a,b
-  cp  -3
-availevels =$-1
-  jr  nz,levselected
-  dec b ;back up
-levselected:
-  jp  menupos
-
-_levselect:
-  ld  b,-3 ;level selected
-  cal menupos
-levselect:
-  halt \ halt
-  psh bc
-  cal GET_KEY
-  pop bc ;GET_KEY destr. b
-  cp  K_UP
-  cal z,levup
-  dec a ;K_DOWN
-  cal z,levdown
-  cp  K_SECOND-1
-  jr  z,loadlevel
-  cp  K_EXIT-1
-  ret z
-  cp  K_ENTER-1
-  jr  nz,levselect
-; jr  z,loadlevel
+loadlevel1:
+  psh ix
+  pop hl
+  ld  b,-2
+  jr  loadlevel
 
-loadlevel:
+readylevelfile: ;selected level at ahl
+; ld  hl,templevels-3/0
   ld  a,b
   add a,3 ;sellev+3 (#0==-3)
   ld  e,a
@@ -352,37 +501,105 @@ loadlevel:
   add a,e ;*3
   ld  e,a
   ld  d,0 ;de=sellev*3
-  ld  hl,templevels-3
   add hl,de
   ld  a,(hl) ;ade=(hl)
-  or  a ;levelfile on page 0 (=internal)
-  jr  z,levelloaded
-
   inc hl
   ld  d,(hl)
   inc hl
   ld  e,(hl)
   ex  de,hl ;ahl=ade
 skiptitle:
-  ld  b,a ;psh ahl
+  ld  d,a ;psh ahl
   psh hl
   cal _GETB_AHL ;ld a,(ahl)
   pop hl
   or  a
-  ld  a,b ;pop ahl
+  ld  a,d ;pop ahl
   psh af
   cal _INC_PTR_AHL ;ahl++
   pop af ;cp 0
   jr  nz,skiptitle ;goto #0-terminator
+  ret
+
+levup:
+  cal menupos
+  dec b ;up
+  ld  a,b
+  cp  -3
+  jr  nz,levselect
+  inc b ;undo
+  jr  levselect
+levdown:
+  cal menupos
+  inc b ;down
+  ld  a,b
+  cp  -2
+availevels =$-1
+  jr  nz,levselect
+  dec b ;back up
+levselect:
+  cal menupos
+  ld  hl,$3900
+  ld  (_penCol),hl
+  pop hl
+  psh hl
+  cal readylevelfile
+  cal _load_ram_ahl ;hl=ahl
+  ld  de,$FFA0 ;desc.text
+  xor a
+levdescclearloop:
+  ld (de),a ;empty
+  inc de
+  cp  d ;de>$FFFF (offscreen)
+  jr  nz,levdescclearloop
+  cal _vputs
+  jr  levselectmenuloop+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
+levselectmenuloop:
+  psh hl
+  psh bc
+  cal ubergetkey
+  pop bc ;GET_KEY destr. b
+  dec a ;cp K_DOWN
+  jr  z,levdown
+  sub K_UP-1
+  jr  z,levup
+  pop hl
+  inc a ;cp K_RIGHT
+  jp  z,levelselectmenu
+  cp  K_ENTER-K_RIGHT
+  jr  z,loadlevel
+  sub K_EXIT-K_RIGHT
+  jp  z,ExitNoStats
+  inc a ;cp K_SECOND
+  jr  nz,levselectmenuloop
+; jr  z,loadlevel
 
+loadlevel:
+  cal readylevelfile
+#ifdef intlevels
+  or  a ;levelfile on page 0 (=internal)
+  jr  z,levelloaded
+#endif
+  cal skiptitle ;skip description
+leveldataAHL:
   cal _Get_Word_ahl
   ld  (leveldataSize),de
-  ld  d,8 ;counter
-  ld  bc,datalevels-2
+
+  ld  d,9 ;counter
+  ld  bc,datalevels
   cal loadgametype
-  ld  (hilvlposa),a
+  ld  (hilvlposa),a ;singleplayer levels
   ld  (hilvlposhl),hl
-  ld  d,4
+  ld  d,5
   cal loadgametype
 
   cal _SET_ABS_SRC_ADDR ;levelsstart
@@ -391,8 +608,7 @@ skiptitle:
   cal _SET_ABS_DEST_ADDR ;store in mem.
   ld  hl,0
 leveldataSize =$-2
-  cal _SET_MM_NUM_BYTES
-  cal _mm_ldir
+  cal _MM_LDIR_SET_SIZE
 
   cal _LOAD_ABS_SRC_ADDR ;->ahl
   ld  (hiscrposa),a
@@ -406,29 +622,55 @@ leveldataSize =$-2
 levelloaded:
   cal _RAM_PAGE_1
 
+;_______________________________________________________________________________
+; _______  _____   ______ _______       _____ __   _ _____ _______
+; |  |  | |     | |_____/ |______         |   | \  |   |      |
+; |  |  | |_____| |    \_ |______ _____ __|__ |  \_| __|__    |
+;_______________________________________________________________________________
+
+; cal _runindicoff   ;this is after level selection (run from yas1 or restart)
+; cal _flushallmenus ;so this stuff should already be done earlier or by yas
+  ld  (SpSave),sp
+
+  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 ;...it *does* work ;)
+
   res 2,(iy+13) ;appAutoScroll
   ld  a,r
   ld  (Seed),a
 
   ld  hl,datasingle+3
   ld  b,8
+  ld  de,8
 setdeflevels:
   ld  (hl),1 ;def=level#1
-  inc hl
-  inc hl
-  inc hl
-  inc hl
+  add hl,de ;next
   dnz setdeflevels
 
-;-----------------------------
-;----- build trig tables -----
-;-----------------------------
+;--- trig tables ---------------------------------------------------------------
 
-  ld  hl,TrigPrecalc
-  ld  de,SinCosTable
-  psh de                        ; >> 1
-  ld  bc,65
-  ldir
+  ld  hl,trigtable   ;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:
@@ -437,7 +679,7 @@ MirrorSineWave:
   ld  (de),a
   inc de
   dnz MirrorSineWave
-  pop hl                         ; << 0k
+  pop hl ;SinCosTable
   ld  b,128+64
 NegativeSineWave:
   xor a
@@ -447,167 +689,447 @@ NegativeSineWave:
   inc de
   dnz NegativeSineWave
 
-;-----------------------------
-;---------- menu -------------
-;-----------------------------
+;_______________________________________________________________________________
+; _______ _______ _____ __   _       _______ _______ __   _ _     _
+; |  |  | |_____|   |   | \  |       |  |  | |______ | \  | |     |
+; |  |  | |     | __|__ |  \_| _____ |  |  | |______ |  \_| |_____|
+;_______________________________________________________________________________
+
+;--- draw menu -----------------------------------------------------------------
 
-DisplayMenu: ;---draw menu---
+DisplayMenu:
+  cal linkok
   cal _clrWindow
   ld  de,$FC40 ;(0,4)
   ld  hl,wtPicture
-  ld  bc,16*16
+  ld  a,3
+optimize__w00t: ;may look like crap, but actually saves 3 bytes!
+  ldi
+  ld  bc,6
+  ex  de,hl
+  add hl,bc
+  ex  de,hl ;add de,6
+  ld  c,16-7 ;=bc
   ldir
-
+  dec a
+  jr  nz,optimize__w00t
+  ld  c,13*16 ;=bc
+  ldir
+  ld  hl,$FC00+$010 ;(*,01)
+  cal hr
+  ld  hl,$FC00+$160 ;(*,22)
+  cal hr
+  ld  hl,$FC00+$3E0 ;(*,62)
+  cal hr
+dispmainmenu:
+  ld  a,(gametype)
+  dec a ;will be inced @changegame
+  cal changedgame
+  ld  hl,changegame ;dispmenusets ;mainMenu
+  psh hl ;jump here after ret
   ld  hl,txtMenu
   ld  ix,posMenu
-  ld  b,6
+;Mode|Level|Link|Worms|worm #|controls
+; jr  dispmenucommon ;cal
+
+dispmenucommon_:
+  ld  b,36*16/4
+dispmenucommon:
+  ld  de,$FD80 ;begin pos
+  xor a
+clroldmenuloop:
+  ld  c,4
+  ld  (de),a
+  inc de
+  dec c
+  jr  nz,clroldmenuloop+2
+  dnz clroldmenuloop
+
+  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 ;Mode \ Level \ Limit \ Worms \ worm # \ controls
+  cal _vputs
   dnz dispmenuloop
+; ld  b,0 ;b=menu#
+  ret
 
-  ld  b,0 ;b=menu#
-  jr  _dispmenusets ;mainMenu
+hr: ;draw horizontal line at hl
+  ld  b,16
+; jp  menuinvloop ;shorter but not good for pausescreen
+hrloop:
+  ld  (hl),-1
+  inc hl
+  dnz hrloop
+  ret
 
-;--- menu loop ---
+;--- options menu --------------------------------------------------------------
 
-mainMenu:
+dispoptionmenu:
+  ld  hl,txtoMenu
+  ld  ix,posoMenu
+;Back|Lives|Limit|Speed|Rotation|Growth
+  cal dispmenucommon_
+
+dispomenusets:
+#ifdef spprotect
+  ld  a,(gamecar)
+  and _datasingl
+  jp  nz,LetsGetThisPartyOn ;SP -> start game
+#endif
+  cal clrold
+
+  ld  hl,$1E3E
+  ld  (_penCol),hl
+  cal loadgamecar
+  psh hl
+  cal cshowA ;lives
+
+  ld  hl,$2A3E
+  ld  (_penCol),hl
+  pop hl ;loadgamecar
+  inc hl \ inc hl \ inc hl
+  psh hl
+  ld  a,(hl) ;(Speed)
+  inc a ;1..99
+  jr  nz,dispspeed
+  ld  hl,txtDef
+  cal _vputs
+  jr  dispspeeddone
+dispspeed:
+  cal cshowA
+dispspeeddone:
+
+  ld  hl,$363E
+  ld  (_penCol),hl
+  pop hl ;loadgamecar
+  inc hl
+  psh hl
+  ld  a,(hl) ;(growth)
+  inc a ;-1=None; 0..98->1..99
+  cal cshowA
+
+  ld  hl,$303E
+  ld  (_penCol),hl
+  pop hl ;loadgamecar
+  inc hl
+  psh hl
+  ld  a,(hl)
+  cp  8
+  jr  nz,dispturn
+  ld  hl,txtDef
+  cal _vputs
+  jr  dispturndone
+dispturn:
+  cal cshowA ;turn speed
+dispturndone:
+
+  ld  hl,$243E
+  ld  (_penCol),hl
+  pop hl ;loadgamecar
+  inc hl
+  ld  a,(hl) ;(scorelimit)
+  or  a
+  psh af
+  cal cshowA ;limit
+  pop af ;a==0?
+  jr  z,optionMenu ;do not display 0 behind 'None'
+  ld  a,c ;(gamecar)
+  rla ;and _dataPmult
+  jr  nz,optionMenu ;in multifood limit == #peas
+  ld  a,'0'
+  cal _vputmap ;x10
+
+optionMenu:
   cal menupos
   cal menucall
-  jr  nz,notselect
-select:   ;2nd/enter
+  jr  nz,notoselect
+oselect:
   cal menupos
   ld  a,b
-  sub 4 ;4th item?
-  jp  z,changeworms
-  dec a ;5th?
-  jp  z,changekeys
-  jp  LetsGetThisPartyOn ;1/2/3/5
-notselect
+  or  a ;1st item?
+  jp  z,dispmainmenu ;mainMenu
+  jr  optionMenu
+notoselect
   cp  K_EXIT
-  jp  z,ExitNoStats
+  jp  z,dispmainmenu
   psh af
   cal menupos
   cal loadgamecar
   inc hl
   pop af
-  cp  K_LEFT
-  jr  z,selleft
-  cp  K_RIGHT
+  sub K_LEFT
+  jr  z,seloleft
+  dec a ;K_RIGHT
   ld  a,b
-  jr  nz,mainMenu
+  jr  nz,optionMenu
 
-selright:
-  or  a
-  jr  z,changegame
-  dec a
-  jp  z,changelevel ;&&&jr??
-  dec a
+seloright:
+  dec a ;Lives
   jr  z,changelives
-  dec a
-  jr  z,changenrworms
-; dec a
-; jr  z,changecurworm
+  dec a ;Limit
+  jr  z,changelimit
+  dec a ;Speed
+  jr  z,changespeed
+  dec a ;Rotation
+  jr  z,changeturn
+  dec a ;Growth
+  jr  z,changegrowth
+        ;Back
+seloleft:
+  ld  a,b
+  dec a ;Lives
+  jr  z,bchangelives
+  dec a ;Limit
+  jr  z,bchangelimit
+  dec a ;Speed
+  jr  z,bchangespeed
+  dec a ;Rotation
+  jr  z,bchangeturn
+  dec a ;Growth
+  jr  z,bchangegrowth
+_optionMenu: ;Back
+  jr  optionMenu
 
-changecurworm:
-; hl=nrworms
-  ld  a,(curworm)
-  cp  (hl)
-  jr  nc,mainMenu ;may not become >(nrworms)
+changelives:
+  cal loadgamecar ;a=(hl)
   inc a
-changedcurworm:
-  ld  (curworm),a
-  jr  _dispmenusets ;mainMenu
+  cp  100
+  jr  nc,optionMenu ;>99
+changedlives:
+  ld  (hl),a
+_dispomenusets:
+  jp  dispomenusets ;optionMenu
+bchangelives:
+  cal loadgamecar
+  sub 1 ;dec does not set cf
+  jr  c,optionMenu ;<0
+  jr  changedlives
 
-selleft:
-  ld  a,b
-  or  a
-  jr  z,bchangegame
+changelimit:
+  cal changelimitInit
+  inc a
+  cp  100
+  jr  nc,optionMenu ;>99
+changedlimit:
+  ld  (hl),a
+  jr  _dispomenusets ;optionMenu
+bchangelimit:
+  cal changelimitInit
+  sub 1 ;dec does not set cf
+  jr  c,optionMenu ;<0
+  jr  changedlimit
+changelimitInit:
+  cal loadgamecar
+  ld  de,6
+  add hl,de
+  ld  a,(hl) ;(scorelimit)
+  ret
+
+changespeed:
+  cal changespeedInit
+  inc a
+  cp  20
+  jr  nc,_optionMenu ;>98
+changedspeed:
+  dec hl ;(Speed)
+  ld  (hl),a
+  jr  _dispomenusets ;optionMenu
+bchangespeed:
+  cal changespeedInit
   dec a
-  jr  z,bchangelevel
+  cp  -2
+__optionMenu: ;w/ zf
+  jr  z,_optionMenu ;<-1
+  jr  changedspeed
+changespeedInit:
+  cal loadgamecar
+  ld  de,3
+  add hl,de
+  ld  a,(hl) ;(Speed)
+  inc hl ;=saves 2 bytes :P
+  ret
+
+changeturn:
+  cal changespeedInit
+  inc hl ;(turnspeed)
+  ld  a,(hl)
+  inc a
+  cp  26
+  jr  nc,_optionMenu ;>25
+changedturn:
+  ld  (hl),a
+  jr  _dispomenusets ;optionMenu
+bchangeturn:
+  cal changespeedInit
+  inc hl
+  ld  a,(hl)
   dec a
-  jr  z,bchangelives
+  cp  3
+  jr  c,_optionMenu ;<3
+  jr  changedturn
+
+changegrowth:
+  cal changespeedInit
+  ld  a,(hl)
+  inc a
+  cp  99
+  jr  nc,_optionMenu ;>98
+changedgrowth:
+  ld  (hl),a
+  jr  _dispomenusets ;optionMenu
+bchangegrowth:
+  cal changespeedInit
+  ld  a,(hl)
   dec a
+  cp  -2
+  jr  z,__optionMenu ;<-1
+  jr  changedgrowth
+
+;--- main menu -----------------------------------------------------------------
+
+mainMenu:
+  cal menupos
+  cal menucall
+  jr  nz,notselect
+select:   ;2nd/enter
+  cal menupos
+  ld  a,b
+  dec a ;2nd item: level
+  jp  z,dispoptionmenu
+  sub 3 ;5th item: wormname
+  jp  z,changeworms
+  dec a ;6th: controls
+  jp  z,changekeys
+  jp  LetsGetThisPartyOn ;otherwise
+
+changenrworms:
+  cal change4spOnly
+  ld  a,(hl) ;hl=nrworms
+  inc a
+  cp  7
+  jr  nc,mainMenu ;may not be >4+2
+changednrworms:
+  ld  (hl),a
+  jr  _dispmenusets ;mainMenu
+
+notselect
+  cp  K_EXIT
+  jp  z,ExitNoStats
+  cp  K_MORE
+  jp  z,codestart
+  psh af
+  cal menupos
+  cal loadgamecar
+  inc hl
+  pop af
+  sub K_LEFT
+  jr  z,selleft
+  dec a ;K_RIGHT
+  ld  a,b
+  jr  nz,mainMenu
+
+selright:
+  or  a ;Mode
+  jr  z,changegame
+  dec a ;Level
+  jr  z,changelevel
+  dec a ;Link
+  jr  z,changelink
+  dec a ;Worms
+  jr  z,changenrworms
+; dec a ;worm#
+; jr  z,changecurworm
+
+changecurworm:
+  ld  hl,curworm
+  ld  a,(hl)
+  cp  4
+  jr  nc,mainMenu ;may not become >4
+  inc (hl)
+  jr  _dispmenusets ;mainMenu
+
+selleft:
+  ld  a,b
+  or  a ;Mode
+  jr  z,bchangegame
+  dec a ;Level
+  jr  z,bchangelevel
+  dec a ;Link
+  jr  z,bchangelink
+  dec a ;Worms
   jr  z,bchangenrworms
-; dec a
+; dec a ;worm#
 ; jr  z,bchangecurworm
 
 bchangecurworm:
-  ld  a,(curworm)
-  dec a ;0-3
-  jr  nz,changedcurworm ;save >0
+  ld  hl,curworm
+  ld  a,(hl)
+  dec (hl) ;0-3
+  jr  nz,_dispmenusets ;save >0
+  inc (hl)
+_mainMenu:
   jr  mainMenu
 
-changenrworms:
-  ld  a,(Gametype)
+bchangenrworms:
+  cal change4spOnly
+  ld  a,(hl) ;hl=nrworms
+  dec a ;0-(3+2)
   cp  2
-  jr  c,mainMenu ;type 0/1
-  ;hl=nrworms
-  ld  a,(hl)
-  inc a
-  cp  5
-  jr  nc,mainMenu ;may not be >4
-changednrworms:
+  jr  nc,changednrworms ;save >=2
+  jr  _mainMenu
+
+change4spOnly:
+  ld  a,(gametype)
+  cp  3
+  ret nc
+  pop hl ;cal
+  jr  _mainMenu ;don't change for singleplayer
+
+changelink:
+bchangelink:
+  cal change4spOnly
+  dec hl ;inced earlier
+  dec hl ;gamecar
+  ld  a,1 ;change LS-bit (=link)
+  xor (hl) ;0=1; 1=0
   ld  (hl),a
 _dispmenusets:
   jr  dispmenusets ;mainMenu
-bchangenrworms:
-  ;hl=nrworms
-  ld  a,(hl)
-  dec a ;0-3
-  jr  nz,changednrworms ;save >0
-_mainMenu:
-  jr  mainMenu
 
 changegame:
-  ld  a,0
-Gametype =$-1
+  ld  a,(gametype)
   inc a
-changedgame:
-  and 7 ;mod 8
-  ld  (Gametype),a
+  cal changedgame
+  jr  z,changegame
   jr  dispmenusets ;mainMenu
+changedgame:
+  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
+  cp  (hl)
+  ret
 bchangegame:
-  ld  a,(Gametype)
+  ld  a,(gametype)
   dec a
-  jr  changedgame
-
-changelives:
-  cal changelivesInit
-  inc a
-  cp  100
-  jr  nc,_mainMenu ;&& _?
-changedlives:
-  ld  (hl),a
+  cal changedgame
+  jr  z,bchangegame
   jr  dispmenusets ;mainMenu
-bchangelives:
-  cal changelivesInit
-  dec a
-  jr  z,_mainMenu
-  jr  changedlives
-changelivesInit:
-  cal loadgamecar ;c=(gameCar)
-;a=(hl)=(Gametype+1)=(wormbeglives)
-  ld  a,(Gametype) ;&&&
-  cp  3
-  ld  a,(hl)
-  ret nc ;change lives
-  pop hl ;restore stack
-  jr  _mainMenu ;singleplayer (no limit)
 
 changelevel:
   inc hl ;hl=loadgamecar+2
   psh hl
   ld  a,(hl) ;(curlevel)
-  ld  hl,Gametype
-  ld  d,0
-  ld  e,(hl)
-  ld  hl,nrlevels
-  add hl,de
+  cal getnrlevels
   cp  (hl) ;max level for sel.game
   pop hl
   jr  z,_mainMenu
@@ -622,91 +1144,89 @@ bchangelevel:
   jr  nz,changedlevel
   jr  _mainMenu
 
+getnrlevels: ;for current gametype at hl
+  ld  hl,gametype
+  ld  d,0
+  ld  e,(hl)
+  ld  hl,nrlevels
+  add hl,de
+  ret
+
 getcustomkey:
   cal _vputs
   dec ix
 waitcustomkey:
-  halt \ halt
   psh hl
-  cal GET_KEY
+  cal ubergetkey
   pop hl
   or  a
   jr  z,waitcustomkey
   cp  K_EXIT
-  ret z
+  ret z ;cancel
   cp  K_MORE
-  jr  z,waitcustomkey
+  jr  z,waitcustomkey ;ignore
   ld  (ix),a
   ret
 
 changekeys:
   cal getwormname
-  ld  hl,txtKeyleft
+  ld  hl,txtKleft
   cal getcustomkey ;left
+  ld  a,93
+  ld  (_penCol),a
   cal getcustomkey ;right
 ; jr  dispmenusets
 
-;---display current settings---
+;--- display current settings --------------------------------------------------
 
 dispmenusets:
-  ld  hl,$FD97 ;begin pos
-  ld  de,7 ;bytes to add
-  ld  a,35 ;nr of lines
-clroldsettings:
-  ld  c,9 ;bytes to clear
-clroldsetsloop:
-  ld  (hl),d ;=0
-  inc hl
-  dec c
-  jr  nz,clroldsetsloop
-  add hl,de
-  dec a
-  jr  nz,clroldsettings
-
   ld  de,$183E
   ld  (_penCol),de
-  ld  d,0
-  ld  a,(Gametype)
-  ld  e,a
-  ld  hl,posGame
-  add hl,de ;hl=posGame+(Gametype)
-  ld  a,(hl) ;str.offset
-  ld  e,a ;^d=0^
-  ld  hl,txtGame
-  add hl,de ;txtGameX
-  ld  (CURtxtGame),hl ;save for g/o
-  cal _vputs ;Singleplayer
-
-  cal loadgamecar
-  psh hl
-  ld  hl,$243E
-  ld  (_penCol),hl
-  cal cshowA ;liveslimit
-  sub '0' ;original A
-  ld  l,a
-  ld  a,c
-  and _datascore
-  ld  a,' '
-  jr  z,limitok
-  ld  a,'0'
-limitok:
-  cal _vputmap ;x10
+  cal clrold
+  cal loadtxtgame
+  cal _vputs ;Singleplayer or smtn
 
   ld  hl,$2A3E ;worms
   ld  (_penCol),hl
-  pop hl ;cal loadgamecar
-  inc hl
+  cal loadgamecar
   psh hl
+  inc hl
   ld  a,(hl)
+  dec a ;0-5
+  and 3 ;0-3
+  inc a ;1-4
   add a,'0'
   cal _vputmap
+  ld  a,(hl)
+  cp  5
+  ld  hl,txtteamed
+  cal nc,_vputs
+
+  ld  hl,$243E
+  ld  (_penCol),hl
+  rr  c ;(gamecar)
+  ld  hl,txtNo
+  jr  nc,displink
+  ld  hl,txtYes
+displink:
+  cal _vputs
 
   ld  hl,$1E3E ;level
   ld  (_penCol),hl
-  pop hl ;loadgamecar; hl++
-  inc hl
-  ld  a,(hl) ;(curlevel)
-  cal cshowA
+  pop hl ;loadgamecar
+  psh bc
+  ld  d,0
+  cal hlatlevel
+  ld  a,(gametype)
+  or  a ;gamesingle
+  jr  nz,displvlname
+  ld  a,(Level)
+  cal cshowA00
+  jr  lvldisped
+displvlname:
+  cal _vputs
+lvldisped:
+  pop bc
 
   ld  hl,$3032
   ld  (_penCol),hl
@@ -717,22 +1237,21 @@ curworm =$-1
   ld  hl,$303E
   ld  (_penCol),hl
   cal getwormname
-  ld  hl,worm1name-18
-  add hl,de
+  psh ix ;wormNname
+  pop hl ;ld hl,ix
   cal _vputs
   ld  hl,$363E ;controls
   ld  (_penCol),hl
-;  ld  hl,txtMenu
-;  cal _vputs
+  ld  hl,txtMenuR
+  cal _vputs
   jp  mainMenu
 
-;--- handle menukeys ---
+;--- handle menukeys -----------------------------------------------------------
 
 menucall:
   psh bc
 menuwaitkey:
-  halt \ halt
-  cal GET_KEY
+  cal ubergetkey
   or  a
   jr  z,menuwaitkey
   pop bc ;GET_KEY destr. b
@@ -788,112 +1307,161 @@ menunewok:
   ld  b,a
   jr  menupos
 
-;--- change name ---
-; of worm#(curworm)
+;--- change name ---------------------------------------------------------------
 
 getwormname: ;of (curworm)
   ld  a,(curworm)
-  add a,a  ;2x
   ld  e,a
+  add a,a  ;2x
   add a,a  ;4x
   add a,a  ;8x
   add a,a ;16x
-  add a,e ;18x
+  sub e   ;15x
   ld  e,a
   ld  d,0 ;de=a
 
-  ld  ix,worm1name-18
+  ld  ix,worm1name-15
   add ix,de
   ret
 
 changeworms:
-  cal _clrWindow
-  ld  hl,txtEName
-  cal _puts ;"Enter name player "
-  ld  a,(curworm)
-  add a,'0'
-  cal _putc
-
   cal getwormname
-  ld  a,maxnamelength
-  cal entername
-  ld  (ix),0 ;end mark
-  jp  DisplayMenu
-
-entername:
-  ld  h,1
-  ld  l,h ;)
-  ld  (_curRow),hl
+  psh ix
+  pop hl ;ld hl,ix
+  psh hl
+  ld  b,8
+emptyname:
+  ld  (hl),' '
+  inc hl
+  dnz emptyname
+  ld  a,maxnamesize
   ld  (namelength),a
 enternameloop:
+  ld  hl,$FF07 ;begin pos
+  ld  a,6 ;nr of lines
+  cal clroldcustom
+  ld  hl,$303E
+  ld  (_penCol),hl
+  pop hl
+  psh hl
+  ld  (ix),a ;clroldcustom -> a=0
+  cal __vputs
   ld  a,'_'
-  cal _putc
-  ld  hl,_curCol
-  dec (hl)
+  cal __vputmap
 nokeypressed:
-  halt
-  cal GET_KEY
+  cal ubergetkey
   or  a
   jr  z,nokeypressed
 
+  ld  hl,namelength
   cp  K_DEL
   jr  nz,continue
 backspace:
-  ld  hl,namelength
   ld  a,(hl)
-  cp  maxnamelength
+  cp  maxnamesize
   jr  nc,nokeypressed
   inc (hl)
-
   dec ix
-  ld  a,' '
-  ld  (ix),a
-  cal _putc
-  ld  hl,_curCol
-  dec (hl)
-  dec (hl)
   jr  enternameloop
 continue:
+  ld  d,0
   cp  K_ENTER
-  ret z
+  jr  z,nameentered
   cp  K_EXIT
-  ret z
-
-  ld  hl,namelength
-  dec (hl)
-  ret z
+  jr  z,nameentered
 
-  ld  hl,chartable
-  ld  e,a
-  ld  d,0
+  dec (hl) ;(namelength)
+  jr  z,nameentered
+  ld  hl,chartable-1
+  ld  e,a ;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
+  .db ".<>!"           ;down|L|R|up|-|-|-|-|[enter]
+  .db "w00t!"          ;(makes code look way better)
+  .db "XTOJE0",'w'     ;+|-|*|/|^|clear|-              w
+  .db " WSNID9",$F8    ;(-)|3|6|9|)|tan|custom|-       o
+  .db "ZVRMHC8",$A7    ;.|2|5|8|(|cos|prgm|[del]       o
+  .db "YUQLGB7#",$C2   ;0|1|4|7|ee|sin|table|xvar|[on] t
+  .db "-PKFA6'"        ;sto|,|x2|ln|log|graph|alpha
+  .db "54321*",$AE,$D0 ;F5|F4|F3|F2|F1|2nd|[exit]|more
+
+nameentered: ;d=0
+  pop ix ;stringbegin
+  ld  (ix+8),d ;end mark
+  jp  DisplayMenu
 
-;--proc
+;_______________________________________________________________________________
+; _______ _____ _______ _______        _____   ______  _____  _______ _______
+; |  |  |   |   |______ |             |_____] |_____/ |     | |       |______
+; |  |  | __|__ ______| |_____  _____ |       |    \_ |_____| |_____  ______|
+;_______________________________________________________________________________
 
-skiplevel: ;@hl - destr:ab - alter:hl
-  inc hl
+ubergetkey:
+  halt ;woo hoo
+  halt ;save them batteries! yeah!
+  jp  GET_KEY
+
+clrold: ;destr:acdehl (acd=0)
+  ld  hl,$FD97 ;begin pos
+  ld  a,35 ;nr of lines
+clroldcustom:
+  ld  de,7 ;bytes to add
+clroldsettings:
+  ld  c,9 ;bytes to clear
+clroldsetsloop:
+  ld  (hl),d ;=0
   inc hl
+  dec c
+  jr  nz,clroldsetsloop
+  add hl,de
+  dec a
+  jr  nz,clroldsettings
+  ret
+
+hlatlevel: ;d must be 0
+  psh hl ;loadgamecar
+  ld  a,(gametype)
+  add a,a
+  ld  e,a ;=de
+  ld  hl,datalevels
+  add hl,de ;+2*mode
+  cal _ldHLind ;ld hl,(hl)
+  ex  (sp),hl ;hl=loadgamecar
+  ld  e,2 ;=de
+  add hl,de
+  ld  a,(hl) ;(curlevel)
+  ld  (Level),a
+  ld  c,a ;begin level
+  pop hl ;@level1
+skiplevelloop:
+  dec c ;levels to skip
+  ret z
+  cal skiplevel
+  jr  skiplevelloop
+  ret ;hl=begin of correct level
+
+skiplvltitle: ;zf=singleplayer
+  ld  a,(hl)
+  or  a ;null-terminator
   inc hl
-  inc hl ;skip 4
+  jr  nz,skiplvltitle
+  ret
+
+skiplevel: ;@hl; de=2 - destr:ab - alter:hl
+  ld  a,(gametype)
+  or  a ;gamesingle
+  psh af
+  cal nz,skiplvltitle
+  add hl,de
+  add hl,de ;skip 4
   ld  b,(hl) ;spritesize
   inc b
 skipsprite:
@@ -902,209 +1470,326 @@ skipsprite:
   ld  b,(hl) ;balls
   inc b
   inc b ;skip 6
-  ld  a,c
-  cp  _datasp
-  jr  z,skipworms
+  pop af ;cp (gametype),0
+  jr  z,skipstuff
   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:
-
+skipstuff:
+  add hl,de
+  inc hl ;3x(balls+2)
+  dnz skipstuff
+  sub gamerace ;a=(gametype)
+  jr  z,skiplaps
+  dec a ;gamectf
+  jr  nz,skipobjects
+  add hl,de
+skiplaps:
+  add hl,de
 skipobjects:
-  ld  a,(hl)
-  inc hl
-  or  a
+  xor a
+  or  (hl)
+  inc hl ;nf
   ret z ;0=end
-  inc hl
-  inc hl
-  inc hl
-  inc hl
+  add hl,de
+  add hl,de
   jr  skipobjects
 
 loadgamecar:
-;in:    (Gametype)
-;out:   Gametype+1=hl
-;build: c=(gameCar)=(hl-1)
+;in:    (gametype)
+;out:   hl=dataTYPE
+;build: c=(gamecar)=(hl-1)
 ;       a=(wormbeglives)=(hl)
 ;destr: acdehl
   ld  hl,datasingle
-  ld  a,(Gametype)
+  ld  a,(gametype)
   add a,a
   add a,a
+  add a,a ;8 bytes per mode
   ld  e,a
   ld  d,0
   add hl,de
   ld  a,(hl)
-  ld  (gameCar),a
+  ld  (gamecar),a
   ld  c,a
   inc hl
   ld  a,(hl)
   ld  (wormbeglives),a
   ret
 
-;-----------------------------
-;-------- start game ---------
-;-----------------------------
+;_______________________________________________________________________________
+; _______ _______ _______  ______ _______        ______ _______ _______ _______
+; |______    |    |_____| |_____/    |          |  ____ |_____| |  |  | |______
+; ______|    |    |     | |    \_    |    _____ |_____| |     | |  |  | |______
+;_______________________________________________________________________________
 
 LetsGetThisPartyOn:
   ld  a,$17 ;no exit
   ld  (CheckExit),a ;set exit state
 
-  cal loadgamecar
-  ld  b,a ;psh a
-  inc hl ;nrworms
-  ld  a,(hl)
-  ld  (nrworms),a
-  ld  l,b ;pop a
-  ld  h,0             ;hl=a
-  cal _HLTIMES10      ;hl=10*(hl)
-  ld  (scorelimit),hl ;set limit
-
-  cal loadgamecar ;nc
-  psh hl
-  ld  a,(Gametype) ;4bytes -> 3bytes
-  add a,a ;3->2bytes
-  add a,24+1 ;go to datalevels
-  ld  e,a ;=de
-  sbc hl,de ;datalevels
+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  (hl),b ;+score=0
+  inc hl
+  ld  (hl),b ;+score+1=0
+  inc hl
+  ld  c,2
+  ld  (hl),c ;+wdelay=2
+  inc hl
+  ld  (hl),3 ;+lives=x
+wormbeglives =$-1
+  inc hl
+  ex  de,hl  ;de=wormX+head
+  ldir       ;+head=+tail (2)
+  dec hl
+  dec hl
+  ld  c,wormsize-tail ;=bc
+  ldir       ;copy 15 bytes
+  dec a      ;loop
+  jr  nz,createwormsloop
 
-  ld  a,c ;(gameCar)
-  and _datascore
-  jr  nz,scorelimitset
-  dec a ;ld a,$FF ;=no_limit
-  ld  (scorelimit),a
-scorelimitset:
+OhMyGodItsALabel:  ;pj34r my coding skillz
+  cal loadgamecar
+  psh hl ;datatype
+  cal hlatlevel
+  ex  (sp),hl ;pop \ psh leveldata
+  psh hl ;psh loadgamecar
+  ld  a,(gamecar)
+  rra ;and _datalink
+  jr  nc,_StartLevel
 
-  cal _ldHLind ;ld hl,(hl)
-  pop de ;de=loadgamecar
-  inc de \ inc de
-  ld  a,(de) ;(curlevel)
-  ld  (Level),a
-  ld  d,a ;begin level
-skiplevelloop:
-  dec d ;levels to skip
-  jr  z,levelsskipped
-  cal skiplevel
-  jr  skiplevelloop
-levelsskipped:
+;--- link ----------------------------------------------------------------------
 
-  psh hl  ;1st level
-  ld  a,c
-  and _datalink
-  jr  z,GameOver
+wormVhost   = 095
+wormVclient = 195
 
 linkmatch:
   cal _clrWindow
   ld  c,wormVhost
   cal Qsend
-  ld  hl,txtWaiting
+  ld  hl,txtWaitn
   cal _puts
   cal Crecv
   ld  a,c
   cp  wormVclient
-  jr  z,client
-  cp  wormVhost
-  jr  nz,linkiniterror
-host:
-  ld  c,wormVclient
-  cal Qsend
-  ld  a,$18
-  jr  multiplayer
+  jr  nz,host
 
-linkiniterror:
-  pop hl
-  jp  DisplayMenu
+;--- client --------------------------------------------------------------------
 
 client:
-  ld  hl,txtReceive
-  cal _puts
-  ld  a,$E6
-multiplayer:
-  ld  (SwapPos),a
-  ld  a,2
-  ld  (nrworms),a
+; ld  hl,txtReceiv
+; cal _puts ;shouldnt be necessary since this part always seems to work afaik
+
+ ;name/keys: wormy#1 = worm #1 = ok
+ ;                 2 = link    = 0  + link (name1)
+ ;                 3 = worm #2 = #2 + local(name2)
+ ;                 4 = link    = 0  + link (name2)
+  ld  e,worm3+wleft&255
+  cal moveworm2 ;3=2
+  ld  l,worm1+name&255
+  cal sendworm
+  ld  l,worm2+wleft&255
+  cal linkworm ;worm2+4 over link
+  pop hl ;loadgamecar
+  pop de ;leveldata
+  ld  de,linklevel
+  ld  hl,datalink
+  psh de
+  psh hl ;loadgamecar
+  ld  b,8
+  cal recvstuff ;game setup
+  ld  hl,gametype ;+gamecar
+  ld  b,2
+  cal recvstuff ;transmit game
+  ex  de,hl
+  ld  b,168
+  cal recvstuff ;level
+  ld  d,b
+  cal loadtxtgame ;set CURtxtGame
 
-;-----------------------------
-;--------- game over ---------
-;-----------------------------
+_StartLevel:
+  jr  StartLevel
 
-GameOver:
-  ld  a,%11000000
-  out (7),a ;link normal
-  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
+linkerror:
+  pop hl ;error
+  jp  DisplayMenu ;return to menu
+
+;--- set/send worms ------------------------------------------------------------
+
+moveworm2:
+  ld  hl,worm2+wleft
+moveworm: ;hl=wormN+wleft
+  ld  d,worm1/256
+  ld  bc,11
+  ldir ;keys+name worm(de) = worm(hl)
+  ret
+linkworm: ;hl=wormN+wleft
+  ld  (hl),0 ;worm1|2+wleft
+  inc hl
+  inc hl ;+name
+  ld  b,9
+  cal recvstuff
+  ld  bc,worm3-worm1-11 ;+2
+  add hl,bc ;b=0
+  ld  (hl),b ;worm3|4+wleft
   inc hl
-  ld  (hl),0 ;score=0
+  inc hl ;+name
+  ld  b,9
+  jp  recvstuff
+sendworm: ;hl=wormN+name
+  ld  b,9
+  cal sendstuff
+  ld  bc,worm3-worm1-9
+  add hl,bc ;worm(N+2)+name
+  ld  b,9
+  jp  sendstuff
+
+;--- host ----------------------------------------------------------------------
+
+host:
+  cp  wormVhost
+  jr  nz,linkerror
+  ld  c,wormVclient
+  cal Qsend
+
+ ;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  e,worm4+wleft&255
+  cal moveworm2 ;4=2
+  ld  e,worm2+wleft&255
+  ld  hl,worm1+wleft
+  cal moveworm ;2=1
+  ld  l,worm1+wleft&255
+  cal linkworm ;worm1+3 over link
+  ld  l,worm2+name&255
+  cal sendworm
+  pop hl ;loadgamecar
+  pop de ;leveldata
+  psh de
+  psh hl ;loadgamecar
+  ld  b,8
+  cal sendstuff ;setup
+  ld  hl,gametype ;+gamecar
+  ld  b,2
+  cal sendstuff ;game
+  ex  de,hl
+  ld  b,168
+  cal sendstuff ;level
+
+;--- load level ----------------------------------------------------------------
+
+StartLevel:
+  pop hl ;loadgamecar
+  ld  a,(hl)
+  ld  (wormbeglives),a
+  inc hl ;nrworms
+  ld  b,$11 ;=ignore (ld)
+  ld  a,(hl)
+  cp  5
+  jr  c,teamset
+  sub 2
+  ld  b,$CD ;=continue (call)
+teamset:
+  ld  (nrworms),a
+  ld  a,b
+  ld  (doteam),a ;do team score (CD) or not (11)
+  inc hl ;level
   inc hl
-  ld  (hl),0 ;score+1=0
+  ld  a,(hl)
+  ld  (customspeed),a
   inc hl
-  ld  (hl),2 ;delay=2
+  ld  a,(hl)
+  ld  (growspeed),a
+  ld  (turn),a
   inc hl
-  ld  (hl),3 ;lives=x
-wormbeglives =$-1
+  ld  a,(hl)
+  ld  (turnleft),a
+  ld  (turnright),a ;more efficient
   inc hl
-  ex  de,hl  ;de=wormX+head
-  ld  bc,18
-  ldir       ;copy 18 bytes
-  dec a      ;loop
-  jr  nz,createwormsloop
+  ld  l,(hl)
+  ld  h,0
+  ld  a,(gamecar)
+  rla ;and _dataPmult
+  ld  a,h ;(Left)=256
+  jr  nc,setscorelimit
+  ld  a,l
+  ld  l,h
+setscorelimit:
+  ld  (customleft),a
+  cal _HLTIMES10 ;hl=10*(hl)
+  ld  (scorelimit),hl
 
+Nextlevel:
+  cal _clrWindow
   pop hl ;begin of current level
-
-StartLevel:
-  ld  de,Left
   ld  a,(hl)
   inc a ;=255?
-  jp  nz,nextlevel
+  jp  nz,donextlevel
 
+  psh hl
   ld  hl,Level
   dec (hl) ;curlevel-- (not beyond last lvl)
-  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
+donextlevel:
+  ld  de,gametype
+  ld  a,(de)
+  or  a ;gamesingle
+  psh af
+  jr  nz,customnrpeas
+;--sp--
+  inc de
+  ld  a,(de) ;gamecar
+  rla ;prepare a
+  rlc (hl) ;bit 7 of (hl)...
+  rra ;...to bit 7 of (gamecar)
+  rrc (hl) ;restore (hl)
+  ld  (de),a
+  ld  a,(hl)
+  and 127 ;actual #peas
+  jr  setnrpeas
+;--!sp--
+customnrpeas:
+  cal skiplvltitle
+  ld  a,0
+customleft =$-1
+
+setnrpeas:
+  ld  (Left),a
+  inc a
+  ld  (lefttotal),a
+  inc hl
   ld  de,Speed
-  ldi
+  ld  a,0
+customspeed =$-1
+  inc a ;$FF=def
+  jr  nz,setspeed
+  ld  a,(hl) ;speed from level
+  inc a
+setspeed:
+  dec a
+  ld  (de),a ;custom speed
+  inc hl
   ld  de,peagrowth
   ldi
-  ld  a,(hl)
-  ld  (worm1+grow),a
-  ld  (worm2+grow),a
-  ld  (worm3+grow),a
-  ld  (worm4+grow),a
-  ld  (beginsize),a
-  inc hl
+  ld  de,growsize
+  ldi
 
   ld  a,(hl)
   inc hl
@@ -1117,10 +1802,14 @@ nextlevel:
   add hl,bc ;hl=behind sprite
   jr  setsprite
 defaultsprite:
-  ld  a,defspritesz
+#ifndef intlevels
+  ld  a,42 ;always overwritten
+#else
+  ld  a,defsprsz
+#endif
 defsprsize =$-1
 defsprite  =$+1
-  ld  de,defspriteimg
+  ld  de,defspr
 setsprite: ;de=@sprite ;a=sprsize
   ld  (sprsize),a
   ld  (spritepos),de
@@ -1145,34 +1834,43 @@ toobad_noballs:
 #endif
 
   ld  hl,worm1
-  ld  a,(gameCar)
-  cp  _datasp
+  pop af ;cp (gametype),0
   ld  b,1
   jr  z,worminit
   ld  b,4
 worminit:
-  psh bc                        ; >> 1
+  psh bc ;>1
   ex  de,hl
-  ldi          ;d
+  ldi        ;+d
   ld  a,SinCosTable/256
   ld  (de),a
   inc de
-  ldi          ;y
-  ldi          ;x
+  ldi        ;+y
+  ldi        ;+x
   ex  de,hl
-
   xor a
-  ld  (hl),a   ;y2
+  ld  (hl),a ;+y2
+  inc hl
+  ld  (hl),a ;+x2
   inc hl
-  ld  (hl),a   ;x2
+  ld  a,(growsize)
+  ld  (hl),a ;+growL
+  inc hl
+  xor a
+  ld  (hl),a ;+growH=0
 
-  ld  bc,(worm2-worm1)-5
+  ld  bc,(worm2-worm1)-7
   add hl,bc
-  pop bc                         ; << 0k
+  pop bc ;<0
   dnz worminit
 
-;-------- draw level ---------
+  inc a ;ld a,1
+  ld  (turn10),a
+  ld  (flashtime),a
+
+;--- draw level ----------------------------------------------------------------
 
+initlevel:
   ld  a,(de)
   inc de
   sub 128
@@ -1191,29 +1889,23 @@ setfieldy:
   psh de                        ; >> levelp
   ld  a,l ;pop
   sub 5
-  ld  l,a
-  ld  h,0
-  add hl,hl
-  add hl,hl
-  add hl,hl
-  add hl,hl
-  add hl,hl
+  cal ldhl32a
   ex  de,hl
 
   ld  hl,ScrBuffer
   psh hl                        ; >> 1
   psh de                        ; >> 2
   ld  de,ScrBuffer+1
-  ld  bc,63
+  ld  bc,63 ;first 2 rows
   ld  (hl),%11111111
-  ldir
+  ldir ;draw upper border
   inc hl
-  ld  (hl),%11000000
+  ld  (hl),%11000000 ;first left border
   inc hl
   ld  b,31
 ClearLine:
-  ld  (hl),c
-  inc hl
+  ld  (hl),c ;=0
+  inc hl ;clear rest of line
   dnz ClearLine
   psh hl                        ; >> 3
 
@@ -1225,12 +1917,12 @@ ClearLine:
   rra
   rra
   ld  l,a
-  ld  h,0
+  ld  h,c ;0
   add hl,de
   pop af                         ; << 3
   and %00000111
   ld  b,a
-  ld  c,0
+; ld  c,0
   ld  a,%11000000
   jr  z,NoVertShift
 VertShift:
@@ -1252,50 +1944,55 @@ NoVertShift:
 
 
   pop hl                         ; << levelp
-  ld  a,(Gametype)
-  cp  gamectf
-  jr  nz,noctf
+  ld  a,(gametype)
+  cp  gamerace ;or gamectf
+  jr  c,levelhasbeensetup
   ld  de,peaspos
-  ld  bc,4
+  ld  c,2 ;ld bc,2 (2 bytes)
+  jr  z,loadextralevelstuff ;cp gamerace
+  ld  c,4 ;ld bc,4 (2nd flag in ctf)
+loadextralevelstuff:
   ldir
-  psh hl
-  cal DrawAllPeas
-  pop hl
-noctf:
+  ld  a,1 ;draw delay
+  ld  (drawctfpea1),a
+  ld  (drawctfpea2),a
+levelhasbeensetup:
 
   cal drawstuff
 
-;-----------------------------
+;--- prepare -------------------------------------------------------------------
 
+leveldone:
   psh hl                        ; >> levelp new
-  cal showstats
-  ld  a,(gameCar)
-  and _datafood
-  jr  z,nofood
-  cal NewPea
+  cal forceshowstats
+  cal handlethoseneatlittleballs
+
+  ld  a,(gamecar)
+  rla ;and _dataPmult
+  cal c,multnewpea ;a=0
+  rla ;and _datafood
+  cal nc,NewPea
 nofood:
   ld  bc,(worm1+pos)
   cal DisplayField
 
 #ifdef readymask
   ld  hl,$FC70
-  ld  d,%10101010
-  ld  c,56
+  ld  de,57*256+%10101010
 maskloop:
-  ld  a,d
-  xor %11111111
-  ld  d,a
+  ld  a,e
+  cpl
+  ld  e,a
   ld  b,$10
 maskline:
   ld  a,(hl)
-  or  d
+  and e
   ld  (hl),a
   inc hl
   dnz maskline
-  dec c
+  dec d
   jr  nz,maskloop
 #endif
-
 #ifdef readytext
   ld  hl,$FDE0
   ld  de,$FDE1
@@ -1310,35 +2007,26 @@ maskline:
   res 3,(iy+5)
 #endif
 
-  ld  a,0
-gameCar =$-1
-  and _datalink
-  jr  z,initfinished ;no link
-  xor a
-  ld  (Speed),a ;max.speed
-SwapPos: ;$18 xx -> $E6 xx
-         ; jr xx -> and xx
-  jr  sethost
-setclient:
-  ld  (worm1+left),a ;worm 1 via link
-  jr  initfinished
-sethost:
-  ld  (worm2+left),a ;worm 2 via link
-initfinished:
-
   ld  b,startdelay
 ReadyDelay:
   halt
   dnz ReadyDelay
   cal releasekeys
 
-;-----------------------------
-;----------- LOOP ------------
-;-----------------------------
+;_______________________________________________________________________________
+;  ______ _______ _______ _______               _____   _____   _____
+; |  ____ |_____| |  |  | |______       |      |     | |     | |_____]
+; |_____| |     | |  |  | |______ _____ |_____ |_____| |_____| |
+;_______________________________________________________________________________
 
 GameLoop:
-  ld  bc,(worm1+pos)
-  cal DisplayField
+  ld  bc,(worm1+pos) ;camera worm #1
+  ld  a,(worm1+wleft)
+  or  a ;if #1 not over link
+  jr  nz,showfield
+  ld  bc,(worm2+pos) ;otherwise view from #2
+showfield:
+  cal DisplayField ;display piece of level
 
   ld  a,1
 flashtime =$-1
@@ -1352,7 +2040,7 @@ screeninvertloop:
   ld  (hl),a
   inc hl
   xor a
-  cp  h
+  cp  h ;end at >$FFFF
   jr  nz,screeninvertloop
 noflash:
 
@@ -1366,12 +2054,41 @@ Delay:
   jr  nz,Delay
 NoDelay:
 
-  ld  (handledworm),a ;=0
+  ld  (handledworm),a ;reset
 
-  ld  a,0
-nrballs =$-1
-  or  a
-  cal nz,handlethoseneatlittleballs
+  ld  hl,turn
+  ld  a,(hl)
+  inc a ;-1
+  jr  z,nextturnok
+  dec (hl)
+  dec a ;>=0
+  jr  nz,nextturnok
+growspeed =$+1
+  ld  (hl),$FF ;reset
+nextturnok:
+
+  ld  a,(gamecar)
+  and _datatime
+  jr  z,nodispupdate
+  ld  hl,turn10
+  dec (hl)
+  jr  nz,nodispupdate ;just once every 10 turns
+  ld  (hl),10 ;reset counter
+  cal forceshowstats ;update score
+nodispupdate:
+
+  ld  a,(gametype)
+  cp  gamectf
+  jr  nz,noctfpeas2draw
+  ld  de,drawctfpea1
+  ld  hl,(peaspos)
+  cal tryDrawPea ;pea#1
+  ld  de,drawctfpea2
+  ld  hl,(peaspos+2)
+  cal tryDrawPea ;pea#2
+noctfpeas2draw:
+
+  cal handlethoseneatlittleballs
 
   ld  ix,worm1
   ld  a,1
@@ -1384,106 +2101,148 @@ handleworms:
   add ix,bc
   pop bc
   ld  hl,handledworm
-  inc (hl) ;1..nrworms
+  inc (hl) ;0..nrworms-1
   dnz handleworms
 
-;-----------------------------
-;---------- keys -------------
-;-----------------------------
+;_______________________________________________________________________________
+; _     _ _______ __   __ _______
+; |____/  |______   \_/   |______
+; |    \_ |______    |    ______|
+;_______________________________________________________________________________
 
 HandleKeys:
   ld  a,%10111111
   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
 
-WormDead:
-#ifdef invincible
-  jp  stopworm
-#else
-  ld  a,2
-  ld  (flashtime),a
-  ld  (ix+delay),respawndelay
-
-thislevel =$+1
-  ld  hl,0
-  ld  de,0
-handledworm =$-2
-  add hl,de
-  add hl,de
-  add hl,de
-  ld  a,(hl)
-  inc hl
-  ld  (ix+heading),a
-  ld  a,(hl)
-  ld  (ix+pos),a
-  inc hl
-  ld  a,(hl)
-  ld  (ix+pos+1),a
+;--- pause menu ----------------------------------------------------------------
+
+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
-  cal 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,(gameCar)
-  and _datalivel
-  ret z ;don't end game
-  ld  a,(Gametype)
-  cp  gametron
-  jr  nz,anyworm ;if not Tron, quit at any worm's death
-  ld  a,(nrworms)
-  ld  b,a ;# of worms
-  ld  hl,worm1+lives-(worm2-worm1)
-  ld  de,worm2-worm1
-  xor a ;check for 0 lives
-checklives:
-  add hl,de ;next worm
-  cp  (hl) ;lives==0?
-  ret nz ;any >0: don't exit
-  dnz checklives
-anyworm:
-  ld  a,$A7 ;exit@end of turn
-  ld  (CheckExit),a ;set exit state
-  ret ;finish turn
-#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
   ld  sp,0 ;pop all
 SpSave = $-2
-  ld  a,D0HD1H
-  out (7),a
+  ld  a,D0LD1L
+  out (7),a    ;both wires low = game over signal
   cal _clrWindow
+#ifdef coolzgfx
+  ld  de,$FC30 ;(0,1)
+  ld  hl,wtWormy
+  ld  bc,16*7
+  ldir
+  ld  hl,$FC10
+  ld  b,16*11
+  cal menuinvloop ;invert
+  ld  hl,$FC00+$180
+  cal hr ;menuinvloop w/ b=16
+  ld  hl,$FC00+$E0
+  cal hr
+  ld  hl,_curRow
+  ld  (hl),2
+#else
   ld  hl,txtGO
   cal _puts
   ld  hl,$FC00
   ld  b,16*8
   cal menuinvloop ;invert
-  inc h ;$FD80
-  ld  b,16
-  cal menuinvloop ;<hr>
-  ld  hl,$FCE0
-  ld  b,16
-  cal menuinvloop ;<hr>
-; ld  l,$74
-; ld  b,8
-; cal menuinvloop
+  inc h ;$FC00+$180
+  cal hr ;menuinvloop w/ b=16
+  ld  hl,$FC00+$E0
+  cal hr
   ld  hl,_curRow
   inc (hl)
+#endif
   ld  hl,txtGame
 CURtxtGame =$-2
   cal _puts
@@ -1495,25 +2254,77 @@ CURtxtGame =$-2
   ld  (_penCol),de
   ld  hl,txtName
   cal _vputs ;Name
-  ld  a,$4F
+  ld  a,$3C
   ld  (_penCol),a
   cal _vputs ;Died    Score
   ld  de,$0004
   ld  (_curRow),de
 
+;--- who won? ------------------------------------------------------------------
+
+findwinner:
+  ld  hl,(worm1+score)
+  ld  (winnerscore),hl
+  ld  b,3 ;(nrworms)-1
+  ld  hl,worm2+score
+findwinnerloop:
+  psh hl
+  cal _ldHLind
+  ld  de,(winnerscore)
+  ld  a,h
+  cp  d
+  jr  c,nonewwinner ;h<d
+  jr  nz,newwinner  ;h>d
+  ld  a,e
+  cp  l
+  jr  nc,nonewwinner ;l<e
+newwinner:
+  ld  (winnerscore),hl
+nonewwinner:
+  pop hl
+  ld  de,worm2-worm1
+  add hl,de
+  dnz findwinnerloop
+
+  ld  a,(nrworms)
+  ld  b,a
+  cpl ;high value (>$FB)
+  ld  hl,worm1+died
+finddmwinner:
+  cp  (hl)
+  jr  c,nonewdmwinner
+  ld  a,(hl) ;less deaths
+nonewdmwinner:
+  ld  de,worm2-worm1
+  add hl,de
+  dnz finddmwinner
+  ld  (dmwinner),a
+
+;--- display worms -------------------------------------------------------------
+
+;x123456789012345678901
+;>>>>>> GAME OVER <<<<<
+;2Multiplayer
+;3Level 01
+;4           Died Score:
+;5NameName     03 00070
+;6Worm#02 @    05 00120
+;7Worm#03      15 00030
+;8Snaky   @    00 04820
+
   ld  a,(nrworms)
   ld  b,a
   ld  hl,worm1+died
 displayWormStats:
   psh bc
-  psh hl
 
-  ld  bc,left-died
-  add hl,bc ;+left
+  psh hl
+  ld  bc,wleft-died
+  add hl,bc ;+wleft
   xor a
-  cp  (hl)  ;input=0 = link
+  cp  (hl)  ;wleft=0 = link
   jr  nz,NoLinkIndic
-  ld  a,8
+  ld  a,9
   ld  (_curCol),a
   ld  a,$DC ;-O
   cal _putc
@@ -1523,29 +2334,50 @@ NoLinkIndic:
   inc hl
   inc hl ;+name
   cal _puts
-
   pop hl
+
   psh hl
   ld  a,13
   ld  (_curCol),a
   ld  a,(hl) ;worm+died
-  cal showA
+  cal showA0
   pop hl
-  psh hl
 
+  psh hl
+  ld  a,(gametype)
+  cp  gamedeathm
+  jr  nz,nodmwinner ;deathmatch?
+  ld  a,0 ;winner's deaths
+dmwinner =$-1
+  cp  (hl) ;equals this worm?
+  scf ;jr nz,notwinner
+  cal z,iswinner
+nodmwinner:
+  jr  c,notwinner ;no singleplayer winners
+  inc hl ;worm+score
+  cal _ldHLind ;ld hl,(hl)
+  ld  de,0
+winnerscore =$-2
+  cal _cphlde ;==highest score..
+  cal z,iswinner
+notwinner:
   ld  a,16
   ld  (_curCol),a
+  pop hl
+  psh hl
   inc hl ;worm+score
-  cal _ldHLind ;ld hl,(hl)
-  cal showHL ;worm+score
-
+  cal _ldHLind
+  cal _D_HL_DECI
+  cal _puts ;showHL
   pop hl
+
   ld  bc,worm2-worm1
   add hl,bc
   pop bc
   dnz displayWormStats
 
-  ld  a,(Gametype)
+  ld  de,gametype
+  ld  a,(de)
   or  a ;singleplayer (0) only
   jr  nz,hilevelcheckdone
 checkhilevel:
@@ -1562,65 +2394,108 @@ hilvlposhl =$-2 ;save external
   cal _writeb_inc_ahl ;ld (ahl),c
 hilevelcheckdone:
 
-  ld  a,(gameCar)
+  inc de
+  ld  a,(de) ;gamecar
   and _datasingl
-
-  jr  z,hiscorecheckdone
+  jr  z,hiscorecheckdone ;no SP
 checkhiscore:
-  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
+  cal loadhiscoreposinahl ;cf=0 (and)
+  cal _SET_ABS_SRC_ADDR ;from ahl (lvlfile)
+;-wild insertation-
+  xor a
+  ;Be Root to fix a Unix problem
+  ld  hl,savestr
+  ;ReBoot to fix a Windows problem
+  cal _SET_ABS_DEST_ADDR ;to local
+  ;W00t W00t to fix an assembly problem
+  cal mmldir5 ;get old score+name
+  ld  de,(savestr)     ;de=prev. hiscore
+  ld  hl,(worm1+score) ;hl=worm1's score
+  cal _cphlde ;sub hl,de
+  jr  c,NotNewHigh ;new<old
+  jr  z,NotNewHigh ;new<=old
+newhigh:           ;New>Old
+  ld  (savestr),hl  ;store new hiscore
+  ld  de,savestr+2  ;to
+  ld  hl,worm1+name ;from
+  ld  bc,3 ;3 chars
+  ldir ;store new hiname
+  cal loadhiscoreposinahl ;cf=0 (jr c)
+  cal _SET_ABS_DEST_ADDR ;to ahl
+  xor a
+  ld  hl,savestr
+  cal _SET_ABS_SRC_ADDR ;from local
+  cal mmldir5 ;save new score+name
+  ld  hl,_curRow
+  dec (hl)
+  cal iswinner
 
-NotNewHigh: ;de=current hiscore
-  ld  hl,$0807
-  ld  (_curRow),hl
+NotNewHigh:
+  ld  hl,$3149
+  ld  (_penCol),hl
   ld  hl,txthiscore
+  cal _vputs
+  ld  hl,$0C07
+  ld  (_curRow),hl
+  ld  hl,savestr+2
   cal _puts
-  ex  de,hl ;pop
-  cal showHL
+  ld  hl,_curCol
+  inc (hl)
+  ld  hl,(savestr)
+  cal _D_HL_DECI
+  cal _puts ;showHL
 hiscorecheckdone:
 
-  cal releasekeys
 waitkey:
-  halt
-  halt
-  cal GET_KEY
+  ld  hl,DisplayMenu
+  psh hl ;main menu
+waitkeyloop:
+  cal ubergetkey
   cp  K_ENTER
-  jp  z,DisplayMenu
+  ret z
   cp  K_SECOND
-  jp  z,DisplayMenu
+  ret z
   cp  K_EXIT
-  jr  nz,waitkey
+  jr  nz,waitkeyloop
+  ret
 
-;x123456789012345678901
-;>>>>>> GAME OVER <<<<<
-;2Multiplayer
-;3Level 01
-;4           Died Score:
-;5NameName     03 00070
-;6Worm#02 @    05 00120
-;7Worm#03      15 00030
-;8Snaky   @    00 04820
+loadhiscoreposinahl:
+  sbc hl,hl ;cf=0
+  ld  a,(gametype)
+  or  a ;Singleplayer?
+  jr  z,hi__
+  dec a ;peaworm?
+  jr  z,hi_
+  ld  a,(nrlevels+1) ;skip peaworm slots if tron mode
+hi_:
+  ld  bc,(Level)
+  add a,c
+  ld  b,a ;levels to skip (including 1 for singleplayer)
+  ld  de,5 ;to add per level
+addlevelposition:
+  add hl,de ;one word+3 bytes for name
+  dnz addlevelposition
+hi__:
+  xor a ;ahl=0(+hl)
+  ld  bc,defhiscrpos
+hiscrposhl =$-2
+  add hl,bc
+hiscrposa =$+1
+  adc a,0 ;ahl=saveloc
+  ret
+savestr: ;hiscore (01ABC) _D_HL_DECI (01234)
+  .db $BB,"w00t",0
+
+iswinner:
+  ld  a,10
+  ld  (_curCol),a
+  ld  a,'*'
+  jp  _putc ;..then put *
+
+;--- quit ----------------------------------------------------------------------
 
 ExitNoStats:
+  cal linkok
   ld  hl,_asapvar
   rst 20h ;_ABS_MOV10TOOP1
   rst 10h ;_FINDSYM
@@ -1634,8 +2509,7 @@ ExitNoStats:
   ld  hl,savestart
   cal _SET_ABS_SRC_ADDR
   ld  hl,saveend-savestart
-  cal _SET_MM_NUM_BYTES
-  cal _mm_ldir
+  cal _MM_LDIR_SET_SIZE
 
   cal releasekeys
   res 4,(iy+9)
@@ -1643,45 +2517,14 @@ ExitNoStats:
   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 ------------
-;-----------------------------
+;_______________________________________________________________________________
+; _  _  _  _____   ______ _______       _______ _______ _     _ _______ _______
+; |  |  | |     | |_____/ |  |  |       |______    |    |     | |______ |______
+; |__|__| |_____| |    \_ |  |  | _____ ______|    |    |_____| |       |
+;_______________________________________________________________________________
 
 respawncheck:
-  cp  respawndelay-1
+  cp  rspawndelay-1
   jr  nz,unnamedlabel
   cal saverespawncounter
 removeworm:
@@ -1691,30 +2534,25 @@ removeworm:
   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
+  cal removetailbit
   inc (ix+grow)
+  jr  nz,DoesWormTailEqualsWormHead
+  inc (ix+grow+1) ;+256
 DoesWormTailEqualsWormHead:
   cal _cphlde
-  jr  nz,removewormloop
+  jr  nz,removewormloop ;head=tail/size=0
 
-  ld  a,(gameCar)
+  ld  a,(gamecar)
   and _datasingl
-  jr  nz,safewormsizedone
+  jr  nz,savetailpos
+  ld  (ix+grow+1),a ;=0
   ld  a,0
-beginsize =$-1
+growsize =$-1
   ld  (ix+grow),a
-safewormsizedone:
 
-  ;de=ix+head
-  ld  (ix+tail+1),d
-  ld  (ix+tail),e ;head=tail/size=0
+savetailpos:
+  ld  (ix+tail+1),h
+  ld  (ix+tail),l
   ret
 
 unnamedlabel:
@@ -1727,15 +2565,11 @@ respawndue:
   ld  a,h ;previous
   cp  l   ;changed?
   ret z
-  ld  (ix+delay),a ;=0
+  ld  (ix+wdelay),a ;=0
   ret
 saverespawncounter:
-  ld  (ix+delay),a
+  ld  (ix+wdelay),a
   jr  inputcall
-;  ld  a,(ix+input)
-;  or  a
-;  jr  z,inlink
-;  ret
 
 chkkey: ;key=a
   dec a
@@ -1766,54 +2600,63 @@ inkeys: ;use jp not call!
   jr  nc,notright
   ld  a,l
   add a,8
+turnright =$-1
   ld  l,a
 notright:
-  ld  a,(ix+right)
+  ld  a,(ix+wright)
   cal chkkey
   ret nc
   ld  a,l
   sub 8
+turnleft =$-1
   ld  l,a
   ret
 inputcall:
-  ld  a,(ix+left)
+  ld  a,(ix+wleft)
   or  a
   jr  z,inlink ;input by link
   cal inkeys ;input by keys
-  ld  a,(gameCar)
-  and _datalink
-  ret z ;no link
+  ld  a,(gamecar)
+  rra ;and _datalink
+  ret nc ;no link
   ld  c,l ;send our keys
-  psh hl
-  cal Qsend ;Csend
-  pop hl
-  ret
+  jp  Qsend
 inlink:
-  psh hl
   cal Qrecv ;Crecv
-  pop hl
   ld  l,c
   ret
 
-;------- handle worm ---------
+;_______________________________________________________________________________
+; _  _  _  _____   ______ _______       _______        _____ _    _ _______
+; |  |  | |     | |_____/ |  |  |       |_____| |        |    \  /  |______
+; |__|__| |_____| |    \_ |  |  | _____ |     | |_____ __|__   \/   |______
+;_______________________________________________________________________________
 
 HandleWorm:
-  ld  a,(gameCar)
-  cpl
-  and _datalivel
-  add a,(ix+lives)
+  xor a
+  cp  (ix+lives)
+  jr  nz,alive
+  ld  a,(wormbeglives)
   or  a
-  ret z ;dead
-  ld  a,(ix+delay)
+  ret nz ;live limit
+alive:
+  ld  a,(ix+wdelay)
   dec a
   jp  nz,respawncheck
 
-  ld  a,(Gametype)
-  cp  gametron
-  jr  nz,notron
-  ld  de,1
+  xor a
+  cp  0
+turn =$-1
+  jr  nz,nogrow
+  inc (ix+grow)
+nogrow:
+
+  ld  a,(gamecar)
+  and _datatime
+  jr  z,notimescore
+  ld  e,1
   cal IncScore
-notron:
+notimescore:
 
   ld  l,(ix+heading)
   cal inputcall
@@ -1826,22 +2669,10 @@ 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 ----------
+;--- move worm -----------------------------------------------------------------
 
-Wormmove:
-  psh bc                        ; >> pos
+wormmove:
+  psh bc ;pos
   ld  a,(hl)
   add a,a
   add a,d
@@ -1869,301 +2700,116 @@ notnegY:
 notmoveY: ;bc=newpos
   ld  (ix+pos2),e
   ld  (ix+pos2+1),d
-  ld  (ix+pos),c
-  ld  (ix+pos+1),b
 
 ;-check-
-  pop hl                         ; << pos (old)
+  pop hl ;pos (old)
   ld  a,h
-  sub b
-  and 1
+  sub b ;Xold-Xnew
+  and 1 ;abs
   ld  h,a
   ld  a,l
   sub c
-  and 1
-  add a,h
-  ld  d,4
+  and 1 ;|Yold-Ynew|
+  add a,h ;pixels moved |Dx|+|Dy|
+  ld  d,4 ;same pos = 4of4 bytes drawn
   jr  z,GotFour
-  xor 3
-  ld  d,a
+  xor 3 ;1 pixel = 2of4 blank; 2 pixels = 3of4 blank
+  ld  d,a ;#pixels that should be drawn
 GotFour:
-  cal chk4pixels
-  rl  d
-  jp  nc,Drawworm
+  cal chk4pixels ;d-=pixels at b,c
+  rl  d ;<0 meaning there were >d pixels
+  cal c,hitworm ;so that wasn't us
 
-;--------- worm hit ----------
+;--- draw worm -----------------------------------------------------------------
 
-Hitworm:
-  ld  a,(gameCar)
-  ld  h,a
-  and _datadie
-  cal z,checkhitotherworm
-  ld  a,h
-  and _datamultpeas ;&&bit
-  jr  nz,multiple_peas
-  ld  a,h
-  and _datafood
-  jp  z,WormDead ;no food
+drawworm:
+  ld  (ix+pos),c
+  ld  (ix+pos+1),b
 
-  ld  hl,0
-PeaY =$-2
-PeaX =$-1
-  cal chkpeahit
-  jp  nc,WormDead
-  cal DrawPea ;remove pea
-  ld  a,(ix+grow)
-  add a,15
-peagrowth =$-1
-  ld  (ix+grow),a
-  cal NewPea
-  ld  hl,Left
-  dec (hl)
-  psh af
-  ld  de,10
-  cal IncScore
-  pop af
-  jp  nz,Drawworm ;continue
-  ld  a,(gameCar)
-  and _datafoodl
-  jp  z,Drawworm
-  ld  a,(Gametype)
-  or  a
-  jp  nz,Exit ;stack restored
+  ld  a,(gametype)
+  cp  gamerace
+  cal z,checkhitlapline
 
-  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
-  ld  (ix+delay),2
-  jp  StartLevel
+  cal set4pixels
+  dec c
+  ld  a,(growspeed)
+  or  a ;0=tron
+  ret z ;keep tail in "Tron"
 
-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
+  ld  l,(ix+head)
+  ld  h,(ix+head+1)
+  ld  (hl),c
+  inc hl
+  ld  (hl),b
+  inc hl
+  ;(resbit)
+  ld  a,h
+  and (ix+storepos)
+  ld  h,a
+  ld  (ix+head),l
+  ld  (ix+head+1),h
+
+  ld  l,(ix+grow)
+  ld  h,(ix+grow+1)
+  dec hl
+  ld  a,h
+  or  l
+  jr  z,removetail
+  ld  (ix+grow),l
+  ld  (ix+grow+1),h
+  ret
+
+removetail:
+  ld  l,(ix+tail)
+  ld  h,(ix+tail+1)
+  cal removetailbit
+  cal savetailpos ;ld (ix+tail),hl
+  ld  c,(hl)
+  inc hl
+  ld  b,(hl)
+  jr  set4pixels ;redraw new last bit
 
-flagcaptured:
+removetailbit:
+  ld  c,(hl)
+  inc hl
+  ld  b,(hl)
+  inc hl
+  ;(resbit)
+  ld  a,h
+  and (ix+storepos)
+  ld  h,a
   psh hl
-  ld  de,30
-  cal IncScore
+  cal res4pixels ;rm last bit
   pop hl
-sillylabel:
-  cal WormDead
-DrawAllPeas:
-  ld  hl,(peaspos)
-  cal DrawPea
-  ld  hl,(peaspos+2)
-  jp  DrawPea
+  ret
 
-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,WormDead ;stopworm ;own pea hit
+res4pixels:
+  cal ResPixel
+  inc b
+  cal ResPixel
+  inc c
+  cal ResPixel
+  dec b
+ResPixel:
+  cal FindPixel
+  cpl
+  and (hl)
+  ld  (hl),a
+  ret
 
-  ld  a,e ;peek a (that's 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
-
-;-----------------------------
-
-nextotherwormbit:
-  ld  a,c
-  sub (hl)
-  inc hl
-  inc a
-  cp  4
-  jr  nc,nothit1 ;no
-  ld  a,b
-  sub (hl)
-  inc a
-  cp  4
-  ret c ;nz ;yes
-nothit1:
-  inc hl
-  cal resbit
-ChkWorm:
-  cal _cphlde
-  jr  nz,nextotherwormbit
-  ret ;z
-
-checkhitlapline:
-  ld  a,63
-  sub b
-  jr  z,nextlaphalf
-  inc a
-  ret nz
-nextlaphalf:
-  ld  a,c
-  and 32 ;y>=32?
-  jr  nz,nolap
-  cp  (ix+reserv)
-  jr  z,nolap
-  psh bc
-  ld  de,20
-  cal IncScore
-  pop bc
-  xor a
-nolap:
-  ld  (ix+reserv),a
-  ret
-
-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
-
-;-------- draw worm ----------
-
-Drawworm:
-  ld  c,(ix+pos)
-  ld  b,(ix+pos+1)
-
-  ld  a,(Gametype)
-  ld  d,a
-  cp  gamerace
-  cal z,checkhitlapline
-
-  cal set4pixels
-  dec c
-  ld  a,d
-  cp  gametron
-  ret z ;keep tail in "Tron"
-
-  ld  l,(ix+head)
-  ld  h,(ix+head+1)
-  ld  (hl),c
-  inc hl
-  ld  (hl),b
-  inc hl
-  cal resbit
-  ld  (ix+head),l
-  ld  (ix+head+1),h
-
-  ld  a,(ix+grow)
-  dec a
-  jr  z,removetail
-  ld  (ix+grow),a
-  ret
-
-removetail:
-  ld  l,(ix+tail)
-  ld  h,(ix+tail+1)
-  ld  c,(hl)
-  inc hl
-  ld  b,(hl)
-  inc hl
-  cal resbit
-  ld  (ix+tail),l
-  ld  (ix+tail+1),h
-
-res4pixels:
-  cal ResPixel
-  inc b
-  cal ResPixel
-  inc c
-  cal ResPixel
-  dec b
-ResPixel:
-  cal FindPixel
-  cpl
-  and (hl)
-  ld  (hl),a
-  ret
-
-;-----------------------------
-;---------- ball -------------
-;-----------------------------
+;_______________________________________________________________________________
+; ______   _____  _     _ __   _ _______ __   __ ______  _______
+; |_____] |     | |     | | \  | |         \_/   |_____] |_____| |      |
+; |_____] |_____| |_____| |  \_| |_____     |    |_____] |     | |_____ |_____
+;_______________________________________________________________________________
 
 handlethoseneatlittleballs:
+  ld  a,0
+nrballs =$-1
+  or  a
+  ret z ;no bouncies to handle
+  ld  b,a ;(nrballs)
   ld  hl,balls
-  ld  b,a ;a=(nrballs)
 handleballs
   psh bc
   psh hl
@@ -2252,51 +2898,317 @@ checkballhit:
   pop de
   ret
 
-;-----------------------------
-;----------- procs -----------
-;-----------------------------
+;_______________________________________________________________________________
+; _  _  _  _____   ______ _______ __   __       _     _ _____ _______
+; |  |  | |     | |_____/ |  |  |   \_/         |_____|   |      |
+; |__|__| |_____| |    \_ |  |  |    |    _____ |     | __|__    |
+;_______________________________________________________________________________
 
-releasekeys:
-  halt
+;--- multifood -----------------------------------------------------------------
+
+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
+  jr  _wormdead
+pickmultpea:
+  ld  a,247
+  ld  (de),a
+  dec de
+  ld  (de),a
+  jp  pickedpea
+
+;--- ctf -----------------------------------------------------------------------
+
+chkctfpeas: ;ctf
+  ld  hl,(peaspos) ;1st pea
+  ld  a,(ix+reserv)
+  ld  e,a ;push a
+  and %01 ;ourpea (0|1)
+  jr  z,sel_otherpea
+  ld  hl,(peaspos+2) ;2nd pea
+sel_otherpea:
+  cal chkpeahit
+  jr  c,hitflag
+;no peas hit:
+  ld  a,e ;peek a (that's x86asm for pop\push ;)
+  bit 1,a ;%1O = carrying flag?
+  jr  z,_wormdead ;if not just die
+  and %1 ;which flag?
+  ld  hl,drawctfpea1 ;restore #1
+  jr  nz,nottheotherflag
+  inc hl ;ld hl,drawctfpea2
+  inc hl ;restore #2
+nottheotherflag:
+  ld  (hl),3 ;draw delay 3 turns
+_wormdead:
+  jp  wormdead
+
+hitflag: ;correct pea hit
+  ld  a,e ;pop a
+  xor %11 ;invert flag taken + ownflag
+  ld  (ix+reserv),a
+  and %10 ;just returned?
+  psh bc ;safe position
+  psh af ;safe z-flag
+  cal DrawPea ;remove
+  pop af
+  pop bc
+  ret nz ;flag taken: continue game ;drawworm
+  ld  e,20 ;flag captured+returned
+  psh bc
+  cal IncScore
+  pop bc
+  ld  a,3 ;draw delay
+  ld  (drawctfpea1),a ;redraw..
+  ld  (drawctfpea2),a ;..both flags
+  ret ;drawworm
+
+;--- main ----------------------------------------------------------------------
+
+hitworm:
+  ld  a,(gamecar)
+  bit __bitPctf,a
+  jr  nz,chkctfpeas
+  rla ;and _dataPmult
+  jr  c,chkmultpeas
+  rla ;and _datafood
+  jr  c,_wormdead ;no food
+
+;--- foodmatch|SP --------------------------------------------------------------
+
+  ld  hl,0
+PeaY =$-2
+PeaX =$-1
+  cal chkpeahit
+  jp  nc,wormdead
+
+;--- take pea ------------------------------------------------------------------
+
+  psh hl
+  cal NewPea
+  pop hl
+pickedpea:
+  cal DrawPea ;remove pea
+  ld  a,(ix+grow) ;grow
+  add a,15
+peagrowth =$-1
+  ld  (ix+grow),a
+  jr  nc,wormset2grow
+  inc (ix+grow+1)
+wormset2grow:
+  ld  hl,Left
+  dec (hl) ;dec left _before_ display
+  psh af
+  ld  e,10
+  cal IncScore
+  pop af
+  ld  c,(ix+pos) ;same position
+  ld  b,(ix+pos+1) ;we'll just leave pos2 - doubt anybody will care|notice..
+  ret nz ;(Left)>0 ;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 hitworm
+  pop hl ;<<call HandleWorm
+  pop hl ;<<$some other call
+  ld  (ix+wdelay),2
+  jp  Nextlevel
+
+chkpeahit: ;bc=ownpos;hl=peapos (destr:ad)
+  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
+
+;--- misc ----------------------------------------------------------------------
+
+checkhitlapline:
+  ld  a,(peaspos) ;63 usually
+  sub b ;x==63
+  jr  z,nextlaphalf
+  inc a ;(more checkin' since wormies just have those _huge_ heads ;)
+  ret nz ;x!=62
+nextlaphalf: ;x==62|63; a=0
+  ld  a,(peaspos+1) ;yline
+  cp  c ;ypos
+  ld  a,1
+  jr  nc,checklap ;y>yline -> a=1
+  xor a ;y<yline -> a=0
+checklap:
+  cp  (ix+reserv)
+  ret z ;same as before
+  ld  (ix+reserv),a ;1st time
+  ld  e,a
+  ld  a,(handledworm)
+  and 1 ;group 0 (1,3) or 1 (2,4)
+  xor e
+  ret z ;(group 0 and y<yline) or (group 1 and y>yline)
+  psh bc
+  ld  e,20
+  cal IncScore ;lap!
+  pop bc
+  ret
+
+;_______________________________________________________________________________
+;  _____   ______  _____  _______ _______
+; |_____] |_____/ |     | |       |______
+; |       |    \_ |_____| |_____  ______|
+;_______________________________________________________________________________
+
+releasekeys: ;---------->promise me you'll never let go...
+  halt ;-------------------->i won't let go....
   ld  a,%10000000    ;all key-masks
   out (1),a
-  in  a,(1)
+  in  a,(1) ;--------------->i'll never let go.....
   inc a              ;cp %11111111 (no keys pressed)
   jr  nz,releasekeys ;keep waitin
   cal GET_KEY        ;clear buffer
-  ret
-
-resbit:
-  ld  a,h
-  and (ix+storepos)
-  ld  h,a
-  ret
+  ret ;--------------------->*die* (we are VICTORIOUS! muha)
 
 randompos:
   ld  b,a
 Random: ;(2..b+2)
-  ld  a,r
+  ld  a,r ;0..127
+  scf ;not just even values:
+  rla ;6543210C
 Seed =$+1
   add a,0
   ld  (Seed),a
-  and %01111110
   cp  b
   jr  nc,Random
   add a,2
   ret
 
-NewPea:
-  ld  a,(FieldWidth)
-  add a,127-4
-  cal randompos
-  ld  h,a
-  ld  a,(FieldHeight)
-  add a,56-4
-  cal randompos
+ldhl32a:
   ld  l,a
-  ld  (PeaY),hl
+  ld  h,0 ;=hl
+  add hl,hl
+  add hl,hl
+  add hl,hl
+  add hl,hl
+  add hl,hl ;32=scr.width
+  ret ;ld hl,32*a
+
+mmldir5:
+  ld  hl,5 ;=ahl
+  cal _MM_LDIR_SET_SIZE
+  jp  _RAM_PAGE_1
 
-CheckPea:
+wormdead:
+  pop hl ;<<call
+  ld  a,2
+  ld  (flashtime),a
+#ifdef w00t
+  ld  h,201
+ .org $-2
+  nop
+ .org $+1
+#endif
+  ld  (ix+wdelay),rspawndelay
+
+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
+
+  ld  a,(handledworm) ;who are we? (1-4)
+  cpl ;invert (just bit 0 actually)
+  and 1 ;group 1 (1,3) or 0 (2,4)
+  ld  (ix+reserv),a ;reset halflap|flags to starting settings
+
+  inc (ix+died)
+  dec (ix+lives)
+  psh af
+  ld  a,(gamecar)
+  and _datadecs ;ctf and race no death penalty
+  cal nz,DecScore10
+  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
+
+loadtxtgame: ;in:d=0; out:hl=txtGame+(gametype); destr:ade
+  ld  a,(gametype)
+  ld  e,a
+  ld  hl,posGame
+  add hl,de ;hl=posGame+(gametype)
+  ld  a,(hl) ;str.offset
+  ld  e,a ;^d=0^
+  ld  hl,txtGame
+  add hl,de ;txtGameX
+  ld  (CURtxtGame),hl ;save for g/o
+  ret
+
+CheckPea: ;@hl; destr:abcde
   ld  c,l
   ld  a,(sprsize)
   ld  e,a
@@ -2309,23 +3221,133 @@ chkloopx:
   cal FindPixel
   and (hl)
   pop hl
-  jr  nz,NewPea ;pixel found
+  ret nz ;nz=pixel found
   inc b
   dec d
   jr  nz,chkloopx
   inc c
   dec e
   jr  nz,chkloopy
-;all ok; empty space
+  ret ;z=empty space
+
+tryDrawPea: ;hl=peapos;bc=dopea
+  ld  a,(de)
+  or  a ;0=drawn
+  ret z
+  psh de
+  cal CheckPea
+  pop de
+  ret nz ;unsuccesful
+  ex  de,hl
+  dec (hl) ;hl=appeartime
+  ex  de,hl ;hl=peaspos
+  jr  z,DrawPea
+  ret
+
+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
+  ld  a,-1
+  ret
+
+NewPea:
+  ld  de,$293A ;counter :)
+newpealoop:
+  dec de
+  ld  a,d
+  or  e
+  jp  z,Exit ;break after 10554 tries to prevent freeze when field filled
+  ld  a,(FieldWidth)
+  add a,126
+  cal randompos
+  ld  h,a
+  ld  a,(FieldHeight)
+  add a,55
+  cal randompos
+  ld  l,a
+  psh de
+  cal CheckPea
+  pop de ;counter
+  jr  nz,newpealoop
+  cal sendnewpeaoverlink
+  ld  (PeaY),hl
+DrawPea: ;hl=(PeaY)
+  ld  b,h
+  ld  c,l
+drawpea_:
+  ld  de,0
+spritepos =$-2
+; jp PutSprite
+
+PutSprite:  ;||@(b,c)
+  ;by SHIAR  only ix saved
+  cal FindPixel
+  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
 
-DrawPea: ;hl=(PeaY)
-  ld  b,h
-  ld  c,l
-  ld  de,0
-spritepos =$-2
-  jp  PutSprite ;||-ed
+;_______________________________________________________________________________
+; _______ _______  _____   ______ _______
+; |______ |       |     | |_____/ |______
+; ______| |_____  |_____| |    \_ |______
+;_______________________________________________________________________________
 
-;----------- score -----------
+addteamscore:
+  ld  a,(handledworm)
+  cp  2
+  ld  de,worm3-worm1
+  jr  c,bla
+  ld  de,worm1-worm3
+bla:
+  psh ix
+  add ix,de
+  ex  de,hl
+  cal ldscoreinhl
+  pop ix
+  add hl,de
+  ret
 
 _divHLby1000:
   psh hl
@@ -2337,78 +3359,162 @@ divideagain: ;3x
   pop hl
   ret
 
-IncScore:
-  ld  h,(ix+score+1)
-  ld  l,(ix+score)
+DecScore10:
+  cal ldscoreinhl
+  ld  de,-10
+  add hl,de
+  jr  nc,showstats ;<0=0
+  jr  scorecommon
+
+extralives:
   cal _divHLby1000
   ld  c,a
-  add hl,de
+  add hl,de ;increase score
   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
-  jr  c,showstats ;<0=0
+
+timematchscore:
+  ;piece of crap checking whether you've already won in timematch
+  ld  a,(nrworms)
+  ld  b,a ;# of worms
+  dec a
+  ret z ;singleplayer
+  ld  hl,worm1+lives
+  ld  de,worm2-worm1
+  ld  a,(handledworm)
+  ld  c,a ;wormcounter
+chktimematchover:
+  xor a
+  cp  c
+  jr  z,nneexxtt ;yourself
+  cp  (hl)
+  ret nz ;someone else still alive
+  dec hl ;+del0ay
+  dec hl ;+score+1
+  ld  a,(hl)
+  cp  (ix+score+1)
+  jr  c,nneexxtt_ ;you>him
+  ret nz ;not highest
+  dec hl ;+score
+  ld  a,(hl)
+  cp  (ix+score)
+  ret nc ;you<=him
+  inc hl
+nneexxtt_:
+  inc hl
+  inc hl
+nneexxtt:
+  dec c
+  add hl,de
+  dnz chktimematchover
+  jp  anyworm ;g/o
+
+IncScore: ;inc score by e
+  ld  d,0
+_IncScore ; inc by de
+  cal ldscoreinhl
+  ld  a,(gametype)
+  or  a ;if singleplayer...
+  jr  z,extralives
+  add hl,de ;score+=de
 scorecommon:
   ld  (ix+score+1),h
-  ld  (ix+score),l
+  ld  (ix+score),l ;save
+doteam:
+  cal addteamscore ;cal=CD | ld de,*=11
   ld  de,0
 scorelimit =$-2
-  inc e
-  jr  z,showstats ;de=$FF??=no limit
-  dec e
+  ld  a,d
+  or  e
+  jr  z,showstats ;de=0=no limit
   cal _cphlde
   jp  nc,Exit
 
 showstats:
-  ld  a,(Gametype)
-  cp  gametron
-  ret z
-showstatsEven4tron:
+  ld  a,(gamecar)
+  and _datatime
+  jr  nz,timematchscore ;no disp for timematches
+forceshowstats:
   psh ix
-  ld  h,0
-  ld  l,h
+  and a
+  sbc hl,hl ;hl=0
   ld  (_penCol),hl
   ld  a,(nrworms)
   ld  b,a
   ld  ix,worm1
-  ld  a,(gameCar)
-  and _datanextl
+  ld  a,(gamecar)
+  and _datasingl
   jr  nz,showstatsS
 showstatloop:
+#ifdef gamenames
+#ifdef longnames
   psh bc
-  cal showstat
-  ld  de,worm2-worm1
-  add ix,de
-  ld  hl,_penCol
-  ld  a,(hl)
-  add a,10
-  ld  (hl),a
+  ld  b,3
+  psh ix
+shownameloop: ;1st 3 chars
+  ld  a,(ix+name)
+  or  a
+  jr  z,nameshown
+  cal __vputmap
+  inc ix
+  dnz shownameloop
+nameshown:
+  ld  a,':'
+  cal _vputmap
+  pop ix
   pop bc
+#else
+  ld  a,(ix+name)
+  cal __vputmap
+  ld  a,':'
+  cal __vputmap
+#endif
+#endif
+  ld  a,(wormbeglives)
+  or  a
+  cal nz,showlives ;lives when initlives>0
+  ld  a,' '
+  cal __vputmap ;small div
+  ld  a,(gametype)
+  cp  gamedeathm
+  cal nz,showscore ;score in !dm
+  ld  a,$D8
+  cal __vputmap ;div
+
+  ld  de,worm2-worm1
+  add ix,de ;next
   dnz showstatloop
   pop ix
   ret
 
-showstat:
-  ld  a,(gameCar)
-  and _datascore
-  jr  z,showlives
 showscore:
-  ld  h,(ix+score+1)
-  ld  l,(ix+score)
+  cal ldscoreinhl
+  psh bc
   cal _D_HL_DECI
-  jr __vputs
-showlives:
-  ld  a,(Gametype)
-  cp  gametron
-  jr  z,showscore
+  pop bc
+  jr  __vputs
+
+cshowA: ;small w/ leading 0; 0='none'
+  or  a ;destr. ahl
+  jr  nz,cshowA00
+  ld  hl,txtNone
+  jp  _vputs
 
+showlives:
   ld  a,(ix+lives)
+cshowA00: ;small w/ leading 0
+  ld  l,a
+  ld  h,0
+  cal _divHLby10
+  psh af
+  ld  a,l
+  add a,'0'
+  cal __vputmap
+  pop af
+cshowA0:
   add a,'0'
 __vputmap:
   psh ix
@@ -2416,37 +3522,30 @@ __vputmap:
   pop ix
   ret
 
-showstatsS:
+showstatsS: ;(singleplayer)
   ld  hl,txtLevel
   cal __vputs
   ld  a,0
 Level =$-1
   cp  10
-  jr  c,tilllevel9
-  ld  l,a
-  ld  h,0
-  cal _divHLby10
   psh af
-  ld  a,l
-  add a,'0'
-  cal __vputmap
+  cal c,cshowA0
   pop af
-tilllevel9:
-  add a,'0'
-  cal __vputmap
+  cal nc,cshowA00
 
-  ld  a,98
+  ld  a,97
   ld  (_penCol),a
   cal showscore
   ld  a,123
   ld  (_penCol),a
-  cal showlives
-  ld  a,(gameCar)
+  ld  a,(ix+lives)
+  cal cshowA0 ;showlives
+  ld  a,(gamecar)
   and _datafoodl
   pop ix
   ret z
 showleft:
-  ld  a,31
+  ld  a,33
   ld  (_penCol),a
   ld  a,0
 Left =$-1
@@ -2463,7 +3562,7 @@ showLevel:
   ld  hl,txtLevel
   cal _puts
   ld  a,(Level)
-showA:
+showA0: ;big w/ leading 0
   ld  l,a
   ld  h,0
   cal _divHLby10
@@ -2475,41 +3574,32 @@ showA:
   add a,'0'
   jp  _putc
 
-cshowA:
-  ld  l,a
-  ld  h,0
-  cal _divHLby10
-  psh af
-  ld  a,l
-  add a,'0'
-  cal __vputmap
-  pop af
-  add a,'0'
-  jp  __vputmap
-
-showHL:
-  cal _D_HL_DECI
-  jp  _puts
-
 _D_HL_DECI:
-  ld  de,savestr+4
+  ld  de,savestr+5
   ld  b,5
 ldhld:
   cal _divHLby10
   add a,'0'
-  ld  (de),a
   dec de
+  ld  (de),a
   dnz ldhld
-  ld  hl,savestr
+  ex  de,hl ;ld hl,savestr
+  ret
+
+ldscoreinhl:
+  ld  h,(ix+score+1)
+  ld  l,(ix+score)
   ret
-savestr:
-  .db "00000",0
 
-;-----------------------------
+;_______________________________________________________________________________
+; ______  _____ _______  _____         _______ __   __
+; |     \   |   |______ |_____] |      |_____|   \_/
+; |_____/ __|__ ______| |       |_____ |     |    |
+;_______________________________________________________________________________
 
-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:
@@ -2518,13 +3608,7 @@ FieldHeight =$-1
   jr  c,NotMaxYScroll
   ld  a,(FieldHeight)
 NotMaxYScroll:
-  ld  l,a
-  ld  h,0
-  add hl,hl
-  add hl,hl
-  add hl,hl
-  add hl,hl
-  add hl,hl
+  cal ldhl32a
   psh bc                        ; >> 1
   psh de                        ; >> 2
   ld  de,ScrBuffer
@@ -2729,295 +3813,102 @@ ChunkRow:
   ld  c,$37 ;scf
   ret
 
-;----------- draw ------------
+;_______________________________________________________________________________
+; ______   ______ _______ _  _  _
+; |     \ |_____/ |_____| |  |  |
+; |_____/ |    \_ |     | |__|__|
+;_______________________________________________________________________________
 
-;--- pixel ---
+;--- pixel ---------------------------------------------------------------------
 
-chk4pixels: ;&&
+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  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
-  dec a ;4 = circle
-  cal z,drawcircle
-  dec a ;5 = hline
-#ifdef hlines
-  cal z,drawhline
-#else
-  cal z,drawline
-#endif
-
-  pop hl
-  inc hl
-  jr  drawstuff
-
-drawbox: ;(d,e)-(h,l)
-  ld  b,l ;Delta-y
-#ifdef hlines
-boxloop:
-  cal drawhline
-  inc e
-  dnz boxloop
-  ret
-drawhline: ;(d,e)-(h,e)
-  psh bc
-  ld  b,d
-  ld  c,e
-  psh hl
-  cal FindPixel
-  ld  c,a ;starting mask
-  ld  a,h
-  sub b
-  ld  b,a
-  inc b ;1+x2-x1
-hlineloop:
-  ld  a,(hl)
-  or  c
-  ld  (hl),a
-  rrc c ;mask >>
-  jr  nc,hlinenext
-  inc hl ;next byte
-hlinenext:
-  dnz hlineloop
-  pop hl
-  pop bc
-  ret
-#else
-  ld  l,e
-boxloop:
-  cal drawline
-  inc l
-  inc e
-  dnz boxloop
-  ret
-#endif
-
-drawfatline:
-  cal drawline
-  inc d
-  inc h
-  cal drawline
-  inc e
-  inc l
-  cal drawline
+  inc c
+  cal CheckPixel
+  dec b
+  cal CheckPixel
+  dec c
+  ret
+CheckPixel: ;at bc in d
+  cal FindPixel
+  and (hl)
+  ret z
   dec d
-  dec h
-  jp  drawline
+  ret
 
-;LINE (d,e)-(h,l)
-;destroyes a
+;--- findpixel -----------------------------------------------------------------
 
-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  b,d
-  ld  c,e
-  psh hl
+;Based on Snake86's findpixel
+;160-262 cycles; 31 bytes
+FindPixel: ;(b,c) to hl:a
   psh bc
-  cal FindPixel
-  pop bc
-  pop de
-connectedLine:
-  psh hl
-  ld  h,c
-  ld  c,a
-  ld  a,d
-  sub b
+  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=32y
+  rra       ;a=x/8
+  or  l
+  ld  l,a
+  ld  a,b   ;x
+  and 7
+  inc a
   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  h,a
-  xor a
-  sub b
-  add a,a
-  ld  (line1sm+1),a
-  ld  a,h
-  sub b
-  pop hl
-LineLoopGentle:
-  psh af
+  ld  a,1
+pixelloop:
+  rrca
+  dnz pixelloop
+  ld  bc,ScrBuffer
+  add hl,bc
+  pop bc ;destr:none
+  ret
+
+;--- objects -------------------------------------------------------------------
+
+drawstuff:
   ld  a,(hl)
-  or  c
-  ld  (hl),a
-  rrc c
-  jr  nc,$+3
   inc hl
-  pop af
-  jp  m,line2sm
-line1sm:
-  add a,0
-  add hl,de
-line2sm:
-  add a,0
-  dnz LineLoopGentle
-DoneLine:
-  ld  a,(hl)
-  or  c
-  ld  (hl),a
-  pop de
-  pop hl
-  pop bc
-  ret
-SteepLine:
-  ld  h,a
-  neg
-  add a,a
-  ld  (line3sm+1),a
-  ld  a,b
-  add a,a
-  ld  (line4sm+1),a
-  sub h
-  ld  b,h
+  or  a ;0 =
+  ret z ;no more
+
+  ld  d,(hl)
+  inc hl
+  ld  e,(hl)
+  inc hl
+  ld  b,(hl)
+  inc hl
+  psh hl
+  ld  l,(hl)
+  ld  h,b
+  cal drawsmtn
   pop hl
-LineLoopSteep:
-  psh af
-  ld  a,(hl)
-  or  c
-  ld  (hl),a
-  add hl,de
-  pop af
-  jp  m,line4sm
-line3sm:
-  add a,0
-  rrc c
-  jr  nc,$+3
   inc hl
-line4sm:
-  add a,0
-  dnz LineLoopSteep
-  jr  DoneLine
+  jr  drawstuff
+
+drawsmtn:
+  dec a ;1 = line
+  jr  z,drawline
+  dec a ;2 = fatline
+  jr  z,drawfatline
+  dec a ;3 = box
+  jr  z,drawbox
+; dec a ;4 = circle
+; jp  z,drawcircle
+
+;--- circle --------------------------------------------------------------------
+
+;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
@@ -3068,6 +3959,8 @@ circledraw:               ;destr:de
   psh hl
   ld  a,h              ;hl=x,y
   sub b                ;bc=xx,yy
+       jr  nc,$+3              ;x<xx
+       xor a                   ;left of screen -> x=0
   ld  d,a              ;d=x-xx
   add hl,bc            ;h=x+xx; l=y+yy
   ld  e,l              ;e=y+yy
@@ -3075,6 +3968,8 @@ circledraw:               ;destr:de
   ld  a,l
   sub c                ;a=y again
   sub c
+       jr  nc,$+3              ;y<yy
+       xor a                   ;above screen -> y=0
   ld  l,a              ;l=y-yy
   ld  e,l              ;e=l=y-yy
   cal drawline         ;(h-b,l-c)-(h+b,l-c)
@@ -3082,180 +3977,200 @@ circledraw:           ;destr:de
   ld  b,c
   ld  c,a              ;ex b,c
   pop hl
+  ret                  ;thats it
+
+;--- box -----------------------------------------------------------------------
+
+drawbox: ;(d,e)-(h,l)
+  ld  b,l ;Delta-y
+  ld  l,e
+boxloop:
+  cal drawline
+  inc l
+  inc e
+  dnz boxloop
   ret
 
+;--- fatline -------------------------------------------------------------------
+
+drawfatline:
+  cal drawline
+  inc d
+  inc h
+  cal drawline
+  inc e
+  inc l
+  cal drawline
+  dec d
+  dec h
+; jp  drawline
+
+;--- line ----------------------------------------------------------------------
 
+;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              ;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              ;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
+  ld  (line1sm+1),a    ;a=-deltax
+  rra
+  add a,h              ;a=deltay-deltax/2
+  pop hl               ;       :<hl
 
+linedrawxloop:
+  psh af               ;init z=2dy-dx
+  ld  a,(hl)
+  or  c                        ;|c:hl
+  ld  (hl),a
+  rrc c
+  jr  nc,$+3
+  inc hl               ;(x++,y)
+  pop af
+  jp  m,line2sm                ;z<0
+line1sm:
+  add a,0              ;z-=deltax
+  add hl,de            ;(x,y++)
+line2sm:
+  add a,0              ;z+=deltay
+  dnz linedrawxloop    ;|deltax| times
 
-;**** link routines ****
-;these are identical in concept to the routines used in ZTetris, ZPong, and probably
-;every other link game out there.  However, these are commented :)
-losses: .dw 0
-Csend:
-  ld  b,32
-csendwait:
-  nop
-  dnz csendwait
-  cal Qsend
-  jr  c,Csend
-  ret
-Qsend:
-send:
-;inputs: c=byte to send, both wires must be high by default
-;outputs: b=8-number of bits sent, both wires high, goes to game over on certain conditions
-;destroys: af,bc,de
-       in a,(7)
-       and %11
-       jr z,killlink           ;if both lines low, get out of here (game over signal)
-       ld b,8                          ;sending 8 bits
-sendloop:
-       ld de,$8000                     ;error timer
-       rl c                            ;force high bit into carry
-       ld a,%11010100          ;lower the red wire by default (sending 0) ($d4)
-       jr nc,selected          ;if high bit was 0, use above value
-       ld a,%11101000          ;if 1, lower the white wire instead ($e8)
-selected:
-       out (7),a                       ;put it out the link port
-waitconfirm:
-       call linktimer
-       in a,(7)                        ;see what the wires are doing
-       and %00000011           ;check lower 2 bits
-       jr nz,waitconfirm       ;if both bits 0, data was received ok (both wires low)
-       ld a,%11000000
-       out (7),a                       ;give the ok to raise both wires (one will be done automatically) ($c0)
-waitconfirm2:
-       call linktimer
-       in a,(7)
-       and %00000011
-       cp 3
-       jr nz,waitconfirm2      ;wait for other calc to raise the other wire
-       djnz sendloop           ;continue sending
-       xor a                           ;reset c; ld a,0
-       ld (losses),a           ;reset number of losses
-       ret
-
-
-Crecv:
-  cal receive
-  jr  c,Crecv
+DoneLine:
+  ld  a,(hl)
+  or  c                        ;|c:hl
+  ld  (hl),a           ;draw end
+  pop de
+  pop hl
+  pop bc
   ret
-Qrecv:
-receive:
-;inputs: both wires must be high by default
-;outputs: c=byte received, b=8-number of bits received, both wires high
-;      goes to game over on certain conditions
-;destroys: af,bc,de
-       in a,(7)
-       and %00000011
-       jr z,killlink           ;game over signal applies to receiving too
-       ld b,8                          ;receiving 8 bits
-receiveloop:
-       ld de,$8000                     ;error timer
-waitreceive:
-       call linktimer
-       in a,(7)
-       and %11
-       cp 3                            ;if bits 0 and 1 set, both wires are high
-       jr z,waitreceive        ;wait for one of the wires to go low
-       rra                                     ;check red wire status
-       rl c                            ;if set, red is high (thus white is low), so put the correct bit into c
-       rra                                     ;now check white wire (since the flags are destroyed)
-       ld a,%11010100          ;$d4
-       jr nc,selected2         ;if white is low, lower red and vice versa              
-       ld a,%11101000          ;$e8
-selected2:
-       out (7),a                       ;so now both wires are low
-waitreceive2:
-       call linktimer
-       in a,(7)
-       and %11
-       jr z,waitreceive2       ;wait for the wire we didn't lower to go high again (the other will remain low)
-       ld a,%11000000          ;$c0
-       out (7),a                       ;raise both wires since the other calc will have given the ok sign
-       djnz receiveloop        ;if not done, wait for next bit
-       xor a                           ;reset c
-       ld (losses),a           ;reset number of losses
-       ret
-
-linktimer:                             ;leave if we have to wait too long (and return an error)
-       dec de
-       ld a,d
-       or e                            ;see if de is 0
-       ret nz                          ;if not, keep going as usual
-                                               ;otherwise we have to deal with a link failure
-       ld a,%11000000          ;$c0
-       out (7),a                       ;reset link status (both high)
-       ld a,(losses)           ;see how many consecutive losses we have
-       inc a
-       ld (losses),a           ;add this loss to it
-       pop de                          ;fix the stack to leave the link routine (de is ok to destroy)
-       cp 20                           ;see if this is the 20th consecutive failure
-       ret c                           ;if not, keep playing
-                                               ;otherwise, all is probably lost...
-
-killlink2:
-       jr linkend
-killlink:
-linkend:
-  jp  z,Exit
-
-
-
-
-
-
-
-
-
-#ifdef 0
-;-----------------------------
-;----------- link ------------
-;-----------------------------
-
-timeout = $800
-
-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
+SteepLine:
+  ld  l,a
+  neg
+  ld  (line3sm+1),a    ;=-deltay
+  rra
+  ld  h,a              ;h=-deltay/2
+  ld  a,b
+  ld  (line4sm+1),a    ;=deltax
+  add a,h              ;a=deltax-deltay/2
+  ld  b,l              ;b=deltay
+  pop hl               ;       :<hl
+linedrawyloop:
+  psh af               ;init z=2dx-dy
+  ld  a,(hl)
+  or  c                        ;|c:hl
+  ld  (hl),a
+  add hl,de            ;(x,y++)
+  pop af
+  jp  m,line4sm                ;z<0
+line3sm:
+  add a,0              ;z-=deltay
+  rrc c
+  jr  nc,$+3
+  inc hl               ;(x++,y)
+line4sm:
+  add a,0              ;z+=deltax
+  dnz linedrawyloop    ;|deltay| times
+  jr  DoneLine
 
-  in  a,(7)
-  and %11
-  ret
 
-linkerror:
-  scf
-  ld  a,%11
-  pop hl
+;..and last but not least..:
+;_______________________________________________________________________________
+;        _____ __   _ _     _   /
+; |        |   | \  | |____/   /
+; |_____ __|__ |  \_| |    \_ .
+;_______________________________________________________________________________
+
+timeout = $8000
+lossout = 20
+
+;--- multiple bytes ------------------------------------------------------------
+
+sendstuff:
+  psh de
+sendstuffloop:
+  psh bc
+  ld  c,(hl)
+  inc hl
+  cal Qsend
+  pop bc
+  dnz sendstuffloop
+  pop de
+  ret
+recvstuff:
+  psh de
+recvstuffloop:
+  psh bc
+  cal Qrecv
+  ld  (hl),c
+  inc hl
+  pop bc
+  dnz recvstuffloop
+  pop de
   ret
 
-;--------------
-;---- SEND ----
-;--------------
+;--- foo -----------------------------------------------------------------------
 
-Csend:         ;--- send 8 bits in A --- destr:abcdehl ---
-  ld  c,a
-Csendloop:
+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,(worm1+wleft)
+  or  a
+  jr  z,receivenewpeaoverlink
+  ld  c,l ;send pea's pos
   cal Qsend
-  ret nc               ;NC = all ok
-  ld  a,D0HD1H
-  out (7),a            ;both high
-  jr  Csendloop        ;CF = error
+  ld  c,h
+; jr  Qsend ;that's why it's here
 
-Qsend:         ;--- try to send 8 bits in C; CF=error --- destr:abcdehl ---
-  ld  de,timeout
-  cal checklink
-  cp  %11              ;are they?
-  scf
-  ret nz               ;nope, wait
+;--- send ----------------------------------------------------------------------
+
+Qsend:         ;--- try to send 8 bits in C; CF=error --- destr:abcde ---
+  nop \ nop
+  cal linkfine
+  jr  z,linkerr                ;both wires low = exit signal
   ld  b,8              ;bits to send
 sendloop:
   ld  de,timeout
@@ -3268,42 +4183,35 @@ sendbit:
 sendwaitack:
   cal checklink                ;other calc must lower other wire
   jr  nz,sendwaitack
-  ld  a,D0HD1H         ;raise one, ok to raise other
-  out (7),a
+  cal linkok           ;raise one, ok to raise other (out (7),D0HD1H)
 sendfinish:
   cal checklink
   cp  %11              ;both raised (by other calc)
   jr  nz,sendfinish
-  nop \ nop
+; nop \ nop
   dnz sendloop         ;repeat for all bits
   xor a                        ;nc...
+  ld (linklosses),a    ;reset number of losses
   ret                  ;=ok
 
-;--------------
-;---- RECV ----
-;--------------
+;--- 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
-  ld  a,D0HD1H
-  out (7),a            ;raise both on error
   jr  Crecv            ;and try again
 
-Qrecv:         ;--- receive 8 bits into A/C; CF=error --- destr:abcdehl ---
-  ld  de,timeout
-  cal checklink
-  jp  z,Exit           ;both low = error, quit
-  cp  %11
-  scf
-  ret z                        ;both high = nothing yet, wait
+Qrecv:         ;--- receive 8 bits into A/C; CF=error --- destr:abCde ---
+  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
@@ -3314,243 +4222,327 @@ received:
 recvwaitack:
   cal checklink
   jr  z,recvwaitack    ;same wire will be raised again by other calc
-  ld  a,D0HD1H
-  out (7),a            ;raise both
+  cal linkok           ;raise both
 recvfinish:
   dnz recvloop         ;repeat for all bits
   xor a                        ;nc=no error
-  ld  a,c              ;result in a
+  ld (linklosses),a    ;reset number of losses
+  ret
+
+;--- common --------------------------------------------------------------------
+
+linkok:
+  ld  a,D0HD1H
+  out (7),a            ;raise both wires = link ok
   ret
-#endif
 
-;-----------------------------
-;---------- levels -----------
-;-----------------------------
+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
+  jr  z,linkerr                ;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
+;_______________________________________________________________________________
+; _____ __   _ _______              _______ _    _ _______        _______
+;   |   | \  |    |          |      |______  \  /  |______ |      |______
+; __|__ |  \_|    |    _____ |_____ |______   \/   |______ |_____ ______|
+;_______________________________________________________________________________
 
 LevelDef:
   .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                ;no additional lines, boxes
-  .db 255
-   ret
+
+  .db 255              ;last level
+   ret                 ;ending code
 
 LevelDefM:
-  .db 8,4,15,15,0,0
+  .db "Empty Arena",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 8,0,18,12,5
+  .db "Fast Fun :))",0
+  .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
   .db 0
 
+  .db "Two Circles",0
   .db 8,5,18,12,0,0
   .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
   .db 128,57
- .db 4,40,26,20,0
- .db 4,90,40,11,0,0
 .db 4,40,26,20,0
 .db 4,90,40,11,0,0
 
 LevelDefT: ;tron=no delay
+  .db "Empty Tron Level",0
   .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
 
+LevelDefR: ;race
+  .db "Round and Round",0
+  .db 8,4,18,12,5
+  .db %1110000,%10001000,%10001000,%10001000,%1110000,0
+  .db $40,23,2,$C0,23,125, $40,35,2,$C0,35,125
+  .db 128,57
+  .db 63,27
+  .db 4,63,27,10,0,0
+
 LevelDefC: ;ctf
+  .db "Default CTF",0
   .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 $40,23,2,$C0,23,125, $40,35,2,$C0,35,125
   .db 128,57
-  .db 10,10,50,50
+  .db 27,8,27,116
   .db 0
 
-;-----------------------------
-;---------- data -------------
-;-----------------------------
-
-wdPicture = 16
-wtPicture:
-.db %00000000,%00000000,%00000111,%10000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01110000,%00000000,%00000000,%00000000,%00000000,%00000000
-.db %00000000,%00000000,%00001111,%10000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111000,%00000000,%00000000,%00000110,%01111011,%00100000
-.db %00000000,%00000000,%00011100,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00011100,%00001110,%00000000,%00001001,%00010011,%01000000
-.db %00000000,%00000000,%00011000,%00011111,%00000000,%01111111,%11000000,%00111100,%00011110,%01111000,%00001100,%00011111,%00000000,%10100111,%00110000,%10000000
-.db %00000000,%00000000,%00111000,%00111111,%10000000,%11111111,%11100000,%11111110,%00111111,%11111100,%00001100,%00111011,%00000000,%10100001,%00001001,%01100000
-.db %00000000,%00000000,%00110000,%01110001,%11000001,%11000000,%01110001,%11100110,%01110011,%11001110,%00001100,%00110001,%10000000,%01001110,%01110010,%01100000
-.db %00000000,%00000000,%00110000,%01100000,%11000001,%10000000,%00111001,%10000000,%01100111,%11100110,%00001110,%01110001,%10000000,%00000000,%00000000,%00000000
-.db %00000000,%00000000,%00110000,%01100000,%11000001,%10110000,%00011011,%10000000,%11101110,%01110111,%00001110,%01110001,%10000000,%00000000,%00000000,%00000000
-.db %00000000,%00000000,%00110000,%01110001,%11000001,%10110000,%00011011,%00000000,%11001100,%00110011,%00000111,%11100001,%10000000,%00000000,%00000000,%00000000
-.db %00000000,%00000000,%00110000,%00110001,%10000001,%10110000,%00011011,%00000000,%11001100,%00110011,%00000011,%11000011,%10000000,%00000000,%00000000,%00000000
-.db %00000000,%00000000,%00111000,%00111011,%10000011,%10110000,%00011011,%00000000,%11001110,%01110011,%00000000,%00000011,%00110101,%01001001,%10000000,%00000000
-.db %00000000,%00000000,%00011000,%00011111,%00000011,%00110000,%00011011,%00000000,%11000111,%11100011,%10000000,%00000011,%01000101,%00010101,%01000011,%01100011
-.db %00000000,%00000000,%00011100,%00001110,%00000111,%00111000,%00111011,%10000000,%11000011,%11000001,%10000000,%00000111,%01100101,%01010101,%01000101,%01010100
-.db %00000000,%00000000,%00001110,%00111111,%10001110,%00011100,%01110001,%10000000,%11100000,%00000001,%11100000,%00001110,%00110111,%01011101,%10010101,%01100101
-.db %00000000,%00000000,%00000111,%11111011,%11111100,%00001111,%11100001,%11000000,%01100000,%00000000,%11111111,%11111100,%00010101,%01010101,%01000101,%01010101
-.db %00000000,%00000000,%00000011,%11100000,%11111000,%00000111,%11000000,%11000000,%01100000,%00000000,%00111111,%11111000,%01100101,%01010101,%01000110,%01010011
-
-txtMenu:  .db "Mode",0  ;1st menu item
-         .db "Level",0 ;2nd
-         .db "Limit",0 ;...
-         .db "Worms",0
-         .db "worm #",0
-         .db "controls",0
-posMenu:  .dw $$2418,$231E,$2524,$1F2A,$1730,$1936
-txtGame:  .db "Singleplayer",0
-txtGame1: .db "Peaworm",0
-txtGame2: .db "Tron",0
-txtGame3: .db "Deathmatch",0
-txtGame4: .db "Foodmatch",0
-txtGame5: .db "LinkMatch",0
-txtGame6: .db "Race",0
-txtGame7: .db "CTF",0
-;            .db "Domination",0    ;8
-posGame:  .db 0,txtGame1-txtGame
-         .db txtGame2-txtGame
-         .db txtGame3-txtGame
-         .db txtGame4-txtGame
-         .db txtGame5-txtGame
-         .db txtGame6-txtGame
-         .db txtGame7-txtGame
-
-txtKeyleft: .db "Left",0
-txtKeyright:.db " | Right",0
-txtLevsel:  .db $CF," Select levels: ",5,0
-txtEName:   .db "Enter name player ",0
-txtWaiting: .db "Waiting...",0
-txtReceive: .db "Receiving..." ;,0
-
-TrigPrecalc:
-.db   0,  3,  6,  9, 12, 15, 18, 21
-.db  24, 27, 30, 33, 36, 39, 42, 45
-.db  48, 51, 54, 57, 59, 62, 65, 67
-.db  70, 73, 75, 78, 80, 82, 85, 87
-.db  89, 91, 94, 96, 98,100,102,103
-.db 105,107,108,110,112,113,114,116
-.db 117,118,119,120,121,122,123,123
-.db 124,125,125,126,126,126,126,126
-.db 127
-
-txtLevel:  .db "Level ",0
-txtWorms:  .db "Worms: 0",0    ;follows txtLevel
-txtName:   .db "Name",0
-txtDied:   .db "Died    "      ;follows txtName
-txtScore:  .db "Score",0       ;follows txtDied
-txtLeft:   .db " left",0       ;follows txtScore
-txthiscore:.db "HiScore:",0
-txtReady:  .db "Prepare!",0
-txtposReady = 7
+#endif
+
+;_______________________________________________________________________________
+; ______  _______ _______ _______
+; |     \ |_____|    |    |_____|
+; |_____/ |     |    |    |     |
+;_______________________________________________________________________________
+
+;--- graphics ------------------------------------------------------------------
+
+wtPicture: ;title
+;             %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,
+.db %00011110,                                                            %00000001,%11000000,%00000000,%00000000,%00000001,%10000000,%00000000,%00001111,%10000000
+.db %00111110,                                                            %00000001,%11100000,%00000000,%00000011,%11000010,%01000011,%10011100,%00110000,%01100000
+.db %01110000,                                                            %00000000,%01110000,%00111000,%00001100,%00110001,%00110100,%01100011,%01000000,%00010000
+.db %01100000,%01111100,%00000001,%11111111,%00000000,%11110000,%01111001,%11100000,%00110000,%01111100,%00010001,%11001001,%00001000,%00100000,%10000010,%00010000
+.db %11100000,%11111110,%00000011,%11111111,%10000011,%11111000,%11111111,%11110000,%00110000,%11101100,%00010001,%11000100,%10000001,%00000100,%10001110,%00001000
+.db %11000001,%11000111,%00000111,%00000001,%11000111,%10011001,%11001111,%00111000,%00110000,%11000110,%00001100,%00000010,%01100010,%10011100,%00010001,%00001000
+.db %11000001,%10000011,%00000110,%00000000,%11100110,%00000001,%10011111,%10011000,%00111001,%11000110,%00000011,%11000010,%00011100,%01100010,%00100001,%01101000
+.db %11000001,%10000011,%00000110,%11000000,%01101110,%00000011,%10111001,%11011100,%00111001,%11000110,%01111000,%00100001,%00000000,%00000001,%11000001,%01101000
+.db %11000001,%11000111,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100,%00011111,%10000110,%10000101,%11100001,%00000000,%00000000,%00000001,%00010000
+.db %11000000,%11000110,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100,%00001111,%00001110,%10010110,%00010001,%00000000,%00000000,%00000000,%11100000
+.db %11100000,%11101110,%00001110,%11000000,%01101100,%00000011,%00111001,%11001100,%00000000,%00001100,%01100100,%00001001,%00111111,%11111111,%11000000,%00000000
+.db %01100000,%01111100,%00001100,%11000000,%01101100,%00000011,%00011111,%10001110,%00000000,%00001100,%01000000,%10000001,%01000000,%00000000,%00000000,%00000000
+.db %01110000,%00111000,%00011100,%11100000,%11101110,%00000011,%00001111,%00000110,%00000000,%00011100,%01000000,%11000001,%01100101,%01001001,%10000011,%01100011
+.db %00111000,%11111110,%00111000,%01110001,%11000110,%00000011,%10000000,%00000111,%10000000,%00111000,%01000001,%00100001,%00110101,%00010101,%01000101,%01010100
+.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
+
+#ifdef coolzgfx
+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
+.db %00100000,%00000000,%00001110,%00110010,%00011001,%10011011,%01101010,%11100000,%00110011,%01101101,%11000111,%10000001,%00011100,%00000000,%00000000,%00001100
+.db %01001100,%00011000,%00000000,%00000100,%00011000,%11011111,%01100010,%11001100,%00110011,%01101101,%10000111,%11000001,%00011100,%00111000,%00011000,%10000010
+.db %01010010,%00100100,%01100000,%00011000,%00011111,%11011011,%11101110,%11111100,%00011111,%01111000,%11110110,%11100000,%11000000,%11000110,%00101001,%10000010
+.db %01100001,%11000011,%10011111,%11100000,%00001111,%10001001,%11001100,%01111000,%00001110,%00110000,%01100110,%01100000,%00111111,%00000001,%11000110,%01111100
+;.db %00000000,%00000001,%10000000,%00000000,%00001111,%10000000
+#else
 txtGO:     .db 5,5,5,5,5," GAME OVER ",$CF,$CF,$CF,$CF,$CF,0
+#endif
 
-_datalink  = %00000001 ;linkplay
-_datalivel = %00000010 ;lives=0 limit
-_datafoodl = %00000100 ;left=0 limit
-_datanextl = %00001000 ;next level if left=0
-_datasingl = %00001000 ;singleplayer=1
-                       ;1=hiscore+keep_length
-_datafood  = %00010000 ;food present
-_datadie   = %01000000 ;worm dies on impact
-_datascore = %10000000 ;score>=100 limit
-_datamultpeas = %00100000
-_datasp    = %01011110
-
-datalevels: .dw LevelDef, LevelDefM
-            .dw LevelDefT,LevelDefM
-            .dw LevelDefM,LevelDefM
-            .dw LevelDefM,LevelDefC
-nrlevels:   .db 1,3,1,3,3,3,3,1     ;=defaults
-
-savestart:
-
-gamesingle   =  0
-datasingle: .db %01011110,3,1,1 ;3 lives (<must b unique)
-gamepeas     =  1
-datapeas:   .db %01011010,1,1,1 ;1 "
-gametron     =  2
-datatron:   .db %01000010,1,1,1
-gamedeathm   =  3
-datadeathm: .db %01000010,3,2,1
-gamefoodm    =  4
-datafoodm:  .db %11010000,10,2,1 ;10 score limit (=100)
-gamelinkm    =  5
-datalinkm:  .db %01000011,3,2,1
-gamerace     =  6
-datarace:   .db %10000000,10,2,1
-gamectf      =  7
-datactf:    .db %11100000,9,4,1
-;gamedomin    =  8
-;datadomin:  .db %01100000,3 ;==(8 modes)
-
-worm1set:  .dw worm1p,worm1p
-           .db %11110111,%00,-01,K_RIGHT,K_LEFT
-worm1name: .db "Wormy   ",0
-worm2set:  .dw worm2p,worm2p
-           .db %11111011,%11,-01,K_F2,K_F1
-worm2name: .db "Viper   ",0
-worm3set:  .dw worm3p,worm3p
-           .db %11111011,%00,-01,K_COMMA,K_STO
-worm3name: .db "Nibbler ",0
-worm4set:  .dw worm4p,worm4p
-           .db %11111011,%00,-01,K_PLUS,K_ENTER
-worm4name: .db "Jim     ",0
+;--- menus ---------------------------------------------------------------------
+
+txtMenu:   .db                  "Mode",0 ;1st menu item
+          .db                 "Level",0 ;2nd
+          .db                  "Link",0 ;...
+          .db                 "Worms",0
+          .db                "worm #",0
+posMenu:   .db 5
+          .dw $2418,$231E,$2824,$1F2A,$1730
+txtteamed: .db                 " vs 2",0 ;4th tail
+txtMenuR:  .db              "controls",0 ;6th
+
+txtoMenu:  .db                  "Back",0 ;1st menu item
+          .db                 "Lives",0 ;2nd
+          .db                 "Limit",0 ;...
+          .db                 "Speed",0
+          .db              "Rotation",0
+          .db                "Growth",0
+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
+
+;--- text ----------------------------------------------------------------------
+
+txtGame:   .db          "Singleplayer",0
+txtGame1:  .db               "Peaworm",0
+txtGame2:  .db                  "Tron",0
+txtGame3:  .db            "Deathmatch",0
+txtGame4:  .db             "Foodmatch",0
+txtGame5:  .db        "Multifoodmatch",0
+txtGame6:  .db             "Timematch",0
+txtGame7:  .db                  "Race",0
+txtGame8:  .db                  "CTF";,0
+posGame:   .db                         0
+          .db          txtGame1-txtGame
+          .db          txtGame2-txtGame
+          .db          txtGame3-txtGame
+          .db          txtGame4-txtGame
+          .db          txtGame5-txtGame
+          .db          txtGame6-txtGame
+          .db          txtGame7-txtGame
+          .db          txtGame8-txtGame
+
+txtNone:   .db                  "None",0
+txtDef:    .db               "Default",0
+txtYes:    .db                   "Yes",0
+txtNo:     .db                    "No",0
+txtKleft:  .db                 ":left",0
+txtKright: .db                 "right",0
+posLevsel   =  $0320
+txtLevsel: .db $CF," SELECT LEVELS ",5,0
+txtWaitn:  .db         "Waiting";"...",0
+txtReceiv: .db                   "...",0
 
+#ifdef readytext
+txtReady:  .db              "Prepare!",0
+txtposReady =  7
+#endif
+txtLevel:  .db                "Level ",0
+txtWorms:  .db              "Worms: 0",0 ;follows txtLevel
+txtName:   .db                  "Name",0
+txtWinner: .db                "Wins",$D8 ;follows txtName
+txtDied:   .db                "Died",$D8 ;follows txtWinner
+txtScore:  .db                 "Score",0 ;follows txtDied
+txtLeft:   .db                 " left",0 ;follows txtScore
+txthiscore:.db             "HiScore:";,0
+
+;--- foo -----------------------------------------------------------------------
+
+trigtable: .db    0,  3,  6,  9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45
+           .db   48, 51, 54, 57, 59, 62, 65, 67, 70, 73, 75, 78, 80, 82, 85, 87
+           .db   89, 91, 94, 96, 98,100,102,103,105,107,108,110,112,113,114,116
+           .db  117,118,119,120,121,122,123,123,124,125,125,126,126,126,126,126
+           .db                                                              127
+
+#ifdef intlevels
+datalevels:.dw  LevelDef,LevelDefM,LevelDefT,LevelDefM,LevelDefM
+           .dw           LevelDefM,LevelDefM,LevelDefR,LevelDefC
+nrlevels:  .db                               2,3,1,3,3,3,3,3,1,0
 defhiscrpos:
-  .dw 0,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|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 "Internal Levels" ;,0
-
-  .db 0,deflevels/256,deflevels&255
+           .db 0,0,"SHI",0,0,"SHI",0,0,"SHI",0,0,"SHI",0,0,"SHI"
+#else
+defhiscrpos =  -42
+#endif
+
+;--- game settings -------------------------------------------------------------
+
+savestart:;---
+
+worm1set:  .dw worm1p
+           .db  %11110111,1,K_RIGHT,K_LEFT
+worm1name: .db   "WORMY   ",0 ;15 bytes
+worm2set:  .dw worm2p
+           .db  %11111011,0,K_F2,K_F1
+worm2name: .db   "VIPER   ",0
+worm3set:  .dw worm3p
+           .db  %11111011,1,K_COMMA,K_STO
+worm3name: .db   "NIBBLER ",0
+worm4set:  .dw worm4p
+           .db  %11111101,0,K_PLUS,K_ENTER
+worm4name: .db   "JIM     ",0
+
+_datalink   =  %00000001 ;linkplay (1!)
+_datafoodl  =  %00000010 ;left=0 limit
+_datasingl  =  %00000100 ;singleplayer=1 (=hiscore+keep_length+nextlevel)
+_dataPctf   =  %00001000 ;ctf peas=1
+__bitPctf   =  3
+_datatime   =  %00010000 ;time incs score (timematch)
+_datadecs   =  %00100000 ;decrease score on death=1
+_datafood   =  %01000000 ;food present=0 (6!)
+_dataPmult  =  %10000000 ;multiple peas=1 (no _datafood) (7!)
+
+         ;            �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 %00100110,3,1,1,-1,-1, 8, 0 ;Singleplayer (SP; 3 lives)
+gamepeas    =  1
+datapeas:  .db %00100100,1,1,1,-1,126,8, 0 ;Peaworm (SP; 1 live, 127 growth)
+gametron    =  2
+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,42, 8, 0 ;Deathmatch (3 lives, 50 growth)
+gamefoodm   =  4
+datafoodm: .db %00100000,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 (1 live, cont.growth)
+gamerace    =  7
+datarace:  .db %01000000,0,2,1,-1,-1, 8,10 ;Race (100 score)
+gamectf     =  8
+datactf:   .db %01001000,0,6,1,-1,-1, 8,10 ;CTF (100 score)
+
+gametype:  .db 0 ;last gamemode
+gamecar:         ;made before needed (not saved)
+
+saveend:;---
+
+startdelay  =  42
+rspawndelay =  31
+maxnamesize =  8+1
+
+#ifdef intlevels
+           .db $42 ;gamecar
+defsprsz    =  4
+defspr:    .db %01100000
+           .db %11110000
+           .db %11110000
+           .db %01100000
+
+deflevels: .db "Internal Levels",0
+           .db       "by Shiar";,0
+
+           .db 0,deflevels/256,deflevels&255
+#endif
 templevels:
 
-;-----------------------------
-;----------- end -------------
-;-----------------------------
+;_______________________________________________________________________________
+; _______ _     _ _______ _______ . _______       _______
+;    |    |_____| |_____|    |    ' |______       |_____| |      |
+;    |    |     | |     |    |      ______| _____ |     | |_____ |_____
+;_______________________________________________________________________________
 
   .end