33c8038c154f01e023f7350cc8f1a9781cd20321
[wormy.git] / worm.asm
1 ; -WonderWorm--v0.9-
2 ; by Matthew Shepcar
3 ; 30th December 1998
4
5 ; modified by Jonah Cohen 11-19-99
6
7 #include "TI86.inc"
8
9 .org _asm_exec_ram
10
11   nop
12   jp Start
13   .dw 0,WormMsg
14 Start:
15   ld (SpSave),sp
16   call _runIndicOff
17   call _flushAllMenus
18   call _clrLCD
19
20 ;build trig tables
21   ld hl,TrigPrecalc
22   ld de,SinCosTable
23   push de
24   ld bc,65
25   ldir
26   dec hl
27   ld b,63
28 MirrorSineWave:
29   dec hl
30   ld a,(hl)
31   ld (de),a
32   inc de
33   djnz MirrorSineWave
34   pop hl
35   ld b,128+64
36 NegativeSineWave:
37   xor a
38   sub (hl)
39   ld (de),a
40   inc hl
41   inc de
42   djnz NegativeSineWave
43
44   ld a,r
45   ld (Seed),a
46
47   ld hl,0
48   ld (Score),hl
49   ld a,1
50   ld (Level),a
51   ld a,3
52   ld (Lives),a
53   ld hl,Levels
54
55 StartLevel:
56   ld a,(hl)
57   ld (Left),a
58   inc hl
59   ld a,(hl)
60   ld (Speed),a
61   inc hl
62   ld a,25
63 NextLife:
64   ld (GrowAmt),a
65   push hl
66   ld d,(hl)
67   inc hl
68   ld e,(hl)
69   inc hl
70   ld a,(hl)
71   inc hl
72   ld (Heading),a
73   push de
74   ld a,(hl)
75   inc hl
76   sub 128
77   ld (FieldWidth),a
78   ld a,(hl)
79   inc hl
80   sub 57
81   ld (FieldHeight),a
82   add a,57-5
83   push hl
84   ld l,a
85   ld h,0
86   add hl,hl
87   add hl,hl
88   add hl,hl
89   add hl,hl
90   add hl,hl
91   ex de,hl
92
93   ld hl,ScrBuffer
94   push hl
95   push de
96   ld de,ScrBuffer+1
97   ld bc,63
98   ld (hl),%11111111
99   ldir
100   inc hl
101   ld (hl),%11000000
102   inc hl
103   ld b,31
104 ClearLine:
105   ld (hl),c
106   inc hl
107   djnz ClearLine
108   push hl
109
110   ld a,(FieldWidth)
111   add a,126
112   push af
113   and %11111000
114   rra
115   rra
116   rra
117   ld l,a
118   ld h,0
119   add hl,de
120   pop af
121   and %00000111
122   ld b,a
123   ld c,0
124   ld a,%11000000
125   jr z,NoVertShift
126 VertShift:
127   rra
128   rr c
129   djnz VertShift
130 NoVertShift:
131   ld (hl),a
132   inc hl
133   ld (hl),c
134
135   ex de,hl
136   pop de
137   pop bc
138   ldir
139   pop hl
140   ld c,64
141   ldir
142
143   pop hl
144
145   ld a,(hl)
146   inc hl
147   or a
148   jr z,NoLines
149 DrawLines:
150   push af
151   ld d,(hl)
152   inc hl
153   ld e,(hl)
154   inc hl
155   ld a,(hl)
156   inc hl
157   push hl
158   ld l,(hl)
159   ld h,a
160   call Line
161   inc d
162   inc h
163   call Line
164   inc e
165   inc l
166   call Line
167   dec d
168   dec h
169   call Line
170   pop hl
171   inc hl
172   pop af
173   dec a
174   jr nz,DrawLines
175 NoLines:
176   push hl
177
178   ld hl,0
179   ld (_penCol),hl
180   ld hl,LivesMsg
181   call _vputs
182   ld a,(Lives)
183   add a,'0'
184   call _vputmap
185
186   ld a,40
187   ld (_penCol),a
188   call _vputs ;scoremsg
189   ld a,100
190   ld (_penCol),a
191   call _vputs
192   ld a,(Left)
193   call PutNum
194
195   call PutScore
196
197   call NewPea
198
199   pop hl
200   pop bc
201   push bc
202   push hl
203   call DisplayField
204   ld hl,LevelMsg
205   ld a,7
206   push hl
207   ld h,a
208   ld l,4
209   ld (_curRow),hl
210   ld hl,0FDE0h
211   ld de,0FDE1h
212   ld (hl),-1
213   ld bc,0BFh
214   ldir
215   pop hl
216   set 3,(iy+5)
217   call _puts
218   ld a,(Level)
219   cp 10
220   jr c,LevelBelowTen
221   ld l,a
222   ld h,0
223   call _divHLby10
224   push af
225   ld a,l
226   add a,'0'
227   call _putc
228   pop af
229 LevelBelowTen:
230   add a,'0'
231   call _putc
232   res 3,(iy+5)
233
234   xor a
235 ReadyDelay:
236   halt
237   dec a
238   jr nz,ReadyDelay
239
240   ld hl,(HeadPos)                               ;<====NEW
241   ld (TailPos),hl
242   pop hl
243   pop bc
244   push hl
245   ld de,0
246
247 GameLoop:
248   call DisplayField
249
250   ld a,2
251 Speed =$-1
252   or a
253   jr z,HeadPos-1
254 Delay:
255   halt
256   dec a
257   jr nz,Delay
258
259   ld hl,WormPos
260 HeadPos =$-2
261   ld (hl),c
262   inc hl
263   ld (hl),b
264   inc hl
265   res 2,h                               ;<====NEW
266   ld (HeadPos),hl
267
268   ld hl,SinCosTable
269 Heading =$-2
270
271   ld a,0FEh
272   out (1),a
273   in a,(1)
274   rra
275   rra
276   jr c,NotRight
277   push af
278   ld a,l
279   add a,8
280   ld l,a
281   pop af
282 NotRight:
283   rra
284   jr c,NotLeft
285   ld a,l
286   sub 8
287   ld l,a
288 NotLeft:
289
290   ld (Heading),hl
291
292   push bc
293   ld a,(hl)
294   add a,a
295   add a,d
296   ld d,a
297   bit 7,(hl)
298   jr z,NotNegX
299   dec b
300 NotNegX:
301   jr nc,NotMoveX
302   inc b
303 NotMoveX:
304   ld a,l
305   add a,40h
306   ld l,a
307   ld a,(hl)
308   add a,a
309   add a,e
310   ld e,a
311   bit 7,(hl)
312   jr z,NotNegY
313   dec c
314 NotNegY:
315   jr nc,NotMoveY
316   inc c
317 NotMoveY:
318
319   pop hl
320   push de
321   ld a,h
322   sub b
323   and 1
324   ld h,a
325   ld a,l
326   sub c
327   and 1
328   add a,h
329   ld d,4
330   jr z,GotFour
331   xor 3
332   ld d,a
333 GotFour:
334
335   call CheckPixel
336   inc b
337   call CheckPixel
338   inc c
339   call CheckPixel
340   dec b
341   call CheckPixel
342   dec c
343   rl d
344   jr nc,WormNotCrashed
345   ld hl,0
346 PeaY =$-2
347 PeaX =$-1
348   ld a,b
349   sub h
350   inc a
351   cp 4
352   jp nc,WormDead
353   ld a,c
354   sub l
355   inc a
356   cp 4
357   jp nc,WormDead
358   push bc
359   call DrawPea
360   ld a,0
361 GrowAmt =$-1
362   add a,15
363   ld (GrowAmt),a
364   call NewPea
365   ld de,10
366   call IncScore
367   ld a,119
368   ld (_penCol),a
369   ld hl,Left
370   dec (hl)
371   jr nz,NotNextLevel
372   ld hl,Level
373   ld a,(hl)
374   inc (hl)
375   pop bc
376   pop de
377   pop hl
378   pop de
379   cp NUM_LEVELS
380   jp nz,StartLevel
381   jr Exit
382
383 NotNextLevel:
384   ld a,(hl)
385   call PutNum
386   pop bc
387 WormNotCrashed:
388
389   push bc
390   ld a,3
391 WormCol =$-1
392   call SetPixel
393   inc b
394   call SetPixel
395   inc c
396   call SetPixel
397   dec b
398   call SetPixel
399
400 ;  xor 2
401 ;  ld (WormCol),a
402
403   ld hl,GrowAmt
404   dec (hl)
405   jr nz,GrowWorm
406   inc (hl)
407   ld hl,$b000
408 TailPos =$-2
409   ld c,(hl)
410   inc hl
411   ld b,(hl)
412   inc hl
413   res 2,h                               ;<====NEW
414   ld (TailPos),hl
415
416   call ResPixel
417   inc b
418   call ResPixel
419   inc c
420   call ResPixel
421   dec b
422   call ResPixel
423
424 GrowWorm:
425
426   ld a,0BFh
427   out (1),a
428   in a,(1)
429   rla
430   jr c,NotPaused
431   ld bc,$0103
432   out (c),b
433   halt
434   ld b,11
435   out (c),b
436 NotPaused:
437   pop bc
438   pop de
439   rla
440   jp c,GameLoop
441   jr Exit
442 ; push hl
443 WormDead:
444   pop de
445   pop hl
446   ld hl,(HeadPos)
447   ld de,(TailPos)
448   sbc hl,de
449   ld a,l
450   rr h
451   rra
452   ld hl,Lives
453   dec (hl)
454   pop hl
455   jp nz,NextLife
456 Exit:
457
458 #if 0
459   ld a,(Eaten)
460   ld hl,HiScore
461   cp (hl)
462   jr c,NotNewHigh
463   ld (hl),a
464   ld hl,_asapvar
465   rst 20h
466   rst 10h
467   call 460Bh
468   ld de,HiScore-_asm_exec_ram+2
469   add hl,de
470   adc a,0
471   call _load_ram_ahl
472   ld a,(HiScore)
473   ld (hl),a
474 NotNewHigh:
475 #endif
476   res 4,(iy+9)
477   ld sp,0
478 SpSave = $-2
479   jp _clrWindow
480
481 NewPea: ;------------------------------procs                            ;<====NEW
482 ;random routine
483   ld hl,0
484   ld de,12345
485 Seed =$-2
486   ld a,7921 & 255
487   ld bc,1000h+(7921/256)
488 domult16:
489   add hl,hl
490   rla
491   rl c
492   jr nc,noadd16
493   add hl,de
494 noadd16:
495   djnz domult16
496   inc hl
497   ld (Seed),hl ;seed=(seed*7921+1) MOD 65536
498   ld a,(FieldWidth)
499   add a,123
500   cp h
501   jr c,NewPea
502   inc h
503   inc h
504   ld a,(FieldHeight)
505   add a,51
506   cp l
507   jr c,NewPea
508   inc l
509   inc l
510   ld (PeaY),hl
511   ld d,2
512   push hl
513   call CheckPea
514   pop hl
515   dec d
516   jr z,NewPea
517 DrawPea:
518   ld d,0
519 CheckPea:
520   ld b,h
521   ld c,l
522   call PeaPixel
523   inc c
524   call PeaPixel
525   inc b
526   call PeaPixel
527   dec c
528 PeaPixel:
529   push de
530   call FindPixel
531   pop de
532   ld e,a
533   ld a,d
534   or a
535   ld a,e
536   jr z,DrawPeaPixel
537   and (hl)
538   ret z
539   ld d,1
540   ret
541 DrawPeaPixel:
542   xor (hl)
543   ld (hl),a
544   ret
545
546 ;no random routine here                         ;<====NEW
547
548 ResPixel: ;at bc
549   call FindPixel
550   cpl
551   and (hl)
552   ld  (hl),a
553   ret
554
555 SetPixel: ;at bc
556   call FindPixel
557   or  (hl)
558   ld  (hl),a
559   ret
560
561 CheckPixel: ;at bc in d
562   push de
563   call FindPixel
564   and (hl)
565   pop de
566   ret z
567   dec d
568   ret
569
570 FindPixel: ;bc to ahl + de gone                         ;<====NEW
571   push bc
572   ld a,b
573   and 7
574   add a,offsets_table & 255
575   ld e,a
576   ld d,offsets_table/256
577   ld h,0
578   ld l,c
579   add hl,hl
580   add hl,hl
581   add hl,hl
582   add hl,hl
583   add hl,hl
584   ld a,b
585   and %11111000
586   rra
587   rra
588   rra
589   or l
590   ld l,a
591   ld a,(de)
592   ld de,ScrBuffer
593   add hl,de
594   pop bc
595   ret
596
597 IncScore:
598   ld hl,(Score)
599   add hl,de
600   ld (Score),hl
601 PutScore:
602   ld de,_penCol
603   ld a,79
604   ld (de),a
605   ld b,5
606 DoPutScore:
607   push bc
608   push de
609   call _divHLby10
610   call PutDigit
611   pop de
612   ld a,(de)
613   sub 8
614   ld (de),a
615   pop bc
616   djnz DoPutScore
617   ret
618
619 PutNum:
620   ld l,a
621   ld h,0
622   call _divHLby10
623   push af
624   ld a,l
625   call PutDigit
626   pop af
627 PutDigit:
628   add a,'0'
629   jp _vputmap
630
631 offsets_table:
632   .db 128,64,32,16,8,4,2,1
633
634 DisplayField:                           ;<====NEW
635   ld a,c
636   sub 29
637   jr nc,NotMinYScroll
638   xor a
639 NotMinYScroll:
640   cp 43
641 FieldHeight =$-1
642   jr c,NotMaxYScroll
643   ld a,(FieldHeight)
644 NotMaxYScroll:
645   ld l,a
646   ld h,0
647   add hl,hl
648   add hl,hl
649   add hl,hl
650   add hl,hl
651   add hl,hl
652   push bc
653   push de
654   ld de,ScrBuffer
655   add hl,de
656   ld a,b
657   sub 64
658   jr nc,NotMinXScroll
659   xor a
660 NotMinXScroll:
661   cp 128
662 FieldWidth = $-1
663   jr c,NotMaxXScroll
664   ld a,(FieldWidth)
665 NotMaxXScroll:
666   push af
667   and %11111000
668   rra
669   rra
670   rra
671   ld c,a
672   ld b,0
673   ld de,DispBuffer
674   pop af
675   and %00000111
676   push af
677   cp 6
678   jr c,CopyScreen
679   inc c
680 CopyScreen:
681   add hl,bc
682   ld b,57
683 CopyScreenLoop:
684   push bc
685   ld bc,16
686   ldir
687   ld c,16
688   add hl,bc
689   pop bc
690   djnz CopyScreenLoop
691   pop af
692   ld c,$b7                              ;or a
693 Bit0:
694   jr nz,Bit1
695   halt
696   halt
697   jr AfterShiftDelay
698 Bit1:
699   dec a
700   jr nz,Bit2
701   call ShiftRight1
702   jr AfterShiftDelay
703 Bit2:
704   dec a
705   jr nz,Bit3
706   ld a,2
707   call ShiftRight
708   jr AfterShiftDelay
709 Bit3:
710   dec a
711   jr nz,Bit4
712   call Chunk
713   call ShiftLeft1
714   jr AfterShift
715 Bit4:
716   dec a
717   jr nz,Bit5
718   call Chunk
719   jr AfterShiftDelay
720 Bit5:
721   dec a
722   jr nz,Bit6
723   call Chunk
724   call ShiftRight1
725   jr AfterShift
726 Bit6:
727   dec a
728   jr nz,Bit7
729   ld a,2
730   call ShiftLeft
731   jr AfterShift
732 Bit7:
733   call ShiftLeft
734 AfterShiftDelay:
735   halt
736 AfterShift:
737   ld hl,DispBuffer
738   ld de,$fc00+$70
739   ld bc,1024-$70
740   ldir
741   pop de
742   pop bc
743   ret
744
745 ShiftRight1:                            ;<====NEW
746   ld a,1
747 ShiftRight:
748   ld (ShiftRightCounter),a
749   ld a,c
750   ld (ShiftRightChunk),a
751   ld c,16
752   add hl,bc
753   ld b,57
754 ShiftRightLoop:
755   push bc
756   ld bc,-32
757   add hl,bc
758   ex de,hl
759   ld a,(de)
760 ShiftRightChunk:
761   or a
762   call c,_SHLACC
763   ld c,0
764 ShiftRightCounter = $-1
765 ShiftRowsLeft:
766   push hl
767   rla
768   ld b,16
769 ShiftRowLeft:
770   dec hl
771   rl (hl)
772   djnz ShiftRowLeft
773   pop hl
774   dec c
775   jr nz,ShiftRowsLeft
776   ld bc,-16
777   add hl,bc
778   ex de,hl
779   pop bc
780   djnz ShiftRightLoop
781   ret
782
783 ShiftLeft1:                             ;<====NEW
784   ld a,1
785 ShiftLeft:
786   ld (ShiftLeftCounter),a
787   ld a,c
788   ld (ShiftLeftChunk),a
789   rla
790   jr nc,ShiftLeftSameByte
791   dec hl
792 ShiftLeftSameByte:
793   ex de,hl
794   ld bc,-16
795   add hl,bc
796   ex de,hl
797   ld b,57
798 ShiftLeftLoop:
799   push bc
800   ld bc,-32
801   add hl,bc
802   ex de,hl
803   ld a,(de)
804 ShiftLeftChunk:
805   or a
806   call c,_SHRACC
807   ld c,0
808 ShiftLeftCounter = $-1
809 ShiftRowsRight:
810   push hl
811   rra
812   ld b,16
813 ShiftRowRight:
814   rr (hl)
815   inc hl
816   djnz ShiftRowRight
817   pop hl
818   dec c
819   jr nz,ShiftRowsRight
820   ld bc,-16
821   add hl,bc
822   ex de,hl
823   pop bc
824   djnz ShiftLeftLoop
825   ret
826
827 Chunk:                          ;<====NEW
828   push hl
829   push de
830   ld c,16
831   add hl,bc
832   ld b,57
833 ChunkScreen:
834   push bc
835   ld bc,-32
836   add hl,bc
837   ex de,hl
838   ld a,(de)
839   call _SHRACC
840   ld b,16
841 ChunkRow:
842   dec hl
843   rld
844   djnz ChunkRow
845   ex de,hl
846   pop bc
847   djnz ChunkScreen
848   pop de
849   pop hl
850   ld c,$37                              ;scf
851   ret
852
853
854 NUM_LEVELS = 9
855
856 Levels:
857
858   .db 5,3           ;5 peas, speed 5
859   .db 64,4,0        ;x,y,d
860   .db 0,0            ;field width, height
861   .db 0             ;no additional lines
862
863   .db 8,4
864   .db 4,14,$40
865   .db 128,57
866   .db 1
867   .db 28,28,100,28
868
869   .db 9,4
870   .db 4,8,$40
871   .db 128,57
872   .db 2
873   .db 28,14,100,14
874   .db 28,41,100,41
875
876   .db 9,3
877   .db 4,8,$40
878   .db 128,80
879   .db 2
880   .db 64,14,64,66
881   .db 20,40,108,40
882
883   .db 10,3
884   .db 4,8,$40
885   .db 128,90
886   .db 3
887   .db 18,20,18,70
888   .db 110,20,110,70
889   .db 18,45,110,45
890
891   .db 7,3
892   .db 64,4,0
893   .db 128,86
894   .db 6
895   .db 34,13,56,35
896   .db 34,71,56,49
897   .db 72,35,94,13
898   .db 72,49,94,71
899   .db 16,20,16,64
900   .db 110,20,110,64
901
902   .db 9,2
903   .db 4,10,$40
904   .db 128,82
905   .db 3
906   .db 0,20,74,20
907   .db 54,40,128,40
908   .db 0,60,74,60
909
910   .db 12,2
911   .db 64,4,0
912   .db 128,90
913   .db 6
914   .db 20,16,54,16
915   .db 74,16,110,16
916   .db 20,16,20,72
917   .db 110,16,110,72
918   .db 20,72,54,72
919   .db 74,72,110,72
920
921   .db 8,2
922   .db 72,52,$c0
923   .db 128,128
924   .db 13
925   .db 34,56,56,34
926   .db 34,72,56,94
927   .db 72,34,94,56
928   .db 72,94,94,72
929   .db 46,64,80,64
930   .db 22,11,22,33
931   .db 11,22,33,22
932   .db 22,95,22,117
933   .db 11,106,33,106
934   .db 103,11,103,33
935   .db 91,22,115,22
936   .db 103,95,103,117
937   .db 91,106,115,106
938
939
940
941 #include "trigtab.asm"
942 #include "line.asm"
943
944 WormMsg .db "Wonderworm!",0
945 LevelMsg .db "Level ",0
946 LivesMsg .db "Lives: ",0
947 ScoreMsg .db "Score: ",0
948 LeftMsg  .db "Food: ",0
949 HiScore .db 0
950
951 Left =$
952 Lives =$+1
953 Level =$+2
954 Score =$+3
955 DispBuffer =$+5
956
957 ScrBuffer =$8200 ;32x256 bytes
958 SinCosTable =$a200
959 WormPos = $b000
960
961 .end