shiar: multiplayer, menu
authorMischa Poslawsky <wormy@shiar.org>
Fri, 3 Dec 1999 14:27:32 +0000 (15:27 +0100)
committerMischa Poslawsky <wormy@shiar.org>
Sun, 22 Feb 2009 11:31:58 +0000 (12:31 +0100)
- multiplayer upto *four* players, deathmatch and foodmatch
- menu before game
- initial work on link play

trigtab.asm [deleted file]
worm.asm

diff --git a/trigtab.asm b/trigtab.asm
deleted file mode 100644 (file)
index f3807f1..0000000
+++ /dev/null
@@ -1,10 +0,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
index 33c8038c154f01e023f7350cc8f1a9781cd20321..b71663dbd40a0f6ed0b186d9b94a63352997150e 100644 (file)
--- a/worm.asm
+++ b/worm.asm
@@ -1,26 +1,49 @@
 ; -WonderWorm--v0.9-
-; by Matthew Shepcar
-; 30th December 1998
+; by Matthew Shepcar 30.XII.98
+; modified by Jonah Cohen 19.XI .99
+;               and Shiar 01.XII.99
 
-; modified by Jonah Cohen 11-19-99
+;to-do:
+; * picks not correctly removed
+; * linkplay
+; * hot pursuit + ctf
+; * ending (+stats after multiplayer)
 
 #include "TI86.inc"
 
+
 .org _asm_exec_ram
 
+_divHLby10     = $4044
+_getcsc        = _getky
+_clrWindow     = $4a86
+_runIndicOff   = _runindicoff
+_flushAllMenus = _flushallmenus
+_SHRACC        = _shracc
+_SHLACC        = $438B
+
   nop
   jp Start
   .dw 0,WormMsg
+
 Start:
-  ld (SpSave),sp
+; ld (SpSave),sp
   call _runIndicOff
   call _flushAllMenus
   call _clrLCD
 
-;build trig tables
+  ld  a,r
+  ld  (Seed),a
+  xor a
+  ld  (_asapvar+1),a
+
+;-----------------------------
+;----- build trig tables -----
+;-----------------------------
+
   ld hl,TrigPrecalc
   ld de,SinCosTable
-  push de
+  push de                        ; >> 1
   ld bc,65
   ldir
   dec hl
@@ -31,7 +54,7 @@ MirrorSineWave:
   ld (de),a
   inc de
   djnz MirrorSineWave
-  pop hl
+  pop hl                         ; << 0k
   ld b,128+64
 NegativeSineWave:
   xor a
@@ -41,122 +64,272 @@ NegativeSineWave:
   inc de
   djnz NegativeSineWave
 
-  ld a,r
-  ld (Seed),a
+;-----------------------------
+;---------- menu -------------
+;-----------------------------
 
-  ld hl,0
-  ld (Score),hl
-  ld a,1
-  ld (Level),a
-  ld a,3
-  ld (Lives),a
-  ld hl,Levels
+DisplayMenu:
+  call _clrLCD
+  ld  hl,txtWelcome
+  call _puts
+  ld  hl,txtMenu
+  ld  de,$0203
+  ld  b,4
+DispMenuLoop:
+  inc de
+  ld  (_curRow),de
+  call _puts
+  djnz DispMenuLoop
+
+  ld  hl,$0805
+  ld  (_curRow),hl
+  ld  hl,txtGame
+  call _puts
+
+  xor a
+menudraw:
+  and 3        ;-1>>3; 4>>0
+  push af
+
+  ld  h,0
+  add a,4
+  ld  l,a
+  ld  (_curRow),hl
+  ld  a,5 ;arrow
+  call _putc
+
+  ld  h,0
+  ld  a,1
+Previous =$-1
+  add a,4
+  ld  l,a
+  ld  (_curRow),hl
+  ld  a,' '
+  call _putc
+
+  pop af
+  push af
+  ld  (Previous),a
+WKCP:
+  halt \ halt
+  call GET_KEY
+  cp  K_EXIT
+  jp  z,Exit
+  cp  K_ENTER
+  jr  z,select
+  cp  K_SECOND
+  jr  z,select
+  cp  K_UP
+  jr  nz,notup
+  pop af
+  dec a
+  jr  menudraw
+notup:
+  cp  K_DOWN
+  jr  nz,WKCP
+  pop af
+  inc a
+  jr  menudraw
+
+select:
+  pop af
+  ld  b,a
+  or  a ;1st
+  jr  z,ThePartyIsOn
+  dec a ;2nd
+  jr  z,Variation
+  dec a ;3rd
+  jp  Exit
+
+Variation:
+  ld  hl,$0805
+  ld  (_curRow),hl
+  ld  a,0
+Gametype =$-1
+  ld  hl,txtGame2
+NEXTtxtGame =$-2
+  inc a
+  and 3
+  jr  nz,okilydokily
+  ld  hl,txtGame
+okilydokily:
+  ld  (Gametype),a
+  call _puts
+  ld  (NEXTtxtGame),hl
+  ld  a,b
+  jr  menudraw
+
+singleplayer:
+  inc a
+  ld  (nrworms),a
+  ld  de,LevelsS
+  jr  GameOver
+
+ThePartyIsOn:
+  ld  a,(Gametype)
+  or  a
+  jr  z,singleplayer
+  ld  a,2
+  ld  (nrworms),a
+  ld  de,LevelsDM
+
+;-----------------------------
+;--------- game over ---------
+;-----------------------------
+
+GameOver:
+  push de
+  call _clrLCD
+  pop de
+  ld  a,1
+  ld  (Level),a
+  ld  hl,0
+  ld  (worm1+score),hl
+  ld  (worm2+score),hl
+  ld  a,3
+  ld  (worm1+lives),a
+  ld  (worm2+lives),a
 
 StartLevel:
