wormy 0.93.1304: circles, customisable controls
[wormy.git] / wormy.z80
1 ; Title                      : Wormy
2 ; Version                    : 93%
3 ; Release Date               : summer 2001
4 ; Filename                   : wormy.86p (5kb)
5 ; Author(s)                  : Shiar
6 ; Email Address              : shiar0@hotmail.com
7 ; ICQ UIN                    : #43840958
8 ; Web Page                   : www.shiar.org
9 ; Description                : ruling Nibbles-like game 1-4 players
10 ; Where to get this game     : www.shiar.org (home of Wormy)
11 ; Other games by author(s)   : Nemesis beta
12 ; Additional Credits to      : Matthew Shepcar (wrote original Peaworm, end'98)
13 ;                              Jonah Cohen (helped writing worm)
14
15 ;-----------------------------
16 ;----------- TO-DO -----------
17 ;-----------------------------
18
19 ; 93% = DONE
20
21 ;     * internal levels
22 ;       * check levels/gametype
23 ;       * enough hiscore saves!
24 ;     * complete readme
25 ;  1% * misc (pollish, bugs, &&&)
26 ;   * LINK
27 ;  2% * fix deaths linkplay and transmit game/level data
28 ;  2% * make linkplay available for all gametypes (not just deathmatch)
29 ;   * CTF
30 ;  1% * fix pea XOR problem in ctf (+dom?)
31 ;     * fix wormstop
32 ;  1% * domination?: take control points by running over them and hold them
33
34 ;100% = bugs fixed + levels done
35
36 ;-----------------------------
37 ;-----------------------------
38 ;---------  W O R M  ---------
39 ;-----------------------------
40 ;-----------------------------
41
42 #define buffer      ;use display buffer (otherwise write directly to screen)
43 #define readymask   ;"grays" out the field before starting a level
44
45 ;#define readytext  ;displays "prepare" before level starts
46 ;#define invincible ;worms cannot die =)
47
48 #define cal call
49 #define psh push
50 #define dnz djnz
51
52 #include "asm86.h"
53 #include "ti86asm.inc"
54
55 _SHRACC            = $4383
56 _SHLACC            = $438B
57 _divHLby10         = $4044 ;hl=hl/10
58 _divAby10          = $4DAF ;a=a/10
59 _HLTIMES10         = $41BF ;hl=hl*10
60 _cphlde            = $403C
61 _clrWindow         = $4A86 ;clear screen
62 _asapvar           = $D6FC ;own name (worm)
63 _MOV4B             = $429B ;4x ld (de),(hl)
64 _MOV5B             = $4297 ;5x ld (de),(hl)
65 _mov9b             = $4283 ;9x ld (de),(hl)
66 _ldHLind           = $4010 ;ld hl,(hl)
67 _swapt_            = $45F3 ;ex_ahl_bde
68 _Get_Word_ahl      = $521D ;ld de,(ahl)
69 _Set_Word_ahl      = $5221 ;ld (ahl),de
70 _INC_PTR_AHL       = $4637 ;ahl=ahl+1
71 _AHL_PLUS_2_PG3    = $4C3F ;ahl=ahl+2
72 _SET_ABS_SRC_ADDR  = $4647 ;set source for mm.ldir =ahl
73 _LOAD_ABS_SRC_ADDR = $5209 ;ahl = mm.ldir source
74 _SET_ABS_DEST_ADDR = $5285 ;set destination for mm.ldir = ahl
75 _SET_MM_NUM_BYTES  = $464F ;number of bytes for mm.ldir = ahl
76 _mm_ldir           = $52ED ;24bit ldir
77 _RAM_PAGE_1        = $47E3 ;set $8000+ to page 1
78 _RAM_PAGE_7        = $47F3
79 _PTEMP_END         = $D29A ;end of VAT
80 _load_ram_ahl      = $462F ;ahl->page+hl
81 _writeb_inc_ahl    = $5567 ;ld (ahl),c
82 _jforce            = $409C ;TI-OS stack restored
83 _EXLP              = $4493 ;swap (hl),(de) b times
84
85 ;-----------------------------
86 ;------- data  storage -------
87 ;-----------------------------
88
89 ;--- permanent
90
91 ScrBuffer   = $8820 ;-A7FF (20*FF=1FE0)
92 worm2p      = $A800 ;-ABFF (400)      %10101O00
93 worm1       = $AC00 ;-AC1D (31d)
94 worm2       = $AC1F ;-AC3B (1F)
95 worm3       = $AC3E ;-AC59 (1F)
96 worm4       = $AC5D ;-AC77 (1F)
97 balls       = $AC7C ;-ACFF (3x43d)
98 SinCosTable = $AD00 ;-AE00 (4x40)
99         ;free $AE01 ;-AFFF (1FF)
100 worm1p      = $B000 ;-B7FF (800)      %1011O000
101 worm3p      = $B800 ;-BBFF (400)      %10111O00
102         ;free $BF91 ;-BFFF (6F)
103
104      ;program $D748 ;-E7FF (106D+4A)
105         ;free $E800 ;-EFFF (800)
106 worm4p      = $F000 ;-F3FF (400)      %11110O00
107 leveldata   = $F400 ;-FA70 (<=671)
108
109 peaspos = $AE01
110
111 ;--- temporary
112
113 namelength  = $BC00 ;(1)         @menu
114 #ifdef buffer
115 DispBuffer  = $BC00 ;(10x57d)    @game
116 #else
117 DispBuffer  = $FC70
118 #endif
119
120 ;-----------------------------
121 ;------- program start -------
122 ;-----------------------------
123
124 .org _asm_exec_ram
125
126 wormVhost   = 093
127 wormVclient = 193
128
129 start:
130   nop
131   jp Start
132   .dw 1
133   .dw WormTxt
134   .dw WormIcon
135
136 WormTxt:
137   .db "WORMY by SHIAR -- alpha 93%",0
138 WormIcon:
139   .db 9,2
140   .db %10010110,%01101111
141   .db %10110101,%01001011
142   .db %01110011,%01001001
143   .db %00000011,%10000000
144   .db %00000001,%11100000
145   .db %00111000,%11111000
146   .db %01111110,%00111111
147   .db %11101111,%00001111
148   .db %11000011,%10000000
149
150 levelhead  = 'w'
151 levelhead2 = 93 ;wormy levels header = "93"
152
153 int_handler:
154   ex af,af'
155   in a,($03)
156   bit 3,a
157   jp z,$0039
158   res 0,a
159   out ($03),a
160   jp $0039
161 int_end:
162
163 Start:
164   ld  (SpSave),sp
165   cal _runindicoff
166   cal _flushallmenus
167
168   im  1
169   ld  a,$D4
170   ld  h,a
171   ld  l,0     ;ld hl,$D400
172   ld  d,a
173   ld  e,1     ;ld de,$D401
174   ld  b,e
175   ld  c,l     ;ld bc,$0100
176   dec a       ;ld a,$D3
177   ld  (hl),a
178   ldir
179   ld  hl,int_handler
180   ld  d,a
181   ld  e,a     ;ld de,$D3D3
182   ld  bc,int_end-int_handler
183   ldir
184   inc a       ;ld a,$D4
185   ld  i,a
186   im  2
187
188   cal _RAM_PAGE_7
189   ld  hl,$BFFF ;VAT start
190   ld  bc,templevels
191 searchloop:
192   ld  de,(_PTEMP_END+1) ;VAT end
193   or  a ;nc
194   sbc hl,de ;hl<de?
195   jr  c,searchcomplete
196   add hl,de
197   psh hl
198   ld  a,(hl)
199   cp  $0C ;string
200   jr  z,stringfound
201 searchnext:
202  cal _RAM_PAGE_7
203   pop hl
204   dec hl ;5x
205   dec hl
206   dec hl
207   dec hl
208   dec hl
209  psh bc
210   ld  b,(hl) ;name size
211   inc b
212 skipname:
213   dec hl
214   dnz skipname
215  pop bc
216   jr  searchloop
217
218 stringfound:
219   dec hl
220   ld  e,(hl)
221   dec hl
222   ld  d,(hl)
223   dec hl
224   ld  a,(hl)
225   ex  de,hl ;ld ahl,(hl)
226   cal _AHL_PLUS_2_PG3 ;string id
227   cal _Get_Word_ahl ;ld de,(ahl)
228  cal _RAM_PAGE_1
229  ld (bc),a
230   ld  a,levelhead
231   cp  e
232   jr  nz,searchnext ;not worm
233   ld  a,levelhead2
234   cp  d
235   jr  nz,searchnext
236
237  inc bc
238  ld a,h
239  ld (bc),a
240  inc bc
241  ld a,l
242  ld (bc),a
243  inc bc
244  jr searchnext
245
246 loadgametype:
247   psh de
248   inc bc
249   inc bc
250   cal _Get_Word_ahl ;ld de,(ahl++)
251   psh af
252   ld  a,d
253   or  e
254   jr  z,defaultlevels
255   ld  a,e ;set new level
256   ld  (bc),a
257   inc bc
258   ld  a,d
259   ld  (bc),a
260   dec bc
261 defaultlevels:
262   pop af
263   pop de ;counter
264   dec d ;8x
265   jr  nz,loadgametype
266   ret
267
268 searchcomplete:
269   cal _RAM_PAGE_1
270   ld  a,255
271   ld  (bc),a ;end mark
272   ld  hl,templevels-3
273 dispnextlevel:
274   cal _RAM_PAGE_1
275   psh hl
276   cal _clrWindow
277   ld  a,2
278   ld  (_curRow),a
279   ld  hl,txtLevsel
280   cal _puts ;"< Select levels: >"
281   ld  hl,$0004
282   ld  (_curRow),hl
283   pop hl
284   ld  a,(hl)
285   cp  255 ;&&
286   jr  nz,displevel
287   ld  hl,templevels-3
288   ld  a,(hl)
289 displevel:
290   inc hl
291   ld  d,(hl)
292   inc hl
293   ld  e,(hl)
294   inc hl  ;ade=(hl)
295   psh hl  ;HL
296   ld  c,a
297   ld  h,d
298   ld  l,e ;cde=ahl=(hl)
299   cal _load_ram_ahl ;hl=ahl
300   ld  b,(hl) ;b=title size
301   psh bc
302   cal _putps ;destr=abchl
303   pop bc  ;cde=hl
304   pop hl  ;HL
305 levselect:
306   halt
307   psh hl
308   psh de
309   psh bc
310   cal GET_KEY
311   pop bc
312   pop de
313   pop hl
314   cp  K_RIGHT
315   jr  z,dispnextlevel
316   sub K_SECOND
317   jr  z,loadlevel
318   dec a ;K_EXIT
319   ret z
320   cp  K_ENTER-K_EXIT+256
321   jr  nz,levselect
322
323 loadlevel:
324   ld  a,c
325   or  a ;levelfile on page 0 (=internal)
326   jr  z,levelloaded
327
328   ex  de,hl ;ahl=cde
329   inc b ;b=titlesize+1
330 skiptitle:
331   cal _INC_PTR_AHL
332   dnz skiptitle
333
334   cal _Get_Word_ahl
335   ld  (leveldataSize),de
336   ld  d,8 ;counter
337   ld  bc,datalevels-2
338   cal loadgametype
339   ld  (hilvlposa),a
340   ld  (hilvlposhl),hl
341   ld  d,4
342   cal loadgametype
343
344   cal _SET_ABS_SRC_ADDR ;levelsstart
345   xor a
346   ld  hl,leveldata
347   cal _SET_ABS_DEST_ADDR ;store in mem.
348   ld  hl,0
349 leveldataSize =$-2
350   cal _SET_MM_NUM_BYTES
351   cal _mm_ldir
352
353   cal _LOAD_ABS_SRC_ADDR ;->ahl
354   ld  (hiscrposa),a
355   ld  (hiscrposhl),hl
356   cal _RAM_PAGE_1
357
358   ld  hl,leveldata
359   ld  de,defsprsize
360   ldi ;(de),(hl)\inc hl
361   ld  (defsprite),hl
362 levelloaded:
363   cal _RAM_PAGE_1
364
365   res 2,(iy+13) ;appAutoScroll
366   ld  a,r
367   ld  (Seed),a
368
369 ;-----------------------------
370 ;----- build trig tables -----
371 ;-----------------------------
372
373   ld  hl,TrigPrecalc
374   ld  de,SinCosTable
375   psh de                        ; >> 1
376   ld  bc,65
377   ldir
378   dec hl
379   ld  b,63
380 MirrorSineWave:
381   dec hl
382   ld  a,(hl)
383   ld  (de),a
384   inc de
385   dnz MirrorSineWave
386   pop hl                         ; << 0k
387   ld  b,128+64
388 NegativeSineWave:
389   xor a
390   sub (hl)
391   ld  (de),a
392   inc hl
393   inc de
394   dnz NegativeSineWave
395
396 ;-----------------------------
397 ;---------- menu -------------
398 ;-----------------------------
399
400 DisplayMenu: ;---draw menu---
401   cal _clrWindow
402   ld  de,$FC40 ;(0,4)
403   ld  hl,wtPicture
404   ld  bc,16*16
405   ldir
406
407   ld  hl,txtMenu
408   ld  ix,posMenu
409   ld  b,6
410 dispmenuloop:
411   ld  d,(ix)
412   inc ix
413   ld  e,(ix)
414   inc ix
415   ld  (_penCol),de
416   cal _vputs ;Mode \ Level \ Limit \ Worms \ worm # \ controls
417   dnz dispmenuloop
418
419   ld  b,0 ;b=menu#
420   jr  setgame ;> dispmenusets > mainMenu
421
422 ;--- menu loop ---
423
424 mainMenu:
425   cal menupos
426   cal menucall
427   jr  nz,notselect
428 select:   ;2nd/enter
429   cal menupos
430   ld  a,b
431   sub 4 ;4th item?
432   jp  z,changeworms
433   dec a ;5th?
434   jp  z,changekeys
435   jp  LetsGetThisPartyOn ;1/2/3/5
436 notselect
437   cp  K_EXIT
438   jp  z,ExitNoStats
439   psh af
440   cal menupos
441   cal loadgamecar
442   inc hl
443   pop af
444   cp  K_LEFT
445   jr  z,selleft
446   cp  K_RIGHT
447   ld  a,b
448   jr  nz,mainMenu
449
450 selright:
451   or  a
452   jr  z,changegame
453   dec a
454   jp  z,changelevel ;&&&jr??
455   dec a
456   jr  z,changelives
457   dec a
458   jr  z,changenrworms
459 ; dec a
460 ; jr  z,changecurworm
461
462 changecurworm:
463 ; hl=nrworms
464   ld  a,(curworm)
465   cp  (hl)
466   jr  nc,mainMenu ;may not become >(nrworms)
467   inc a
468 changedcurworm:
469   ld  (curworm),a
470   jp  dispmenusets ;mainMenu
471
472 selleft:
473   ld  a,b
474   or  a
475   jr  z,bchangegame
476   dec a
477   jr  z,bchangelevel
478   dec a
479   jr  z,bchangelives
480   dec a
481   jr  z,bchangenrworms
482 ; dec a
483 ; jr  z,bchangecurworm
484
485 bchangecurworm:
486   ld  a,(curworm)
487   dec a ;0-3
488   jr  nz,changedcurworm ;save >0
489   jr  mainMenu
490
491 changenrworms:
492   ld  a,(Gametype)
493   cp  2
494   jr  c,mainMenu ;type 0/1
495   ;hl=nrworms
496   ld  a,(hl)
497   inc a
498   cp  5
499   jr  nc,mainMenu ;may not be >4
500 changednrworms:
501   ld  (hl),a
502   jr  dispmenusets ;mainMenu
503 bchangenrworms:
504   ;hl=nrworms
505   ld  a,(hl)
506   dec a ;0-3
507   jr  nz,changednrworms ;save >0
508 _mainMenu:
509   jr  mainMenu
510
511 changegame:
512   ld  a,0
513 Gametype =$-1
514   inc a
515 changedgame:
516   and 7 ;mod 8
517   ld  (Gametype),a
518 setgame:
519   ld  a,1
520   ld  (curlevel),a ;reset level#
521   jr  dispmenusets ;mainMenu
522 bchangegame:
523   ld  a,(Gametype)
524   dec a
525   jr  changedgame
526
527 changelives:
528   cal changelivesInit
529   inc a
530   cp  100
531   jr  nc,_mainMenu ;&& _?
532 changedlives:
533   ld  (hl),a
534   jr  dispmenusets ;mainMenu
535 bchangelives:
536   cal changelivesInit
537   dec a
538   jr  z,_mainMenu
539   jr  changedlives
540 changelivesInit:
541   cal loadgamecar ;c=(gameCar)
542 ;a=(hl)=(Gametype+1)=(wormbeglives)
543   ld  a,(Gametype) ;&&&
544   cp  3
545   ld  a,(hl)
546   ret nc ;change lives
547   pop hl ;restore stack
548   jr  _mainMenu ;singleplayer (no limit)
549
550 changelevel:
551   ld  hl,Gametype
552   ld  d,0
553   ld  e,(hl)
554   ld  hl,nrlevels
555   add hl,de
556   ld  d,(hl) ;max level for sel.game
557 curlevel =$+1
558   ld  a,1
559   cp  d
560   jr  z,_mainMenu
561   inc a
562 changedlevel:
563   ld  (curlevel),a
564   jr  dispmenusets ;mainMenu
565 bchangelevel:
566   ld  a,(curlevel)
567   dec a
568   jr  nz,changedlevel
569   jr  _mainMenu
570
571 getcustomkey:
572   cal _vputs
573   dec ix
574 waitcustomkey:
575   halt \ halt
576   psh hl
577   cal GET_KEY
578   pop hl
579   or  a
580   jr  z,waitcustomkey
581   cp  K_EXIT
582   ret z
583   cp  K_MORE
584   jr  z,waitcustomkey
585   ld  (ix),a
586   ret
587
588 changekeys:
589   cal getwormname
590   ld  hl,txtKeyleft
591   cal getcustomkey ;left
592   cal getcustomkey ;right
593 ; jr  dispmenusets
594
595 ;---display current settings---
596
597 dispmenusets:
598   ld  hl,$FD97 ;begin pos
599   ld  de,7 ;bytes to add
600   ld  a,35 ;nr of lines
601 clroldsettings:
602   ld  c,9 ;bytes to clear
603 clroldsetsloop:
604   ld  (hl),d ;=0
605   inc hl
606   dec c
607   jr  nz,clroldsetsloop
608   add hl,de
609   dec a
610   jr  nz,clroldsettings
611
612   ld  de,$183E
613   ld  (_penCol),de
614   ld  d,0
615   ld  a,(Gametype)
616   ld  e,a
617   ld  hl,posGame
618   add hl,de ;hl=posGame+(Gametype)
619   ld  a,(hl) ;str.offset
620   ld  e,a ;^d=0^
621   ld  hl,txtGame
622   add hl,de ;txtGameX
623   ld  (CURtxtGame),hl ;save for g/o
624   cal _vputs ;Singleplayer
625
626   ld  hl,$1E3E ;level
627   ld  (_penCol),hl
628   ld  a,(curlevel)
629   cal cshowA
630
631   cal loadgamecar
632   psh hl
633   ld  hl,$243E
634   ld  (_penCol),hl
635   cal cshowA ;liveslimit
636   sub '0' ;original A
637   ld  l,a
638   ld  a,c
639   and _datascore
640   ld  a,' '
641   jr  z,limitok
642   ld  a,'0'
643 limitok:
644   cal _vputmap ;x10
645
646   ld  hl,$2A3E ;worms
647   ld  (_penCol),hl
648   pop hl ;cal loadgamecar
649   inc hl
650   ld  a,(hl)
651   add a,'0'
652   cal _vputmap
653
654   ld  hl,$3032
655   ld  (_penCol),hl
656   ld  a,1
657 curworm =$-1
658   add a,'0'
659   cal _vputmap
660   ld  hl,$303E
661   ld  (_penCol),hl
662   cal getwormname
663   ld  hl,worm1name-18
664   add hl,de
665   cal _vputs
666   ld  hl,$363E ;controls
667   ld  (_penCol),hl
668 ;  ld  hl,txtMenu
669 ;  cal _vputs
670   jp  mainMenu
671
672 ;--- handle menukeys ---
673
674 menucall:
675   psh bc
676 menuwaitkey:
677   halt \ halt
678   cal GET_KEY
679   or  a
680   jr  z,menuwaitkey
681   pop bc ;GET_KEY destr. b
682   cp  K_UP
683   cal z,menuup
684   cp  K_DOWN
685   cal z,menudown
686   cp  K_ENTER
687   ret z
688   cp  K_SECOND
689   ret ;z=select
690
691 menupos: ;highlight #b
692   ld  c,b ;psh b
693   ld  a,b
694   add a,3
695   add a,a
696   add a,a
697   sub b
698   add a,a
699   add a,a
700   add a,a ;*24
701   ld  h,$FC/4
702   ld  l,a
703   add hl,hl
704   add hl,hl ;$FD20+item*96
705   ld  b,16*7
706 menuinvloop:
707   ld  a,(hl)
708   cpl
709   ld  (hl),a
710   inc hl
711   dnz menuinvloop
712   ld  b,c ;pop b
713   ret ;a=-1
714 menudown:
715   cal menupos
716   inc b
717   jr  menuupdown
718 menuup:
719   cal menupos
720   dec b
721 menuupdown:
722   ld  a,b
723   cp  6
724   jr  nz,menunewchk
725   xor a ;6=0
726 menunewchk:
727   inc b
728   jr  nz,menunewok
729   ld  a,5 ;-1=5
730 menunewok:
731   ld  b,a
732   jr  menupos
733
734 ;--- change name ---
735 ; of worm#(curworm)
736
737 getwormname: ;of (curworm)
738   ld  a,(curworm)
739   add a,a  ;2x
740   ld  e,a
741   add a,a  ;4x
742   add a,a  ;8x
743   add a,a ;16x
744   add a,e ;18x
745   ld  e,a
746   ld  d,0 ;de=a
747
748   ld  ix,worm1name-18
749   add ix,de
750   ret
751
752 changeworms:
753   cal _clrWindow
754   ld  hl,txtEName
755   cal _puts ;"Enter name player "
756   ld  a,(curworm)
757   add a,'0'
758   cal _putc
759
760   cal getwormname
761   ld  a,maxnamelength
762   cal entername
763   ld  (ix),0 ;end mark
764   jp  DisplayMenu
765
766 entername:
767   ld  h,1
768   ld  l,h ;)
769   ld  (_curRow),hl
770   ld  (namelength),a
771 enternameloop:
772   ld  a,'_'
773   cal _putc
774   ld  hl,_curCol
775   dec (hl)
776 nokeypressed:
777   halt
778   cal GET_KEY
779   or  a
780   jr  z,nokeypressed
781
782   cp  K_DEL
783   jr  nz,continue
784 backspace:
785   ld  hl,namelength
786   ld  a,(hl)
787   cp  maxnamelength
788   jr  nc,nokeypressed
789   inc (hl)
790
791   dec ix
792   ld  a,' '
793   ld  (ix),a
794   cal _putc
795   ld  hl,_curCol
796   dec (hl)
797   dec (hl)
798   jr  enternameloop
799 continue:
800   cp  K_ENTER
801   ret z
802   cp  K_EXIT
803   ret z
804
805   ld  hl,namelength
806   dec (hl)
807   ret z
808
809   ld  hl,chartable
810   ld  e,a
811   ld  d,0
812   add hl,de
813   ld  a,(hl)
814   or  a
815   jr  z,nokeypressed
816
817   ld  (ix),a
818   cal _putc
819   inc ix
820   cal releasekeys
821   jr  enternameloop
822
823
824 chartable:
825   .db 0,".<>!",0,0,0,0  ;down,L,R,up
826   .db 0,"XTOJE0",0      ;enter..clear
827   .db " WSNID9",0       ;(-)..custom
828   .db "ZVRMHC8",0       ;dot..del
829   .db "YUQLGB7#"        ;0..xvar
830   .db $D9,"-PKFA6'"     ;on..alpha
831   .db "54321*",0,$D0    ;F5..more
832
833 ;--proc
834
835 skiplevel: ;@hl - destr:ab - alter:hl
836   inc hl
837   inc hl
838   inc hl
839   inc hl ;skip 4
840   ld  b,(hl) ;spritesize
841   inc b
842 skipsprite:
843   inc hl
844   dnz skipsprite
845   ld  b,(hl) ;balls
846   inc b
847   inc b ;skip 6
848   ld  a,c
849   cp  _datasp
850   jr  z,skipworms
851   inc b ;multiplayer lvl
852   inc b
853   inc b ;skip other 3 worms (9 bytes)
854 skipworms:
855   ld  a,b
856   add a,a
857   add a,b
858   ld  b,a ;3x(balls+2)
859 skipballs:
860   inc hl
861   dnz skipballs
862
863 skipflags:
864   ld  a,(Gametype)
865   cp  gamectf
866   jr  nz,noflagstoskip
867   inc hl
868   inc hl
869   inc hl
870   inc hl
871 noflagstoskip:
872
873 skipobjects:
874   ld  a,(hl)
875   inc hl
876   or  a
877   ret z ;0=end
878   inc hl
879   inc hl
880   inc hl
881   inc hl
882   jr  skipobjects
883
884 loadgamecar:
885 ;in:    (Gametype)
886 ;out:   Gametype+1=hl
887 ;build: c=(gameCar)=(hl-1)
888 ;       a=(wormbeglives)=(hl)
889 ;destr: acdehl
890   ld  hl,datasingle
891   ld  a,(Gametype)
892   ld  e,a
893   add a,a
894   add a,e
895   ld  e,a
896   ld  d,0
897   add hl,de
898   ld  a,(hl)
899   ld  (gameCar),a
900   ld  c,a
901   inc hl
902   ld  a,(hl)
903   ld  (wormbeglives),a
904   ret
905
906 ;-----------------------------
907 ;-------- start game ---------
908 ;-----------------------------
909
910 LetsGetThisPartyOn:
911   ld  a,$17 ;no exit
912   ld  (CheckExit),a ;set exit state
913
914   cal loadgamecar
915   ld  b,a ;psh a
916   inc hl ;nrworms
917   ld  a,(hl)
918   ld  (nrworms),a
919   ld  l,b ;pop a
920   ld  h,0             ;hl=a
921   cal _HLTIMES10      ;hl=10*(hl)
922   ld  (scorelimit),hl ;set limit
923
924   cal loadgamecar ;nc
925   ld  a,(Gametype) ;3bytes -> 2bytes
926   add a,24+1 ;go to datalevels
927   ld  e,a ;=de
928   sbc hl,de ;datalevels
929
930   ld  a,c ;(gameCar)
931   and _datascore
932   jr  nz,scorelimitset
933   dec a ;ld a,$FF ;=no_limit
934   ld  (scorelimit),a
935 scorelimitset:
936
937   cal _ldHLind ;ld hl,(hl)
938   ld  a,(curlevel)
939   ld  (Level),a
940   ld  d,a ;begin level
941 skiplevelloop:
942   dec d ;levels to skip
943   jr  z,levelsskipped
944   cal skiplevel
945   jr  skiplevelloop
946 levelsskipped:
947
948   psh hl  ;1st level
949   ld  a,c
950   and _datalink
951   jr  z,GameOver
952
953 linkmatch:
954   cal _clrWindow
955   ld  c,wormVhost
956   cal Qsend
957   ld  hl,txtWaiting
958   cal _puts
959   cal Crecv
960   ld  a,c
961   cp  wormVclient
962   jr  z,client
963   cp  wormVhost
964   jr  nz,linkiniterror
965 host:
966   ld  c,wormVclient
967   cal Qsend
968   ld  a,$18
969   jr  multiplayer
970
971 linkiniterror:
972   pop hl
973   jp  DisplayMenu
974
975 client:
976   ld  hl,txtReceive
977   cal _puts
978   ld  a,$E6
979 multiplayer:
980   ld  (SwapPos),a
981   ld  a,2
982   ld  (nrworms),a
983
984 ;-----------------------------
985 ;--------- game over ---------
986 ;-----------------------------
987
988 GameOver:
989   ld  a,%11000000
990   out (7),a ;link normal
991   cal _clrLCD
992   ld  hl,worm1set
993   ld  de,worm1
994   ld  a,4 ;4x (all worms)
995 createwormsloop:
996   ex  de,hl
997   ld  bc,died
998   add hl,bc
999   ld  (hl),0 ;died=0
1000   inc hl
1001   ld  (hl),0 ;score=0
1002   inc hl
1003   ld  (hl),0 ;score+1=0
1004   inc hl
1005   ld  (hl),2 ;delay=2
1006   inc hl
1007   ld  (hl),3 ;lives=x
1008 wormbeglives =$-1
1009   inc hl
1010   ex  de,hl  ;de=wormX+head
1011   ld  bc,18
1012   ldir       ;copy 18 bytes
1013   dec a      ;loop
1014   jr  nz,createwormsloop
1015
1016   pop hl ;begin of current level
1017
1018 StartLevel:
1019   ld  de,Left
1020   ld  a,(hl)
1021   inc a ;=255?
1022   jp  nz,nextlevel
1023
1024   psh hl
1025   cal releasekeys
1026   cal _clrWindow
1027   pop hl
1028 ;show end msg or smtn
1029   ld  bc,Exit
1030   psh bc   ;where to go afterwards
1031   inc hl   ;location of ending-code
1032   jp  (hl) ;go there ("call")
1033 nextlevel:
1034   ldi
1035   ld  de,Speed
1036   ldi
1037   ld  de,peagrowth
1038   ldi
1039   ld  a,(hl)
1040   ld  (worm1+grow),a
1041   ld  (worm2+grow),a
1042   ld  (worm3+grow),a
1043   ld  (worm4+grow),a
1044   ld  (beginsize),a
1045   inc hl
1046
1047   ld  a,(hl)
1048   inc hl
1049   or  a
1050   jr  z,defaultsprite
1051   ld  d,h
1052   ld  e,l ;ld de,hl
1053   ld  c,a
1054   ld  b,0 ;bc=sprite size
1055   add hl,bc ;hl=behind sprite
1056   jr  setsprite
1057 defaultsprite:
1058   ld  a,defspritesz
1059 defsprsize =$-1
1060 defsprite  =$+1
1061   ld  de,defspriteimg
1062 setsprite: ;de=@sprite ;a=sprsize
1063   ld  (sprsize),a
1064   ld  (spritepos),de
1065
1066   ld  a,(hl)
1067   inc hl
1068   ld  (nrballs),a
1069   or  a
1070   jr  z,toobad_noballs
1071   ld  c,a
1072   add a,a
1073   add a,c
1074   ld  c,a
1075   ld  b,0
1076   ld  de,balls
1077   ldir
1078 toobad_noballs:
1079
1080   ex  de,hl
1081 #ifndef invincible
1082   ld  (thislevel),de
1083 #endif
1084
1085   ld  hl,worm1
1086   ld  a,(gameCar)
1087   cp  _datasp
1088   ld  b,1
1089   jr  z,worminit
1090   ld  b,4
1091 worminit:
1092   psh bc                        ; >> 1
1093   ex  de,hl
1094   ldi          ;d
1095   ld  a,SinCosTable/256
1096   ld  (de),a
1097   inc de
1098   ldi          ;y
1099   ldi          ;x
1100   ex  de,hl
1101
1102   xor a
1103   ld  (hl),a   ;y2
1104   inc hl
1105   ld  (hl),a   ;x2
1106
1107   ld  bc,(worm2-worm1)-5
1108   add hl,bc
1109   pop bc                         ; << 0k
1110   dnz worminit
1111
1112 ;-------- draw level ---------
1113
1114   ld  a,(de)
1115   inc de
1116   sub 128
1117   ld  (FieldWidth),a
1118   ld  a,(de)
1119   inc de
1120   sub 57
1121   ld  (FieldHeight),a
1122   add a,57-5
1123   psh de                        ; >> levelp
1124   ld  l,a
1125   ld  h,0
1126   add hl,hl
1127   add hl,hl
1128   add hl,hl
1129   add hl,hl
1130   add hl,hl
1131   ex  de,hl
1132
1133   ld  hl,ScrBuffer
1134   psh hl                        ; >> 1
1135   psh de                        ; >> 2
1136   ld  de,ScrBuffer+1
1137   ld  bc,63
1138   ld  (hl),%11111111
1139   ldir
1140   inc hl
1141   ld  (hl),%11000000
1142   inc hl
1143   ld  b,31
1144 ClearLine:
1145   ld  (hl),c
1146   inc hl
1147   dnz ClearLine
1148   psh hl                        ; >> 3
1149
1150   ld  a,(FieldWidth)
1151   add a,126
1152   psh af                        ; >> 4
1153   and %11111000
1154   rra
1155   rra
1156   rra
1157   ld  l,a
1158   ld  h,0
1159   add hl,de
1160   pop af                         ; << 3
1161   and %00000111
1162   ld  b,a
1163   ld  c,0
1164   ld  a,%11000000
1165   jr  z,NoVertShift
1166 VertShift:
1167   rra
1168   rr  c
1169   dnz VertShift
1170 NoVertShift:
1171   ld  (hl),a
1172   inc hl
1173   ld  (hl),c
1174
1175   ex  de,hl
1176   pop de                         ; << 2
1177   pop bc                         ; << 1
1178   ldir
1179   pop hl                         ; << 0k
1180   ld  c,64
1181   ldir
1182
1183
1184   pop hl                         ; << levelp
1185   ld  a,(Gametype)
1186   cp  gamectf
1187   jr  nz,noctf
1188   ld  de,peaspos
1189   ld  bc,4
1190   ldir
1191   psh hl
1192   cal DrawAllPeas
1193   pop hl
1194 noctf:
1195
1196   cal drawstuff
1197
1198 ;-----------------------------
1199
1200   psh hl                        ; >> levelp new
1201   cal showstats
1202   ld  a,(gameCar)
1203   and _datafood
1204   jr  z,nofood
1205   cal NewPea
1206 nofood:
1207   ld  bc,(worm1+pos)
1208   cal DisplayField
1209
1210 #ifdef readymask
1211   ld  hl,$FC70
1212   ld  d,%10101010
1213   ld  c,56
1214 maskloop:
1215   ld  a,d
1216   xor %11111111
1217   ld  d,a
1218   ld  b,$10
1219 maskline:
1220   ld  a,(hl)
1221   or  d
1222   ld  (hl),a
1223   inc hl
1224   dnz maskline
1225   dec c
1226   jr  nz,maskloop
1227 #endif
1228
1229 #ifdef readytext
1230   ld  hl,$FDE0
1231   ld  de,$FDE1
1232   ld  (hl),%11111111
1233   ld  bc,$BF
1234   ldir
1235   ld  hl,4+(txtposReady*256)
1236   ld  (_curRow),hl
1237   set 3,(iy+5)
1238   ld  hl,txtReady
1239   cal _puts
1240   res 3,(iy+5)
1241 #endif
1242
1243   ld  a,0
1244 gameCar =$-1
1245   and _datalink
1246   jr  z,initfinished ;no link
1247   xor a
1248   ld  (Speed),a ;max.speed
1249 SwapPos: ;$18 xx -> $E6 xx
1250          ; jr xx -> and xx
1251   jr  sethost
1252 setclient:
1253   ld  (worm1+left),a ;worm 1 via link
1254   jr  initfinished
1255 sethost:
1256   ld  (worm2+left),a ;worm 2 via link
1257 initfinished:
1258
1259   ld  b,startdelay
1260 ReadyDelay:
1261   halt
1262   dnz ReadyDelay
1263   cal releasekeys
1264
1265 ;-----------------------------
1266 ;----------- LOOP ------------
1267 ;-----------------------------
1268
1269 GameLoop:
1270   ld  bc,(worm1+pos)
1271   cal DisplayField
1272
1273   ld  a,1
1274 flashtime =$-1
1275   dec a
1276   jr  z,noflash
1277   ld  (flashtime),a
1278   ld  hl,$fc00+(16*7)
1279 screeninvertloop:
1280   ld  a,(hl)
1281   cpl
1282   ld  (hl),a
1283   inc hl
1284   xor a
1285   cp  h
1286   jr  nz,screeninvertloop
1287 noflash:
1288
1289   ld  a,0
1290 Speed =$-1
1291   or  a
1292   jr  z,NoDelay
1293 Delay:
1294   halt
1295   dec a
1296   jr  nz,Delay
1297 NoDelay:
1298
1299   ld  (handledworm),a ;=0
1300
1301   ld  a,0
1302 nrballs =$-1
1303   or  a
1304   cal nz,handlethoseneatlittleballs
1305
1306   ld  ix,worm1
1307   ld  a,1
1308 nrworms =$-1
1309   ld  b,a
1310 handleworms:
1311   psh bc
1312   cal HandleWorm
1313   ld  bc,worm2-worm1
1314   add ix,bc
1315   pop bc
1316   ld  hl,handledworm
1317   inc (hl) ;1..nrworms
1318   dnz handleworms
1319
1320 ;-----------------------------
1321 ;---------- keys -------------
1322 ;-----------------------------
1323
1324 HandleKeys:
1325   ld  a,%10111111
1326   out (1),a
1327   in  a,(1)
1328   rla ;MORE?
1329   jr  c,CheckExit
1330   ld  bc,$0103
1331   out (c),b
1332   halt ;pause/off
1333   ld  b,11
1334   out (c),b
1335
1336 CheckExit:
1337   rla  ;=$17 (c=EXIT-key)
1338       ;or$A7 (c=0)
1339   jp  c,GameLoop
1340   jr  Exit
1341
1342 WormDead:
1343 #ifdef invincible
1344   jp  stopworm
1345 #else
1346   ld  a,2
1347   ld  (flashtime),a
1348   ld  (ix+delay),respawndelay
1349
1350 thislevel =$+1
1351   ld  hl,0
1352   ld  de,0
1353 handledworm =$-2
1354   add hl,de
1355   add hl,de
1356   add hl,de
1357   ld  a,(hl)
1358   inc hl
1359   ld  (ix+heading),a
1360   ld  a,(hl)
1361   ld  (ix+pos),a
1362   inc hl
1363   ld  a,(hl)
1364   ld  (ix+pos+1),a
1365
1366   inc (ix+died)
1367   dec (ix+lives)
1368   psh af
1369   ld  de,10
1370   cal DecScore
1371   pop af
1372   ret nz ;HandleWorm done
1373   ld  a,(gameCar)
1374   and _datalivel
1375   ret z
1376   ld  a,$A7 ;exit@end of turn
1377   ld  (CheckExit),a ;set exit state
1378   ret ;finish turn
1379 #endif
1380
1381 Exit:
1382   ld  sp,0 ;pop all
1383 SpSave = $-2
1384   ld  a,D0HD1H
1385   out (7),a
1386   cal _clrWindow
1387   ld  hl,txtGO
1388   cal _puts
1389   ld  hl,$FC00
1390   ld  b,16*8
1391   cal menuinvloop ;invert
1392   inc h ;$FD80
1393   ld  b,16
1394   cal menuinvloop ;<hr>
1395   ld  hl,$FCE0
1396   ld  b,16
1397   cal menuinvloop ;<hr>
1398 ; ld  l,$74
1399 ; ld  b,8
1400 ; cal menuinvloop
1401   ld  hl,_curRow
1402   inc (hl)
1403   ld  hl,txtGame
1404 CURtxtGame =$-2
1405   cal _puts
1406   ld  a,$0D ;$0D02
1407   ld  (_curCol),a
1408   cal showLevel
1409
1410   ld  de,$1901
1411   ld  (_penCol),de
1412   ld  hl,txtName
1413   cal _vputs ;Name
1414   ld  a,$4F
1415   ld  (_penCol),a
1416   cal _vputs ;Died    Score
1417   ld  de,$0004
1418   ld  (_curRow),de
1419
1420   ld  a,(nrworms)
1421   ld  b,a
1422   ld  hl,worm1+died
1423 displayWormStats:
1424   psh bc
1425   psh hl
1426
1427   ld  bc,left-died
1428   add hl,bc ;+left
1429   xor a
1430   cp  (hl)  ;input=0 = link
1431   jr  nz,NoLinkIndic
1432   ld  a,8
1433   ld  (_curCol),a
1434   ld  a,$DC ;-O
1435   cal _putc
1436   xor a
1437   ld  (_curCol),a
1438 NoLinkIndic:
1439   inc hl
1440   inc hl ;+name
1441   cal _puts
1442
1443   pop hl
1444   psh hl
1445   ld  a,13
1446   ld  (_curCol),a
1447   ld  a,(hl) ;worm+died
1448   cal showA
1449   pop hl
1450   psh hl
1451
1452   ld  a,16
1453   ld  (_curCol),a
1454   inc hl ;worm+score
1455   cal _ldHLind ;ld hl,(hl)
1456   cal showHL ;worm+score
1457
1458   pop hl
1459   ld  bc,worm2-worm1
1460   add hl,bc
1461   pop bc
1462   dnz displayWormStats
1463
1464   ld  a,(Gametype)
1465   or  a ;singleplayer (0) only
1466   jr  nz,hilevelcheckdone
1467 checkhilevel:
1468   ld  hl,nrlevels
1469   ld  a,(Level)
1470   cp  (hl)
1471   jr  c,hilevelcheckdone
1472   ld  (hl),a    ;save local
1473   ld  c,a
1474   ld  a,0
1475 hilvlposa =$-1
1476   ld  hl,nrlevels
1477 hilvlposhl =$-2 ;save external
1478   cal _writeb_inc_ahl ;ld (ahl),c
1479 hilevelcheckdone:
1480
1481   ld  a,(gameCar)
1482   and _datasingl
1483
1484   jr  z,hiscorecheckdone
1485 checkhiscore:
1486   cal loadhiscoreposinahl
1487   cal _Get_Word_ahl ;de=old_hi
1488  psh de
1489  cal _RAM_PAGE_1 ;&&
1490  pop de
1491   ld  hl,(worm1+score)
1492
1493   ld  a,h           ;New
1494   cp  d             ;Old
1495   jr  c,NotNewHigh  ;New<Old
1496   jr  nz,newhigh    ;New>Old
1497
1498   ld  a,e           ;old
1499   cp  l             ;new
1500   jr  nc,NotNewHigh ;new<old
1501
1502 newhigh:            ;New>=Old
1503   ex  de,hl
1504   cal loadhiscoreposinahl
1505   cal _Set_Word_ahl ;de->(ahl)
1506  cal _RAM_PAGE_1
1507
1508 NotNewHigh: ;de=current hiscore
1509   ld  hl,$0807
1510   ld  (_curRow),hl
1511   ld  hl,txthiscore
1512   cal _puts
1513   ex  de,hl ;pop
1514   cal showHL
1515 hiscorecheckdone:
1516
1517   cal releasekeys
1518 waitkey:
1519   halt
1520   halt
1521   cal GET_KEY
1522   cp  K_ENTER
1523   jp  z,DisplayMenu
1524   cp  K_SECOND
1525   jp  z,DisplayMenu
1526   cp  K_EXIT
1527   jr  nz,waitkey
1528
1529 ;x123456789012345678901
1530 ;>>>>>> GAME OVER <<<<<
1531 ;2Multiplayer
1532 ;3Level 01
1533 ;4           Died Score:
1534 ;5NameName     03 00070
1535 ;6Worm#02 @    05 00120
1536 ;7Worm#03      15 00030
1537 ;8Snaky   @    00 04820
1538
1539 ExitNoStats:
1540   ld  hl,_asapvar
1541   rst 20h ;_ABS_MOV10TOOP1
1542   rst 10h ;_FINDSYM
1543   ld  hl,savestart-_asm_exec_ram+4
1544   xor a
1545   add hl,de
1546   adc a,b ;ahl=bde+4
1547   cal _SET_ABS_DEST_ADDR
1548
1549   xor a
1550   ld  hl,savestart
1551   cal _SET_ABS_SRC_ADDR
1552   ld  hl,saveend-savestart
1553   cal _SET_MM_NUM_BYTES
1554   cal _mm_ldir
1555
1556   cal releasekeys
1557   res 4,(iy+9)
1558   set 2,(iy+13)
1559   im  1 ;remove keyfix
1560   jp  _clrWindow
1561
1562 loadhiscoreposinahl:
1563   ld  a,(Level)
1564   ld  b,a
1565
1566   ld  h,0            ;hl=
1567   ld  a,(nrlevels+1) ;# peaworm lvls
1568   add a,a
1569   ld  l,a
1570
1571   ld  a,(Gametype)
1572   dec a
1573   ld  c,a
1574   dec a              ;z=(Gametype)=2
1575   jr  z,tronhi
1576   ld  l,h            ;hl=0
1577 tronhi:
1578
1579   xor a              ;ahl=0(+x)
1580   psh bc
1581   ld  bc,defhiscrpos
1582 hiscrposhl =$-2
1583   add hl,bc
1584   pop bc
1585   adc a,0
1586 hiscrposa =$-1       ;ahl=saveloc
1587
1588   inc c
1589   ret z              ;(Gametype)=0
1590 addlevelposition:
1591   cal _AHL_PLUS_2_PG3
1592   dnz addlevelposition
1593   ret
1594
1595 ;-----------------------------
1596 ;----------- worm ------------
1597 ;-----------------------------
1598
1599 respawncheck:
1600   cp  respawndelay-1
1601   jr  nz,unnamedlabel
1602   cal saverespawncounter
1603 removeworm:
1604   ld  h,(ix+tail+1)
1605   ld  l,(ix+tail)
1606   ld  d,(ix+head+1)
1607   ld  e,(ix+head)
1608   jr  DoesWormTailEqualsWormHead ;chk4 size=0
1609 removewormloop:
1610   ld  c,(hl)
1611   inc hl
1612   ld  b,(hl)
1613   inc hl
1614   cal resbit
1615   psh hl
1616   cal res4pixels
1617   pop hl
1618   inc (ix+grow)
1619 DoesWormTailEqualsWormHead:
1620   cal _cphlde
1621   jr  nz,removewormloop
1622
1623   ld  a,(gameCar)
1624   and _datasingl
1625   jr  nz,safewormsizedone
1626   ld  a,0
1627 beginsize =$-1
1628   ld  (ix+grow),a
1629 safewormsizedone:
1630
1631   ;de=ix+head
1632   ld  (ix+tail+1),d
1633   ld  (ix+tail),e ;head=tail/size=0
1634   ret
1635
1636 unnamedlabel:
1637   cp  1
1638   ld  h,a
1639   jr  nz,saverespawncounter
1640 respawndue:
1641   ld  l,a
1642   cal inputcall
1643   ld  a,h ;previous
1644   cp  l   ;changed?
1645   ret z
1646   ld  (ix+delay),a ;=0
1647   ret
1648 saverespawncounter:
1649   ld  (ix+delay),a
1650   jr  inputcall
1651 ;  ld  a,(ix+input)
1652 ;  or  a
1653 ;  jr  z,inlink
1654 ;  ret
1655
1656 chkkey: ;key=a
1657   dec a
1658   ld  b,a
1659   srl b
1660   srl b
1661   srl b ;b=a/8
1662   and 7 ;a=a\8
1663   ld  c,a ;push keybit
1664   ld  a,-1
1665   out (1),a
1666   inc b
1667   ld  a,%01111111 ;default
1668 bitmask:
1669   rlca ;rotate left
1670   dnz bitmask ;a/8 times
1671   out (1),a ;send bitmask
1672   in  a,(1) ;input keys
1673   ld  b,c ;pop keybit
1674   inc b
1675 keybit:
1676   rra
1677   dnz keybit ;check match (cf set)
1678   ret
1679
1680 inkeys: ;use jp not call!
1681   cal chkkey
1682   jr  nc,notright
1683   ld  a,l
1684   add a,8
1685   ld  l,a
1686 notright:
1687   ld  a,(ix+right)
1688   cal chkkey
1689   ret nc
1690   ld  a,l
1691   sub 8
1692   ld  l,a
1693   ret
1694 inputcall:
1695   ld  a,(ix+left)
1696   or  a
1697   jr  z,inlink ;input by link
1698   cal inkeys ;input by keys
1699   ld  a,(gameCar)
1700   and _datalink
1701   ret z ;no link
1702   ld  c,l ;send our keys
1703   psh hl
1704   cal Qsend ;Csend
1705   pop hl
1706   ret
1707 inlink:
1708   psh hl
1709   cal Qrecv ;Crecv
1710   pop hl
1711   ld  l,c
1712   ret
1713
1714 ;------- handle worm ---------
1715
1716 HandleWorm:
1717   ld  a,(ix+delay)
1718   dec a
1719   jp  nz,respawncheck
1720
1721   ld  a,(Gametype)
1722   cp  gametron
1723   jr  nz,notron
1724   ld  de,1
1725   cal IncScore
1726 notron:
1727
1728   ld  l,(ix+heading)
1729   cal inputcall
1730 donediddelydone:
1731   ld  (ix+heading),l
1732   ld  h,(ix+heading+1)
1733
1734   ld  c,(ix+pos)
1735   ld  b,(ix+pos+1)
1736   ld  e,(ix+pos2)
1737   ld  d,(ix+pos2+1)
1738
1739   psh hl
1740   ld  hl,previouspos
1741   ld  (hl),c
1742   inc hl
1743   ld  (hl),b
1744   inc hl
1745   inc hl
1746   ld  (hl),e
1747   inc hl
1748   ld  (hl),d
1749   pop hl
1750
1751 ;-------- move worm ----------
1752
1753 Wormmove:
1754   psh bc                        ; >> pos
1755   ld  a,(hl)
1756   add a,a
1757   add a,d
1758   ld  d,a
1759   bit 7,(hl)
1760   jr  z,notnegX
1761   dec b
1762 notnegX:
1763   jr  nc,notmoveX
1764   inc b
1765 notmoveX:
1766   ld  a,l
1767   add a,$40
1768   ld  l,a
1769   ld  a,(hl)
1770   add a,a
1771   add a,e
1772   ld  e,a
1773   bit 7,(hl)
1774   jr  z,notnegY
1775   dec c
1776 notnegY:
1777   jr  nc,notmoveY
1778   inc c
1779 notmoveY: ;bc=newpos
1780   ld  (ix+pos2),e
1781   ld  (ix+pos2+1),d
1782   ld  (ix+pos),c
1783   ld  (ix+pos+1),b
1784
1785 ;-check-
1786   pop hl                         ; << pos (old)
1787   ld  a,h
1788   sub b
1789   and 1
1790   ld  h,a
1791   ld  a,l
1792   sub c
1793   and 1
1794   add a,h
1795   ld  d,4
1796   jr  z,GotFour
1797   xor 3
1798   ld  d,a
1799 GotFour:
1800   cal chk4pixels
1801   rl  d
1802   jp  nc,Drawworm
1803
1804 ;--------- worm hit ----------
1805
1806 Hitworm:
1807   ld  a,(gameCar)
1808   ld  h,a
1809   and _datadie
1810   cal z,checkhitotherworm
1811   ld  a,h
1812   and _datamultpeas ;&&bit
1813   jr  nz,multiple_peas
1814   ld  a,h
1815   and _datafood
1816   jp  z,WormDead ;no food
1817
1818   ld  hl,0
1819 PeaY =$-2
1820 PeaX =$-1
1821   cal chkpeahit
1822   jp  nc,WormDead
1823   cal DrawPea ;remove pea
1824   ld  a,(ix+grow)
1825   add a,15
1826 peagrowth =$-1
1827   ld  (ix+grow),a
1828   cal NewPea
1829   ld  hl,Left
1830   dec (hl)
1831   psh af
1832   ld  de,10
1833   cal IncScore
1834   pop af
1835   jp  nz,Drawworm ;continue
1836   ld  a,(gameCar)
1837   and _datafoodl
1838   jp  z,Drawworm
1839   ld  a,(Gametype)
1840   or  a
1841   jp  nz,Exit ;stack restored
1842
1843   ld  hl,Level
1844   ld  a,(hl)
1845   inc (hl)
1846   ld  l,a ;hl=Level
1847   ld  h,0
1848   add hl,hl
1849   add hl,hl
1850   cal _HLTIMES10
1851   ex  de,hl
1852   cal IncScore ;score+(40*level)
1853   cal removeworm
1854   pop hl                         ; << call
1855   pop hl                         ; << call
1856   pop hl                         ; << levelp new
1857   ld  (ix+delay),2
1858   jp  StartLevel
1859
1860 chkpeahit: ;hl=peapos
1861   ld  a,(sprsize)
1862   inc a
1863   ld  d,a
1864   ld  a,b
1865   sub h
1866   inc a
1867   cp  d ;=(sprsize)+1
1868   ret nc ;nc=no pea
1869   ld  a,c
1870   sub l
1871   inc a
1872   cp  d
1873   ret ;c=pea
1874
1875 flagcaptured:
1876   psh hl
1877   ld  de,30
1878   cal IncScore
1879   pop hl
1880 sillylabel:
1881   cal WormDead
1882 DrawAllPeas:
1883   ld  hl,(peaspos)
1884   cal DrawPea
1885   ld  hl,(peaspos+2)
1886   jp  DrawPea
1887
1888 multiple_peas:
1889   ld  hl,(peaspos) ;1st pea
1890   psh hl
1891   ld  a,(ix+reserv)
1892   ld  e,a ;push a
1893   and %01
1894   jr  nz,sel_ownpea
1895   ld  hl,(peaspos+2) ;2nd pea
1896 sel_ownpea:
1897   cal chkpeahit
1898   pop hl ;(peapos) 1st pea
1899   jp  c,WormDead ;stopworm ;own pea hit
1900
1901   ld  a,e ;peek a (that's x86 asm for pop\push ;)
1902   and %01
1903   jr  z,sel_otherpea
1904   ld  hl,(peaspos+2) ;2nd pea
1905 sel_otherpea:
1906   cal chkpeahit
1907   jp  c,hitflag
1908
1909 ;no peas hit
1910   ld  a,e
1911   cal flagtoken
1912   jp  z,WormDead
1913   ld  b,a ;%10
1914   srl b   ;%01
1915   add a,b ;%11
1916   ld  (ix+reserv),a
1917   cal DrawPea ;restore own flag
1918   jr  sillylabel ;inv both\die
1919
1920 hitflag: ;correct pea hit
1921   ld  a,e ;pop a
1922   xor %01 ;0=1;1=0
1923   ld  (ix+reserv),a
1924   cal flagtoken
1925   psh af ;safe z-flag
1926   cal DrawPea ;remove
1927   pop af
1928   jr  z,flagcaptured
1929   jr  stopworm
1930
1931 flagtoken:
1932   and %01 ;current
1933   add a,a ;<< for cp
1934   ld  b,a ;in b
1935   ld  a,e
1936   and %10 ;own
1937   cp  b   ;same?
1938   ret ;Z=yes: no flag taken
1939
1940 ;-----------------------------
1941
1942 nextotherwormbit:
1943   ld  a,c
1944   sub (hl)
1945   inc hl
1946   inc a
1947   cp  4
1948   jr  nc,nothit1 ;no
1949   ld  a,b
1950   sub (hl)
1951   inc a
1952   cp  4
1953   ret c ;nz ;yes
1954 nothit1:
1955   inc hl
1956   cal resbit
1957 ChkWorm:
1958   cal _cphlde
1959   jr  nz,nextotherwormbit
1960   ret ;z
1961
1962 checkhitlapline:
1963   ld  a,63
1964   sub b
1965   jr  z,nextlaphalf
1966   inc a
1967   ret nz
1968 nextlaphalf:
1969   ld  a,c
1970   and 32 ;y>=32?
1971   jr  nz,nolap
1972   cp  (ix+reserv)
1973   jr  z,nolap
1974   psh bc
1975   ld  de,20
1976   cal IncScore
1977   pop bc
1978   xor a
1979 nolap:
1980   ld  (ix+reserv),a
1981   ret
1982
1983 checkhitotherworm:
1984  .db  $dd,$7d ;ld a,lx
1985   cp  worm2&255
1986  psh ix
1987  jr nz,chkworm2 ; ret nz
1988   ld  ix,worm1
1989  jr chkworm
1990 chkworm2:
1991  ld ix,worm2
1992
1993 chkworm:
1994  ld h,(ix+tail+1)
1995  ld l,(ix+tail)
1996  ld e,(ix+head)
1997  ld d,(ix+head+1)
1998   cal ChkWorm
1999  pop ix
2000   ret z ;not hit
2001   pop bc ;call
2002 stopworm:
2003   ld  bc,0
2004 previouspos =$-2
2005   ld  de,0
2006   ld  (ix+pos),c
2007   ld  (ix+pos+1),b
2008   ld  (ix+pos2),e
2009   ld  (ix+pos2+1),d
2010   ret
2011
2012 ;-------- draw worm ----------
2013
2014 Drawworm:
2015   ld  c,(ix+pos)
2016   ld  b,(ix+pos+1)
2017
2018   ld  a,(Gametype)
2019   ld  d,a
2020   cp  gamerace
2021   cal z,checkhitlapline
2022
2023   cal set4pixels
2024   dec c
2025   ld  a,d
2026   cp  gametron
2027   ret z ;keep tail in "Tron"
2028
2029   ld  l,(ix+head)
2030   ld  h,(ix+head+1)
2031   ld  (hl),c
2032   inc hl
2033   ld  (hl),b
2034   inc hl
2035   cal resbit
2036   ld  (ix+head),l
2037   ld  (ix+head+1),h
2038
2039   ld  a,(ix+grow)
2040   dec a
2041   jr  z,removetail
2042   ld  (ix+grow),a
2043   ret
2044
2045 removetail:
2046   ld  l,(ix+tail)
2047   ld  h,(ix+tail+1)
2048   ld  c,(hl)
2049   inc hl
2050   ld  b,(hl)
2051   inc hl
2052   cal resbit
2053   ld  (ix+tail),l
2054   ld  (ix+tail+1),h
2055
2056 res4pixels:
2057   cal ResPixel
2058   inc b
2059   cal ResPixel
2060   inc c
2061   cal ResPixel
2062   dec b
2063 ResPixel:
2064   cal FindPixel
2065   cpl
2066   and (hl)
2067   ld  (hl),a
2068   ret
2069
2070 ;-----------------------------
2071 ;---------- ball -------------
2072 ;-----------------------------
2073
2074 handlethoseneatlittleballs:
2075   ld  hl,balls
2076   ld  b,a ;a=(nrballs)
2077 handleballs
2078   psh bc
2079   psh hl
2080   ld  c,(hl)
2081   inc hl
2082   ld  b,(hl)
2083   inc hl
2084   ld  d,(hl)
2085   cal handleball
2086   dec c
2087   pop hl
2088   ld  (hl),c
2089   inc hl
2090   ld  (hl),b
2091   inc hl
2092   ld  (hl),d
2093   inc hl
2094   pop bc
2095   dnz handleballs
2096   ret
2097
2098 handleball:
2099   cal res4pixels
2100   dec c
2101
2102 ballxmove:
2103   bit 0,d ;1=L; 0=R
2104   jr  z,ballright
2105 ballleft:
2106   dec b
2107   cal checkballhit
2108   jr  z,ballymove
2109   inc b ;undo
2110   res 0,d ;go right
2111   jr  ballymove
2112 ballright:
2113   inc b
2114   cal checkballhit
2115   jr  z,ballymove
2116   dec b ;back
2117   set 0,d ;>left
2118
2119 ballymove:
2120   bit 1,d ;1=up; 0=down
2121   jr  z,balldown
2122 ballup:
2123   dec c
2124   cal checkballhit
2125   jr  z,balldone
2126   inc c
2127   res 1,d ;go down
2128   jr  balldone
2129 balldown:
2130   inc c
2131   cal checkballhit
2132   jr  z,balldone
2133   dec c
2134   set 1,d ;up
2135 balldone:
2136
2137 set4pixels: ;@(b,c)
2138   cal SetPixel
2139   inc b
2140   cal SetPixel
2141   inc c
2142   cal SetPixel
2143   dec b
2144 SetPixel: ;at bc
2145   cal FindPixel
2146   or  (hl)
2147   ld  (hl),a
2148   ret
2149
2150 letsmovetheotherway:
2151   ld  a,1
2152   xor (hl)
2153   ld  (hl),a
2154   ret
2155
2156 checkballhit:
2157   psh de
2158   ld  d,0
2159   cal chk4pixels
2160   xor a
2161   cp  d
2162   pop de
2163   ret
2164
2165 ;-----------------------------
2166 ;----------- procs -----------
2167 ;-----------------------------
2168
2169 releasekeys:
2170   halt
2171   ld  a,%10000000    ;all key-masks
2172   out (1),a
2173   in  a,(1)
2174   inc a              ;cp %11111111 (no keys pressed)
2175   jr  nz,releasekeys ;keep waitin
2176   cal GET_KEY        ;clear buffer
2177   ret
2178
2179 resbit:
2180   ld  a,h
2181   and (ix+storepos)
2182   ld  h,a
2183   ret
2184
2185 randompos:
2186   ld  b,a
2187 Random: ;(2..b+2)
2188   ld  a,r
2189 Seed =$+1
2190   add a,0
2191   ld  (Seed),a
2192   and %01111110
2193   cp  b
2194   jr  nc,Random
2195   add a,2
2196   ret
2197
2198 NewPea:
2199   ld  a,(FieldWidth)
2200   add a,127-4
2201   cal randompos
2202   ld  h,a
2203   ld  a,(FieldHeight)
2204   add a,56-4
2205   cal randompos
2206   ld  l,a
2207   ld  (PeaY),hl
2208
2209 CheckPea:
2210   ld  c,l
2211   ld  a,(sprsize)
2212   ld  e,a
2213 chkloopy:
2214   ld  b,h
2215   ld  a,(sprsize)
2216   ld  d,a
2217 chkloopx:
2218   psh hl
2219   cal FindPixel
2220   and (hl)
2221   pop hl
2222   jr  nz,NewPea ;pixel found
2223   inc b
2224   dec d
2225   jr  nz,chkloopx
2226   inc c
2227   dec e
2228   jr  nz,chkloopy
2229 ;all ok; empty space
2230
2231 DrawPea: ;hl=(PeaY)
2232   ld  b,h
2233   ld  c,l
2234   ld  de,0
2235 spritepos =$-2
2236   jp  PutSprite ;||-ed
2237
2238 ;----------- score -----------
2239
2240 _divHLby1000:
2241   psh hl
2242   ld  b,3
2243 divideagain: ;3x
2244   cal _divHLby10
2245   dnz divideagain
2246   ld  a,l ;a=hl/1000
2247   pop hl
2248   ret
2249
2250 IncScore:
2251   ld  h,(ix+score+1)
2252   ld  l,(ix+score)
2253   cal _divHLby1000
2254   ld  c,a
2255   add hl,de
2256   cal _divHLby1000
2257   cp  c
2258   jr  z,scorecommon ;hl/1000 not increased
2259   inc (ix+lives)
2260   jr  scorecommon
2261 DecScore: ;&&&
2262   ld  h,(ix+score+1)
2263   ld  l,(ix+score)
2264   or  a
2265   sbc hl,de
2266   jr  c,showstats ;<0=0
2267 scorecommon:
2268   ld  (ix+score+1),h
2269   ld  (ix+score),l
2270   ld  de,0
2271 scorelimit =$-2
2272   inc e
2273   jr  z,showstats ;de=$FF??=no limit
2274   dec e
2275   cal _cphlde
2276   jp  nc,Exit
2277
2278 showstats:
2279   ld  a,(Gametype)
2280   cp  gametron
2281   ret z
2282 showstatsEven4tron:
2283   psh ix
2284   ld  h,0
2285   ld  l,h
2286   ld  (_penCol),hl
2287   ld  a,(nrworms)
2288   ld  b,a
2289   ld  ix,worm1
2290   ld  a,(gameCar)
2291   and _datanextl
2292   jr  nz,showstatsS
2293 showstatloop:
2294   psh bc
2295   cal showstat
2296   ld  de,worm2-worm1
2297   add ix,de
2298   ld  hl,_penCol
2299   ld  a,(hl)
2300   add a,10
2301   ld  (hl),a
2302   pop bc
2303   dnz showstatloop
2304   pop ix
2305   ret
2306
2307 showstat:
2308   ld  a,(gameCar)
2309   and _datascore
2310   jr  z,showlives
2311 showscore:
2312   ld  h,(ix+score+1)
2313   ld  l,(ix+score)
2314   cal _D_HL_DECI
2315   jr __vputs
2316 showlives:
2317   ld  a,(Gametype)
2318   cp  gametron
2319   jr  z,showscore
2320
2321   ld  a,(ix+lives)
2322   add a,'0'
2323 __vputmap:
2324   psh ix
2325   cal _vputmap
2326   pop ix
2327   ret
2328
2329 showstatsS:
2330   ld  hl,txtLevel
2331   cal __vputs
2332   ld  a,0
2333 Level =$-1
2334   cp  10
2335   jr  c,tilllevel9
2336   ld  l,a
2337   ld  h,0
2338   cal _divHLby10
2339   psh af
2340   ld  a,l
2341   add a,'0'
2342   cal __vputmap
2343   pop af
2344 tilllevel9:
2345   add a,'0'
2346   cal __vputmap
2347
2348   ld  a,98
2349   ld  (_penCol),a
2350   cal showscore
2351   ld  a,123
2352   ld  (_penCol),a
2353   cal showlives
2354   ld  a,(gameCar)
2355   and _datafoodl
2356   pop ix
2357   ret z
2358 showleft:
2359   ld  a,31
2360   ld  (_penCol),a
2361   ld  a,0
2362 Left =$-1
2363   cal cshowA
2364
2365   ld  hl,txtLeft
2366 __vputs:
2367   psh ix
2368   cal _vputs
2369   pop ix
2370   ret
2371
2372 showLevel:
2373   ld  hl,txtLevel
2374   cal _puts
2375   ld  a,(Level)
2376 showA:
2377   ld  l,a
2378   ld  h,0
2379   cal _divHLby10
2380   psh af
2381   ld  a,l
2382   add a,'0'
2383   cal _putc
2384   pop af
2385   add a,'0'
2386   jp  _putc
2387
2388 cshowA:
2389   ld  l,a
2390   ld  h,0
2391   cal _divHLby10
2392   psh af
2393   ld  a,l
2394   add a,'0'
2395   cal __vputmap
2396   pop af
2397   add a,'0'
2398   jp  __vputmap
2399
2400 showHL:
2401   cal _D_HL_DECI
2402   jp  _puts
2403
2404 _D_HL_DECI:
2405   ld  de,savestr+4
2406   ld  b,5
2407 ldhld:
2408   cal _divHLby10
2409   add a,'0'
2410   ld  (de),a
2411   dec de
2412   dnz ldhld
2413   ld  hl,savestr
2414   ret
2415 savestr:
2416   .db "00000",0
2417
2418 ;-----------------------------
2419
2420 DisplayField:
2421   ld  a,c
2422   sub 29
2423   jr  nc,NotMinYScroll
2424   xor a
2425 NotMinYScroll:
2426   cp  43
2427 FieldHeight =$-1
2428   jr  c,NotMaxYScroll
2429   ld  a,(FieldHeight)
2430 NotMaxYScroll:
2431   ld  l,a
2432   ld  h,0
2433   add hl,hl
2434   add hl,hl
2435   add hl,hl
2436   add hl,hl
2437   add hl,hl
2438   psh bc                        ; >> 1
2439   psh de                        ; >> 2
2440   ld  de,ScrBuffer
2441   add hl,de
2442   ld  a,b
2443   sub 64
2444   jr  nc,NotMinXScroll
2445   xor a
2446 NotMinXScroll:
2447   cp  128
2448 FieldWidth = $-1
2449   jr  c,NotMaxXScroll
2450   ld  a,(FieldWidth)
2451 NotMaxXScroll:
2452   psh af                        ; >> 3
2453   and %11111000
2454   rra
2455   rra
2456   rra
2457   ld  c,a
2458   ld  b,0
2459   ld  de,DispBuffer
2460   pop af                         ; << 2
2461   and %00000111
2462   psh af                        ; >> 3
2463   cp  6
2464   jr  c,CopyScreen
2465   inc c
2466 CopyScreen:
2467   add hl,bc
2468   ld  b,57
2469 CopyScreenLoop:
2470   psh bc                        ; >> 4
2471   ld  bc,16
2472   ldir
2473   ld  c,16
2474   add hl,bc
2475   pop bc                         ; << 3
2476   dnz CopyScreenLoop
2477   pop af                         ; << 2
2478   ld  c,$b7 ;or a
2479 Bit0:
2480   jr  nz,Bit1
2481   halt
2482   halt
2483   jr  AfterShiftDelay
2484 Bit1:
2485   dec a
2486   jr  nz,Bit2
2487   cal ShiftRight1
2488   jr  AfterShiftDelay
2489 Bit2:
2490   dec a
2491   jr  nz,Bit3
2492   ld  a,2
2493   cal ShiftRight
2494   jr  AfterShiftDelay
2495 Bit3:
2496   dec a
2497   jr  nz,Bit4
2498   cal Chunk
2499   cal ShiftLeft1
2500   jr  AfterShift
2501 Bit4:
2502   dec a
2503   jr  nz,Bit5
2504   cal Chunk
2505   jr  AfterShiftDelay
2506 Bit5:
2507   dec a
2508   jr  nz,Bit6
2509   cal Chunk
2510   cal ShiftRight1
2511   jr  AfterShift
2512 Bit6:
2513   dec a
2514   jr  nz,Bit7
2515   ld  a,2
2516   cal ShiftLeft
2517   jr  AfterShift
2518 Bit7:
2519   cal ShiftLeft
2520 AfterShiftDelay:
2521   halt
2522 AfterShift:
2523 #ifdef buffer
2524   ld  hl,DispBuffer
2525   ld  de,$fc00+$70
2526   ld  bc,1024-$70
2527   ldir
2528 #endif
2529   pop de                         ; << 1
2530   pop bc                         ; << 0k
2531   ret
2532
2533 ShiftRight1:
2534   ld  a,1
2535 ShiftRight:
2536   ld  (ShiftRightCounter),a
2537   ld  a,c
2538   ld  (ShiftRightChunk),a
2539   ld  c,16
2540   add hl,bc
2541   ld  b,57
2542 ShiftRightLoop:
2543   psh bc
2544   ld  bc,-32
2545   add hl,bc
2546   ex  de,hl
2547   ld  a,(de)
2548 ShiftRightChunk:
2549   or  a
2550   cal c,_SHLACC
2551   ld  c,0
2552 ShiftRightCounter = $-1
2553 ShiftRowsLeft:
2554   psh hl
2555   rla
2556   ld  b,16
2557 ShiftRowLeft:
2558   dec hl
2559   rl  (hl)
2560   dnz ShiftRowLeft
2561   pop hl
2562   dec c
2563   jr  nz,ShiftRowsLeft
2564   ld  bc,-16
2565   add hl,bc
2566   ex  de,hl
2567   pop bc
2568   dnz ShiftRightLoop
2569   ret
2570
2571 ShiftLeft1:
2572   ld  a,1
2573 ShiftLeft:
2574   ld  (ShiftLeftCounter),a
2575   ld  a,c
2576   ld  (ShiftLeftChunk),a
2577   rla
2578   jr  nc,ShiftLeftSameByte
2579   dec hl
2580 ShiftLeftSameByte:
2581   ex  de,hl
2582   ld  bc,-16
2583   add hl,bc
2584 NewSprite:
2585   ex  de,hl
2586   ld  b,57
2587 ShiftLeftLoop:
2588   psh bc                        ; >> 1
2589   ld  bc,-32
2590   add hl,bc
2591   ex  de,hl
2592   ld  a,(de)
2593 ShiftLeftChunk:
2594   or  a
2595   cal c,_SHRACC
2596   ld  c,0
2597 ShiftLeftCounter = $-1
2598 ShiftRowsRight:
2599   psh hl                        ; >> 2
2600   rra
2601   ld  b,16
2602 ShiftRowRight:
2603   rr  (hl)
2604   inc hl
2605   dnz ShiftRowRight
2606   pop hl                         ; << 1
2607   dec c
2608   jr  nz,ShiftRowsRight
2609   ld  bc,-16
2610   add hl,bc
2611   ex  de,hl
2612   pop bc                         ; << 0k
2613   dnz ShiftLeftLoop
2614   ret
2615
2616 Chunk:
2617   psh hl                        ; >> 1
2618   psh de                        ; >> 2
2619   ld  c,16
2620   add hl,bc
2621   ld  b,57
2622 ChunkScreen:
2623   psh bc                        ; >> 3
2624   ld  bc,-32
2625   add hl,bc
2626   ex  de,hl
2627   ld  a,(de)
2628   cal _SHRACC
2629   ld  b,16
2630 ChunkRow:
2631   dec hl
2632   rld
2633   dnz ChunkRow
2634   ex  de,hl
2635   pop bc                         ; << 2
2636   dnz ChunkScreen
2637   pop de                         ; << 1
2638   pop hl                         ; << 0k
2639   ld  c,$37 ;scf
2640   ret
2641
2642 ;----------- draw ------------
2643
2644 ;--- pixel ---
2645
2646 chk4pixels: ;&&
2647   cal CheckPixel
2648   inc b
2649   cal CheckPixel
2650   inc c
2651   cal CheckPixel
2652   dec b
2653   cal CheckPixel
2654   dec c
2655   ret
2656 CheckPixel: ;at bc in d
2657   cal FindPixel
2658   and (hl)
2659   ret z
2660   dec d
2661   ret
2662
2663 ;CLEM's FIND_PIXEL (131+? cycles; 28+4 bytes)
2664 ;(b,c) to hl:a; "destroyes" ahl
2665
2666 FindPixel: ;(b,c) to hl:a
2667   ld  h,0
2668   ld  l,c    ;hl=y
2669   add hl,hl
2670   add hl,hl
2671   ld  a,b    ;a=x
2672   rra
2673   add hl,hl
2674   rra
2675   add hl,hl
2676   add hl,hl  ;hl=32*y
2677   rra        ;a=x/8
2678   or  l
2679   ld  l,a
2680   ld  a,b
2681   and 7
2682   cpl
2683   rlca
2684   rlca
2685   rlca
2686   ld  (FP_Bit),a
2687   xor a
2688 FP_Bit =$+1
2689   set 0,a
2690
2691   psh de ;&&&
2692   ld  de,ScrBuffer
2693   add hl,de
2694   pop de
2695   ret
2696
2697 ;--- sprite ---
2698
2699 PutSprite:  ;||@(b,c)
2700   ;by SHIAR  only ix saved
2701   cal FindPixel
2702 putspr:
2703   ld  (beginbit),a
2704   ld  a,0
2705 sprsize =$-1
2706   ld  b,a ;rows
2707 sprloopy:
2708   psh bc ;rows
2709   psh hl
2710   ld  a,(de)
2711   ld  c,a
2712   inc de
2713   ld  a,(sprsize)
2714   ld  b,a ;width
2715 beginbit =$+1
2716   ld  a,1
2717 sprloopx:
2718   sla c ;draw?
2719   jr  nc,sprnodraw
2720   psh af
2721   xor (hl)
2722   ld  (hl),a
2723   pop af
2724 sprnodraw:
2725   rrca ;next bit
2726   jp  nc,nextbitok
2727   inc hl ;next byte
2728 nextbitok:
2729   dnz sprloopx
2730
2731   pop hl
2732   ld  bc,32 ;next line
2733   add hl,bc
2734   pop bc
2735   dnz sprloopy
2736   ret
2737
2738 ;--- objects ---
2739
2740 drawstuff:
2741   ld  a,(hl)
2742   inc hl
2743   or  a ;0 =
2744   ret z ;no more
2745
2746   ld  d,(hl)
2747   inc hl
2748   ld  e,(hl)
2749   inc hl
2750   ld  b,(hl)
2751   inc hl
2752   psh hl
2753   ld  l,(hl)
2754   ld  h,b
2755
2756   dec a ;1 = line
2757   cal z,drawline
2758   dec a ;2 = fatline
2759   cal z,drawfatline
2760   dec a ;3 = box
2761   cal z,drawbox
2762   dec a ;4 = circle
2763   cal z,circle
2764
2765   pop hl
2766   inc hl
2767   jr  drawstuff
2768
2769 drawbox: ;(d,e)-(h,l)
2770   ld  b,l ;Delta-y
2771   ld  l,e
2772 boxloop:
2773   cal drawline
2774   inc l
2775   inc e
2776   dnz boxloop
2777   ret
2778
2779 drawfatline:
2780   cal drawline
2781   inc d
2782   inc h
2783   cal drawline
2784   inc e
2785   inc l
2786   cal drawline
2787   dec d
2788   dec h
2789   jp  drawline
2790
2791 ;LINE (d,e)-(h,l)
2792 ;destroyes a
2793
2794 drawline:
2795   psh bc
2796   psh hl
2797   psh de
2798   ld  a,d
2799   cp  h
2800   jr  c,lineOrdered
2801   ex  de,hl
2802 lineOrdered:
2803   ld  b,d
2804   ld  c,e
2805   psh hl
2806   psh bc
2807   cal FindPixel
2808   pop bc
2809   pop de
2810 connectedLine:
2811   psh hl
2812   ld  h,c
2813   ld  c,a
2814   ld  a,d
2815   sub b
2816   ld  b,a
2817   ld  a,e
2818   jr  nz,LineNotPoint
2819   cp  h
2820   jr  nz,LineNotPoint
2821   pop hl
2822   jr  DoneLine
2823 LineNotPoint:
2824   sub h
2825   ld  de,32
2826   jr  nc,LinePositiveY
2827   neg
2828   ld  de,-32
2829 LinePositiveY:
2830   cp  b
2831   jr  nc,SteepLine
2832   add a,a
2833   ld  (line2sm+1),a
2834   ld  h,a
2835   xor a
2836   sub b
2837   add a,a
2838   ld  (line1sm+1),a
2839   ld  a,h
2840   sub b
2841   pop hl
2842 LineLoopGentle:
2843   psh af
2844   ld  a,(hl)
2845   or  c
2846   ld  (hl),a
2847   rrc c
2848   jr  nc,$+3
2849   inc hl
2850   pop af
2851   jp  m,line2sm
2852 line1sm:
2853   add a,0
2854   add hl,de
2855 line2sm:
2856   add a,0
2857   dnz LineLoopGentle
2858 DoneLine:
2859   ld  a,(hl)
2860   or  c
2861   ld  (hl),a
2862   pop de
2863   pop hl
2864   pop bc
2865   ret
2866 SteepLine:
2867   ld  h,a
2868   neg
2869   add a,a
2870   ld  (line3sm+1),a
2871   ld  a,b
2872   add a,a
2873   ld  (line4sm+1),a
2874   sub h
2875   ld  b,h
2876   pop hl
2877 LineLoopSteep:
2878   psh af
2879   ld  a,(hl)
2880   or  c
2881   ld  (hl),a
2882   add hl,de
2883   pop af
2884   jp  m,line4sm
2885 line3sm:
2886   add a,0
2887   rrc c
2888   jr  nc,$+3
2889   inc hl
2890 line4sm:
2891   add a,0
2892   dnz LineLoopSteep
2893   jr  DoneLine
2894
2895 ;CIRCLE (d,e),h
2896 ;destroyes ?
2897
2898 circle:                 ;de=x,y; h=z
2899   ld  c,h               ;c=yy=z
2900   ld  a,h
2901   neg
2902   ld  l,a               ;l=-z
2903   xor a
2904   ld  b,a               ;b=xx=0
2905   dec a                 ;-$00**
2906   ld  h,a               ;hl=zz=-z
2907 circloop:
2908   psh de                ;x,y
2909   ex  (sp),hl           ;push zz \ pop x,y
2910   cal circledraw        ;(x-xx,y+yy)-(x+xx,y+yy)
2911                         ;(x-xx,y-yy)-(x+xx,y-yy)
2912   cal circledraw        ;(x-yy,y+xx)-(x+yy,y+xx)
2913                         ;(x-yy,y-xx)-(x+yy,y-xx)
2914
2915   ex  (sp),hl           ;push x,y \ pop zz
2916   xor a
2917   ld  d,a               ;d=0
2918   dec a                 ;-256<h<0 = $FF**
2919   cp  h                 ;h<0?
2920   jr  z,circlenext      ;jump if zz<0
2921
2922   ld  a,c               ;yy
2923   dec a                 ;89<a<128
2924   add a,a               ;a=2yy-2 ;nc
2925   ld  e,a               ;de=a
2926   sbc hl,de             ;zz=zz-2yy+2
2927   dec c                 ;yy--
2928 circlenext:
2929   ld  a,b               ;xx
2930   inc a                 ;0<a<92
2931   add a,a               ;2xx+2
2932   inc a
2933   ld  e,a               ;de=a
2934   add hl,de             ;zz=zz+2xx+3
2935
2936   pop de                ;x,y
2937   ld  a,b
2938   cp  c
2939   ret nc                ;xx>=yy
2940   inc b                 ;xx++
2941   jr  circloop
2942
2943 circledraw:             ;destr:de
2944   psh hl
2945   ld  a,h               ;hl=x,y
2946   sub b                 ;bc=xx,yy
2947   ld  d,a               ;d=x-xx
2948   add hl,bc             ;h=x+xx; l=y+yy
2949   ld  e,l               ;e=y+yy
2950   cal drawline          ;(h-b,l+c)-(h+b,l+c)
2951   ld  a,l
2952   sub c                 ;a=y again
2953   sub c
2954   ld  l,a               ;l=y-yy
2955   ld  e,l               ;e=l=y-yy
2956   cal drawline          ;(h-b,l-c)-(h+b,l-c)
2957   ld  a,b               ;swap xx and yy
2958   ld  b,c
2959   ld  c,a               ;ex b,c
2960   pop hl
2961   ret
2962
2963
2964
2965
2966
2967 ;**** link routines ****
2968 ;these are identical in concept to the routines used in ZTetris, ZPong, and probably
2969 ;every other link game out there.  However, these are commented :)
2970 losses: .dw 0
2971 Csend:
2972   cal Qsend
2973   jr  c,Csend
2974   ret
2975 Qsend:
2976 send:
2977 ;inputs: c=byte to send, both wires must be high by default
2978 ;outputs: b=8-number of bits sent, both wires high, goes to game over on certain conditions
2979 ;destroys: af,bc,de
2980         in a,(7)
2981         and %00000011
2982         jr z,killlink           ;if both lines low, get out of here (game over signal)
2983         ld b,8                          ;sending 8 bits
2984 sendloop:
2985         ld de,$8000                     ;error timer
2986         rl c                            ;force high bit into carry
2987         ld a,%11010100          ;lower the red wire by default (sending 0) ($d4)
2988         jr nc,selected          ;if high bit was 0, use above value
2989         ld a,%11101000          ;if 1, lower the white wire instead ($e8)
2990 selected:
2991         out (7),a                       ;put it out the link port
2992 waitconfirm:
2993         call linktimer
2994         in a,(7)                        ;see what the wires are doing
2995         and %00000011           ;check lower 2 bits
2996         jr nz,waitconfirm       ;if both bits 0, data was received ok (both wires low)
2997         ld a,%11000000
2998         out (7),a                       ;give the ok to raise both wires (one will be done automatically) ($c0)
2999 waitconfirm2:
3000         call linktimer
3001         in a,(7)
3002         and %00000011
3003         cp 3
3004         jr nz,waitconfirm2      ;wait for other calc to raise the other wire
3005         djnz sendloop           ;continue sending
3006         xor a                           ;reset c; ld a,0
3007         ld (losses),a           ;reset number of losses
3008         ret
3009
3010
3011 Crecv:
3012   cal receive
3013   jr  c,Crecv
3014   ret
3015 Qrecv:
3016 receive:
3017 ;inputs: both wires must be high by default
3018 ;outputs: c=byte received, b=8-number of bits received, both wires high
3019 ;       goes to game over on certain conditions
3020 ;destroys: af,bc,de
3021         in a,(7)
3022         and %00000011
3023         jr z,killlink           ;game over signal applies to receiving too
3024         ld b,8                          ;receiving 8 bits
3025 receiveloop:
3026         ld de,$8000                     ;error timer
3027 waitreceive:
3028         call linktimer
3029         in a,(7)
3030         and %00000011
3031         cp 3                            ;if bits 0 and 1 set, both wires are high
3032         jr z,waitreceive        ;wait for one of the wires to go low
3033         rra                                     ;check red wire status
3034         rl c                            ;if set, red is high (thus white is low), so put the correct bit into c
3035         rra                                     ;now check white wire (since the flags are destroyed)
3036         ld a,%11010100          ;$d4
3037         jr nc,selected2         ;if white is low, lower red and vice versa              
3038         ld a,%11101000          ;$e8
3039 selected2:
3040         out (7),a                       ;so now both wires are low
3041 waitreceive2:
3042         call linktimer
3043         in a,(7)
3044         and %00000011
3045         jr z,waitreceive2       ;wait for the wire we didn't lower to go high again (the other will remain low)
3046         ld a,%11000000          ;$c0
3047         out (7),a                       ;raise both wires since the other calc will have given the ok sign
3048         djnz receiveloop        ;if not done, wait for next bit
3049         xor a                           ;reset c
3050         ld (losses),a           ;reset number of losses
3051         ret
3052
3053 linktimer:                              ;leave if we have to wait too long (and return an error)
3054         dec de
3055         ld a,d
3056         or e                            ;see if de is 0
3057         ret nz                          ;if not, keep going as usual
3058                                                 ;otherwise we have to deal with a link failure
3059         ld a,%11000000          ;$c0
3060         out (7),a                       ;reset link status (both high)
3061         ld a,(losses)           ;see how many consecutive losses we have
3062         inc a
3063         ld (losses),a           ;add this loss to it
3064         pop de                          ;fix the stack to leave the link routine (de is ok to destroy)
3065         cp 20                           ;see if this is the 20th consecutive failure
3066         ret c                           ;if not, keep playing
3067                                                 ;otherwise, all is probably lost...
3068
3069 killlink2:
3070         jr linkend
3071 killlink:
3072 linkend:
3073   jp  z,Exit
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083 #ifdef 0
3084 ;-----------------------------
3085 ;----------- link ------------
3086 ;-----------------------------
3087
3088 timeout = $800
3089
3090 checklink:
3091   dec de
3092   ld  a,d
3093   or  e
3094   jr  z,linkerror
3095
3096   ld  a,$BF
3097   out (1),a
3098   in  a,(1)
3099   bit 6,a
3100   jp  z,Exit
3101
3102   in  a,(7)
3103   and %11
3104   ret
3105
3106 linkerror:
3107   scf
3108   ld  a,%11
3109   pop hl
3110   ret
3111
3112 ;--------------
3113 ;---- SEND ----
3114 ;--------------
3115
3116 Csend:          ;--- send 8 bits in A --- destr:abcdehl ---
3117   ld  c,a
3118 Csendloop:
3119   cal Qsend
3120   ret nc                ;NC = all ok
3121   ld  a,D0HD1H
3122   out (7),a             ;both high
3123   jr  Csendloop         ;CF = error
3124
3125 Qsend:          ;--- try to send 8 bits in C; CF=error --- destr:abcdehl ---
3126   ld  de,timeout
3127   cal checklink
3128   cp  %11               ;are they?
3129   scf
3130   ret nz                ;nope, wait
3131   ld  b,8               ;bits to send
3132 sendloop:
3133   ld  de,timeout
3134   rl  c                 ;bit to send in cf
3135   ld  a,D0LD1H          ;0: lower white
3136   jr  nc,sendbit
3137   ld  a,D0HD1L          ;1: lower red
3138 sendbit:
3139   out (7),a             ;lower one (send bit)
3140 sendwaitack:
3141   cal checklink         ;other calc must lower other wire
3142   jr  nz,sendwaitack
3143   ld  a,D0HD1H          ;raise one, ok to raise other
3144   out (7),a
3145 sendfinish:
3146   cal checklink
3147   cp  %11               ;both raised (by other calc)
3148   jr  nz,sendfinish
3149   nop \ nop
3150   dnz sendloop          ;repeat for all bits
3151   xor a                 ;nc...
3152   ret                   ;=ok
3153
3154 ;--------------
3155 ;---- RECV ----
3156 ;--------------
3157
3158 Crecv:          ;--- receive 8 bits into A/C --- destr:abcdehl ---
3159   cal Qrecv
3160   ret nc                ;return if all went ok
3161   ld  a,D0HD1H
3162   out (7),a             ;raise both on error
3163   jr  Crecv             ;and try again
3164
3165 Qrecv:          ;--- receive 8 bits into A/C; CF=error --- destr:abcdehl ---
3166   ld  de,timeout
3167   cal checklink
3168   jp  z,Exit            ;both low = error, quit
3169   cp  %11
3170   scf
3171   ret z                 ;both high = nothing yet, wait
3172   ld  b,8               ;bits to receive
3173 recvloop:
3174   ld  de,timeout
3175 recvwait:
3176   cal checklink
3177   cp  %11
3178   jr  z,recvwait        ;both high = nothing sent (yet)
3179   rra                   ;received bit in cf
3180   ld  a,D0LD1H
3181   jr  c,received        ;lower white wire as well
3182   ld  a,D0HD1L          ;lower red
3183 received:
3184   rl  c                 ;save bit in c
3185   out (7),a             ;both wires low
3186 recvwaitack:
3187   cal checklink
3188   jr  z,recvwaitack     ;same wire will be raised again by other calc
3189   ld  a,D0HD1H
3190   out (7),a             ;raise both
3191 recvfinish:
3192   dnz recvloop          ;repeat for all bits
3193   xor a                 ;nc=no error
3194   ld  a,c               ;result in a
3195   ret
3196 #endif
3197
3198 ;-----------------------------
3199 ;---------- levels -----------
3200 ;-----------------------------
3201
3202 LevelDef:
3203   .db 5,4,15,15,0,0     ;peas,speed,growth,begin_size,sprite,balls
3204   .db 0,2,63            ;start d, y, x
3205   .db 128,57            ;field width (128-255), height (57-255)
3206   .db 0                 ;no additional lines, boxes
3207   .db 255
3208    ret
3209
3210 LevelDefM:
3211   .db 8,4,15,15,0,0
3212   .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3213   .db 128,57
3214   .db 0
3215
3216   .db 8,0,18,12,5
3217   .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3218   .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3219   .db 128,57
3220   .db 0
3221
3222   .db 8,5,18,12,0,0
3223   .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3224   .db 128,57
3225  .db 4,40,26,20,0
3226  .db 4,90,40,11,0,0
3227
3228 LevelDefT: ;tron=no delay
3229   .db 8,4,18,12,5
3230   .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3231   .db $40,30,64,$C0,30,64, $00,30,64,$80,30,64
3232   .db 128,57
3233   .db 0
3234
3235 LevelDefC: ;ctf
3236   .db 8,4,18,12,5
3237   .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3238   .db $40,30,64,$C0,30,64, $00,30,64,$80,30,64
3239   .db 128,57
3240   .db 10,10,50,50
3241   .db 0
3242
3243 ;-----------------------------
3244 ;---------- data -------------
3245 ;-----------------------------
3246
3247 wdPicture = 16
3248 wtPicture:
3249 .db %01001010,%00101001,%00000111,%10000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01110000,%00000000,%00000000,%00000000,%01000000,%00000000
3250 .db %10001010,%10101000,%10001111,%10000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111000,%00000000,%00000000,%00000000,%10100100,%01000000
3251 .db %10101010,%10101010,%10011100,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00011100,%00001110,%00000000,%00000000,%10101010,%10100000
3252 .db %01010001,%01000101,%00011000,%00011111,%00000000,%01111111,%11000000,%00111100,%00011110,%01111000,%00001100,%00011111,%00000000,%00000000,%11001001,%10100000
3253 .db %00000000,%00000000,%00111000,%00111111,%10000000,%11111111,%11100000,%11111110,%00111111,%11111100,%00001100,%00111011,%10000000,%00000011,%10001000,%00100000
3254 .db %01101010,%10010011,%00110000,%01110001,%11000001,%11000000,%01110001,%11100110,%01110011,%11001110,%00001100,%00110001,%10000000,%00000000,%10010000,%00100000
3255 .db %10001010,%00101010,%10110000,%01100000,%11000001,%10000000,%00111001,%10000000,%01100111,%11100110,%00001110,%01110001,%10000000,%00000000,%01100000,%01000000
3256 .db %11101110,%10111011,%00110000,%01100000,%11000001,%10110000,%00011011,%10000000,%11101110,%01110111,%00001110,%01110001,%10000011,%11100000,%00000011,%10000000
3257 .db %00101010,%10101010,%10110000,%01110001,%11000001,%10110000,%00011011,%00000000,%11001100,%00110011,%00000111,%11100001,%10001100,%00011000,%00010000,%00000000
3258 .db %11001010,%10101010,%10110000,%00110001,%10000001,%10110000,%00011011,%00000000,%11001100,%00110011,%00000011,%11000011,%10010000,%00000100,%00100011,%00001100
3259 .db %00000000,%00000000,%00111000,%00111011,%10000011,%10110000,%00011011,%00000000,%11001110,%01110011,%00000000,%00000011,%00010011,%00000100,%00100100,%10010010
3260 .db %00111001,%11000111,%00011000,%00011111,%00000011,%00110000,%00011011,%00000000,%11000111,%11100011,%10000000,%00000011,%00001100,%10000100,%00101000,%10010100
3261 .db %01100101,%00101000,%00011100,%00001110,%00000111,%00111000,%00111011,%10000000,%11000011,%11000001,%10000000,%00000111,%00000000,%01001110,%00101000,%10011000
3262 .db %01001101,%11001011,%00001110,%00111111,%10001110,%00011100,%01110001,%10000000,%11100000,%00000001,%11100000,%00001110,%00000000,%01010101,%00101000,%10011000
3263 .db %00111001,%01100111,%00000111,%11111011,%11111100,%00001111,%11100001,%11000000,%01100000,%00000000,%11111111,%11111100,%00000000,%10010101,%00100110,%00010100
3264 .db %00000000,%00000000,%00000011,%11100000,%11111000,%00000111,%11000000,%11000000,%01100000,%00000000,%00111111,%11111000,%11111111,%00001000,%11000001,%11100011
3265
3266 txtMenu:  .db "Mode",0  ;1st menu item
3267           .db "Level",0 ;2nd
3268           .db "Limit",0 ;...
3269           .db "Worms",0
3270           .db "worm #",0
3271           .db "controls",0
3272 posMenu:  .dw $$2418,$231E,$2524,$1F2A,$1730,$1936
3273 txtGame:  .db "Singleplayer",0
3274 txtGame1: .db "Peaworm",0
3275 txtGame2: .db "Tron",0
3276 txtGame3: .db "Deathmatch",0
3277 txtGame4: .db "Foodmatch",0
3278 txtGame5: .db "LinkMatch",0
3279 txtGame6: .db "Race",0
3280 txtGame7: .db "CTF",0
3281 ;            .db "Domination",0    ;8
3282 posGame:  .db 0,txtGame1-txtGame
3283           .db txtGame2-txtGame
3284           .db txtGame3-txtGame
3285           .db txtGame4-txtGame
3286           .db txtGame5-txtGame
3287           .db txtGame6-txtGame
3288           .db txtGame7-txtGame
3289
3290 txtKeyleft: .db "Left",0
3291 txtKeyright:.db " | Right",0
3292 txtLevsel:  .db $CF," Select levels: ",5,0
3293 txtEName:   .db "Enter name player ",0
3294 txtWaiting: .db "Waiting...",0
3295 txtReceive: .db "Receiving..." ;,0
3296
3297 TrigPrecalc:
3298 .db   0,  3,  6,  9, 12, 15, 18, 21
3299 .db  24, 27, 30, 33, 36, 39, 42, 45
3300 .db  48, 51, 54, 57, 59, 62, 65, 67
3301 .db  70, 73, 75, 78, 80, 82, 85, 87
3302 .db  89, 91, 94, 96, 98,100,102,103
3303 .db 105,107,108,110,112,113,114,116
3304 .db 117,118,119,120,121,122,123,123
3305 .db 124,125,125,126,126,126,126,126
3306 .db 127
3307
3308 txtLevel:  .db "Level ",0
3309 txtWorms:  .db "Worms: 0",0     ;follows txtLevel
3310 txtName:   .db "Name",0
3311 txtDied:   .db "Died    "       ;follows txtName
3312 txtScore:  .db "Score",0        ;follows txtDied
3313 txtLeft:   .db " left",0        ;follows txtScore
3314 txthiscore:.db "HiScore:",0
3315 txtReady:  .db "Prepare!",0
3316 txtposReady = 7
3317 txtGO:     .db 5,5,5,5,5," GAME OVER ",$CF,$CF,$CF,$CF,$CF,0
3318
3319 _datalink  = %00000001 ;linkplay
3320 _datalivel = %00000010 ;lives=0 limit
3321 _datafoodl = %00000100 ;left=0 limit
3322 _datanextl = %00001000 ;next level if left=0
3323 _datasingl = %00001000 ;singleplayer=1
3324                        ;1=hiscore+keep_length
3325 _datafood  = %00010000 ;food present
3326 _datadie   = %01000000 ;worm dies on impact
3327 _datascore = %10000000 ;score>=100 limit
3328 _datamultpeas = %00100000
3329 _datasp    = %01011110
3330
3331 datalevels: .dw LevelDef, LevelDefT
3332             .dw LevelDefT,LevelDefM
3333             .dw LevelDefM,LevelDefM
3334             .dw LevelDefM,LevelDefC
3335 nrlevels:   .db 1,3,1,3,3,3,3,1     ;=defaults
3336
3337 savestart:
3338
3339 gamesingle   =  0
3340 datasingle: .db %01011110,3,1 ;3 lives (<must b unique)
3341 gamepeas     =  1
3342 datapeas:   .db %01011010,1,1 ;1 "
3343 gametron     =  2
3344 datatron:   .db %01000010,1,2
3345 gamedeathm   =  3
3346 datadeathm: .db %01000010,3,2
3347 gamefoodm    =  4
3348 datafoodm:  .db %11010000,10,2 ;10 score limit (=100)
3349 gamelinkm    =  5
3350 datalinkm:  .db %01000011,3,2
3351 gamerace     =  6
3352 datarace:   .db %10000000,10,2
3353 gamectf      =  7
3354 datactf:    .db %11100000,9,4
3355 ;gamedomin    =  8
3356 ;datadomin:  .db %01100000,3 ;==(8 modes)
3357
3358 worm1set:  .dw worm1p,worm1p
3359            .db %11110111,%00,%01111110,K_RIGHT,K_LEFT
3360 worm1name: .db "Wormy   ",0
3361 worm2set:  .dw worm2p,worm2p
3362            .db %11111011,%11,%00111111,K_F2,K_F1
3363 worm2name: .db "Viper   ",0
3364 worm3set:  .dw worm3p,worm3p
3365            .db %11111011,0,%01011111,K_COMMA,K_STO
3366 worm3name: .db "Nibbler ",0
3367 worm4set:  .dw worm4p,worm4p
3368            .db %11111011,0,%01111101,K_PLUS,K_ENTER
3369 worm4name: .db "Spunky  ",0
3370
3371 defhiscrpos:
3372   .dw 0,0,0,0,0,0
3373
3374 saveend:
3375
3376                ;set:
3377 heading  = 0   ;level*
3378 pos      = 2   ;level*
3379 pos2     = 4   ;level
3380 grow     = 6   ;level
3381 died     = 8   ;game
3382 score    = 9   ;game
3383 delay    = 11  ;game
3384                ;19B @game
3385 lives    = 12
3386 head     = 13  ;4B (head=tail)
3387 tail     = 15  ;also@next level
3388 storepos = 17
3389 reserv   = 18  ;loop (race:lap|ctf:pea)
3390 input    = 19
3391 left     = 20
3392 right    = 21
3393 name     = 22
3394 wormsize = 31
3395
3396 startdelay    = 30
3397 respawndelay  = 30
3398 maxnamelength = 8+1
3399
3400 .db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
3401 .db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
3402 .db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
3403 .db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
3404 .db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
3405 .db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
3406 .db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
3407 .db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
3408 .db "WWW.SHIAR.ORG  WWW.SHIAR.ORG  "
3409 .db "   shiar0@hotmail.com",0
3410
3411 defspritesz = 4
3412 defspriteimg:   .db %01100000
3413                 .db %11110000
3414                 .db %11110000
3415                 .db %01100000
3416
3417 deflevels:
3418   .db 15,"Internal Levels"
3419
3420   .db 0,deflevels/256,deflevels&255
3421 templevels:
3422
3423 ;-----------------------------
3424 ;----------- end -------------
3425 ;-----------------------------
3426
3427   .end
3428
3429 .end