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