-  ld a,(hl)
-  ld (Left),a
-  inc hl
-  ld a,(hl)
-  ld (Speed),a
-  inc hl
-  ld a,25
+  ld  a,(de)
+  ld  (Left),a
+  inc de
+  ld  a,(de)
+  ld  (Speed),a
+  inc de
+  ld  a,15
+  ld  (worm1+grow),a
+  ld  (worm2+grow),a
 NextLife:
-  ld (GrowAmt),a
-  push hl
-  ld d,(hl)
+  push de                        ; >> levelp old
+  ld  b,2
+  ld  hl,worm1
+
+worminit:
+  push bc                        ; >> 1
+  ld  a,(de)
+  ld  (hl),a   ;d
+  inc de
   inc hl
-  ld e,(hl)
+  ld  a,SinCosTable/256
+  ld  (hl),a
   inc hl
-  ld a,(hl)
+
+  ld  a,(de)
+  ld  (hl),a   ;y
+  inc de
   inc hl
-  ld (Heading),a
-  push de
-  ld a,(hl)
+  ld  a,(de)
+  ld  (hl),a   ;x
+  inc de
   inc hl
-  sub 128
-  ld (FieldWidth),a
-  ld a,(hl)
+
+  xor a
+  ld  (hl),a   ;y2
   inc hl
+  ld  (hl),a   ;x2
+
+  ld  bc,20-5
+  add hl,bc
+  pop bc                         ; << 0k
+  djnz worminit
+
+  ld  hl,Worm1
+  ld  (worm1+head),hl
+  ld  (worm1+tail),hl
+  ld  hl,Worm2
+  ld  (worm2+head),hl
+  ld  (worm2+tail),hl
+
+;-------- draw level ---------
+
+  ld  a,(de)
+  inc de
+  sub 128
+  ld  (FieldWidth),a
+  ld  a,(de)
+  inc de
   sub 57
-  ld (FieldHeight),a
+  ld  (FieldHeight),a
   add a,57-5
-  push hl
-  ld l,a
-  ld h,0
+  push de                        ; >> levelp
+  ld  l,a
+  ld  h,0
   add hl,hl
   add hl,hl
   add hl,hl
   add hl,hl
   add hl,hl
-  ex de,hl
-
-  ld hl,ScrBuffer
-  push hl
-  push de
-  ld de,ScrBuffer+1
-  ld bc,63
-  ld (hl),%11111111
+  ex  de,hl
+
+  ld  hl,ScrBuffer
+  push hl                        ; >> 1
+  push de                        ; >> 2
+  ld  de,ScrBuffer+1
+  ld  bc,63
+  ld  (hl),%11111111
   ldir
   inc hl
-  ld (hl),%11000000
+  ld  (hl),%11000000
   inc hl
-  ld b,31
+  ld  b,31
 ClearLine:
-  ld (hl),c
+  ld  (hl),c
   inc hl
   djnz ClearLine
-  push hl
+  push hl                        ; >> 3
 
-  ld a,(FieldWidth)
+  ld  a,(FieldWidth)
   add a,126
-  push af
+  push af                        ; >> 4
   and %11111000
   rra
   rra
   rra
-  ld l,a
-  ld h,0
+  ld  l,a
+  ld  h,0
   add hl,de
-  pop af
+  pop af                         ; << 3
   and %00000111
-  ld b,a
-  ld c,0
-  ld a,%11000000
-  jr z,NoVertShift
+  ld  b,a
+  ld  c,0
+  ld  a,%11000000
+  jr  z,NoVertShift
 VertShift:
   rra
-  rr c
+  rr  c
   djnz VertShift
 NoVertShift:
-  ld (hl),a
+  ld  (hl),a
   inc hl
-  ld (hl),c
+  ld  (hl),c
 
-  ex de,hl
-  pop de
-  pop bc
+  ex  de,hl
+  pop de                         ; << 2
+  pop bc                         ; << 1
   ldir
-  pop hl
-  ld c,64
+  pop hl                         ; << 0k
+  ld  c,64
   ldir
 
-  pop hl
+;-draw lines-
 
-  ld a,(hl)
+  pop hl                         ; << levelp
+  ld  a,(hl)
   inc hl
-  or a
-  jr z,NoLines
+  or  a
+  jr  z,NoLines
 DrawLines:
