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