worm 0.84pre.0325: common includes, code cleanup
[wormy.git] / worm.z80
1 ; Title                      : Worm
2 ; Version                    : 0.92
3 ; Release Date               : soon (I hope)
4 ; Filename                   : worm.86p (3404)
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 ;       Shiar 3.III.00
20
21 ;Feel like doing something? (name indicates who's working on it)
22 ;  * linkplay
23 ;  * singleplay ending
24 ;  * titlescreen
25 ;  * make linkplay available for all gametypes (not just deathmatch)
26 ;  * two worms collide with heads -> both should die
27 ;  * game types:
28 ;1)  * ctf: take enemy flag (right-bottom) and return to your flag (left-top)
29 ;1)  * domination?: take control points by running over them and hold them
30 ;1)* sprites for picks instead of blocks
31
32 ;1) Working on a new pickup-system allowing more than one "food" and different pickup-handling
33
34 #include "asm86.h"
35 #include "ti86asm.inc"
36 #include "ti86abs.inc"
37
38 _SHRACC    = $4383
39 _SHLACC    = $438B
40 _divHLby10 = $4044
41 _divAby10  = $4DAF
42 _cphlde    = $403C
43 _clrWindow = $4A86
44 _asapvar   = $D6FC
45 _MOV4B     = $429B ;4x ld (de),(hl)
46 _MOV5B     = $4297 ;5x ld (de),(hl)
47 _mov9b     = $4283 ;9x ld (de),(hl)
48 _ldHLind   = $4010 ;ld hl,(hl)
49 _swapt_    = $45F3 ;ex_ahl_bde
50
51 ;-----------------------------
52 ;------- program start -------
53 ;-----------------------------
54
55 .org _asm_exec_ram
56 start:
57   nop
58   jp Start
59   .dw 1
60   .dw WormMsg
61   .dw WormIcon
62
63 WormIcon:
64   .db 9,2
65   .db %10010111,%01101111
66   .db %10110101,%01001011
67   .db %11110111,%01001001
68   .db %00000011,%10000000
69   .db %00000001,%11100000
70   .db %00111000,%11111000
71   .db %01111110,%00111111
72   .db %11101111,%00001111
73   .db %11000011,%10000000
74
75 Start:
76   ld  (SpSave),sp
77   call _runindicoff
78   call _flushallmenus
79   call _clrLCD
80   res 2,(iy+13) ;appAutoScroll
81
82   ld  a,r
83   ld  (Seed),a
84
85 ;-----------------------------
86 ;----- build trig tables -----
87 ;-----------------------------
88
89   ld  hl,TrigPrecalc
90   ld  de,SinCosTable
91   push de                        ; >> 1
92   ld  bc,65
93   ldir
94   dec hl
95   ld  b,63
96 MirrorSineWave:
97   dec hl
98   ld  a,(hl)
99   ld  (de),a
100   inc de
101   djnz MirrorSineWave
102   pop hl                         ; << 0k
103   ld  b,128+64
104 NegativeSineWave:
105   xor a
106   sub (hl)
107   ld  (de),a
108   inc hl
109   inc de
110   djnz NegativeSineWave
111
112 ;-----------------------------
113 ;---------- menu -------------
114 ;-----------------------------
115
116 DisplayMenu:
117   ld  a,2
118   ld  (nrworms),a
119 gomainMenu:
120   call _clrWindow
121   ld  hl,txtWelcome
122   call _puts
123   ld  de,$0205
124   ld  (_curRow),de
125   call _puts ;txtOptions
126   dec e ;$0204
127   ld  (_curRow),de
128   ld  hl,(CURtxtGame)
129   call _puts
130
131   xor a
132 mainMenu:
133   call menucall
134   jr  nz,notselect
135 select:
136   ld  a,b
137   or  a
138   jr  nz,gooptionsMenu
139   jp  LetsGetThisPartyOn
140 notselect
141   cp  K_EXIT
142   jp  z,ExitNoStats
143   cp  K_RIGHT
144   ld  a,b
145   jr  nz,mainMenu
146   or  a
147   jr  z,Variation
148
149 gooptionsMenu:
150   call _clrWindow
151   ld  hl,txtWelcome
152   call _puts
153   ld  hl,txtLevel
154   ld  de,$0205
155   ld  (_curRow),de
156   call _puts ;txtLevel
157   dec e ;$0204
158   ld  (_curRow),de
159   call _puts ;txtWorms
160   ld  a,(nrworms)
161   add a,'0'
162   call _putc
163   xor a
164 optionsMenu:
165   call menucall
166   jr  nz,notopselect
167 opselect:
168   ld  a,b
169   or  a
170   jr  nz,changelevel
171 changeworms:
172   ld  hl,nrworms
173   inc (hl)
174   ld  a,4
175   cp  (hl)
176   jr  nc,gooptionsMenu
177   ld  (hl),2
178   jr  gooptionsMenu
179 changelevel:
180   jr  optionsMenu
181
182 notopselect:
183   cp  K_EXIT
184   jr  z,gomainMenu
185   ld  a,b
186   jr  optionsMenu
187
188 Variation:
189   ld  a,0
190 Gametype =$-1
191   ld  hl,txtGame2
192 NEXTtxtGame =$-2
193   inc a
194   and 7 ;mod 8
195   jr  nz,okilydokily
196   ld  hl,txtGame
197 okilydokily:
198   ld  (Gametype),a
199   ld  de,$0204
200   ld  (_curRow),de
201   ld  (CURtxtGame),hl
202   call _puts
203   ld  (NEXTtxtGame),hl
204   ld  a,b
205   jp  mainMenu
206
207 menucall:
208   push af
209   ld  hl,$0004
210   ld  (_curRow),hl
211   ld  a,' '
212   call _putc
213   ld  hl,$0005
214   ld  (_curRow),hl
215   call _putc
216   pop af
217   push af
218   ld  h,0
219   add a,4
220   ld  l,a
221   ld  (_curRow),hl
222   ld  a,'*'
223   call _putc
224   pop af
225   ld  b,a
226 menukeys:
227   halt \ halt
228   call GET_KEY
229   or  a
230   jr  z,menukeys
231   cp  K_UP
232   jr  nz,notup
233 updown:
234   ld  a,b
235   xor 1
236   ld  b,a
237   inc a ;nz
238   ret
239 notup:
240   cp  K_DOWN
241   jr  z,updown
242   cp  K_ENTER
243   ret z
244   cp  K_SECOND
245   ret ;z=select
246
247 ;-----------------------------
248 ;-------- start game ---------
249 ;-----------------------------
250
251 LetsGetThisPartyOn:
252   ld  hl,Gametype
253   ld  a,(hl)
254   add a,a
255   add a,(hl)
256   ld  e,a
257   ld  d,0
258   ld  hl,gamesdata
259   add hl,de
260
261   ld  a,(hl)
262   ld  d,a ;push af
263   and _datasingl
264   jr  z,notsingle
265   ld  a,1
266   ld  (nrworms),a
267   ld  a,d
268   and _datafoodl
269   jr  nz,notsingle
270   ld  a,1
271   ld  (worm1+lives),a
272 notsingle:
273   ld  a,d
274   ld  (gameCar),a
275   push af
276
277   and _datascore
278   ld  de,$FF64 ;virt.infinate
279   jr  z,setscorelimit
280   ld  d,0 ;de=100
281 setscorelimit:
282   ld  (scorelimit),de
283
284   inc hl
285   call _ldHLind
286   pop af
287   push hl
288   and _datalink
289   jr  z,GameOver
290
291 linkmatch:
292   call _clrWindow
293   ld  a,WormVersion
294   call send
295   jr  c,client ;2nd
296
297 host:
298   ld  hl,txtWaiting
299   call _puts
300   call receive
301   cp  WormVersion
302   jp  nz,LinkBreak
303   call send
304
305   ld  hl,SwapPos
306   ld  (hl),$f6
307   jr  multiplayer
308
309 client:
310   ld  hl,txtReceive
311   call _puts
312   call receive
313   cp  WormVersion
314   jp  nz,LinkBreak
315
316 multiplayer:
317   ld  a,2
318   ld  (nrworms),a
319   ld  de,LevelsDM
320
321 ;-----------------------------
322 ;--------- game over ---------
323 ;-----------------------------
324
325 GameOver:
326   call _clrLCD
327   ld  hl,0
328   ld  (worm1+died),hl
329 ;+died=0 \ +score1=0
330   ld  (worm2+died),hl
331   ld  (worm3+died),hl
332   ld  (worm4+died),hl
333   inc h
334   ld  (worm1+score+1),hl
335 ;+score2=0 \ +delay=1
336   ld  (worm2+score+1),hl
337   ld  (worm3+score+1),hl
338   ld  (worm4+score+1),hl
339   ld  a,l
340   ld  (Level),a
341   ld  hl,worm1set+4
342   ld  de,worm1+lives
343   call _MOV5B ;9xld(de),(hl)
344   call _mov9b
345   ld  hl,worm2set+4
346   ld  de,worm2+lives
347   call _MOV5B
348   call _mov9b
349   ld  hl,worm3set+4
350   ld  de,worm3+lives
351   call _MOV5B
352   call _mov9b
353   ld  hl,worm4set+4
354   ld  de,worm4+lives
355   call _MOV5B
356   call _mov9b
357   pop de
358
359 StartLevel:
360   ex  de,hl
361   ld  de,Left
362   ldi
363   ld  de,Speed
364   ldi
365   ld  a,(hl)
366   ld  (worm1+grow),a
367   ld  (worm2+grow),a
368   ld  (worm3+grow),a
369   ld  (worm4+grow),a
370   ld  (beginsize),a
371   inc hl
372
373   ld  a,(hl)
374   inc hl
375   ld  (nrballs),a
376   or  a
377   jr  z,toobad_noballs
378   ld  de,ballpos
379   ldi
380   ldi
381 toobad_noballs:
382
383 #ifdef 0
384   ld  a,(gameCar)
385   and _datahunt
386   jr  z,nohunter
387   ld  a,huntersize
388   ld  (worm2+grow),a
389 nohunter:
390 #endif
391
392   ex  de,hl
393   ld  (thislevel),de
394   push de
395   ld  hl,worm1set
396   ld  de,worm1+head
397   call _MOV4B
398   ld  hl,worm2set
399   ld  de,worm2+head
400   call _MOV4B
401   ld  hl,worm3set
402   ld  de,worm3+head
403   call _MOV4B
404   ld  hl,worm4set
405   ld  de,worm4+head
406   call _MOV4B
407   pop de
408
409   ld  hl,worm1
410   ld  a,(gameCar)
411   and _datanextl
412   ld  b,1
413   jr  nz,worminit
414   ld  b,4
415 worminit:
416   push bc                        ; >> 1
417   ex  de,hl
418   ldi          ;d
419   ld  a,SinCosTable/256
420   ld  (de),a
421   inc de
422   ldi          ;y
423   ldi          ;x
424   ex  de,hl
425
426   xor a
427   ld  (hl),a   ;y2
428   inc hl
429   ld  (hl),a   ;x2
430
431   ld  bc,(worm2-worm1)-5
432   add hl,bc
433   pop bc                         ; << 0k
434   djnz worminit
435
436 ;-------- draw level ---------
437
438   ld  a,(de)
439   inc de
440   sub 128
441   ld  (FieldWidth),a
442   ld  a,(de)
443   inc de
444   sub 57
445   ld  (FieldHeight),a
446   add a,57-5
447   push de                        ; >> levelp
448   ld  l,a
449   ld  h,0
450   add hl,hl
451   add hl,hl
452   add hl,hl
453   add hl,hl
454   add hl,hl
455   ex  de,hl
456
457   ld  hl,ScrBuffer
458   push hl                        ; >> 1
459   push de                        ; >> 2
460   ld  de,ScrBuffer+1
461   ld  bc,63
462   ld  (hl),%11111111
463   ldir
464   inc hl
465   ld  (hl),%11000000
466   inc hl
467   ld  b,31
468 ClearLine:
469   ld  (hl),c
470   inc hl
471   djnz ClearLine
472   push hl                        ; >> 3
473
474   ld  a,(FieldWidth)
475   add a,126
476   push af                        ; >> 4
477   and %11111000
478   rra
479   rra
480   rra
481   ld  l,a
482   ld  h,0
483   add hl,de
484   pop af                         ; << 3
485   and %00000111
486   ld  b,a
487   ld  c,0
488   ld  a,%11000000
489   jr  z,NoVertShift
490 VertShift:
491   rra
492   rr  c
493   djnz VertShift
494 NoVertShift:
495   ld  (hl),a
496   inc hl
497   ld  (hl),c
498
499   ex  de,hl
500   pop de                         ; << 2
501   pop bc                         ; << 1
502   ldir
503   pop hl                         ; << 0k
504   ld  c,64
505   ldir
506
507 ;-draw lines-
508
509   pop hl                         ; << levelp
510   ld  a,(hl)
511   inc hl
512   or  a
513   jr  z,NoLines
514 DrawLines:
515   push af                        ; >> 1
516   call loaddrawdata
517   push hl                        ; >> 2
518   ld  l,(hl)
519   ld  h,a
520   call Line
521   inc d
522   inc h
523   call Line
524   inc e
525   inc l
526   call Line
527   dec d
528   dec h
529   call Line
530   pop hl                         ; << 1
531   inc hl
532   pop af                         ; << 0k
533   dec a
534   jr  nz,DrawLines
535 NoLines:
536
537   ld  a,(hl)
538   inc hl
539   or  a
540   jr  z,noboxes
541 drawboxes:
542   push af
543   call loaddrawdata
544   push hl
545   ld  l,(hl)
546   ld  h,a
547   call drawbox
548   pop hl
549   inc hl
550   pop af
551   dec a
552   jr  nz,drawboxes
553 noboxes:
554
555 ;-----------------------------
556
557   push hl                        ; >> levelp new
558   call showstats
559   ld  a,(gameCar)
560   and _datafood
561   jr  z,nofood
562   call NewPea
563   call DrawPea
564 nofood:
565   ld  bc,(worm1+pos)
566   call DisplayField
567   ld  hl,$FDE0
568   ld  de,$FDE1
569   ld  (hl),%11111111
570   ld  bc,$BF
571   ldir
572   ld  hl,4+(txtposReady*256)
573   ld  (_curRow),hl
574   set 3,(iy+5)
575   ld  hl,txtReady
576   call _puts
577   res 3,(iy+5)
578
579   ld  a,0
580 gameCar =$-1
581   and _datalink
582   jr  z,SwapPos ;no link
583   xor a
584   ld  (worm2+input),a
585   ld  (worm2+left),a
586   ld  (Speed),a
587
588 SwapPos: ;$18 xx -> $F6 xx
589   jr  initfinished
590   inc a
591   ld  (worm2+left),a
592   ld  hl,(worm1+pos)
593   ld  de,(worm2+pos)
594   ld  (worm2+pos),hl
595   ld  (worm1+pos),de
596   ld  a,(worm1+heading)
597   ld  b,a
598   ld  a,(worm2+heading)
599   ld  (worm1+heading),a
600   ld  a,b
601   ld  (worm2+heading),a
602 initfinished:
603
604   ld  b,0
605 ReadyDelay:
606   halt
607   djnz ReadyDelay
608
609 ;-----------------------------
610 ;----------- LOOP ------------
611 ;-----------------------------
612
613 GameLoop:
614   ld  bc,(worm1+pos)
615   call DisplayField
616
617   ld  a,1
618 flashtime =$-1
619   dec a
620   jr  z,noflash
621   ld  (flashtime),a
622   ld  hl,$fc00+(16*7)
623 screeninvertloop:
624   ld  a,(hl)
625   cpl
626   ld  (hl),a
627   inc hl
628   xor a
629   cp  h
630   jr  nz,screeninvertloop
631 noflash:
632
633   ld  a,0
634 Speed =$-1
635   or  a
636   jr  z,NoDelay
637 Delay:
638   halt
639   dec a
640   jr  nz,Delay
641 NoDelay:
642
643   call handlethatneatlittleball
644
645   ld  ix,worm1
646   ld  a,(nrworms)
647   ld  b,a
648 handleworms:
649   push bc
650   call HandleWorm
651   ld  bc,worm2-worm1
652   add ix,bc
653   pop bc
654   djnz handleworms
655
656 ;-----------------------------
657 ;---------- keys -------------
658 ;-----------------------------
659
660 HandleKeys:
661   ld  a,%10111111
662   out (1),a
663   in  a,(1)
664   rla
665   jr  c,NotPaused
666   ld  bc,$0103
667   out (c),b
668   halt
669   ld  b,11
670   out (c),b
671
672 NotPaused:
673   rla
674   jp  c,GameLoop
675   jr  Exit ;&&
676
677 WormDead:
678   ld  a,2
679   ld  (flashtime),a
680
681   ld  h,(ix+tail+1)
682   ld  l,(ix+tail)
683   ld  d,(ix+head+1)
684   ld  e,(ix+head)
685   jr  DoesWormTailEqualsWormHead ;chk4 size=0
686 removewormloop:
687   ld  c,(hl)
688   inc hl
689   ld  b,(hl)
690   inc hl
691   res resbit,h
692   push hl
693   call res4pixels
694   pop hl
695   inc (ix+grow)
696 DoesWormTailEqualsWormHead:
697   call _cphlde
698   jr  nz,removewormloop
699
700   ld  a,(gameCar)
701   and _datasingl
702   jr  nz,safewormsizedone
703   ld  a,0
704 beginsize =$-1
705   ld  (ix+grow),a
706 safewormsizedone:
707
708   ;de=ix+head
709   ld  (ix+tail+1),d
710   ld  (ix+tail),e
711   ld  a,50
712   ld  (ix+delay),a
713
714 thislevel =$+1
715   ld  de,0
716   ld  a,(de)
717   inc de
718   ld  (ix+heading),a
719   ld  a,(de)
720   ld  (ix+pos),a
721   inc de
722   ld  a,(de)
723   ld  (ix+pos+1),a
724
725   inc (ix+died)
726   dec (ix+lives)
727   push af
728   ld  de,10
729   call DecScore
730   pop af
731   ret nz ;HandleWorm done
732   ld  a,(gameCar)
733   and _datalivel
734   ret z
735
736 Exit:
737   ld  sp,0 ;pop all
738 SpSave = $-2
739   call _clrWindow
740   ld  hl,txtGO
741   call _puts
742   ld  hl,txtGame
743 CURtxtGame =$-2
744   call _puts
745   ld  de,0002
746   ld  (_curRow),de
747   call showLevel
748   ld  de,$0B03
749   ld  (_curRow),de
750   ld  hl,txtDied
751   call _puts
752   call _puts ;txtScore
753   xor a
754   ld  (_curCol),a
755
756   ld  b,2
757 nrworms =$-1
758   ld  hl,worm1+died
759 displayWormStats:
760   push bc
761   push hl
762
763   ld  bc,input-died
764   add hl,bc ;+input
765   xor a
766   cp  (hl)
767   jr  nz,NoLinkIndic
768   ld  b,7
769   inc hl ;+left
770   cp  (hl)
771   jr  z,hostLinkIndic
772   dec b
773 hostLinkIndic:
774   ld  a,8
775   ld  (_curCol),a
776   ld  a,b
777   call _putc
778   xor a
779   ld  (_curCol),a
780   dec hl
781 NoLinkIndic:
782   inc hl
783   inc hl
784   inc hl ;+name
785   call _puts
786
787   pop hl
788   push hl
789   ld  a,13
790   ld  (_curCol),a
791   ld  a,(hl) ;worm+died
792   push hl
793   call showA
794   pop hl
795
796   ld  a,16
797   ld  (_curCol),a
798   inc hl ;worm+score
799   call _ldHLind ;ld hl,(hl)
800   call showHL ;worm+score
801
802   pop hl
803   ld  bc,worm2-worm1
804   add hl,bc
805   pop bc
806   djnz displayWormStats
807
808   ld  a,(gameCar)
809   and _datasingl
810   jr  z,hiscorecheckdone
811 checkhiscore:
812   ld  de,(worm1+score)
813 HiScore =$+1
814   ld  hl,0
815   ld  a,d
816   cp  h
817   jr  c,NotNewHigh
818   ld  a,e
819   cp  l
820   jr  c,NotNewHigh
821   ld  (HiScore),de
822   ex  de,hl ;disp.new hiscore
823 NotNewHigh:
824   ex  de,hl ;push
825   ld  hl,$0807
826   ld  (_curRow),hl
827   ld  hl,txthiscore
828   call _puts
829   ex  de,hl ;pop
830   call showHL
831 hiscorecheckdone:
832
833 waitkey:
834   halt
835   halt
836   call GET_KEY
837   cp  K_ENTER
838   jp  z,DisplayMenu
839 ;  cp  K_EXIT
840   jr  nz,waitkey
841
842 ;x123456789012345678901
843 ;1----- GAME OVER -----
844 ;2Multiplayer
845 ;3Level 01
846 ;4           Died Score:
847 ;5NameName     03 00070
848 ;6Worm#02 @    05 00120
849 ;7Worm#03      15 00030
850 ;8Snaky   @    00 04820
851
852 ExitNoStats:
853   ld  hl,_asapvar
854   rst 20h ;_ABS_MOV10TOOP1
855   rst 10h ;_FINDSYM
856   call _swapt_ ;_ex_ahl_bde
857   ld  de,4
858   add hl,de
859   adc a,0
860   call _SET_ABS_DEST_ADDR
861
862   xor a
863   ld  hl,start
864   call _SET_ABS_SRC_ADDR
865   ld  hl,end-start
866   call _SET_MM_NUM_BYTES
867   call _mm_ldir
868
869 ;  xor a
870 ;  ld  (_asapvar+1),a
871   res 4,(iy+9)
872   set 2,(iy+13)
873   jp  _clrWindow
874
875 ;-----------------------------
876 ;----------- worm ------------
877 ;-----------------------------
878
879 inlink:
880   ld  a,0
881 sendbyte =$-1
882   ld  b,(ix+left)
883   dec b
884   jr  z,receivefirst
885   call send
886   call receive
887   ld  l,a
888   ret
889 receivefirst:
890   push af
891   call receive
892   ld   l,a
893   pop  af
894   push hl
895   call send
896   pop  hl
897   ret
898
899 inkeys: ;use jp not call!
900   out (1),a
901   in  a,(1)
902   ld  b,a
903   and (ix+right)
904   jr  z,notright
905   ld  a,l
906   add a,8
907   ld  l,a
908 notright:
909   ld  a,b
910   and (ix+left)
911   jr  z,donediddelydone
912   ld  a,l
913   sub 8
914   ld  l,a
915   jr  donediddelydone
916
917 ;------- handle worm ---------
918
919 HandleWorm:
920   dec (ix+delay)
921   ret nz
922   inc (ix+delay)
923   ld  l,(ix+heading)
924   ld  a,(ix+input)
925   or  a
926   jr  nz,inkeys
927   call inlink
928 donediddelydone:
929   ld  a,l
930   ld  (sendbyte),a
931   ld  (ix+heading),l
932   ld  h,(ix+heading+1)
933
934   ld  c,(ix+pos)
935   ld  b,(ix+pos+1)
936   ld  e,(ix+pos2)
937   ld  d,(ix+pos2+1)
938
939 ;-------- move worm ----------
940
941 Wormmove:
942   push bc                        ; >> pos
943   ld  a,(hl)
944   add a,a
945   add a,d
946   ld  d,a
947   bit 7,(hl)
948   jr  z,notnegX
949   dec b
950 notnegX:
951   jr  nc,notmoveX
952   inc b
953 notmoveX:
954   ld  a,l
955   add a,$40
956   ld  l,a
957   ld  a,(hl)
958   add a,a
959   add a,e
960   ld  e,a
961   bit 7,(hl)
962   jr  z,notnegY
963   dec c
964 notnegY:
965   jr  nc,notmoveY
966   inc c
967 notmoveY: ;bc=newpos
968   ld  (ix+pos2),e
969   ld  (ix+pos2+1),d
970   ld  (ix+pos),c
971   ld  (ix+pos+1),b
972
973 ;-check-
974   pop hl                         ; << pos (old)
975   ld  a,h
976   sub b
977   and 1
978   ld  h,a
979   ld  a,l
980   sub c
981   and 1
982   add a,h
983   ld  d,4
984   jr  z,GotFour
985   xor 3
986   ld  d,a
987 GotFour:
988   call chk4pixels
989   rl  d
990   jp  nc,Drawworm
991
992 ;--------- worm hit ----------
993
994 Hitworm:
995   ld  a,(gameCar)
996   ld  h,a
997   and _datafood
998   jp  z,WormDead
999   ld  a,h
1000   and _datahunt
1001   call nz,checkhitotherworm
1002
1003   ld  hl,0
1004 PeaY =$-2
1005 PeaX =$-1
1006   ld  a,b
1007   sub h
1008   inc a
1009   cp  4
1010   jp  nc,WormDead
1011   ld  a,c
1012   sub l
1013   inc a
1014   cp  4
1015   jp  nc,WormDead
1016   call DrawPea
1017   ld  a,(ix+grow)
1018   add a,15
1019   ld  (ix+grow),a
1020   call NewPea
1021   ld  hl,Left
1022   dec (hl)
1023   push af
1024   ld  de,10
1025   call IncScore
1026   pop af
1027   jr  nz,still_alive_not_dead
1028   ld  a,(gameCar)
1029   and _datafoodl
1030   jr  z,still_alive_not_dead
1031   ld  hl,Level
1032   ld  a,(hl)
1033   inc (hl)
1034   pop hl                         ; << call
1035   pop hl                         ; << call
1036   pop de                         ; << levelp new
1037   cp  NUM_LEVELS
1038   jp  z,Exit
1039   ld  a,(gameCar)
1040   and _datanextl
1041   jp  nz,StartLevel
1042   jp  Exit
1043
1044 ;-----------------------------
1045
1046 checkhitotherworm:
1047   .db $dd,$7d ;ld a,lx
1048   cp  worm2&255
1049   ret nz
1050 ThisIsJustASillyUselessLabel:
1051   ld  hl,(worm1+tail)
1052   ld  de,(worm1+head)
1053 nextotherwormbit:
1054   ld  a,c
1055   sub (hl)
1056   inc hl
1057   inc a
1058   cp  4
1059   jr  nc,nothit1 ;no
1060   ld  a,b
1061   sub (hl)
1062   inc a
1063   cp  4
1064   jr  c,otherwormHIT ;yes
1065 nothit1:
1066   inc hl
1067   res resbit,h
1068   call _cphlde
1069   jr  nz,nextotherwormbit
1070   ret
1071
1072 checkhitlapline:
1073   ld  a,63
1074   sub b
1075   jr  z,nextlaphalf
1076   inc a
1077   ret nz
1078 nextlaphalf:
1079   ld  a,c
1080   and 32 ;y>=32?
1081   jr  nz,nolap
1082   cp  (ix+reserv)
1083   jr  z,nolap
1084   push bc
1085   ld  de,20
1086   call IncScore
1087   pop bc
1088   xor a
1089 nolap:
1090   ld  (ix+reserv),a
1091   ret
1092
1093 otherwormHIT:
1094   push ix
1095   ld  de,10
1096   call IncScore
1097   ld  ix,worm1
1098   call WormDead
1099   pop ix
1100   pop bc
1101 still_alive_not_dead:
1102
1103 ;-------- draw worm ----------
1104
1105 Drawworm:
1106   ld  a,(gameCar)
1107   and _datahunt
1108   call nz,HuntingTimeScore
1109
1110   ld  c,(ix+pos)
1111   ld  b,(ix+pos+1)
1112
1113   ld  a,(gameCar)
1114   and _datalaps
1115   call nz,checkhitlapline
1116
1117   ld  l,(ix+head)
1118   ld  h,(ix+head+1)
1119   ld  (hl),c
1120   inc hl
1121   ld  (hl),b
1122   inc hl
1123   res resbit,h
1124   ld  (ix+head),l
1125   ld  (ix+head+1),h
1126
1127   call set4pixels
1128
1129   ld  a,(ix+grow)
1130   dec a
1131   jr  z,removetail
1132   ld  (ix+grow),a
1133   ret
1134
1135 removetail:
1136   ld  l,(ix+tail)
1137   ld  h,(ix+tail+1)
1138   ld  c,(hl)
1139   inc hl
1140   ld  b,(hl)
1141   inc hl
1142   res resbit,h
1143   ld  (ix+tail),l
1144   ld  (ix+tail+1),h
1145
1146 res4pixels:
1147   call ResPixel
1148   inc b
1149   call ResPixel
1150   inc c
1151   call ResPixel
1152   dec b
1153 ResPixel:
1154   call FindPixel
1155   cpl
1156   and (hl)
1157   ld  (hl),a
1158   ret
1159
1160 ;-----------------------------
1161 ;---------- ball -------------
1162 ;-----------------------------
1163
1164 handlethatneatlittleball:
1165   ld  a,0
1166 nrballs =$-1
1167   or  a
1168   ret z
1169 ballpos =$+1
1170   ld  bc,$0503
1171   call res4pixels
1172   dec c
1173   ld  e,b
1174 ballxmove:
1175   inc b ;=%000100 dec=%000101
1176   call checkballhit
1177   jr  z,ballxdone
1178   ld  b,e
1179   ld  hl,ballxmove
1180   call letsmovetheotherway
1181 ballxdone:
1182   ld  e,c
1183 ballymove:
1184   inc c ;=%001100 dec=%001101
1185   call checkballhit
1186   jr  z,balldone
1187   ld  c,e
1188   ld  hl,ballymove
1189   call letsmovetheotherway
1190 balldone:
1191   ld  (ballpos),bc
1192   jp  set4pixels
1193
1194 letsmovetheotherway:
1195   ld  a,1
1196   xor (hl)
1197   ld  (hl),a
1198   ret
1199
1200 checkballhit:
1201   ld  d,0
1202   call chk4pixels
1203   xor a
1204   cp  d
1205   ret
1206
1207 ;-----------------------------
1208 ;----------- procs -----------
1209 ;-----------------------------
1210
1211 NewPea:
1212 ;random routine
1213   ld hl,0
1214   ld de,12345
1215 Seed =$-2
1216   ld a,7921&255
1217   ld bc,$1000+(7921/256)
1218 domult16:
1219   add hl,hl
1220   rla
1221   rl  c
1222   jr  nc,noadd16
1223   add hl,de
1224 noadd16:
1225   djnz domult16
1226   inc hl
1227   ld  (Seed),hl ;seed=(seed*7921+1)\65536
1228
1229   ld  a,(FieldWidth)
1230   add a,123
1231   cp  h
1232   jr  c,NewPea
1233   inc h
1234   inc h
1235   ld a,(FieldHeight)
1236   add a,51
1237   cp  l
1238   jr  c,NewPea
1239   inc l
1240   inc l
1241   ld  (PeaY),hl
1242   ld  d,2 ;don't draw
1243   push hl
1244   call CheckPea
1245   pop hl
1246   dec d
1247   jr  z,NewPea
1248
1249 DrawPea: ;hl=(PeaY)
1250   ld  d,0 ;draw
1251 CheckPea:
1252   ld  b,h
1253   ld  c,l
1254   call PeaPixel
1255   inc c
1256   call PeaPixel
1257   inc b
1258   call PeaPixel
1259   dec c
1260 PeaPixel:
1261   push de
1262   call FindPixel
1263   pop de
1264   ld  e,a ;>>
1265   ld  a,d
1266   or  a
1267   ld  a,e ;<<
1268   jr  z,DrawPeaPixel ;d=0:draw
1269   and (hl) ;pixel?
1270   ret z
1271   ld  d,1 ;d=1:yes 2:no
1272   ret
1273 DrawPeaPixel:
1274   xor (hl) ;change pixel
1275   ld  (hl),a
1276   ret
1277
1278 ;-------- pixelprocs ---------
1279
1280 set4pixels:
1281   call SetPixel
1282   inc b
1283   call SetPixel
1284   inc c
1285   call SetPixel
1286   dec b
1287 SetPixel: ;at bc
1288   call FindPixel
1289   or  (hl)
1290   ld  (hl),a
1291   ret
1292
1293 chk4pixels: ;&&
1294   call CheckPixel
1295   inc b
1296   call CheckPixel
1297   inc c
1298   call CheckPixel
1299   dec b
1300   call CheckPixel
1301   dec c
1302   ret
1303 CheckPixel: ;at bc in d
1304   call FindPixel
1305   and (hl)
1306   ret z
1307   dec d
1308   ret
1309
1310 ;CLEM's FIND_PIXEL (131+? cycles; 28+4 bytes)
1311 ;                (b,c) to hl:a; destroyes: -)
1312
1313 FindPixel:
1314   ld  h,0
1315   ld  l,c    ;hl=y
1316   add hl,hl
1317   add hl,hl
1318   ld  a,b    ;a=x
1319   rra
1320   add hl,hl
1321   rra
1322   add hl,hl
1323   add hl,hl  ;hl=32*y
1324   rra        ;a=x/8
1325   or  l
1326   ld  l,a
1327   ld  a,b
1328   and 7
1329   cpl
1330   rlca
1331   rlca
1332   rlca
1333   ld  (FP_Bit),a
1334   xor a
1335 FP_Bit =$+1
1336   set 0,a
1337
1338   push de
1339   ld  de,ScrBuffer
1340   add hl,de
1341   pop de
1342   ret
1343
1344 ;----------- score -----------
1345
1346 HuntingTimeScore:
1347   .db $dd,$7d ;ld a,lx
1348   cp  worm2&255
1349   ret z ;=worm#2
1350   dec (ix+reserv)
1351   ret nz
1352   ld  de,10
1353
1354 IncScore:
1355   ld  h,(ix+score+1)
1356   ld  l,(ix+score)
1357   add hl,de
1358   jr  scorecommon
1359 DecScore: ;&&&
1360   ld  h,(ix+score+1)
1361   ld  l,(ix+score)
1362   or  a
1363   sbc hl,de
1364   ret c
1365 scorecommon:
1366   ld  (ix+score+1),h
1367   ld  (ix+score),l
1368   ld  de,0
1369 scorelimit =$-2
1370   call _cphlde
1371   jp  nc,Exit
1372
1373 showstats:
1374   push ix
1375   ld  h,0
1376   ld  l,h
1377   ld  (_penCol),hl
1378   ld  a,(nrworms)
1379   ld  b,a
1380   ld  ix,worm1
1381   ld  a,(gameCar)
1382   and _datanextl
1383   jr  nz,showstatsS
1384 showstatloop:
1385   push bc
1386   call showstat
1387   ld  de,worm2-worm1
1388   add ix,de
1389   ld  hl,_penCol
1390   ld  a,(hl)
1391   add a,10
1392   ld  (hl),a
1393   pop bc
1394   djnz showstatloop
1395   pop ix
1396   ret
1397
1398 showstat:
1399   ld  a,(gameCar)
1400   and _datalivel
1401   jr  nz,showlives
1402 showscore:
1403   ld  h,(ix+score+1)
1404   ld  l,(ix+score)
1405   call _D_HL_DECI
1406   jr __vputs
1407 showlives:
1408   ld  a,(ix+lives)
1409   add a,'0'
1410 __vputmap:
1411   push ix
1412   call _vputmap
1413   pop ix
1414   ret
1415
1416 showstatsS:
1417   ld  hl,txtLevel
1418   call __vputs
1419   ld  a,(Level)
1420   cp  10
1421   jr  c,tilllevel9
1422   ld  l,a
1423   ld  h,0
1424   call _divHLby10
1425   push af
1426   ld  a,l
1427   add a,'0'
1428   call __vputmap
1429   pop af
1430 tilllevel9:
1431   add a,'0'
1432   call __vputmap
1433
1434   ld  a,98
1435   ld  (_penCol),a
1436   call showscore
1437   ld  a,123
1438   ld  (_penCol),a
1439   call showlives
1440   ld  a,(gameCar)
1441   and _datafoodl
1442   pop ix
1443   ret z
1444 showleft:
1445   ld  a,31
1446   ld  (_penCol),a
1447   ld  a,0
1448 Left =$-1
1449   push af
1450   call _divAby10
1451   add a,'0'
1452   call __vputmap
1453   pop af
1454   add a,'0'
1455   call __vputmap
1456   ld  hl,txtLeft
1457 __vputs:
1458   push ix
1459   call _vputs
1460   pop ix
1461   ret
1462
1463 showLevel:
1464   ld  hl,txtLevel
1465   call _puts
1466   ld  a,(Level)
1467 showA:
1468   cp  10
1469   jr  c,LevelBelowTen
1470   ld  l,a
1471   ld  h,0
1472   call _divHLby10
1473   push af
1474   ld  a,l
1475   add a,'0'
1476   call _putc
1477   pop af
1478 LevelBelowTen:
1479   add a,'0'
1480   jp  _putc
1481
1482 showHL:
1483   call _D_HL_DECI
1484   jp  _puts
1485
1486 _D_HL_DECI:
1487   ld  de,savestr+4
1488   ld  b,5
1489 ldhld:
1490   call _divHLby10
1491   add a,'0'
1492   ld  (de),a
1493   dec de
1494   djnz ldhld
1495   ld  hl,savestr
1496   ret
1497 savestr:
1498   .db "00000",0
1499
1500 ;-----------------------------
1501
1502 DisplayField:
1503   ld  a,c
1504   sub 29
1505   jr  nc,NotMinYScroll
1506   xor a
1507 NotMinYScroll:
1508   cp  43
1509 FieldHeight =$-1
1510   jr  c,NotMaxYScroll
1511   ld  a,(FieldHeight)
1512 NotMaxYScroll:
1513   ld  l,a
1514   ld  h,0
1515   add hl,hl
1516   add hl,hl
1517   add hl,hl
1518   add hl,hl
1519   add hl,hl
1520   push bc                        ; >> 1
1521   push de                        ; >> 2
1522   ld  de,ScrBuffer
1523   add hl,de
1524   ld  a,b
1525   sub 64
1526   jr  nc,NotMinXScroll
1527   xor a
1528 NotMinXScroll:
1529   cp 128
1530 FieldWidth = $-1
1531   jr c,NotMaxXScroll
1532   ld a,(FieldWidth)
1533 NotMaxXScroll:
1534   push af                        ; >> 3
1535   and %11111000
1536   rra
1537   rra
1538   rra
1539   ld  c,a
1540   ld  b,0
1541   ld  de,DispBuffer
1542   pop af                         ; << 2
1543   and %00000111
1544   push af                        ; >> 3
1545   cp  6
1546   jr  c,CopyScreen
1547   inc c
1548 CopyScreen:
1549   add hl,bc
1550   ld b,57
1551 CopyScreenLoop:
1552   push bc                        ; >> 4
1553   ld bc,16
1554   ldir
1555   ld c,16
1556   add hl,bc
1557   pop bc                         ; << 3
1558   djnz CopyScreenLoop
1559   pop af                         ; << 2
1560   ld  c,$b7 ;or a
1561 Bit0:
1562   jr  nz,Bit1
1563   halt
1564   halt
1565   jr  AfterShiftDelay
1566 Bit1:
1567   dec a
1568   jr nz,Bit2
1569   call ShiftRight1
1570   jr AfterShiftDelay
1571 Bit2:
1572   dec a
1573   jr nz,Bit3
1574   ld a,2
1575   call ShiftRight
1576   jr AfterShiftDelay
1577 Bit3:
1578   dec a
1579   jr nz,Bit4
1580   call Chunk
1581   call ShiftLeft1
1582   jr AfterShift
1583 Bit4:
1584   dec a
1585   jr nz,Bit5
1586   call Chunk
1587   jr AfterShiftDelay
1588 Bit5:
1589   dec a
1590   jr nz,Bit6
1591   call Chunk
1592   call ShiftRight1
1593   jr AfterShift
1594 Bit6:
1595   dec a
1596   jr nz,Bit7
1597   ld a,2
1598   call ShiftLeft
1599   jr AfterShift
1600 Bit7:
1601   call ShiftLeft
1602 AfterShiftDelay:
1603   halt
1604 AfterShift:
1605   ld hl,DispBuffer
1606   ld de,$fc00+$70
1607   ld bc,1024-$70
1608   ldir
1609   pop de                         ; << 1
1610   pop bc                         ; << 0k
1611   ret
1612
1613 ShiftRight1:
1614   ld a,1
1615 ShiftRight:
1616   ld (ShiftRightCounter),a
1617   ld a,c
1618   ld (ShiftRightChunk),a
1619   ld c,16
1620   add hl,bc
1621   ld b,57
1622 ShiftRightLoop:
1623   push bc
1624   ld bc,-32
1625   add hl,bc
1626   ex de,hl
1627   ld a,(de)
1628 ShiftRightChunk:
1629   or a
1630   call c,_SHLACC
1631   ld c,0
1632 ShiftRightCounter = $-1
1633 ShiftRowsLeft:
1634   push hl
1635   rla
1636   ld b,16
1637 ShiftRowLeft:
1638   dec hl
1639   rl (hl)
1640   djnz ShiftRowLeft
1641   pop hl
1642   dec c
1643   jr nz,ShiftRowsLeft
1644   ld bc,-16
1645   add hl,bc
1646   ex de,hl
1647   pop bc
1648   djnz ShiftRightLoop
1649   ret
1650
1651 ShiftLeft1:
1652   ld a,1
1653 ShiftLeft:
1654   ld (ShiftLeftCounter),a
1655   ld a,c
1656   ld (ShiftLeftChunk),a
1657   rla
1658   jr nc,ShiftLeftSameByte
1659   dec hl
1660 ShiftLeftSameByte:
1661   ex de,hl
1662   ld bc,-16
1663   add hl,bc
1664 NewSprite:
1665   ex de,hl
1666   ld b,57
1667 ShiftLeftLoop:
1668   push bc                        ; >> 1
1669   ld bc,-32
1670   add hl,bc
1671   ex de,hl
1672   ld a,(de)
1673 ShiftLeftChunk:
1674   or a
1675   call c,_SHRACC
1676   ld c,0
1677 ShiftLeftCounter = $-1
1678 ShiftRowsRight:
1679   push hl                        ; >> 2
1680   rra
1681   ld b,16
1682 ShiftRowRight:
1683   rr (hl)
1684   inc hl
1685   djnz ShiftRowRight
1686   pop hl                         ; << 1
1687   dec c
1688   jr nz,ShiftRowsRight
1689   ld bc,-16
1690   add hl,bc
1691   ex de,hl
1692   pop bc                         ; << 0k
1693   djnz ShiftLeftLoop
1694   ret
1695
1696 Chunk:
1697   push hl                        ; >> 1
1698   push de                        ; >> 2
1699   ld  c,16
1700   add hl,bc
1701   ld  b,57
1702 ChunkScreen:
1703   push bc                        ; >> 3
1704   ld  bc,-32
1705   add hl,bc
1706   ex  de,hl
1707   ld  a,(de)
1708   call _SHRACC
1709   ld  b,16
1710 ChunkRow:
1711   dec hl
1712   rld
1713   djnz ChunkRow
1714   ex  de,hl
1715   pop bc                         ; << 2
1716   djnz ChunkScreen
1717   pop de                         ; << 1
1718   pop hl                         ; << 0k
1719   ld  c,$37 ;scf
1720   ret
1721
1722 ;----------- draw ------------
1723
1724 loaddrawdata:
1725   ld  d,(hl)
1726   inc hl
1727   ld  e,(hl)
1728   inc hl
1729   ld  a,(hl)
1730   inc hl
1731   ret
1732
1733 Line: ;draw line from de to hl (d<h)
1734   push hl
1735   push de
1736   ld a,d
1737   cp h
1738   jr c,lineOrdered
1739   ex de,hl
1740 lineOrdered:
1741   ld  b,d
1742   ld  c,e
1743   push hl
1744   push bc
1745   call FindPixel
1746   pop bc
1747   pop de
1748 connectedLine:
1749   push hl
1750   ld  h,c
1751   ld  c,a
1752   ld  a,d
1753   sub b
1754   ld  b,a
1755   ld  a,e
1756   jr  nz,LineNotPoint
1757   cp  h
1758   jr  nz,LineNotPoint
1759   pop hl
1760   jr  DoneLine
1761 LineNotPoint:
1762   sub h
1763   ld  de,32
1764   jr  nc,LinePositiveY
1765   neg
1766   ld  de,-32
1767 LinePositiveY:
1768   cp  b
1769   jr  nc,SteepLine
1770   add a,a
1771   ld  (line2sm+1),a
1772   ld  h,a
1773   xor a
1774   sub b
1775   add a,a
1776   ld  (line1sm+1),a
1777   ld  a,h
1778   sub b
1779   pop hl
1780 LineLoopGentle:
1781   push af
1782   ld  a,(hl)
1783   or  c
1784   ld  (hl),a
1785   rrc c
1786   jr  nc,$+3
1787   inc hl
1788   pop af
1789   jp  m,line2sm
1790 line1sm:
1791   add a,0
1792   add hl,de
1793 line2sm:
1794   add a,0
1795   djnz LineLoopGentle
1796 DoneLine:
1797   ld  a,(hl)
1798   or  c
1799   ld  (hl),a
1800   pop de
1801   pop hl
1802   ret
1803 SteepLine:
1804   ld  h,a
1805   neg
1806   add a,a
1807   ld  (line3sm+1),a
1808   ld  a,b
1809   add a,a
1810   ld  (line4sm+1),a
1811   sub h
1812   ld  b,h
1813   pop hl
1814 LineLoopSteep:
1815   push af
1816   ld  a,(hl)
1817   or  c
1818   ld  (hl),a
1819   add hl,de
1820   pop af
1821   jp  m,line4sm
1822 line3sm:
1823   add a,0
1824   rrc c
1825   jr  nc,$+3
1826   inc hl
1827 line4sm:
1828   add a,0
1829   djnz LineLoopSteep
1830   jr  DoneLine
1831
1832 drawbox:
1833  ld  b,h
1834  ld  c,l
1835  call FindPixel
1836 ;  ld  b,a
1837 ;makefirstbyte:
1838 ;  or  b
1839 ;  rr  b
1840 ;  jr  nc,makefirstbyte
1841 ;  or  (hl) ;()
1842 ;  ld  (hl),a
1843
1844   ld  b,e ;yloop
1845 boxloopy:
1846   push bc ;yloop
1847   ld  b,d ;xloop
1848 boxloopx:
1849   ld  a,%11111111
1850   ld  (hl),a
1851   inc hl
1852   djnz boxloopx
1853
1854   ld  b,0
1855   ld  a,16
1856   sub d
1857   ld  c,a
1858   add hl,bc
1859   pop bc ;yloop
1860   djnz boxloopy
1861   ret
1862
1863 ;-----------------------------
1864 ;----------- link ------------
1865 ;-----------------------------
1866
1867 TIMEOUT = $1000
1868
1869 receive:
1870   call GET_KEY
1871   cp  K_EXIT
1872   jp  z,LinkBreak
1873   in  a,(7)
1874   and %11
1875   cp  %11
1876   jr  z,receive
1877   call Qreceive
1878   jr  c,receive
1879   ret
1880
1881 Qreceive:
1882   ld  b,8
1883   jr  ReceiveCont
1884 receiveloop:
1885   ld  de,TIMEOUT
1886 WaitRecBit:
1887   call CheckLink
1888   jr  z,LinkFailed
1889   cp  %11
1890   jr  z,WaitRecBit
1891 ReceiveCont:
1892         sub 2
1893         ld  a,2
1894         ld  d,D0LD1H
1895         jr  c,ReceiveLow
1896         rra
1897         ld  d,D0HD1L
1898 ReceiveLow:
1899         rr c
1900         ld (AckBit),a
1901         ld a,d
1902         out (7),a
1903         ld  de,TIMEOUT
1904 WaitAckRec:
1905         call CheckLink
1906         cp  0
1907 AckBit =$-1
1908         jr  nz,WaitAckRec
1909         ld  a,D0HD1H
1910         out (7),a
1911         ld  d,4
1912 WaitReadyRec:
1913         dec d
1914         jr  z,ReadyRec
1915         in  a,(7)
1916         cp  %11
1917         jr  nz,WaitReadyRec
1918 ReadyRec:
1919         djnz receiveloop
1920         jr  LinkSuccess
1921
1922 send:
1923   ld  b,9
1924   ld  c,a
1925   jr  SendAcked
1926 SendBits:
1927   rr  c
1928   ld  a,D0LD1H
1929   jr  nc,SendLow
1930   ld  a,D0HD1L
1931 SendLow:
1932   out (7),a
1933   ld  de,TIMEOUT
1934 WaitAckSend:
1935   call CheckLink
1936   jr  nz,WaitAckSend
1937 SendAcked:
1938   ld  a,D0HD1H
1939   out (7),a
1940   ld  de,TIMEOUT
1941 WaitReadySend:
1942   call CheckLink
1943   cp  %11
1944   jr  nz,WaitReadySend
1945   djnz SendBits
1946 LinkSuccess:
1947   ld  a,c ;pop a
1948   ret
1949
1950 LinkFailed:
1951   scf
1952   ld a,c
1953   ret
1954 LinkBreak:
1955   ld  a,D0HD1H
1956   out (7),a
1957   jp  Exit
1958
1959 CheckLink:
1960   pop hl
1961   dec de
1962   ld a,d
1963   or e
1964   jr z,LinkFailed
1965
1966   ld  a,$BF
1967   out (1),a
1968   nop \ nop
1969   in  a,(1)
1970   push af
1971   ld  a,%11111111
1972   out (1),a
1973   pop af
1974   bit 6,a
1975
1976   in  a,(7)
1977   and %11
1978   jp  (hl)
1979
1980
1981 ;-----------------------------
1982 ;---------- levels -----------
1983 ;-----------------------------
1984
1985 LevelsDM:
1986   .db 8,5,15,0
1987   .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
1988   .db 128,57
1989   .db 0,0
1990
1991 LevelsDM2:
1992   .db 8,5,31,0
1993   .db $40,28,2,$C0,28,125, $00,2,63,$80,54,63
1994   .db 128,57
1995   .db 0
1996   .db 4             ;4 boxes
1997   .db 4,19,16,14    ;xsize,ysize,xpos,ypos
1998   .db 4,19,80,14
1999   .db 4,19,16,34
2000   .db 4,19,80,34
2001
2002 LevelsL:
2003   .db 8,0,15,0
2004   .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
2005   .db 228,157
2006   .db 0,0
2007
2008 LevelsR:
2009   .db 8,2,10,0
2010   .db $40,3,2,$40,6,2, $40,9,2,$40,12,2
2011   .db 128,57
2012   .db 0
2013   .db 1
2014   .db 8,29,32,20
2015
2016 LevelsH:
2017   .db 8,7,17,0
2018 #ifdef 0
2019 huntersize = 31
2020 #endif
2021   .db $40,28,2,$C0,28,125, $00,2,63,$80,54,63
2022   .db 128,57
2023   .db 0
2024   .db 4
2025   .db 4,19,16,14
2026   .db 4,19,80,14
2027   .db 4,19,16,34
2028   .db 4,19,80,34
2029
2030 NUM_LEVELS = 10
2031
2032 LevelsS:
2033
2034   .db 5,4,15,0      ;peas,speed,begin_size,balls
2035   .db 0,2,63        ;start d, y, x
2036   .db 128,57        ;field width (128-255), height (57-255)
2037   .db 0,0           ;no additional lines, boxes
2038
2039   .db 8,4,15,0
2040   .db $40,14,2
2041   .db 128,57
2042   .db 1
2043   .db 28,28,100,28  ;line coords: x1,y1,x2,y2
2044   .db 0
2045
2046   .db 9,4,15,0
2047   .db $40,8,2
2048   .db 128,57
2049   .db 2
2050   .db 28,14,100,14
2051   .db 28,41,100,41
2052   .db 0
2053
2054   .db 9,3,15,0
2055   .db $40,8,2
2056   .db 128,80
2057   .db 2
2058   .db 64,14,64,66
2059   .db 20,40,108,40
2060   .db 0
2061
2062   .db 10,3,15,0
2063   .db 2,8,$40
2064   .db 128,90
2065   .db 3
2066   .db 18,20,18,70
2067   .db 110,20,110,70
2068   .db 18,45,110,45
2069   .db 0
2070
2071  .db 4,3,10,1 \ .dw $20F
2072  .db 0,2,63
2073  .db 128,57
2074  .db 2
2075  .db 28,14,100,41
2076  .db 28,41,100,14
2077  .db 0
2078
2079   .db 7,3,15,0
2080   .db 64,4,0
2081   .db 128,86
2082   .db 6
2083   .db 34,13,56,35
2084   .db 34,71,56,49
2085   .db 72,35,94,13
2086   .db 72,49,94,71
2087   .db 16,20,16,64
2088   .db 110,20,110,64
2089   .db 0
2090
2091   .db 9,3,15,0
2092   .db $40,4,10
2093   .db 128,82
2094   .db 3
2095   .db 0,20,74,20
2096   .db 54,40,128,40
2097   .db 0,60,74,60
2098   .db 0
2099
2100   .db 12,3,15,0
2101   .db $40,4,0
2102   .db 128,90
2103   .db 6
2104   .db 20,16,54,16
2105   .db 74,16,110,16
2106   .db 20,16,20,72
2107   .db 110,16,110,72
2108   .db 20,72,54,72
2109   .db 74,72,110,72
2110   .db 0
2111
2112   .db 8,2,15,0
2113   .db $C0,72,48
2114   .db 128,128
2115   .db 13
2116   .db 34,56,56,34
2117   .db 34,72,56,94
2118   .db 72,34,94,56
2119   .db 72,94,94,72
2120   .db 46,64,80,64
2121   .db 22,11,22,33
2122   .db 11,22,33,22
2123   .db 22,95,22,117
2124   .db 11,106,33,106
2125   .db 103,11,103,33
2126   .db 91,22,115,22
2127   .db 103,95,103,117
2128   .db 91,106,115,106
2129   .db 0
2130
2131
2132 ;-----------------------------
2133 ;---------- data -------------
2134 ;-----------------------------
2135
2136 TrigPrecalc:
2137 .db   0,  3,  6,  9, 12, 15, 18, 21
2138 .db  24, 27, 30, 33, 36, 39, 42, 45
2139 .db  48, 51, 54, 57, 59, 62, 65, 67
2140 .db  70, 73, 75, 78, 80, 82, 85, 87
2141 .db  89, 91, 94, 96, 98,100,102,103
2142 .db 105,107,108,110,112,113,114,116
2143 .db 117,118,119,120,121,122,123,123
2144 .db 124,125,125,126,126,126,126,126
2145 .db 127
2146
2147 txtWelcome: .db "Welcome to Worm!! ",
2148             .db "by Shiar",0
2149 txtOptions: .db "Options",0
2150 txtGame:    .db "Singleplayer",0  ;0
2151 txtGame2:   .db "Peaworm     ",0  ;1
2152             .db "Deathmatch",0    ;2
2153             .db "Foodmatch ",0    ;3
2154             .db "LinkMatch",0     ;4 (>options)
2155             .db "Hunting  ",0     ;5
2156             .db "Race   ",0       ;6
2157             .db "CTF ",0          ;7
2158             .db "Domination",0    ;(>=8)
2159 txtWaiting: .db "Waiting...",0
2160 txtReceive: .db "Receiving...",0
2161
2162 WormVersion = 092
2163 WormMsg:   .db "WORM by SHIAR -- test version",0
2164 txtLevel:  .db "Level ",0
2165 txtWorms:  .db "Worms: 0",0 ;follows txtLevel
2166 txtDied:   .db "Died ",0
2167 txtScore:  .db "Score",0  ;follows txtDied
2168 txtLeft:   .db " left",0   ;follows txtScore
2169 txthiscore:.db "HiScore:",0
2170 txtReady:  .db "Prepare!",0
2171 txtposReady = 7
2172 txtGO:     .db "----- GAME OVER -----",0
2173
2174 gamesdata:
2175
2176 _datalink  = %00000001
2177 _datalivel = %00000010 ;ix+lives=0 limit
2178 _datafoodl = %00000100 ;left=0 limit
2179 _datanextl = %00001000 ;next level if left=0
2180 _datasingl = %00001000 ;singleplayer=1
2181 _datafood  = %00010000 ;food present
2182 _datahunt  = %00100000
2183 _datalaps  = %01000000 ;give lap score
2184 _datascore = %10000000 ;score>=100 limit
2185
2186 datasingle: .db %00011110
2187             .dw LevelsS
2188 datapeas:   .db %00011010
2189             .dw LevelsS
2190 datadeathm: .db %00000010
2191             .dw LevelsDM2
2192 datafoodm:  .db %10010000
2193             .dw LevelsDM
2194 datalinkm:  .db %00000011
2195             .dw LevelsL
2196 datahuntin: .db %10100000
2197             .dw LevelsH
2198 datarace:   .db %11000000
2199             .dw LevelsR
2200 datactf:    .db %00000000
2201             .dw LevelsDM
2202 datadomin:  .db %00000000
2203             .dw LevelsDM
2204
2205
2206 resbit  = 2             ;and%11111011
2207 worm1set:  .dw $B000,$B000 ;%10110000
2208            .db 3,0,%01111110,%10,%100 ;< >
2209            .db "Worm #1",0
2210 worm2set:  .dw $B800,$B800 ;%10111000
2211            .db 3,0,%00111111,%10000,%1000 ;f1 f2
2212            .db "Worm #2",0
2213 worm3set:  .dw $F000,$F000 ;$E800=%11101000 ;$D748+$1000+
2214            .db 3,0,%01011111,%10,%100 ;sto ,
2215            .db "Worm #3",0
2216 worm4set:  .dw $A800,$A800 ;$F000=%11110000
2217            .db 3,0,%01111101,%10,%1 ;enter +
2218            .db "Worm #4",0
2219 worm1 = $B400
2220 worm2 = $B42A
2221 worm3 = $B454
2222 worm4 = $B47E ;-A8
2223 end:
2224               ;set:
2225 heading = 0   ;level*
2226 pos     = 2   ;level*
2227 pos2    = 4   ;level
2228 grow    = 6   ;level
2229 died    = 8   ;game
2230 score   = 9   ;game
2231 delay   = 11  ;game
2232
2233 head    = 12  ;level
2234 tail    = 14  ;level
2235 lives   = 16  ;game
2236 reserv  = 17  ;loop
2237  ;race:lap
2238  ;hunt:time
2239 input   = 18  ;&
2240 left    = 19  ;&
2241 right   = 20  ;&
2242 name    = 21  ;game
2243
2244 Level =$+1
2245 DispBuffer =$+2 ;912 bytes
2246
2247 ScrBuffer   = $8100 ;-$A2FF (32x256) mod$800=0
2248 SinCosTable = $B500 ;size=$100 (4x64)
2249
2250 ;-----------------------------
2251 ;----------- end -------------
2252 ;-----------------------------
2253
2254   .end
2255
2256 .end