-  push af
-  ld d,(hl)
+  push af                        ; >> 1
+  ld  d,(hl)
   inc hl
-  ld e,(hl)
+  ld  e,(hl)
   inc hl
-  ld a,(hl)
+  ld  a,(hl)
   inc hl
-  push hl
-  ld l,(hl)
-  ld h,a
+  push hl                        ; >> 2
+  ld  l,(hl)
+  ld  h,a
   call Line
   inc d
   inc h
@@ -167,171 +340,296 @@ DrawLines:
   dec d
   dec h
   call Line
-  pop hl
+  pop hl                         ; << 1
   inc hl
-  pop af
+  pop af                         ; << 0k
   dec a
-  jr nz,DrawLines
+  jr  nz,DrawLines
 NoLines:
-  push hl
 
-  ld hl,0
-  ld (_penCol),hl
-  ld hl,LivesMsg
+;-----------------------------
+
+  push hl                        ; >> levelp new
+
+  ld  hl,0
+  ld  (_penCol),hl
+  ld  hl,LivesMsg
   call _vputs
-  ld a,(Lives)
+  ld  a,(worm1+lives)
   add a,'0'
   call _vputmap
 
-  ld a,40
-  ld (_penCol),a
+  ld  a,40
+  ld  (_penCol),a
   call _vputs ;scoremsg
-  ld a,100
-  ld (_penCol),a
+  ld  a,100
+  ld  (_penCol),a
   call _vputs
-  ld a,(Left)
+  ld  a,1
+Left =$-1
   call PutNum
-
+  ld  ix,worm1
   call PutScore
 
   call NewPea
 
-  pop hl
-  pop bc
-  push bc
-  push hl
+  pop hl                         ; << levelp new
+  push hl                        ; >> levelp new
+  ld  bc,(worm1+pos)
   call DisplayField
-  ld hl,LevelMsg
-  ld a,7
-  push hl
-  ld h,a
-  ld l,4
-  ld (_curRow),hl
-  ld hl,0FDE0h
-  ld de,0FDE1h
-  ld (hl),-1
-  ld bc,0BFh
+  ld  hl,LevelMsg
+  ld  a,7
+  push hl                        ; >> 1
+  ld  h,a
+  ld  l,4
+  ld  (_curRow),hl
+  ld  hl,0FDE0h
+  ld  de,0FDE1h
+  ld  (hl),-1
+  ld  bc,0BFh
   ldir
-  pop hl
+  pop hl                         ; << 0k
   set 3,(iy+5)
   call _puts
-  ld a,(Level)
-  cp 10
-  jr c,LevelBelowTen
-  ld l,a
-  ld h,0
+  ld  a,(Level)
+  cp  10
+  jr  c,LevelBelowTen
+  ld  l,a
+  ld  h,0
   call _divHLby10
-  push af
-  ld a,l
+  push af                        ; >> 1
+  ld  a,l
   add a,'0'
   call _putc
-  pop af
+  pop af                         ; << 0k
 LevelBelowTen:
   add a,'0'
   call _putc
   res 3,(iy+5)
 
-  xor a
+  ld  b,0
 ReadyDelay:
   halt
-  dec a
-  jr nz,ReadyDelay
+  djnz ReadyDelay
 
-  ld hl,(HeadPos)                              ;<====NEW
-  ld (TailPos),hl
-  pop hl
-  pop bc
-  push hl
-  ld de,0
+;-----------------------------
+;----------- LOOP ------------
+;-----------------------------
 
 GameLoop:
+  ld  bc,(worm1+pos)
   call DisplayField
 
-  ld a,2
+  ld  a,0
 Speed =$-1
-  or a
-  jr z,HeadPos-1
+  or  a
+  jr  z,NoDelay
 Delay:
   halt
   dec a
-  jr nz,Delay
-
-  ld hl,WormPos
-HeadPos =$-2
-  ld (hl),c
-  inc hl
-  ld (hl),b
-  inc hl
-  res 2,h                              ;<====NEW
-  ld (HeadPos),hl
+  jr  nz,Delay
+NoDelay:
+
+  ld  ix,worm1
+  call HandleWorm
+  ld  ix,worm2
+  ld  a,(nrworms)
+  cp  2
+  call z,HandleWorm
+
+;-----------------------------
+;---------- keys -------------
+;-----------------------------
+
+HandleKeys:
+  ld  a,%10111111
+  out (1),a
+  in  a,(1)
+  rla
+  jr  c,NotPaused
+  ld  bc,$0103
+  out (c),b
+  halt
+  ld  b,11
+  out (c),b
 
-  ld hl,SinCosTable
-Heading =$-2
+NotPaused:
+  rla
+  jp  c,GameLoop
+Exit2pop:
+  pop hl                         ; << levelp new
+Exit1pop:
+  pop hl                         ; << levelp old
+  jr  Exit
+
+Exit5pop:
+  pop hl
+  pop hl
+  pop hl
+  jr  Exit2pop
 
-  ld a,0FEh
-  out (1),a
-  in a,(1)
+WormDead:
+  pop hl                         ; << call
+  pop hl                         ; << levelp new
+  ld  hl,(worm1+head)
+  ld  de,(worm1+tail)
+  sbc hl,de
+  ld  a,l
+  rr  h
   rra
