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