worm 0.91.0516: send game data over link (wip)
[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
784 ;  cal sendname
785 ;  cal receivename
786
787   ld  a,$18
788   jr  nc,multiplayer
789
790 linkiniterror:
791   pop hl
792   jp  DisplayMenu
793
794 sendname:
795   ld  hl,worm1+name
796   ld  b,maxnamelength
797 sendnameloop:
798   ld  a,(hl)
799   inc hl
800   psh bc
801   psh hl
802   cal send
803   pop hl
804   pop bc
805   dnz sendnameloop
806   ret
807 receivename:
808   ld  hl,worm2+name
809   ld  b,maxnamelength
810 recvnameloop:
811   psh bc
812   psh hl
813   cal receive
814   pop hl
815   pop bc
816   ld  (hl),a
817   inc hl
818   dnz recvnameloop
819   ret
820
821 client:
822   ld  hl,txtReceive
823   cal _puts
824   cal Qreceive
825   jp  c,linkiniterror
826   cp  WormVersion
827   jp  nz,linkiniterror
828
829 ;  cal receivename
830 ;  cal sendname
831
832   ld  a,$f6
833 multiplayer:
834   ld  (SwapPos),a
835   ld  a,2
836   ld  (nrworms),a
837
838 ;-----------------------------
839 ;--------- game over ---------
840 ;-----------------------------
841
842 GameOver:
843   cal _clrLCD
844   ld  hl,worm1set
845   ld  de,worm1
846   ld  a,4 ;4x (all worms)
847 createwormsloop:
848   ex  de,hl
849   ld  bc,died
850   add hl,bc
851   ld  (hl),0 ;died=0
852   inc hl
853   ld  (hl),0 ;score=0
854   inc hl
855   ld  (hl),0 ;score+1=0
856   inc hl
857   ld  (hl),2 ;delay=2
858   inc hl
859   ex  de,hl  ;de=wormX+head
860   ld  bc,19
861   ldir       ;copy 19 bytes
862   dec a      ;loop
863   jr  nz,createwormsloop
864
865   ld  a,(Gametype)
866   cp  1 ;=peaworm
867   jr  nz,worminitdone
868   ld  (worm1+lives),a
869 worminitdone:
870   pop hl ;begin of current level
871
872 StartLevel:
873   ld  de,Left
874   ld  a,(hl)
875   inc a ;=255?
876   jp  nz,nextlevel
877
878   psh hl
879   cal releasekeys
880   cal _clrWindow
881   pop hl
882 ;show end msg or smtn
883   ld  bc,Exit
884   psh bc   ;where to go afterwards
885   inc hl   ;location of ending-code
886   jp  (hl) ;go there ("call")
887 nextlevel:
888   ldi
889   ld  de,Speed
890   ldi
891   ld  de,peagrowth
892   ldi
893   ld  a,(hl)
894   ld  (worm1+grow),a
895   ld  (worm2+grow),a
896   ld  (worm3+grow),a
897   ld  (worm4+grow),a
898   ld  (beginsize),a
899   inc hl
900
901   ld  a,(hl)
902   inc hl
903   or  a
904   jr  z,defaultsprite
905   ld  d,h
906   ld  e,l ;ld de,hl
907   ld  c,a
908   ld  b,0 ;bc=sprite size
909   add hl,bc ;hl=behind sprite
910   jr  setsprite
911 defaultsprite:
912   ld  a,defsprsize
913   ld  de,peasprite
914 setsprite:
915   ld  (sprsize),a
916   ld  (spritepos),de
917
918   ld  a,(hl)
919   inc hl
920   ld  (nrballs),a
921   or  a
922   jr  z,toobad_noballs
923   ld  c,a
924   add a,a
925   add a,c
926   ld  c,a
927   ld  b,0
928   ld  de,balls
929   ldir
930 toobad_noballs:
931
932   ex  de,hl
933 #ifndef invincible
934   ld  (thislevel),de
935 #endif
936
937   ld  hl,worm1
938   ld  a,(gameCar)
939   and _datanextl
940   ld  b,1
941   jr  nz,worminit
942   ld  b,4
943 worminit:
944   psh bc                        ; >> 1
945   ex  de,hl
946   ldi          ;d
947   ld  a,SinCosTable/256
948   ld  (de),a
949   inc de
950   ldi          ;y
951   ldi          ;x
952   ex  de,hl
953
954   xor a
955   ld  (hl),a   ;y2
956   inc hl
957   ld  (hl),a   ;x2
958
959   ld  bc,(worm2-worm1)-5
960   add hl,bc
961   pop bc                         ; << 0k
962   dnz worminit
963
964 ;-------- draw level ---------
965
966   ld  a,(de)
967   inc de
968   sub 128
969   ld  (FieldWidth),a
970   ld  a,(de)
971   inc de
972   sub 57
973   ld  (FieldHeight),a
974   add a,57-5
975   psh de                        ; >> levelp
976   ld  l,a
977   ld  h,0
978   add hl,hl
979   add hl,hl
980   add hl,hl
981   add hl,hl
982   add hl,hl
983   ex  de,hl
984
985   ld  hl,ScrBuffer
986   psh hl                        ; >> 1
987   psh de                        ; >> 2
988   ld  de,ScrBuffer+1
989   ld  bc,63
990   ld  (hl),%11111111
991   ldir
992   inc hl
993   ld  (hl),%11000000
994   inc hl
995   ld  b,31
996 ClearLine:
997   ld  (hl),c
998   inc hl
999   dnz ClearLine
1000   psh hl                        ; >> 3
1001
1002   ld  a,(FieldWidth)
1003   add a,126
1004   psh af                        ; >> 4
1005   and %11111000
1006   rra
1007   rra
1008   rra
1009   ld  l,a
1010   ld  h,0
1011   add hl,de
1012   pop af                         ; << 3
1013   and %00000111
1014   ld  b,a
1015   ld  c,0
1016   ld  a,%11000000
1017   jr  z,NoVertShift
1018 VertShift:
1019   rra
1020   rr  c
1021   dnz VertShift
1022 NoVertShift:
1023   ld  (hl),a
1024   inc hl
1025   ld  (hl),c
1026
1027   ex  de,hl
1028   pop de                         ; << 2
1029   pop bc                         ; << 1
1030   ldir
1031   pop hl                         ; << 0k
1032   ld  c,64
1033   ldir
1034
1035
1036   pop hl                         ; << levelp
1037   ld  a,(Gametype)
1038   cp  gamectf
1039   jr  nz,noctf
1040   ld  de,peaspos
1041   ld  bc,4
1042   ldir
1043   psh hl
1044   cal DrawAllPeas
1045   pop hl
1046 noctf:
1047
1048 ;-draw lines-
1049
1050   ld  a,(hl)
1051   inc hl
1052   or  a
1053   jr  z,NoLines
1054 DrawLines:
1055   psh af                        ; >> 1
1056   cal loaddrawdata
1057   psh hl                        ; >> 2
1058   ld  l,(hl)
1059   ld  h,a
1060   cal Line
1061   inc d
1062   inc h
1063   cal Line
1064   inc e
1065   inc l
1066   cal Line
1067   dec d
1068   dec h
1069   cal Line
1070   pop hl                         ; << 1
1071   inc hl
1072   pop af                         ; << 0k
1073   dec a
1074   jr  nz,DrawLines
1075 NoLines:
1076
1077   ld  a,(hl)
1078   inc hl
1079   or  a
1080   jr  z,noboxes
1081 drawboxes:
1082   psh af
1083   cal loaddrawdata
1084   psh hl
1085   ld  l,(hl)
1086   ld  h,a
1087   cal drawbox
1088   pop hl
1089   inc hl
1090   pop af
1091   dec a
1092   jr  nz,drawboxes
1093 noboxes:
1094
1095 ;-----------------------------
1096
1097   psh hl                        ; >> levelp new
1098   cal showstats
1099   ld  a,(gameCar)
1100   and _datafood
1101   jr  z,nofood
1102   cal NewPea
1103 nofood:
1104   ld  bc,(worm1+pos)
1105   cal DisplayField
1106
1107 #ifdef readymask
1108   ld  hl,$FC70
1109   ld  d,%10101010
1110   ld  c,56
1111 maskloop:
1112   ld  a,d
1113   xor %11111111
1114   ld  d,a
1115   ld  b,$10
1116 maskline:
1117   ld  a,(hl)
1118   or  d
1119   ld  (hl),a
1120   inc hl
1121   dnz maskline
1122   dec c
1123   jr  nz,maskloop
1124 #endif
1125
1126 #ifdef readytext
1127   ld  hl,$FDE0
1128   ld  de,$FDE1
1129   ld  (hl),%11111111
1130   ld  bc,$BF
1131   ldir
1132   ld  hl,4+(txtposReady*256)
1133   ld  (_curRow),hl
1134   set 3,(iy+5)
1135   ld  hl,txtReady
1136   cal _puts
1137   res 3,(iy+5)
1138 #endif
1139
1140   ld  a,0
1141 gameCar =$-1
1142   and _datalink
1143   jr  z,initfinished ;no link
1144
1145   xor a
1146   ld  (worm2+input),a ;worm 2 via link
1147   ld  (worm2+left),a
1148   ld  (Speed),a ;max.speed
1149 SwapPos: ;$18 xx -> $F6 xx
1150          ; jr xx ->  or xx
1151   jr  initfinished
1152   inc a
1153   ld  (worm2+left),a ;1
1154   ld  hl,worm1
1155   ld  de,worm2
1156   ld  b,4 ;+heading +pos
1157   cal _EXLP ;swap positions
1158 ;&&& over link
1159   ld  hl,worm1+name
1160   ld  de,worm2+name
1161   ld  b,maxnamelength
1162   cal _EXLP ;swap positions
1163 initfinished:
1164
1165   ld  b,startdelay
1166 ReadyDelay:
1167   halt
1168   dnz ReadyDelay
1169   cal releasekeys
1170
1171 ;-----------------------------
1172 ;----------- LOOP ------------
1173 ;-----------------------------
1174
1175 GameLoop:
1176   ld  bc,(worm1+pos)
1177   cal DisplayField
1178
1179   ld  a,1
1180 flashtime =$-1
1181   dec a
1182   jr  z,noflash
1183   ld  (flashtime),a
1184   ld  hl,$fc00+(16*7)
1185 screeninvertloop:
1186   ld  a,(hl)
1187   cpl
1188   ld  (hl),a
1189   inc hl
1190   xor a
1191   cp  h
1192   jr  nz,screeninvertloop
1193 noflash:
1194
1195   ld  a,0
1196 Speed =$-1
1197   or  a
1198   jr  z,NoDelay
1199 Delay:
1200   halt
1201   dec a
1202   jr  nz,Delay
1203 NoDelay:
1204
1205   ld  a,0
1206 nrballs =$-1
1207   or  a
1208   cal nz,handlethoseneatlittleballs
1209
1210   ld  ix,worm1
1211   ld  a,(nrworms)
1212   ld  b,a
1213 handleworms:
1214   psh bc
1215   cal HandleWorm
1216   ld  bc,worm2-worm1
1217   add ix,bc
1218   pop bc
1219   dnz handleworms
1220
1221 ;-----------------------------
1222 ;---------- keys -------------
1223 ;-----------------------------
1224
1225 HandleKeys:
1226   ld  a,%10111111
1227   out (1),a
1228   in  a,(1)
1229   rla ;MORE?
1230   jr  c,CheckExit
1231   ld  bc,$0103
1232   out (c),b
1233   halt ;pause/off
1234   ld  b,11
1235   out (c),b
1236
1237 CheckExit:
1238   rla  ;=$17 (c=EXIT-key)
1239       ;or$A7 (c=0)
1240   jp  c,GameLoop
1241   jr  Exit
1242
1243 WormDead:
1244 #ifdef invincible
1245   jp  stopworm
1246 #else
1247   ld  a,2
1248   ld  (flashtime),a
1249   ld  (ix+delay),respawndelay
1250
1251 thislevel =$+1
1252   ld  de,0
1253   ld  a,(de)
1254   inc de
1255   ld  (ix+heading),a
1256   ld  a,(de)
1257   ld  (ix+pos),a
1258   inc de
1259   ld  a,(de)
1260   ld  (ix+pos+1),a
1261
1262   inc (ix+died)
1263   dec (ix+lives)
1264   psh af
1265   ld  de,10
1266   cal DecScore
1267   pop af
1268   ret nz ;HandleWorm done
1269   ld  a,(gameCar)
1270   and _datalivel
1271   ret z
1272   ld  a,$A7 ;exit@end of turn
1273   ld  (CheckExit),a ;set exit state
1274   ret ;finish turn
1275 #endif
1276
1277 Exit:
1278   ld  sp,0 ;pop all
1279 SpSave = $-2
1280   cal _clrWindow
1281   ld  hl,txtGO
1282   cal _puts
1283   ld  hl,txtGame
1284 CURtxtGame =$-2
1285   cal _puts
1286   ld  de,0002
1287   ld  (_curRow),de
1288   cal showLevel
1289   ld  de,$0B03
1290   ld  (_curRow),de
1291   ld  hl,txtDied
1292   cal _puts
1293   cal _puts ;txtScore
1294   xor a
1295   ld  (_curCol),a
1296
1297   ld  a,(nrworms)
1298   ld  b,a
1299   ld  hl,worm1+died
1300 displayWormStats:
1301   psh bc
1302   psh hl
1303
1304   ld  bc,input-died
1305   add hl,bc ;+input
1306   xor a
1307   cp  (hl)  ;input=0 = link
1308   jr  nz,NoLinkIndic
1309   ld  b,7 ;{DOWN}
1310   inc hl ;+left
1311   cp  (hl)
1312   jr  z,hostLinkIndic
1313   dec b   ;{UP}
1314 hostLinkIndic:
1315   ld  a,8
1316   ld  (_curCol),a
1317   ld  a,b
1318   cal _putc
1319   xor a
1320   ld  (_curCol),a
1321   dec hl
1322 NoLinkIndic:
1323   inc hl
1324   inc hl
1325   inc hl ;+name
1326   cal _puts
1327
1328   pop hl
1329   psh hl
1330   ld  a,13
1331   ld  (_curCol),a
1332   ld  a,(hl) ;worm+died
1333   cal showA
1334   pop hl
1335   psh hl
1336
1337   ld  a,16
1338   ld  (_curCol),a
1339   inc hl ;worm+score
1340   cal _ldHLind ;ld hl,(hl)
1341   cal showHL ;worm+score
1342
1343   pop hl
1344   ld  bc,worm2-worm1
1345   add hl,bc
1346   pop bc
1347   dnz displayWormStats
1348
1349   ld  a,(Gametype)
1350   or  a ;singleplayer (0) only
1351   jr  nz,hilevelcheckdone
1352 checkhilevel:
1353   ld  hl,nrlevels
1354   ld  a,(Level)
1355   cp  (hl)
1356   jr  c,hilevelcheckdone
1357   ld  (hl),a    ;save local
1358   ld  c,a
1359   ld  a,0
1360 hilvlposa =$-1
1361   ld  hl,0
1362 hilvlposhl =$-2 ;save external
1363   cal _writeb_inc_ahl ;ld (ahl),c
1364 hilevelcheckdone:
1365
1366   ld  a,(gameCar)
1367   and _datasingl
1368   jr  z,hiscorecheckdone
1369 checkhiscore:
1370   cal loadhiscoreposinahl
1371   cal _Get_Word_ahl ;de=old_hi
1372  psh de
1373  cal _RAM_PAGE_1 ;&&
1374  pop de
1375   ld  hl,(worm1+score)
1376
1377   ld  a,h           ;New
1378   cp  d             ;Old
1379   jr  c,NotNewHigh  ;New<Old
1380   jr  nz,newhigh    ;New>Old
1381
1382   ld  a,e           ;old
1383   cp  l             ;new
1384   jr  nc,NotNewHigh ;new<old
1385
1386 newhigh:            ;New>=Old
1387   ex  de,hl
1388   cal loadhiscoreposinahl
1389   cal _Set_Word_ahl ;de->(ahl)
1390  cal _RAM_PAGE_1
1391
1392 NotNewHigh: ;de=current hiscore
1393   ld  hl,$0807
1394   ld  (_curRow),hl
1395   ld  hl,txthiscore
1396   cal _puts
1397   ex  de,hl ;pop
1398   cal showHL
1399 hiscorecheckdone:
1400
1401   cal releasekeys
1402 waitkey:
1403   halt
1404   halt
1405   cal GET_KEY
1406   cp  K_ENTER
1407   jp  z,DisplayMenu
1408   cp  K_SECOND
1409   jp  z,DisplayMenu
1410   cp  K_EXIT
1411   jr  nz,waitkey
1412
1413 ;x123456789012345678901
1414 ;1----- GAME OVER -----
1415 ;2Multiplayer
1416 ;3Level 01
1417 ;4           Died Score:
1418 ;5NameName     03 00070
1419 ;6Worm#02 @    05 00120
1420 ;7Worm#03      15 00030
1421 ;8Snaky   @    00 04820
1422
1423 ExitNoStats:
1424   ld  hl,_asapvar
1425   rst 20h ;_ABS_MOV10TOOP1
1426   rst 10h ;_FINDSYM
1427   ld  hl,4
1428   xor a
1429   add hl,de
1430   adc a,b ;ahl=bde+4
1431   cal _SET_ABS_DEST_ADDR
1432
1433   xor a
1434   ld  hl,_asm_exec_ram
1435   cal _SET_ABS_SRC_ADDR
1436   ld  hl,end-_asm_exec_ram
1437   cal _SET_MM_NUM_BYTES
1438   cal _mm_ldir
1439
1440   cal releasekeys
1441   res 4,(iy+9)
1442   set 2,(iy+13)
1443   jp  _clrWindow
1444
1445 loadhiscoreposinahl:
1446   ld  a,(Level)
1447   ld  b,a
1448   ld  a,(Gametype)
1449   or  a
1450 externalhiscoresavepos:
1451   ld  a,0
1452 hiscrposa =$-1
1453   ld  hl,0
1454 hiscrposhl =$-2
1455   ret z ;(Gametype)=0
1456 addlevelposition:
1457   cal _AHL_PLUS_2_PG3
1458   dnz addlevelposition
1459   ret
1460
1461 ;-----------------------------
1462 ;----------- worm ------------
1463 ;-----------------------------
1464
1465 respawncheck:
1466   cp  respawndelay-1
1467   jr  nz,unnamedlabel
1468   cal saverespawncounter
1469 removeworm:
1470   ld  h,(ix+tail+1)
1471   ld  l,(ix+tail)
1472   ld  d,(ix+head+1)
1473   ld  e,(ix+head)
1474   jr  DoesWormTailEqualsWormHead ;chk4 size=0
1475 removewormloop:
1476   ld  c,(hl)
1477   inc hl
1478   ld  b,(hl)
1479   inc hl
1480   cal resbit
1481   psh hl
1482   cal res4pixels
1483   pop hl
1484   inc (ix+grow)
1485 DoesWormTailEqualsWormHead:
1486   cal _cphlde
1487   jr  nz,removewormloop
1488
1489   ld  a,(gameCar)
1490   and _datasingl
1491   jr  nz,safewormsizedone
1492   ld  a,0
1493 beginsize =$-1
1494   ld  (ix+grow),a
1495 safewormsizedone:
1496
1497   ;de=ix+head
1498   ld  (ix+tail+1),d
1499   ld  (ix+tail),e ;head=tail/size=0
1500   ret
1501
1502 unnamedlabel:
1503   cp  1
1504   ld  h,a
1505   jr  nz,saverespawncounter
1506 respawndue:
1507   ld  l,a
1508   cal inputcall
1509   ld  (sendbyte),a
1510   ld  a,h ;previous
1511   cp  l   ;changed?
1512   ret z
1513   ld  (ix+delay),a ;=0
1514   ret
1515 saverespawncounter:
1516   ld  (ix+delay),a
1517   jr  inputcall
1518 ;  ld  a,(ix+input)
1519 ;  or  a
1520 ;  jr  z,inlink
1521 ;  ret
1522
1523 inkeys: ;use jp not call!
1524   out (1),a ;nop\nop
1525   in  a,(1)
1526   ld  b,a
1527   and (ix+right)
1528   jr  z,notright
1529   ld  a,l
1530   add a,8
1531   ld  l,a
1532 notright:
1533   ld  a,b
1534   and (ix+left)
1535   ret z
1536   ld  a,l
1537   sub 8
1538   ld  l,a
1539   ret
1540
1541 inputcall:
1542   ld  a,(ix+input)
1543   or  a
1544   jr  nz,inkeys
1545
1546 inlink:
1547   ld  a,0
1548 sendbyte =$-1
1549   ld  b,(ix+left)
1550   dec b
1551   jr  z,receivefirst
1552   psh hl
1553   cal send
1554   cal receive
1555   pop hl
1556   ld  l,a
1557   ret
1558 receivefirst:
1559   psh af
1560   psh hl
1561   cal receive
1562   pop hl
1563   ld  l,a
1564   pop af
1565   psh hl
1566   cal send
1567   pop hl
1568   ret
1569
1570 ;------- handle worm ---------
1571
1572 HandleWorm:
1573   ld  a,(ix+delay)
1574   dec a
1575   jp  nz,respawncheck
1576
1577   ld  l,(ix+heading)
1578   cal inputcall
1579 donediddelydone:
1580   ld  a,l
1581   ld  (sendbyte),a
1582   ld  (ix+heading),l
1583   ld  h,(ix+heading+1)
1584
1585   ld  c,(ix+pos)
1586   ld  b,(ix+pos+1)
1587   ld  e,(ix+pos2)
1588   ld  d,(ix+pos2+1)
1589
1590   psh hl
1591   ld  hl,previouspos
1592   ld  (hl),c
1593   inc hl
1594   ld  (hl),b
1595   inc hl
1596   inc hl
1597   ld  (hl),e
1598   inc hl
1599   ld  (hl),d
1600   pop hl
1601
1602 ;-------- move worm ----------
1603
1604 Wormmove:
1605   psh bc                        ; >> pos
1606   ld  a,(hl)
1607   add a,a
1608   add a,d
1609   ld  d,a
1610   bit 7,(hl)
1611   jr  z,notnegX
1612   dec b
1613 notnegX:
1614   jr  nc,notmoveX
1615   inc b
1616 notmoveX:
1617   ld  a,l
1618   add a,$40
1619   ld  l,a
1620   ld  a,(hl)
1621   add a,a
1622   add a,e
1623   ld  e,a
1624   bit 7,(hl)
1625   jr  z,notnegY
1626   dec c
1627 notnegY:
1628   jr  nc,notmoveY
1629   inc c
1630 notmoveY: ;bc=newpos
1631   ld  (ix+pos2),e
1632   ld  (ix+pos2+1),d
1633   ld  (ix+pos),c
1634   ld  (ix+pos+1),b
1635
1636 ;-check-
1637   pop hl                         ; << pos (old)
1638   ld  a,h
1639   sub b
1640   and 1
1641   ld  h,a
1642   ld  a,l
1643   sub c
1644   and 1
1645   add a,h
1646   ld  d,4
1647   jr  z,GotFour
1648   xor 3
1649   ld  d,a
1650 GotFour:
1651   cal chk4pixels
1652   rl  d
1653   jp  nc,Drawworm
1654
1655 ;--------- worm hit ----------
1656
1657 Hitworm:
1658   ld  a,(gameCar)
1659   ld  h,a
1660   and _datadie
1661   cal z,checkhitotherworm
1662   ld  a,h
1663   and _datamultpeas ;&&bit
1664   jr  nz,multiple_peas
1665   ld  a,h
1666   and _datafood
1667   jp  z,WormDead ;no food
1668
1669   ld  hl,0
1670 PeaY =$-2
1671 PeaX =$-1
1672   cal chkpeahit
1673   jp  nc,WormDead
1674   cal DrawPea ;remove pea
1675   ld  a,(ix+grow)
1676   add a,15
1677 peagrowth =$-1
1678   ld  (ix+grow),a
1679   cal NewPea
1680   ld  hl,Left
1681   dec (hl)
1682   psh af
1683   ld  de,10
1684   cal IncScore
1685   pop af
1686   jp  nz,Drawworm ;continue
1687   ld  a,(gameCar)
1688   and _datafoodl
1689   jp  z,Drawworm
1690   ld  a,(Gametype)
1691   or  a
1692   jp  nz,Exit ;stack restored
1693
1694   ld  hl,Level
1695   ld  a,(hl)
1696   inc (hl)
1697   ld  l,a ;hl=Level
1698   ld  h,0
1699   add hl,hl
1700   add hl,hl
1701   cal _HLTIMES10
1702   ex  de,hl
1703   cal IncScore ;score+(40*level)
1704   cal removeworm
1705   pop hl                         ; << call
1706   pop hl                         ; << call
1707   pop hl                         ; << levelp new
1708   ld  (ix+delay),2
1709   jp  StartLevel
1710
1711 chkpeahit: ;hl=peapos
1712   ld  a,(sprsize)
1713   inc a
1714   ld  d,a
1715   ld  a,b
1716   sub h
1717   inc a
1718   cp  d ;=(sprsize)+1
1719   ret nc ;nc=no pea
1720   ld  a,c
1721   sub l
1722   inc a
1723   cp  d
1724   ret ;c=pea
1725
1726 flagcaptured:
1727   psh hl
1728   ld  de,30
1729   cal IncScore
1730   pop hl
1731 sillylabel:
1732   cal WormDead
1733 DrawAllPeas:
1734   ld  hl,(peaspos)
1735   cal DrawPea
1736   ld  hl,(peaspos+2)
1737   jp  DrawPea
1738
1739 multiple_peas:
1740   ld  hl,(peaspos) ;1st pea
1741   psh hl
1742   ld  a,(ix+reserv)
1743   ld  e,a ;push a
1744   and %01
1745   jr  nz,sel_ownpea
1746   ld  hl,(peaspos+2) ;2nd pea
1747 sel_ownpea:
1748   cal chkpeahit
1749   pop hl ;(peapos) 1st pea
1750   jp  c,stopworm ;own pea hit
1751
1752   ld  a,e ;peek a (that x86 asm for pop\push ;)
1753   and %01
1754   jr  z,sel_otherpea
1755   ld  hl,(peaspos+2) ;2nd pea
1756 sel_otherpea:
1757   cal chkpeahit
1758   jp  c,hitflag
1759
1760 ;no peas hit
1761   ld  a,e
1762   cal flagtoken
1763   jp  z,WormDead
1764   ld  b,a ;%10
1765   srl b   ;%01
1766   add a,b ;%11
1767   ld  (ix+reserv),a
1768   cal DrawPea ;restore own flag
1769   jr  sillylabel ;inv both\die
1770
1771 hitflag: ;correct pea hit
1772   ld  a,e ;pop a
1773   xor %01 ;0=1;1=0
1774   ld  (ix+reserv),a
1775   cal flagtoken
1776   psh af ;safe z-flag
1777   cal DrawPea ;remove
1778   pop af
1779   jr  z,flagcaptured
1780   jr  stopworm
1781
1782 flagtoken:
1783   and %01 ;current
1784   add a,a ;<< for cp
1785   ld  b,a ;in b
1786   ld  a,e
1787   and %10 ;own
1788   cp  b   ;same?
1789   ret ;Z=yes: no flag taken
1790
1791 ;-----------------------------
1792
1793 nextotherwormbit:
1794   ld  a,c
1795   sub (hl)
1796   inc hl
1797   inc a
1798   cp  4
1799   jr  nc,nothit1 ;no
1800   ld  a,b
1801   sub (hl)
1802   inc a
1803   cp  4
1804   ret c ;nz ;yes
1805 nothit1:
1806   inc hl
1807   cal resbit
1808 ChkWorm:
1809   cal _cphlde
1810   jr  nz,nextotherwormbit
1811   ret ;z
1812
1813 checkhitlapline:
1814   ld  a,63
1815   sub b
1816   jr  z,nextlaphalf
1817   inc a
1818   ret nz
1819 nextlaphalf:
1820   ld  a,c
1821   and 32 ;y>=32?
1822   jr  nz,nolap
1823   cp  (ix+reserv)
1824   jr  z,nolap
1825   psh bc
1826   ld  de,20
1827   cal IncScore
1828   pop bc
1829   xor a
1830 nolap:
1831   ld  (ix+reserv),a
1832   ret
1833
1834 checkhitotherworm:
1835  .db  $dd,$7d ;ld a,lx
1836   cp  worm2&255
1837  psh ix
1838  jr nz,chkworm2 ; ret nz
1839   ld  ix,worm1
1840  jr chkworm
1841 chkworm2:
1842  ld ix,worm2
1843
1844 chkworm:
1845  ld h,(ix+tail+1)
1846  ld l,(ix+tail)
1847  ld e,(ix+head)
1848  ld d,(ix+head+1)
1849   cal ChkWorm
1850  pop ix
1851   ret z ;not hit
1852   pop bc ;call
1853 stopworm:
1854   ld  bc,0
1855 previouspos =$-2
1856   ld  de,0
1857   ld  (ix+pos),c
1858   ld  (ix+pos+1),b
1859   ld  (ix+pos2),e
1860   ld  (ix+pos2+1),d
1861   ret
1862
1863 ;-------- draw worm ----------
1864
1865 Drawworm:
1866   ld  c,(ix+pos)
1867   ld  b,(ix+pos+1)
1868
1869   ld  a,(Gametype)
1870   cp  gamerace
1871   cal z,checkhitlapline
1872
1873   ld  l,(ix+head)
1874   ld  h,(ix+head+1)
1875   ld  (hl),c
1876   inc hl
1877   ld  (hl),b
1878   inc hl
1879   cal resbit
1880   ld  (ix+head),l
1881   ld  (ix+head+1),h
1882
1883   cal set4pixels
1884
1885   ld  a,(ix+grow)
1886   dec a
1887   jr  z,removetail
1888   ld  (ix+grow),a
1889   ret
1890
1891 removetail:
1892   ld  l,(ix+tail)
1893   ld  h,(ix+tail+1)
1894   ld  c,(hl)
1895   inc hl
1896   ld  b,(hl)
1897   inc hl
1898   cal resbit
1899   ld  (ix+tail),l
1900   ld  (ix+tail+1),h
1901
1902 res4pixels:
1903   cal ResPixel
1904   inc b
1905   cal ResPixel
1906   inc c
1907   cal ResPixel
1908   dec b
1909 ResPixel:
1910   cal FindPixel
1911   cpl
1912   and (hl)
1913   ld  (hl),a
1914   ret
1915
1916 ;-----------------------------
1917 ;---------- ball -------------
1918 ;-----------------------------
1919
1920 handlethoseneatlittleballs:
1921   ld  hl,balls
1922   ld  b,a ;a=(nrballs)
1923 handleballs
1924   psh bc
1925   psh hl
1926   ld  c,(hl)
1927   inc hl
1928   ld  b,(hl)
1929   inc hl
1930   ld  d,(hl)
1931   cal handleball
1932   dec c
1933   pop hl
1934   ld  (hl),c
1935   inc hl
1936   ld  (hl),b
1937   inc hl
1938   ld  (hl),d
1939   inc hl
1940   pop bc
1941   dnz handleballs
1942   ret
1943
1944 handleball:
1945   cal res4pixels
1946   dec c
1947
1948 ballxmove:
1949   bit 0,d ;1=L; 0=R
1950   jr  z,ballright
1951 ballleft:
1952   dec b
1953   cal checkballhit
1954   jr  z,ballymove
1955   inc b ;undo
1956   res 0,d ;go right
1957   jr  ballymove
1958 ballright:
1959   inc b
1960   cal checkballhit
1961   jr  z,ballymove
1962   dec b ;back
1963   set 0,d ;>left
1964
1965 ballymove:
1966   bit 1,d ;1=up; 0=down
1967   jr  z,balldown
1968 ballup:
1969   dec c
1970   cal checkballhit
1971   jr  z,balldone
1972   inc c
1973   res 1,d ;go down
1974   jr  balldone
1975 balldown:
1976   inc c
1977   cal checkballhit
1978   jr  z,balldone
1979   dec c
1980   set 1,d ;up
1981 balldone:
1982
1983 set4pixels: ;@(b,c)
1984   cal SetPixel
1985   inc b
1986   cal SetPixel
1987   inc c
1988   cal SetPixel
1989   dec b
1990 SetPixel: ;at bc
1991   cal FindPixel
1992   or  (hl)
1993   ld  (hl),a
1994   ret
1995
1996 letsmovetheotherway:
1997   ld  a,1
1998   xor (hl)
1999   ld  (hl),a
2000   ret
2001
2002 checkballhit:
2003   psh de
2004   ld  d,0
2005   cal chk4pixels
2006   xor a
2007   cp  d
2008   pop de
2009   ret
2010
2011 ;-----------------------------
2012 ;----------- procs -----------
2013 ;-----------------------------
2014
2015 releasekeys:
2016   halt
2017   ld  a,%10000000    ;all key-masks
2018   out (1),a
2019   in  a,(1)
2020   inc a              ;cp %11111111 (no keys pressed)
2021   jr  nz,releasekeys ;keep waitin
2022   cal GET_KEY        ;clear buffer
2023   ret
2024
2025 resbit:
2026   ld  a,h
2027   and (ix+storepos)
2028   ld  h,a
2029   ret
2030
2031 randompos:
2032   ld  b,a
2033 Random: ;(2..b+2)
2034   ld  a,r
2035 Seed =$+1
2036   add a,0
2037   ld  (Seed),a
2038   and %01111110
2039   cp  b
2040   jr  nc,Random
2041   add a,2
2042   ret
2043
2044 NewPea:
2045   ld  a,(FieldWidth)
2046   add a,127-4
2047   cal randompos
2048   ld  h,a
2049   ld  a,(FieldHeight)
2050   add a,56-4
2051   cal randompos
2052   ld  l,a
2053   ld  (PeaY),hl
2054
2055 CheckPea:
2056   ld  c,l
2057   ld  a,(sprsize)
2058   ld  e,a
2059 chkloopy:
2060   ld  b,h
2061   ld  a,(sprsize)
2062   ld  d,a
2063 chkloopx:
2064   psh hl
2065   cal FindPixel
2066   and (hl)
2067   pop hl
2068   jr  nz,NewPea ;pixel found
2069   inc b
2070   dec d
2071   jr  nz,chkloopx
2072   inc c
2073   dec e
2074   jr  nz,chkloopy
2075 ;all ok; empty space
2076
2077 DrawPea: ;hl=(PeaY)
2078   ld  b,h
2079   ld  c,l
2080   ld  de,peasprite
2081 spritepos =$-2
2082   jp  PutSprite ;||-ed
2083
2084 ;----------- score -----------
2085
2086 _divHLby1000:
2087   psh hl
2088   ld  b,3
2089 divideagain: ;3x
2090   cal _divHLby10
2091   dnz divideagain
2092   ld  a,l ;a=hl/1000
2093   pop hl
2094   ret
2095
2096 IncScore:
2097   ld  h,(ix+score+1)
2098   ld  l,(ix+score)
2099   cal _divHLby1000
2100   ld  c,a
2101   add hl,de
2102   cal _divHLby1000
2103   cp  c
2104   jr  z,scorecommon ;hl/1000 not increased
2105   inc (ix+lives)
2106   jr  scorecommon
2107 DecScore: ;&&&
2108   ld  h,(ix+score+1)
2109   ld  l,(ix+score)
2110   or  a
2111   sbc hl,de
2112   jr  c,showstats ;<0=0
2113 scorecommon:
2114   ld  (ix+score+1),h
2115   ld  (ix+score),l
2116   ld  de,0
2117 scorelimit =$-2
2118   cal _cphlde
2119   jp  nc,Exit
2120
2121 showstats:
2122   psh ix
2123   ld  h,0
2124   ld  l,h
2125   ld  (_penCol),hl
2126   ld  a,(nrworms)
2127   ld  b,a
2128   ld  ix,worm1
2129   ld  a,(gameCar)
2130   and _datanextl
2131   jr  nz,showstatsS
2132 showstatloop:
2133   psh bc
2134   cal showstat
2135   ld  de,worm2-worm1
2136   add ix,de
2137   ld  hl,_penCol
2138   ld  a,(hl)
2139   add a,10
2140   ld  (hl),a
2141   pop bc
2142   dnz showstatloop
2143   pop ix
2144   ret
2145
2146 showstat:
2147   ld  a,(gameCar)
2148   and _datalivel
2149   jr  nz,showlives
2150 showscore:
2151   ld  h,(ix+score+1)
2152   ld  l,(ix+score)
2153   cal _D_HL_DECI
2154   jr __vputs
2155 showlives:
2156   ld  a,(ix+lives)
2157   add a,'0'
2158 __vputmap:
2159   psh ix
2160   cal _vputmap
2161   pop ix
2162   ret
2163
2164 showstatsS:
2165   ld  hl,txtLevel
2166   cal __vputs
2167   ld  a,0
2168 Level =$-1
2169   cp  10
2170   jr  c,tilllevel9
2171   ld  l,a
2172   ld  h,0
2173   cal _divHLby10
2174   psh af
2175   ld  a,l
2176   add a,'0'
2177   cal __vputmap
2178   pop af
2179 tilllevel9:
2180   add a,'0'
2181   cal __vputmap
2182
2183   ld  a,98
2184   ld  (_penCol),a
2185   cal showscore
2186   ld  a,123
2187   ld  (_penCol),a
2188   cal showlives
2189   ld  a,(gameCar)
2190   and _datafoodl
2191   pop ix
2192   ret z
2193 showleft:
2194   ld  a,31
2195   ld  (_penCol),a
2196   ld  a,0
2197 Left =$-1
2198   ld  l,a
2199   ld  h,0
2200   cal _divHLby10
2201   psh af
2202   ld  a,l
2203   add a,'0'
2204   cal __vputmap
2205   pop af
2206   add a,'0'
2207   cal __vputmap
2208
2209   ld  hl,txtLeft
2210 __vputs:
2211   psh ix
2212   cal _vputs
2213   pop ix
2214   ret
2215
2216 showLevel:
2217   ld  hl,txtLevel
2218   cal _puts
2219   ld  a,(Level)
2220 showA:
2221   ld  l,a
2222   ld  h,0
2223   cal _divHLby10
2224   psh af
2225   ld  a,l
2226   add a,'0'
2227   cal _putc
2228   pop af
2229   add a,'0'
2230   jp  _putc
2231
2232 showHL:
2233   cal _D_HL_DECI
2234   jp  _puts
2235
2236 _D_HL_DECI:
2237   ld  de,savestr+4
2238   ld  b,5
2239 ldhld:
2240   cal _divHLby10
2241   add a,'0'
2242   ld  (de),a
2243   dec de
2244   dnz ldhld
2245   ld  hl,savestr
2246   ret
2247 savestr:
2248   .db "00000",0
2249
2250 ;-----------------------------
2251
2252 DisplayField:
2253   ld  a,c
2254   sub 29
2255   jr  nc,NotMinYScroll
2256   xor a
2257 NotMinYScroll:
2258   cp  43
2259 FieldHeight =$-1
2260   jr  c,NotMaxYScroll
2261   ld  a,(FieldHeight)
2262 NotMaxYScroll:
2263   ld  l,a
2264   ld  h,0
2265   add hl,hl
2266   add hl,hl
2267   add hl,hl
2268   add hl,hl
2269   add hl,hl
2270   psh bc                        ; >> 1
2271   psh de                        ; >> 2
2272   ld  de,ScrBuffer
2273   add hl,de
2274   ld  a,b
2275   sub 64
2276   jr  nc,NotMinXScroll
2277   xor a
2278 NotMinXScroll:
2279   cp  128
2280 FieldWidth = $-1
2281   jr  c,NotMaxXScroll
2282   ld  a,(FieldWidth)
2283 NotMaxXScroll:
2284   psh af                        ; >> 3
2285   and %11111000
2286   rra
2287   rra
2288   rra
2289   ld  c,a
2290   ld  b,0
2291   ld  de,DispBuffer
2292   pop af                         ; << 2
2293   and %00000111
2294   psh af                        ; >> 3
2295   cp  6
2296   jr  c,CopyScreen
2297   inc c
2298 CopyScreen:
2299   add hl,bc
2300   ld  b,57
2301 CopyScreenLoop:
2302   psh bc                        ; >> 4
2303   ld  bc,16
2304   ldir
2305   ld  c,16
2306   add hl,bc
2307   pop bc                         ; << 3
2308   dnz CopyScreenLoop
2309   pop af                         ; << 2
2310   ld  c,$b7 ;or a
2311 Bit0:
2312   jr  nz,Bit1
2313   halt
2314   halt
2315   jr  AfterShiftDelay
2316 Bit1:
2317   dec a
2318   jr  nz,Bit2
2319   cal ShiftRight1
2320   jr  AfterShiftDelay
2321 Bit2:
2322   dec a
2323   jr  nz,Bit3
2324   ld  a,2
2325   cal ShiftRight
2326   jr  AfterShiftDelay
2327 Bit3:
2328   dec a
2329   jr  nz,Bit4
2330   cal Chunk
2331   cal ShiftLeft1
2332   jr  AfterShift
2333 Bit4:
2334   dec a
2335   jr  nz,Bit5
2336   cal Chunk
2337   jr  AfterShiftDelay
2338 Bit5:
2339   dec a
2340   jr  nz,Bit6
2341   cal Chunk
2342   cal ShiftRight1
2343   jr  AfterShift
2344 Bit6:
2345   dec a
2346   jr  nz,Bit7
2347   ld  a,2
2348   cal ShiftLeft
2349   jr  AfterShift
2350 Bit7:
2351   cal ShiftLeft
2352 AfterShiftDelay:
2353   halt
2354 AfterShift:
2355 #ifdef buffer
2356   ld  hl,DispBuffer
2357   ld  de,$fc00+$70
2358   ld  bc,1024-$70
2359   ldir
2360 #endif
2361   pop de                         ; << 1
2362   pop bc                         ; << 0k
2363   ret
2364
2365 ShiftRight1:
2366   ld  a,1
2367 ShiftRight:
2368   ld  (ShiftRightCounter),a
2369   ld  a,c
2370   ld  (ShiftRightChunk),a
2371   ld  c,16
2372   add hl,bc
2373   ld  b,57
2374 ShiftRightLoop:
2375   psh bc
2376   ld  bc,-32
2377   add hl,bc
2378   ex  de,hl
2379   ld  a,(de)
2380 ShiftRightChunk:
2381   or  a
2382   cal c,_SHLACC
2383   ld  c,0
2384 ShiftRightCounter = $-1
2385 ShiftRowsLeft:
2386   psh hl
2387   rla
2388   ld  b,16
2389 ShiftRowLeft:
2390   dec hl
2391   rl  (hl)
2392   dnz ShiftRowLeft
2393   pop hl
2394   dec c
2395   jr  nz,ShiftRowsLeft
2396   ld  bc,-16
2397   add hl,bc
2398   ex  de,hl
2399   pop bc
2400   dnz ShiftRightLoop
2401   ret
2402
2403 ShiftLeft1:
2404   ld  a,1
2405 ShiftLeft:
2406   ld  (ShiftLeftCounter),a
2407   ld  a,c
2408   ld  (ShiftLeftChunk),a
2409   rla
2410   jr  nc,ShiftLeftSameByte
2411   dec hl
2412 ShiftLeftSameByte:
2413   ex  de,hl
2414   ld  bc,-16
2415   add hl,bc
2416 NewSprite:
2417   ex  de,hl
2418   ld  b,57
2419 ShiftLeftLoop:
2420   psh bc                        ; >> 1
2421   ld  bc,-32
2422   add hl,bc
2423   ex  de,hl
2424   ld  a,(de)
2425 ShiftLeftChunk:
2426   or  a
2427   cal c,_SHRACC
2428   ld  c,0
2429 ShiftLeftCounter = $-1
2430 ShiftRowsRight:
2431   psh hl                        ; >> 2
2432   rra
2433   ld  b,16
2434 ShiftRowRight:
2435   rr  (hl)
2436   inc hl
2437   dnz ShiftRowRight
2438   pop hl                         ; << 1
2439   dec c
2440   jr  nz,ShiftRowsRight
2441   ld  bc,-16
2442   add hl,bc
2443   ex  de,hl
2444   pop bc                         ; << 0k
2445   dnz ShiftLeftLoop
2446   ret
2447
2448 Chunk:
2449   psh hl                        ; >> 1
2450   psh de                        ; >> 2
2451   ld  c,16
2452   add hl,bc
2453   ld  b,57
2454 ChunkScreen:
2455   psh bc                        ; >> 3
2456   ld  bc,-32
2457   add hl,bc
2458   ex  de,hl
2459   ld  a,(de)
2460   cal _SHRACC
2461   ld  b,16
2462 ChunkRow:
2463   dec hl
2464   rld
2465   dnz ChunkRow
2466   ex  de,hl
2467   pop bc                         ; << 2
2468   dnz ChunkScreen
2469   pop de                         ; << 1
2470   pop hl                         ; << 0k
2471   ld  c,$37 ;scf
2472   ret
2473
2474 ;----------- draw ------------
2475
2476 ;--- pixel ---
2477
2478 chk4pixels: ;&&
2479   cal CheckPixel
2480   inc b
2481   cal CheckPixel
2482   inc c
2483   cal CheckPixel
2484   dec b
2485   cal CheckPixel
2486   dec c
2487   ret
2488 CheckPixel: ;at bc in d
2489   cal FindPixel
2490   and (hl)
2491   ret z
2492   dec d
2493   ret
2494
2495 ;CLEM's FIND_PIXEL (131+? cycles; 28+4 bytes)
2496 ;(b,c) to hl:a; "destroyes" ahl
2497
2498 FindPixel: ;(b,c) to hl:a
2499   ld  h,0
2500   ld  l,c    ;hl=y
2501   add hl,hl
2502   add hl,hl
2503   ld  a,b    ;a=x
2504   rra
2505   add hl,hl
2506   rra
2507   add hl,hl
2508   add hl,hl  ;hl=32*y
2509   rra        ;a=x/8
2510   or  l
2511   ld  l,a
2512   ld  a,b
2513   and 7
2514   cpl
2515   rlca
2516   rlca
2517   rlca
2518   ld  (FP_Bit),a
2519   xor a
2520 FP_Bit =$+1
2521   set 0,a
2522
2523   psh de ;&&&
2524   ld  de,ScrBuffer
2525   add hl,de
2526   pop de
2527   ret
2528
2529 ;--- sprite ---
2530
2531 PutSprite:  ;||@(b,c)
2532   ;by SHIAR  only ix saved
2533   cal FindPixel
2534 putspr:
2535   ld  (beginbit),a
2536   ld  a,(sprsize)
2537   ld  b,a ;rows
2538 sprloopy:
2539   psh bc ;rows
2540   psh hl
2541   ld  a,(de)
2542   ld  c,a
2543   inc de
2544   ld  a,(sprsize)
2545   ld  b,a ;width
2546 beginbit =$+1
2547   ld  a,1
2548 sprloopx:
2549   sla c ;draw?
2550   jr  nc,sprnodraw
2551   psh af
2552   xor (hl)
2553   ld  (hl),a
2554   pop af
2555 sprnodraw:
2556   rrca ;next bit
2557   jp  nc,nextbitok
2558   inc hl ;next byte
2559 nextbitok:
2560   dnz sprloopx
2561
2562   pop hl
2563   ld  bc,32 ;next line
2564   add hl,bc
2565   pop bc
2566   dnz sprloopy
2567   ret
2568
2569 ;--- line ---
2570
2571 loaddrawdata:
2572   ld  d,(hl)
2573   inc hl
2574   ld  e,(hl)
2575   inc hl
2576   ld  a,(hl)
2577   inc hl
2578   ret
2579
2580 ;LINE (d,e)-(h,l)
2581 ;destroyes a
2582
2583 Line:
2584   psh bc
2585   psh hl
2586   psh de
2587   ld  a,d
2588   cp  h
2589   jr  c,lineOrdered
2590   ex  de,hl
2591 lineOrdered:
2592   ld  b,d
2593   ld  c,e
2594   psh hl
2595   psh bc
2596   cal FindPixel
2597   pop bc
2598   pop de
2599 connectedLine:
2600   psh hl
2601   ld  h,c
2602   ld  c,a
2603   ld  a,d
2604   sub b
2605   ld  b,a
2606   ld  a,e
2607   jr  nz,LineNotPoint
2608   cp  h
2609   jr  nz,LineNotPoint
2610   pop hl
2611   jr  DoneLine
2612 LineNotPoint:
2613   sub h
2614   ld  de,32
2615   jr  nc,LinePositiveY
2616   neg
2617   ld  de,-32
2618 LinePositiveY:
2619   cp  b
2620   jr  nc,SteepLine
2621   add a,a
2622   ld  (line2sm+1),a
2623   ld  h,a
2624   xor a
2625   sub b
2626   add a,a
2627   ld  (line1sm+1),a
2628   ld  a,h
2629   sub b
2630   pop hl
2631 LineLoopGentle:
2632   psh af
2633   ld  a,(hl)
2634   or  c
2635   ld  (hl),a
2636   rrc c
2637   jr  nc,$+3
2638   inc hl
2639   pop af
2640   jp  m,line2sm
2641 line1sm:
2642   add a,0
2643   add hl,de
2644 line2sm:
2645   add a,0
2646   dnz LineLoopGentle
2647 DoneLine:
2648   ld  a,(hl)
2649   or  c
2650   ld  (hl),a
2651   pop de
2652   pop hl
2653   pop bc
2654   ret
2655 SteepLine:
2656   ld  h,a
2657   neg
2658   add a,a
2659   ld  (line3sm+1),a
2660   ld  a,b
2661   add a,a
2662   ld  (line4sm+1),a
2663   sub h
2664   ld  b,h
2665   pop hl
2666 LineLoopSteep:
2667   psh af
2668   ld  a,(hl)
2669   or  c
2670   ld  (hl),a
2671   add hl,de
2672   pop af
2673   jp  m,line4sm
2674 line3sm:
2675   add a,0
2676   rrc c
2677   jr  nc,$+3
2678   inc hl
2679 line4sm:
2680   add a,0
2681   dnz LineLoopSteep
2682   jr  DoneLine
2683
2684 drawbox: ;(d,e)-(h,l)
2685   ld  b,l ;Delta-y
2686   ld  l,e
2687 boxloop:
2688   cal Line
2689   inc l
2690   inc e
2691   dnz boxloop
2692   ret
2693
2694 ;-----------------------------
2695 ;----------- link ------------
2696 ;-----------------------------
2697
2698 TIMEOUT = $1000
2699
2700 receive:
2701   cal GET_KEY
2702   cp  K_EXIT
2703   jp  z,LinkBreak
2704   in  a,(7)
2705   and %11
2706 ;  jr  z,LinkBreak
2707   cp  %11
2708   jr  z,receive
2709   ld  b,8
2710   cal ReceiveCont
2711   jr  c,receive
2712   ret
2713
2714 Qreceive:
2715   ld  b,8
2716 receiveloop:
2717   ld  de,TIMEOUT
2718 WaitRecBit:
2719   cal CheckLink
2720   jr  z,LinkFailed
2721   cp  %11
2722   jr  z,WaitRecBit
2723 ReceiveCont:
2724   sub %10
2725   ld  a,%10
2726   ld  d,D0LD1H ;01
2727   jr  c,ReceiveLow
2728   rra ;ld a,%01
2729   ld  d,D0HD1L ;10
2730 ReceiveLow:
2731   rr  c
2732   ld  (AckBit),a
2733   ld  a,d
2734   out (7),a
2735   ld  de,TIMEOUT
2736 WaitAckRec:
2737   cal CheckLink
2738   cp  0
2739 AckBit =$-1
2740   jr  nz,WaitAckRec
2741   ld  a,D0HD1H ;11
2742   out (7),a
2743   ld  d,4
2744 WaitReadyRec:
2745   dec d
2746   jr  z,ReadyRec
2747   in  a,(7)
2748   cp  %11
2749   jr  nz,WaitReadyRec
2750 ReadyRec:
2751   dnz receiveloop
2752   ld  a,c
2753   ret
2754
2755 LinkBreak:
2756   ld  a,D0HD1L
2757   out (7),a
2758   jp  Exit
2759
2760 send:
2761   ld  c,a
2762   ld  b,8+1
2763   jr  SendAcked
2764 sendloop:
2765   rr  c
2766   ld  a,D0LD1H ;%01
2767   jr  nc,SendLow
2768   ld  a,D0HD1L ;%10
2769 SendLow:
2770   out (7),a
2771   ld  de,TIMEOUT
2772 WaitAckSend:
2773   cal CheckLink
2774   jr  nz,WaitAckSend
2775 SendAcked:
2776   ld  a,D0HD1H ;%11
2777   out (7),a
2778   ld  de,TIMEOUT
2779 WaitReadySend:
2780   cal CheckLink
2781   cp  %11
2782   jr  nz,WaitReadySend
2783   dnz sendloop
2784   ld  a,c
2785   ret
2786
2787 LinkSuccess:
2788  .db  $F6 ;or NN (skip scf)
2789 LinkFailed:
2790   scf
2791   ld  a,c
2792   ret
2793
2794 CheckLink:
2795   pop hl
2796   dec de
2797   ld  a,d
2798   or  e
2799   jr  z,LinkFailed
2800
2801   ld  a,$BF
2802   out (1),a
2803 ; nop \ nop
2804   in  a,(1)
2805   psh af
2806   ld  a,%11111111
2807   out (1),a
2808   pop af
2809   bit 6,a
2810   jr  z,LinkBreak
2811
2812   in  a,(7)
2813   and %11
2814   jp  (hl)
2815
2816 ;-----------------------------
2817 ;---------- levels -----------
2818 ;-----------------------------
2819
2820 LevelDef:
2821   .db 5,4,15,15,0,0 ;peas,speed,growth,begin_size,sprite,balls
2822   .db 0,2,63        ;start d, y, x
2823   .db 128,57        ;field width (128-255), height (57-255)
2824   .db 0,0           ;no additional lines, boxes
2825
2826   .db 255
2827    ret
2828
2829 LevelDefM:
2830   .db 8,0,15,15,0,0
2831   .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
2832   .db 128,57
2833   .db 0,0
2834
2835 ;-----------------------------
2836 ;---------- data -------------
2837 ;-----------------------------
2838
2839 wtPicture:
2840 .db %00011110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
2841 .db %00111110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
2842 .db %01110000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
2843 .db %01100000,%01111100,%00000001,%11111111,%00000000,%11110000,%01111001,%11100000
2844 .db %11100000,%11111110,%00000011,%11111111,%10000011,%11111000,%11111111,%11110000
2845 .db %11000001,%11000111,%00000111,%00000001,%11000111,%10011001,%11001111,%00111000
2846 .db %11000001,%10000011,%00000110,%00000000,%11100110,%00000001,%10011111,%10011000
2847 .db %11000001,%10000011,%00000110,%11000000,%01101110,%00000011,%10111001,%11011100
2848 .db %11000001,%11000111,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100
2849 .db %11000000,%11000110,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100
2850 .db %11100000,%11101110,%00001110,%11000000,%01101100,%00000011,%00111001,%11001100
2851 .db %01100000,%01111100,%00001100,%11000000,%01101100,%00000011,%00011111,%10001100
2852 .db %01110000,%00111000,%00011100,%11100000,%11101110,%00000011,%00001111,%00001100
2853 .db %00111000,%11111110,%00111000,%01110001,%11000110,%00000011,%10000000,%00011100
2854 .db %00011111,%11101111,%11110000,%00111111,%10000111,%00000001,%10000000,%00011000
2855 .db %00001111,%10000011,%11100000,%00011111,%00000011,%00000001,%10000000,%00011000
2856
2857 txtMenu:    .db "by Shiar",0
2858             .db "Have fun!",0 ;4th menu item
2859             .db "Level ",$CF,"??",5,0 ;3rd
2860             .db "Worms ",$CF,"?",5,0  ;2nd
2861 txtGame:    .db "Singleplayer",0  ;0 (1st)
2862 txtGame2:   .db "Peaworm     ",0  ;1 (next 1st)
2863             .db "Deathmatch",0    ;2
2864             .db "Foodmatch ",0    ;3
2865             .db "LinkMatch",0     ;4
2866             .db "Race     ",0     ;5
2867             .db "CTF ",0          ;6
2868             .db "Domination",0    ;7
2869 txtLevsel:  .db $CF," Select levels: ",5,0
2870 txtName:    .db "Enter name player ",0
2871 txtWaiting: .db "Waiting...",0
2872 txtReceive: .db "Receiving..." ;,0
2873
2874 TrigPrecalc:
2875 .db   0,  3,  6,  9, 12, 15, 18, 21
2876 .db  24, 27, 30, 33, 36, 39, 42, 45
2877 .db  48, 51, 54, 57, 59, 62, 65, 67
2878 .db  70, 73, 75, 78, 80, 82, 85, 87
2879 .db  89, 91, 94, 96, 98,100,102,103
2880 .db 105,107,108,110,112,113,114,116
2881 .db 117,118,119,120,121,122,123,123
2882 .db 124,125,125,126,126,126,126,126
2883 .db 127
2884
2885 txtLevel:  .db "Level ",0
2886 txtWorms:  .db "Worms: 0",0 ;follows txtLevel
2887 txtDied:   .db "Died ",0
2888 txtScore:  .db "Score",0    ;follows txtDied
2889 txtLeft:   .db " left",0    ;follows txtScore
2890 txthiscore:.db "HiScore:",0
2891 txtReady:  .db "Prepare!",0
2892 txtposReady = 7
2893 txtGO:     .db "----- GAME OVER -----",0
2894
2895 gamesdata:
2896
2897 _datalink  = %00000001 ;linkplay
2898 _datalivel = %00000010 ;lives=0 limit
2899 _datafoodl = %00000100 ;left=0 limit
2900 _datanextl = %00001000 ;next level if left=0
2901 _datasingl = %00001000 ;singleplayer=1
2902 _datafood  = %00010000 ;food present
2903 _________  = %00100000 ;
2904 _datadie   = %01000000 ;worm dies on impact
2905 _datascore = %10000000 ;score>=100 limit
2906 _datamultpeas = %00100000
2907
2908 gamesingle   =  0
2909 datasingle: .db %01011110
2910 gamepeas     =  1
2911 datapeas:   .db %01011010
2912 gamedeathm   =  2
2913 datadeathm: .db %01000010
2914 gamefoodm    =  3
2915 datafoodm:  .db %11010000
2916 gamelinkm    =  4
2917 datalinkm:  .db %01000011
2918 gamerace     =  5
2919 datarace:   .db %10000000
2920 gamectf      =  6
2921 datactf:    .db %11100000
2922 gamedomin    =  7
2923 datadomin:  .db %01000000 ;==(8 modes)
2924
2925 datalevels: .dw LevelDef, LevelDef
2926             .dw LevelDefM,LevelDefM
2927             .dw LevelDefM,LevelDefM
2928             .dw LevelDefM,LevelDefM
2929 nrlevels:   .db 2,2,2,2,2,2,2,2
2930
2931 worm1set:  .dw worm1p,worm1p
2932            .db %11110111,3,%00,%01111110,%10,%100 ;< >
2933 worm1name: .db "worm #01",0
2934 worm2set:  .dw worm2p,worm2p
2935            .db %11111011,3,%11,%00111111,%10000,%1000 ;f1 f2
2936 worm2name: .db "worm #02",0
2937 worm3set:  .dw worm3p,worm3p
2938            .db %11111011,3,0,%01011111,%10,%100 ;sto ,
2939 worm3name: .db "worm #03",0
2940 worm4set:  .dw worm4p,worm4p
2941            .db %11111011,3,0,%01111101,%10,%1 ;enter +
2942 worm4name: .db "worm #04",0
2943
2944 end:
2945
2946 defsprsize   = 4
2947 sprsize:   .db 4
2948 peasprite: .db %01100000
2949            .db %11110000
2950            .db %11110000
2951            .db %01100000
2952
2953                ;set:
2954 heading  = 0   ;level*
2955 pos      = 2   ;level*
2956 pos2     = 4   ;level
2957 grow     = 6   ;level
2958 died     = 8   ;game
2959 score    = 9   ;game
2960 delay    = 11  ;game
2961                ;19B @game
2962 head     = 12  ;4B (head=tail)
2963 tail     = 14  ;also@next level
2964 storepos = 16
2965 lives    = 17
2966 reserv   = 18  ;loop
2967  ;race:lap
2968  ;ctf:pea
2969 input    = 19
2970 left     = 20
2971 right    = 21
2972 name     = 22
2973 wormsize = 31
2974
2975 startdelay    = 30
2976 respawndelay  = 30
2977 maxnamelength = 8+1
2978
2979 ;-----------------------------
2980 ;----------- end -------------
2981 ;-----------------------------
2982
2983   .end
2984
2985 .end