+  ld  (worm1+grow),a
+
+  ld  hl,(worm2+head)
+  ld  de,(worm2+tail)
+  sbc hl,de
+  ld  a,l
+  rr  h
   rra
-  jr c,NotRight
-  push af
-  ld a,l
+  ld  (worm2+grow),a
+
+  ld  a,(ix+lives)
+  dec a
+  ld  (ix+lives),a
+  pop de                         ; << levelp old
+  jp  nz,NextLife
+Exit:
+
+#if 0
+  ld a,(Eaten)
+  ld hl,HiScore
+  cp (hl)
+  jr c,NotNewHigh
+  ld (hl),a
+  ld hl,_asapvar
+  rst 20h
+  rst 10h
+  call 460Bh
+  ld de,HiScore-_asm_exec_ram+2
+  add hl,de
+  adc a,0
+  call _load_ram_ahl
+  ld a,(HiScore)
+  ld (hl),a
+NotNewHigh:
+#endif
+  res 4,(iy+9)
+;  ld sp,0
+SpSave = $-2
+  jp _clrWindow
+
+;-----------------------------
+;----------- worm ------------
+;-----------------------------
+
+inlink:
+  ld  a,0
+sendbyte =$-1
+  call SendByte
+  jr  c,receivefirst
+  call receive
+  ret
+receivefirst:
+  call receive
+  ld  a,(sendbyte)
+  call SendByte
+  ret
+
+receive:
+receiveloop:
+  call GET_KEY
+  cp  K_EXIT
+  jp  z,Exit5pop
+  call TryReceiveByte
+  jr  c,receiveloop
+  ld  l,a
+  ret
+
+inkeys:
+  out (1),a
+  in  a,(1)
+  ld  b,a
+  and (ix+right)
+  jr  z,NotRight
+  ld  a,l
   add a,8
-  ld l,a
-  pop af
+  ld  l,a
 NotRight:
-  rra
-  jr c,NotLeft
-  ld a,l
+  ld  a,b
+  and (ix+left)
+  ret z
+  ld  a,l
   sub 8
-  ld l,a
-NotLeft:
-
-  ld (Heading),hl
+  ld  l,a
+  ret
 
-  push bc
-  ld a,(hl)
+;------- handle worm ---------
+
+HandleWorm:
+  ld  l,(ix+heading)
+  ld  a,(ix+input)
+  or  a
+  jr  nz,keys
+  call inlink
+  jr  donelydone
+keys:
+  call inkeys
+donelydone:
+  ld  a,l
+  ld  (sendbyte),a
+  ld  (ix+heading),l
+  ld  h,(ix+heading+1)
+
+  ld  c,(ix+pos)
+  ld  b,(ix+pos+1)
+  ld  e,(ix+pos2)
+  ld  d,(ix+pos2+1)
+
+;-------- move worm ----------
+
+Wormmove:
+  push bc                        ; >> pos
+  ld  a,(hl)
   add a,a
   add a,d
-  ld d,a
+  ld  d,a
   bit 7,(hl)
-  jr z,NotNegX
+  jr  z,NotNegX
   dec b
 NotNegX:
-  jr nc,NotMoveX
+  jr  nc,NotMoveX
   inc b
 NotMoveX:
-  ld a,l
+  ld  a,l
   add a,40h
-  ld l,a
-  ld a,(hl)
+  ld  l,a
+  ld  a,(hl)
   add a,a
   add a,e
-  ld e,a
+  ld  e,a
   bit 7,(hl)
-  jr z,NotNegY
+  jr  z,NotNegY
   dec c
 NotNegY:
-  jr nc,NotMoveY
+  jr  nc,NotMoveY
   inc c
-NotMoveY:
+NotMoveY: ;bc=newpos
 
-  pop hl
-  push de
-  ld a,h
+;-check-
+  pop hl                         ; << pos (old)
+  push de                        ; >> pos2
+  ld  a,h
   sub b
   and 1
-  ld h,a
-  ld a,l
+  ld  h,a
+  ld  a,l
   sub c
   and 1
   add a,h
-  ld d,4
-  jr z,GotFour
+  ld  d,4
+  jr  z,GotFour
   xor 3
-  ld d,a
+  ld  d,a
 GotFour:
-
   call CheckPixel
   inc b
   call CheckPixel
@@ -340,55 +638,76 @@ GotFour:
   dec b
   call CheckPixel
   dec c
-  rl d
-  jr nc,WormNotCrashed
-  ld hl,0
+  rl  d
+  pop de                         ; << pos2
+
+  ld  (ix+pos2),e
+  ld  (ix+pos2+1),d
+  ld  (ix+pos),c
+  ld  (ix+pos+1),b
+  jr  nc,Drawworm
+
+;--------- worm hit ----------
+
+Hitworm:
+  ld  hl,0
 PeaY =$-2
 PeaX =$-1
-  ld a,b
+  ld  a,b
   sub h
   inc a
