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