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