-  cp 4
-  jp nc,WormDead
-  ld a,c
+  cp  4
+  jp  nc,WormDead
+  ld  a,c
   sub l
   inc a
-  cp 4
-  jp nc,WormDead
-  push bc
+  cp  4
+  jp  nc,WormDead
+  push bc                        ; >> 1
   call DrawPea
-  ld a,0
-GrowAmt =$-1
+  ld  a,(ix+grow)
   add a,15
-  ld (GrowAmt),a
+  ld  (ix+grow),a
   call NewPea
-  ld de,10
+  ld  de,10
   call IncScore
-  ld a,119
-  ld (_penCol),a
+  ld  a,119
+  ld  (_penCol),a
   ld hl,Left
   dec (hl)
-  jr nz,NotNextLevel
-  ld hl,Level
-  ld a,(hl)
+  jr  nz,NotNextLevel
+  ld  hl,Level
+  ld  a,(hl)
   inc (hl)
-  pop bc
-  pop de
-  pop hl
-  pop de
-  cp NUM_LEVELS
-  jp nz,StartLevel
-  jr Exit
+  pop bc                         ; << 0k
+  pop hl                         ; << call
+  pop de                         ; << levelp new
+  pop hl                         ; << levelp old
+  cp  NUM_LEVELS
+  jp  z,Exit
+  ld  a,(Gametype)
+  or  a
+  jp  z,StartLevel
+  jp  Exit
 
 NotNextLevel:
-  ld a,(hl)
+  ld  a,(hl)
   call PutNum
-  pop bc
-WormNotCrashed:
+  pop bc                         ; << 0k
+
+;-------- draw worm ----------
+
+Drawworm:
+  ld  l,(ix+head)
+  ld  h,(ix+head+1)
+  ld  (hl),c
+  inc hl
+  ld  (hl),b
+  inc hl
+  res resbit,h
+  ld  (ix+head),l
+  ld  (ix+head+1),h
 
-  push bc
-  ld a,3
-WormCol =$-1
   call SetPixel
   inc b
   call SetPixel
@@ -397,21 +716,22 @@ WormCol =$-1
   dec b
   call SetPixel
 
-;  xor 2
-;  ld (WormCol),a
+  ld  a,(ix+grow)
+  dec a
+  jr  z,removetail
+  ld  (ix+grow),a
+  ret
 
-  ld hl,GrowAmt
-  dec (hl)
-  jr nz,GrowWorm
-  inc (hl)
-  ld hl,$b000
-TailPos =$-2
-  ld c,(hl)
+removetail:
+  ld  l,(ix+tail)
+  ld  h,(ix+tail+1)
+  ld  c,(hl)
   inc hl
-  ld b,(hl)
+  ld  b,(hl)
   inc hl
-  res 2,h                              ;<====NEW
-  ld (TailPos),hl
+  res resbit,h
+  ld  (ix+tail),l
+  ld  (ix+tail+1),h
 
   call ResPixel
   inc b
@@ -419,66 +739,13 @@ TailPos =$-2
   inc c
   call ResPixel
   dec b
-  call ResPixel
-
-GrowWorm:
-
-  ld a,0BFh
-  out (1),a
-  in a,(1)
-  rla
-  jr c,NotPaused
-  ld bc,$0103
-  out (c),b
-  halt
-  ld b,11
-  out (c),b
-NotPaused:
-  pop bc
-  pop de
-  rla
-  jp c,GameLoop
-  jr Exit
-; push hl
-WormDead:
-  pop de
-  pop hl
-  ld hl,(HeadPos)
-  ld de,(TailPos)
-  sbc hl,de
-  ld a,l
-  rr h
-  rra
-  ld hl,Lives
-  dec (hl)
-  pop hl
-  jp nz,NextLife
-Exit:
+  jp  ResPixel
 
-#if 0
-  ld a,(Eaten)
-  ld hl,HiScore
-  cp (hl)
-  jr c,NotNewHigh
-  ld (hl),a
-  ld hl,_asapvar
-  rst 20h
-  rst 10h
-  call 460Bh
-  ld de,HiScore-_asm_exec_ram+2
-  add hl,de
-  adc a,0
-  call _load_ram_ahl
-  ld a,(HiScore)
-  ld (hl),a
-NotNewHigh:
-#endif
-  res 4,(iy+9)
-  ld sp,0
-SpSave = $-2
-  jp _clrWindow
+;-----------------------------
+;----------- procs -----------
+;-----------------------------
 
-NewPea: ;------------------------------procs                           ;<====NEW
+NewPea:
 ;random routine
   ld hl,0
   ld de,12345
@@ -509,9 +776,9 @@ noadd16:
   inc l
   ld (PeaY),hl
   ld d,2
-  push hl
+  push hl                        ; >> 1
   call CheckPea
-  pop hl
+  pop hl                         ; << 0k
   dec d
   jr z,NewPea
 DrawPea:
@@ -526,9 +793,9 @@ CheckPea:
   call PeaPixel
   dec c
 PeaPixel:
-  push de
+  push de                        ; >> 1
   call FindPixel
