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