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