-  pop de
+  pop de                         ; << 0k
   ld e,a
   ld a,d
   or a
@@ -543,7 +810,7 @@ DrawPeaPixel:
   ld (hl),a
   ret
 
-;no random routine here                                ;<====NEW
+;-------- pixelprocs ---------
 
 ResPixel: ;at bc
   call FindPixel
@@ -559,16 +826,17 @@ SetPixel: ;at bc
   ret
 
 CheckPixel: ;at bc in d
-  push de
+  push de                        ; >> 1
   call FindPixel
   and (hl)
-  pop de
+  pop de                         ; << 0k
   ret z
   dec d
   ret
 
-FindPixel: ;bc to ahl + de gone                                ;<====NEW
-  push bc
+FindPixel: ;bc to ahl + de gone
+  push de                        ; >> 1
+  push bc                        ; >> 2
   ld a,b
   and 7
   add a,offsets_table & 255
@@ -591,71 +859,78 @@ FindPixel: ;bc to ahl + de gone                           ;<====NEW
   ld a,(de)
   ld de,ScrBuffer
   add hl,de
-  pop bc
+  pop bc                         ; << 1
+  pop de                         ; << 0k
   ret
 
+;-----------------------------
+
 IncScore:
-  ld hl,(Score)
+  ld  h,(ix+score+1)
+  ld  l,(ix+score)
   add hl,de
-  ld (Score),hl
+  ld  (ix+score+1),h
+  ld  (ix+score),l
 PutScore:
-  ld de,_penCol
-  ld a,79
-  ld (de),a
-  ld b,5
+  ld  de,_penCol
+  ld  a,79
+  ld  (de),a
+  ld  b,5
 DoPutScore:
-  push bc
-  push de
+  push bc                        ; >> 1
+  push de                        ; >> 2
   call _divHLby10
   call PutDigit
-  pop de
-  ld a,(de)
+  pop de                         ; << 1
+  ld  a,(de)
   sub 8
-  ld (de),a
-  pop bc
+  ld  (de),a
+  pop bc                         ; << 0k
   djnz DoPutScore
   ret
 
 PutNum:
-  ld l,a
-  ld h,0
+  ld  l,a
+  ld  h,0
   call _divHLby10
-  push af
-  ld a,l
+  push af                        ; >> 1
+  ld  a,l
   call PutDigit
-  pop af
+  pop af                         ; << 0k
 PutDigit:
   add a,'0'
-  jp _vputmap
+  jp  _vputmap
+
+;-----------------------------
 
 offsets_table:
   .db 128,64,32,16,8,4,2,1
 
-DisplayField:                          ;<====NEW
-  ld a,c
+DisplayField:
+  ld  a,c
   sub 29
-  jr nc,NotMinYScroll
+  jr  nc,NotMinYScroll
   xor a
 NotMinYScroll:
-  cp 43
+  cp  43
 FieldHeight =$-1
-  jr c,NotMaxYScroll
-  ld a,(FieldHeight)
+  jr  c,NotMaxYScroll
+  ld  a,(FieldHeight)
 NotMaxYScroll:
-  ld l,a
-  ld h,0
+  ld  l,a
+  ld  h,0
   add hl,hl
   add hl,hl
   add hl,hl
   add hl,hl
   add hl,hl
-  push bc
-  push de
-  ld de,ScrBuffer
+  push bc                        ; >> 1
+  push de                        ; >> 2
+  ld  de,ScrBuffer
   add hl,de
-  ld a,b
+  ld  a,b
   sub 64
-  jr nc,NotMinXScroll
+  jr  nc,NotMinXScroll
   xor a
 NotMinXScroll:
   cp 128
@@ -663,7 +938,7 @@ FieldWidth = $-1
   jr c,NotMaxXScroll
   ld a,(FieldWidth)
 NotMaxXScroll:
-  push af
+  push af                        ; >> 3
   and %11111000
   rra
   rra
@@ -671,9 +946,9 @@ NotMaxXScroll:
   ld c,a
   ld b,0
   ld de,DispBuffer
-  pop af
+  pop af                         ; << 2
   and %00000111
-  push af
+  push af                        ; >> 3
   cp 6
   jr c,CopyScreen
   inc c
@@ -681,15 +956,15 @@ CopyScreen:
   add hl,bc
   ld b,57
 CopyScreenLoop:
-  push bc
+  push bc                        ; >> 4
   ld bc,16
   ldir
   ld c,16
   add hl,bc
-  pop bc
+  pop bc                         ; << 3
   djnz CopyScreenLoop
-  pop af
-  ld c,$b7                             ;or a
+  pop af                         ; << 2
+  ld c,$b7                 ;or a
 Bit0:
   jr nz,Bit1
   halt
@@ -738,11 +1013,11 @@ AfterShift:
   ld de,$fc00+$70
   ld bc,1024-$70
   ldir
-  pop de
-  pop bc
+  pop de                         ; << 1
+  pop bc                         ; << 0k
   ret
 
-ShiftRight1:                           ;<====NEW
+ShiftRight1:
   ld a,1
 ShiftRight:
   ld (ShiftRightCounter),a
