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