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