@@ -752,7 +1027,7 @@ ShiftRight:
   add hl,bc
   ld b,57
 ShiftRightLoop:
-  push bc
+  push bc                        ; >> 1
   ld bc,-32
   add hl,bc
   ex de,hl
@@ -763,24 +1038,24 @@ ShiftRightChunk:
   ld c,0
 ShiftRightCounter = $-1
 ShiftRowsLeft:
-  push hl
+  push hl                        ; >> 2
   rla
   ld b,16
 ShiftRowLeft:
   dec hl
   rl (hl)
   djnz ShiftRowLeft
-  pop hl
+  pop hl                         ; << 1
   dec c
   jr nz,ShiftRowsLeft
   ld bc,-16
   add hl,bc
   ex de,hl
-  pop bc
+  pop bc                         ; << 0k
   djnz ShiftRightLoop
   ret
 
-ShiftLeft1:                            ;<====NEW
+ShiftLeft1:
   ld a,1
 ShiftLeft:
   ld (ShiftLeftCounter),a
@@ -796,7 +1071,7 @@ ShiftLeftSameByte:
   ex de,hl
   ld b,57
 ShiftLeftLoop:
-  push bc
+  push bc                        ; >> 1
   ld bc,-32
   add hl,bc
   ex de,hl
@@ -807,31 +1082,31 @@ ShiftLeftChunk:
   ld c,0
 ShiftLeftCounter = $-1
 ShiftRowsRight:
-  push hl
+  push hl                        ; >> 2
   rra
   ld b,16
 ShiftRowRight:
   rr (hl)
   inc hl
   djnz ShiftRowRight
-  pop hl
+  pop hl                         ; << 1
   dec c
   jr nz,ShiftRowsRight
   ld bc,-16
   add hl,bc
   ex de,hl
-  pop bc
+  pop bc                         ; << 0k
   djnz ShiftLeftLoop
   ret
 
-Chunk:                         ;<====NEW
-  push hl
-  push de
+Chunk:
+  push hl                        ; >> 1
+  push de                        ; >> 2
   ld c,16
   add hl,bc
   ld b,57
 ChunkScreen:
-  push bc
+  push bc                        ; >> 3
   ld bc,-32
   add hl,bc
   ex de,hl
@@ -843,45 +1118,185 @@ ChunkRow:
   rld
   djnz ChunkRow
   ex de,hl
-  pop bc
+  pop bc                         ; << 2
   djnz ChunkScreen
-  pop de
-  pop hl
-  ld c,$37                             ;scf
+  pop de                         ; << 1
+  pop hl                         ; << 0k
+  ld c,$37                  ;scf
   ret
 
+;-----------------------------
+;----------- link ------------
+;-----------------------------
+
+LINKMASK =3
+LINKPORT =7
+TIMEOUT  =$1000
+
+LinkPrep:
+        ex (sp),hl
+        push bc
+        push de
+        set 2,(iy+12h)
+        ld b,8
+        jp (hl)
+
+TryReceiveByte:
+        in  a,(LINKPORT)
+        and LINKMASK
+        cp  LINKMASK
+        scf
+        ret z
+ReceiveByteCont:
+        call LinkPrep
+        jr ReceiveCont
+ReceiveByte:
+        call LinkPrep
+ReceiveBits:
+        ld de,TIMEOUT
+WaitRecBit:
+        call CheckLink
+        jr z,LinkFailed
+        cp LINKMASK
+        jr z,WaitRecBit
+ReceiveCont:
+        sub LINKMASK/3*2
+        ld a,LINKMASK/3*2
+        ld d,D0LD1H
+        jr c,ReceiveLow
+        rra
+        ld d,D0HD1L
+ReceiveLow:
+        rr c
+        ld (AckBit),a
+        ld a,d
+        out (LINKPORT),a
+        ld de,TIMEOUT
+WaitAckRec:
+        call CheckLink
+        cp 0
+AckBit =$-1
+        jr nz,WaitAckRec
+        ld a,D0HD1H
+        out (LINKPORT),a
+        ld d,4
+WaitReadyRec:
+        dec d
+        jr z,ReadyRec
+        in a,(LINKPORT)
+        cp LINKMASK
+        jr nz,WaitReadyRec
+ReadyRec:
+        djnz ReceiveBits
+        jr LinkSuccess
+
+SendByte:
+        call LinkPrep
+        ld c,a
+
+        inc b
+        jr SendAcked
+
+SendBits:
+        rr c
+        ld a,D0LD1H
+        jr nc,SendLow
+        ld a,D0HD1L
+SendLow:
+        out (LINKPORT),a
+        ld de,TIMEOUT
+WaitAckSend:
+        call CheckLink
+        jr nz,WaitAckSend
+SendAcked:
+        ld a,D0HD1H
+        out (LINKPORT),a
+        ld de,TIMEOUT
+WaitReadySend:
+        call CheckLink
+        cp LINKMASK
+        jr nz,WaitReadySend
+        djnz SendBits
+LinkSuccess:
+        or 0
+.org $-1
+LinkFailed:
+        scf
+        ld a,c
+        res 2,(iy+12h)
+        pop de
+        pop bc
+        pop hl
+        ret
+
+CheckLink:
+        pop hl
+        dec de
+        ld a,d
+        or e
+        jr z,LinkFailed
+        ld a,0BFh
+        call _readkeypad
+        bit 6,a
+        jr z,LinkFailed
+        in a,(LINKPORT)
+        and LINKMASK
+        jp (hl)
+
+_readkeypad:
+       out (1),a
+       in a,(1)
+        push af
+       ld a,255
+       out (1),a
+        pop af
+       ret
+
+
+
+;-----------------------------
+;---------- levels -----------
+;-----------------------------
+
+LevelsDM:
+
+  .db 8,0
+  .db $40,30,4,$C0,30,123
+  .db 0,0
+;  .db 128,57
+  .db 0
 
 NUM_LEVELS = 9
 
-Levels:
+LevelsS:
 
   .db 5,3           ;5 peas, speed 5
-  .db 64,4,0        ;x,y,d
-  .db 0,0            ;field width, height
+  .db 0,4,64,0,0,0  ;d,y,x
+  .db 0,0           ;field width, height
   .db 0             ;no additional lines
 
   .db 8,4
-  .db 4,14,$40
+  .db $40,14,4,0,0,0
   .db 128,57
   .db 1
   .db 28,28,100,28
 
   .db 9,4
-  .db 4,8,$40
+  .db $40,8,4,0,0,0
   .db 128,57
   .db 2
   .db 28,14,100,14
   .db 28,41,100,41
 
   .db 9,3
-  .db 4,8,$40
+  .db $40,8,4,0,0,0
   .db 128,80
   .db 2
   .db 64,14,64,66
   .db 20,40,108,40
 
   .db 10,3
-  .db 4,8,$40
+  .db 4,8,$40,0,0,0
   .db 128,90
   .db 3
   .db 18,20,18,70
@@ -889,7 +1304,7 @@ Levels:
   .db 18,45,110,45
 
   .db 7,3
-  .db 64,4,0
+  .db 64,4,0,0,0,0
   .db 128,86
   .db 6
   .db 34,13,56,35
@@ -900,7 +1315,7 @@ Levels:
   .db 110,20,110,64
 
   .db 9,2
-  .db 4,10,$40
+  .db 4,10,$40,0,0,0
   .db 128,82
   .db 3
   .db 0,20,74,20
@@ -908,7 +1323,7 @@ Levels:
   .db 0,60,74,60
 
   .db 12,2
-  .db 64,4,0
+  .db 64,4,0,0,0,0
   .db 128,90
   .db 6
   .db 20,16,54,16
@@ -919,7 +1334,7 @@ Levels:
   .db 74,72,110,72
 
   .db 8,2
-  .db 72,52,$c0
+  .db 72,52,$c0,0,0,0
   .db 128,128
   .db 13
   .db 34,56,56,34
@@ -937,25 +1352,72 @@ Levels:
   .db 91,106,115,106
 
 
+;-----------------------------
+;---------- data -------------
+;-----------------------------
+
+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
 
-#include "trigtab.asm"
 #include "line.asm"
 
-WormMsg .db "Wonderworm!",0
+txtWelcome .db "Welcome to PeaWorm!! ",
+           .db "by Jonah and Shiar",0
+txtMenu    .db "Start Game",0
+           .db "Game: ",0
+           .db "Options",0
+           .db "Quit",0
+txtGame    .db "Singleplayer",0
+txtGame2   .db "Deathmatch  ",0
+           .db "Hot Pursuit",0
+           .db "CTF        ",0
+WormMsg  .db "Wonderworm!",0
 LevelMsg .db "Level ",0
 LivesMsg .db "Lives: ",0
 ScoreMsg .db "Score: ",0
 LeftMsg  .db "Food: ",0
-HiScore .db 0
-
-Left =$
-Lives =$+1
-Level =$+2
-Score =$+3
-DispBuffer =$+5
-
-ScrBuffer =$8200 ;32x256 bytes
-SinCosTable =$a200
-WormPos = $b000
+HiScore  .db 0
+
+nrworms .db 2
+worm1 .dw 0,0,0,0,0,0,0,0
+      .db 0,%11111110,%10,%100
+worm2 .dw 0,0,0,0,0,0,0,0
+      .db 0,0,%10000,%1000
+;     .db 0,%00111111,%10000,%1000
+
+              ;set:
+heading = 0   ;level*
+pos     = 2   ;level*
+pos2    = 4   ;level
+head    = 6   ;level
+tail    = 8   ;level
+grow    = 10  ;level
+lives   = 13  ;game
+score   = 15  ;game
+input   = 17  ;
+left    = 18  ;
+right   = 19  ;
+
+Worm1  = $B000
+Worm2  = $B800
+resbit = 2
+
+Level =$+1
+DispBuffer =$+2
+
+ScrBuffer   = $8200 ;32x256 bytes
+SinCosTable = $A200
+
+;-----------------------------
+;----------- end -------------
+;-----------------------------
 
 .end