-
Notifications
You must be signed in to change notification settings - Fork 0
/
dottoriA-dis.asm
1566 lines (1439 loc) · 50.1 KB
/
dottoriA-dis.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
; Disassembly of "Dottori-Kun" arcade, New Version
; by Chris Covell (www.chrismcovell.com)
; RAM Area:
; 8600 Checksum failed flags in bits 0,1.
; 8601 Random Seed L
; 8602 Random Seed H
; 8603 Palette
; 8604 Joy Press: 7 6 5 4 3 2 1 0
; 8605 Joy Trigger: COIN ST BT2 BT1 R L D U
; 8606 Joy Release
; 8607 VBlank_Pass (FF = VBlank code has passed.)
; 8608 ingame mode
; 8609 Paused
; 860A Message number
; 860B Dot Count
; 860C - 86CB wall/dot map in RAM
; 86CC Level Number
; 86CD Level Display
; 86CE Player has HIT Enemies?
; 86CF-DO Wait_Counter
; 86f0 Program MODE number (0,2,4,6...)
; 86f1 Cursor value
; 86f2 Temporary palette storage
; 8700-1 Player X-position (8.8)
; 8702-3 Player Y-position (8.8)
; Map data from $0795-0854
;Wall/dot format in dot_wall_map+: 76543210
;(walls use bit CLEAR=wall) ??drRLDU
;d = dot, r = redirect player
; 0855-087C are player/monster starting positions
; 087d-08dc are player/monster speeds / presence
; $0bbe- are text strings
; $0c6a-$0d61 are FONT tiles
;Reset
0000 f3 di
0001 310088 ld sp,$8800
0004 ed56 im 1
0006 1833 jr $003b
;------- Return (HL+A) ------------
0008 d5 push de
0009 5f ld e,a
000a 1600 ld d,$00
000c 19 add hl,de
000d 7e ld a,(hl)
000e d1 pop de
000f c9 ret
;--------- Get Random Value & shuffle Rand Seed
0010 e5 push hl
0011 2a0186 ld hl,(RandSeed)
0014 7c ld a,h
0015 0f rrca
0016 0f rrca
0017 ac xor h
0018 0f rrca
0019 ad xor l
001a 0f rrca
001b 0f rrca
001c 0f rrca
001d 0f rrca
001e ad xor l
001f 1f rra
0020 ed6a adc hl,hl
0022 2003 jr nz,+
0024 213c73 ld hl,$733c
+:
ed5f ld a,r
0029 ad xor l
002a 220186 ld (RandSeed),hl
002d e1 pop hl
002e c9 ret
;=========================================
;...
0036 f7 rst $30 ;Checksum bytes?
0037 a9 xor c
0038 c30001 jp $0100 ;Interrupt Routine
;Init continues here
003b 210080 ld hl,$8000 ;Clear screen RAM
003e 110180 ld de,$8001
0041 01ff07 ld bc,$07ff
0044 3600 ld (hl),$00
0046 edb0 ldir
0048 3eb8 ld a,$b8 ;%10_111_000 ;white BG, black chars
004a d300 out (Pal_Register),a ;the only port in this HW, apparently.
;----------------- Test Screen Mem ------------------------------
004c 0600 ld b,$00 ;b = loop 256 times
--:
004e 210080 ld hl,$8000
0051 110008 ld de,$0800
-:
34 inc (hl) ;Cycle all bits in screen memory
0055 23 inc hl
0056 1b dec de
0057 7b ld a,e
0058 b2 or d
0059 20f9 jr nz,-
005b 10f1 djnz --
;-------------------------------------
005d 210080 ld hl,$8000
0060 110008 ld de,$0800
-:
7e ld a,(hl) ;Now test that all bits in memory are Zero
0064 a7 and a
0065 2008 jr nz,+
0067 23 inc hl
0068 1b dec de
0069 7b ld a,e
006a b2 or d
006b 20f6 jr nz,-
006d 1805 jr ++
+:
006f 3e01 ld a,$01 ;Error flag
0071 320086 ld ($8600),a
;-------------------------------------
++:
0074 210000 ld hl,$0000
0077 010010 ld bc,$1000
007a cd1801 call $0118 ;Do the weirdest checksum routine ever???
007d 2a3600 ld hl,($0036)
0080 a7 and a
0081 ed52 sbc hl,de ;Ignore the results of the ROM check anyway...
0083 1805 jr $008a ;jr z,$008a in Ver.1
;(I think they knew their checksum was just busywork.)
; UNUSED Instructions?
0085 210086 ld hl,$8600
0088 cbce set 1,(hl)
008a 210206 ld hl,$0602 ;"RAM"
008d cd7f02 call Copy_Blocks_Dest_Rows_027f
0090 211b06 ld hl,$061b ;"ROM"
0093 cd7f02 call Copy_Blocks_Dest_Rows_027f
0096 3a0086 ld a,($8600)
0099 118882 ld de,$8288
009c 213406 ld hl,$0634
009f cb47 bit 0,a ;Aha, was the RAM test GOOD or BAD?
00a1 2803 jr z,+
00a3 215206 ld hl,$0652
+:
00a6 f5 push af
00a7 cd8302 call Copy_Blocks_Rows_0283
00aa f1 pop af
00ab 118883 ld de,$8388
00ae 213406 ld hl,$0634
00b1 cb4f bit 1,a ;Check the Checksum result
00b3 2803 jr z,+
00b5 215206 ld hl,$0652 ;Write either good or bad
+:
00b8 f5 push af
00b9 cd8302 call Copy_Blocks_Rows_0283
00bc f1 pop af
00bd a7 and a
00be 20fe jr nz,$00be ;LOOP INFINITELY HERE!
;----------------------------------
00c0 3e87 ld a,$87 ;10_000_111 ;Black BG, White Chars
00c2 320386 ld (Palette),a
00c5 218082 ld hl,$8280
00c8 118182 ld de,$8281
00cb 010003 ld bc,$0300
00ce 3600 ld (hl),$00
00d0 edb0 ldir ;Zero-out lower part of screen
00d2 cd4701 call Read_Joy_0147
;----- attract mode restarts here
00d5 af xor a
00d6 320886 ld (ingame_mode),a
00d9 32cc86 ld (LevelNum),a
00dc 3c inc a
00dd 32cd86 ld (Level_Disp),a
00e0 3e80 ld a,$80
00e2 32cf86 ld (wait_counter),a ;Set a waiting time
;Main Program Loop
-:
00e5 fb ei
00e6 310088 ld sp,$8800 ;Reset the stack
00e9 cd1602 call Wait_VB_0216
00ec cd4701 call Read_Joy_0147
00ef cd4509 call $0945 ;Tests COIN, changes program modes.
00f2 cd2d02 call $022d ;Print Stage #, Pause text.
00f5 cdd102 call Ingame_Handler_02d1 ;4 routines based on ingame_mode
00f8 cd5a04 call Player_Movement_045a
00fb cd5205 call Enemy_Movement_0552 ;Moves enemies, handles hit detection
00fe 18e5 jr -
;//////////////////////////////////////////
;========================== Interrupt Routine =============
0100 f5 push af
0101 c5 push bc
0102 d5 push de
0103 e5 push hl
0104 dde5 push ix
0106 fde5 push iy ;A little different here from V1
0108 cd5b01 call Set_Palette_015b ;See if palette needs changing, & do it!
010b cdac0a call $0aac ;Go to a Mode Jump Table!
010e fde1 pop iy
0110 dde1 pop ix
0112 e1 pop hl
0113 d1 pop de
0114 c1 pop bc
0115 f1 pop af
0116 fb ei
0117 c9 ret
;=========================================================
;First checksum routine
0118 110000 ld de,$0000
-:
011b e5 push hl
011c d5 push de
011d 113600 ld de,$0036
0120 a7 and a
0121 ed52 sbc hl,de
0123 d1 pop de
0124 e1 pop hl ;Basically, this is all bullshit, I think.
0125 2004 jr nz,+
0127 23 inc hl
0128 23 inc hl
0129 1816 jr ++
+:
012b 7b ld a,e
012c ae xor (hl)
012d 5f ld e,a
012e 7a ld a,d
012f 23 inc hl
0130 ae xor (hl)
0131 57 ld d,a
0132 23 inc hl
0133 cb3a srl d
0135 cb1b rr e
0137 3008 jr nc,++
0139 7a ld a,d
013a ee88 xor $88
013c 57 ld d,a
013d 7b ld a,e
013e ee10 xor $10
0140 5f ld e,a
++:
0141 0b dec bc
0142 78 ld a,b
0143 b1 or c
0144 20d5 jr nz,-
0146 c9 ret
;-------------------------
;=================================================
Read_Joy_0147:
210486 ld hl,Joy_Press ;Old joy button press
014a db00 in a,($00) ;Get joystick buttons from port
014c 2f cpl
014d 56 ld d,(hl) ;load old
014e 77 ld (hl),a ;replace with new
014f aa xor d ;get difference with old
0150 5f ld e,a
0151 7a ld a,d
0152 2f cpl ;now "unpressed" in old are 1
0153 a3 and e ;mask out "new presses"
0154 23 inc hl
0155 77 ld (hl),a ;save joy trigger in Joy_Trig
0156 7a ld a,d ;"pressed" in old are 1
0157 a3 and e ;mask out "newly released"
0158 23 inc hl
0159 77 ld (hl),a ;save joy release in Joy_Release
015a c9 ret
;------------ Set Palette Routine
Set_Palette_015b:
210386 ld hl,Palette ;Check if high bit set as a palette trigger.
015e 7e ld a,(hl)
015f cb7f bit 7,a
0161 c8 ret z
0162 cbbf res 7,a
0164 d300 out (Pal_Register),a ;Output palette
0166 77 ld (hl),a
0167 c9 ret
;-----------------------------------------------
; in-game, in-VBlank code, I think
0168 3a0886 ld a,(ingame_mode)
016b a7 and a
016c 2804 jr z,+
016e d603 sub $03
0170 3805 jr c,++ ;If DEAD or Attract mode on, do nothing.
+:
0172 0600 ld b,$00 ;Kill time only....?
-:
10fe djnz -
0176 c9 ret
++:
0177 dd210087 ld ix,$8700
017b 112000 ld de,$0020
017e 0604 ld b,$04 ;Potentially 4 characters on-screen....
--:
0180 c5 push bc
0181 d5 push de
0182 0605 ld b,$05
0184 21fb08 ld hl,$08fb ;Player / Enemy graphic MASKS
-:
dd7e07 ld a,(ix+$07) ;(I think this erases player/enemy's old position.)
018a 86 add a,(hl)
018b fec0 cp $c0
018d c5 push bc
018e e5 push hl
018f dde5 push ix
0191 dcae03 call c,$03ae ;If within boundaries, draw tile character
0194 dde1 pop ix
0196 e1 pop hl
0197 c1 pop bc
0198 23 inc hl
0199 10ec djnz -
019b d1 pop de
019c c1 pop bc
019d dd19 add ix,de
019f 10df djnz --
01a1 dd210087 ld ix,$8700
01a5 fd21dd08 ld iy,$08dd ;Player direction graphics
01a9 dd7e06 ld a,(ix+$06)
01ac 110600 ld de,$0006
-:
01af 0f rrca
01b0 3804 jr c,+
01b2 fd19 add iy,de
01b4 18f9 jr - ;Wow, if A ever were blank, infinite loop!
+:
01b6 cdd401 call Shift_Char_To_Screen_01d4
01b9 112000 ld de,$0020
01bc 0603 ld b,$03 ;Do for 3 enemies
01be fd21f508 ld iy,$08f5 ;Enemy graphic
01c2 dd19 add ix,de
01c4 dd7e08 ld a,(ix+$08)
01c7 ddb609 or (ix+$09)
01ca c5 push bc
01cb d5 push de
01cc c4d401 call nz,Shift_Char_To_Screen_01d4
01cf d1 pop de
01d0 c1 pop bc
01d1 10eb djnz $01be
01d3 c9 ret
;=======================================
Shift_Char_To_Screen_01d4:
dd7e01 ld a,(ix+$01)
01d7 d603 sub $03
01d9 47 ld b,a ;Separate character # and pixel pos.
01da cb38 srl b
01dc cb38 srl b
01de cb38 srl b
01e0 e607 and $07
01e2 4f ld c,a
01e3 dd7e03 ld a,(ix+$03)
01e6 d603 sub $03
01e8 6f ld l,a
01e9 2600 ld h,$00
01eb 29 add hl,hl ;Calculate vertical offset
01ec 29 add hl,hl
01ed 29 add hl,hl
01ee 29 add hl,hl
01ef 110080 ld de,$8000 ;Point to right place on screen
01f2 58 ld e,b
01f3 19 add hl,de
01f4 0606 ld b,$06 ;Loop for 6 pixels' height
--:
01f6 fd5e00 ld e,(iy+$00)
01f9 1600 ld d,$00
01fb 79 ld a,c
01fc a7 and a ;Position back in A
01fd 2807 jr z,+ ;Do nothing if it's zero (offscreen?)
-:
01ff cb3b srl e ;Shift source graphic based on position
0201 cb1a rr d
0203 3d dec a
0204 20f9 jr nz,-
+:
0206 7e ld a,(hl)
0207 b3 or e
0208 77 ld (hl),a
0209 23 inc hl
020a 7e ld a,(hl)
020b b2 or d
020c 77 ld (hl),a
020d fd23 inc iy
020f 110f00 ld de,$000f
0212 19 add hl,de
0213 10e1 djnz --
0215 c9 ret
;======================================
;Wait for VBlank to pass
Wait_VB_0216:
210786 ld hl,VBlank_Pass
-:
0219 cb7e bit 7,(hl)
021b 28fc jr z,-
021d 3600 ld (hl),$00
021f c9 ret
;----------------------------
;This code is now unused in the NEW version of Dottori
0220 3a0586 ld a,(Joy_Trig)
0223 cb7f bit 7,a
0225 c8 ret z
;---
0226 210386 ld hl,Palette
0229 34 inc (hl) ;Cycle through all palettes when Coin pressed
022a cbfe set 7,(hl)
022c c9 ret
;--------------------------------------
;------------------- another routine during VBlank -------
022d 3a0586 ld a,(Joy_Trig)
0230 cb6f bit 5,a ;Check button 2 pressed and reverse PAUSE
0232 2009 jr nz,+
0234 210986 ld hl,Paused
0237 cb46 bit 0,(hl)
0239 c8 ret z
;----
023a c3e500 jp $00e5 ;RETURN to main loop!
+:
023d 210986 ld hl,Paused
0240 34 inc (hl)
0241 cb46 bit 0,(hl)
0243 ca4e02 jp z,+
0246 3e01 ld a,$01
0248 cd5602 call ++ ;Clear 6x20 row routine
024b c3e500 jp $00e5 ;RETURN to main loop!
+:
024e cd6302 call $0263 ;Clear 6x20 rows.
0251 3a0a86 ld a,(msg_num)
0254 1805 jr +
++:
0256 f5 push af
0257 cd6302 call $0263 ;Clear 6x20 rows.
025a f1 pop af
+:
a7 and a
025c c47702 call nz,Copy_Block_APtr_0277
025f cd9d02 call $029d ;Print Level # 1/2 digits?
0262 c9 ret
; 6x20 screen clearing routine
0263 21c582 ld hl,$82c5 ;Clear 6 bytes x 20 rows on-screen
0266 110a00 ld de,$000a
0269 0e14 ld c,$14
--:
026b 0606 ld b,$06
-:
026d 3600 ld (hl),$00
026f 23 inc hl
0270 10fb djnz -
0272 19 add hl,de
0273 0d dec c
0274 20f5 jr nz,--
0276 c9 ret
;-----------------------------------
Copy_Block_APtr_0277:
216906 ld hl,$0669 ;Point to short table...
027a 87 add a,a
027b cf rst 08_Get_HL+A ;Add A offset & get word pointer there
027c 23 inc hl
027d 66 ld h,(hl) ;Table points to: 673, 6A1, 6FF, 733 only.
027e 6f ld l,a ;4 graphic strings "Go", "Pause" etc.
; Data header has Destination(W), NumRows(B), ByteLength(B)
Copy_Blocks_Dest_Rows_027f:
5e ld e,(hl)
0280 23 inc hl
0281 56 ld d,(hl)
0282 23 inc hl
Copy_Blocks_Rows_0283:
4e ld c,(hl)
0284 23 inc hl
0285 7e ld a,(hl)
0286 23 inc hl
0287 eb ex de,hl
--:
0288 e5 push hl
0289 47 ld b,a
-:
028a f5 push af
028b 1a ld a,(de)
028c 77 ld (hl),a
028d f1 pop af
028e 13 inc de
028f 23 inc hl
0290 10f8 djnz -
0292 e1 pop hl
0293 d5 push de
0294 111000 ld de,$0010
0297 19 add hl,de
0298 d1 pop de
0299 0d dec c
029a 20ec jr nz,--
029c c9 ret
;============================================
029d 3a0886 ld a,(ingame_mode) ;If this flag is zero, print nothing
02a0 a7 and a
02a1 c8 ret z
;--------
02a2 3acd86 ld a,(Level_Disp) ;Print upper nybble
02a5 e6f0 and $f0
02a7 2807 jr z,+
02a9 0f rrca
02aa 118983 ld de,$8389
02ad cdbb02 call $02bb
+:
02b0 3acd86 ld a,(Level_Disp) ;Print lower nybble
02b3 e60f and $0f
02b5 87 add a,a ;Multiply by 8 (8x8 pixels)
02b6 87 add a,a
02b7 87 add a,a
02b8 118a83 ld de,$838a
;--------
02bb 4f ld c,a
02bc 0600 ld b,$00
02be 214507 ld hl,$0745 ;ROM location for 0-9 Font
02c1 09 add hl,bc
02c2 eb ex de,hl
02c3 0608 ld b,$08
-:
02c5 c5 push bc
02c6 1a ld a,(de)
02c7 77 ld (hl),a
02c8 13 inc de
02c9 011000 ld bc,$0010
02cc 09 add hl,bc
02cd c1 pop bc
02ce 10f5 djnz -
02d0 c9 ret
;--------------------------------------
;--- another routine in VBlank -----------
Ingame_Handler_02d1:
3a0886 ld a,(ingame_mode) ;another "game" mode
02d4 21dd02 ld hl,$02dd
02d7 87 add a,a
02d8 cf rst 08_Get_HL+A
02d9 23 inc hl
02da 66 ld h,(hl)
02db 6f ld l,a
02dc e9 jp (hl) ;Jump off from here!
;a Jump table!
02dd: 2e5,322,339,36e
; if ingame_mode is 0... ... possibly "dead" or "attract" mode.
02e5 3a0486 ld a,(Joy_Press) ;Read (continuous) joystick presses
02e8 cb77 bit 6,a ;Start button?
02ea 201b jr nz,_start_game_0307 ;if pressed, jump!
02ec 21cf86 ld hl,wait_counter
02ef 7e ld a,(hl)
02f0 c604 add a,$04
02f2 77 ld (hl),a
02f3 0e00 ld c,$00
02f5 f2fa02 jp p,+ ;(If (HL)+A was positive...)
02f8 0e02 ld c,$02
+:
02fa 210a86 ld hl,msg_num ;This probably flashes "Press Start"
02fd 7e ld a,(hl)
02fe b9 cp c
02ff c8 ret z
;------
0300 71 ld (hl),c
0301 cd4e02 call $024e ;clear 6x20 rows...
0304 c3e500 jp $00e5 ;Return to main loop
;----------------------------------
_start_game_0307:
f3 di
0308 cd7e03 call Put_Map_On_Screen_037e
030b cd0c04 call Fill_PlayerMonster_Defs_040c
030e fb ei
030f 3e01 ld a,$01 ;set ingame 0 -> 1 (playing)
0311 320886 ld (ingame_mode),a
0314 3e3c ld a,$3c ;I think this is a delay value
0316 32cf86 ld (wait_counter),a
0319 3e03 ld a,$03 ;I think this says "READY" or sth.
031b 320a86 ld (msg_num),a
031e cd4e02 call $024e ;Print text message (level number too?)
0321 c9 ret
;--------------------------
; if ingame_mode is 1... wait only(?)
0322 21cf86 ld hl,wait_counter
0325 35 dec (hl)
0326 c0 ret nz
;-----
0327 3e02 ld a,$02 ;OK, now ingame mode 2.
0329 320886 ld (ingame_mode),a
032c af xor a
032d 32ce86 ld (player_collided),a ;NOT HIT!
0330 3e04 ld a,$04
0332 320a86 ld (msg_num),a ;Print a message ("GO")
0335 cd4e02 call $024e
0338 c9 ret
;-------------------------------
; if ingame_mode is 2...
0339 3a0b86 ld a,(DotCount) ;It's like clockwork from here. Check # of dots
033c a7 and a
033d 2016 jr nz,+
;---
033f 21cc86 ld hl,LevelNum ;If dots are Zero, next level
0342 7e ld a,(hl)
0343 3c inc a
0344 fe0b cp $0b
0346 3001 jr nc,++ ;Don't increase internal game level if past $0B
0348 77 ld (hl),a
++:
0349 23 inc hl ;to "Level Display"
034a 3e01 ld a,$01
034c 86 add a,(hl)
034d 27 daa ;...stored in BCD
034e ca0703 jp z,_start_game_0307 ;(max is 99, I guess)
0351 77 ld (hl),a
0352 c30703 jp _start_game_0307 ;Restart from next level!
;------
+:
0355 3ace86 ld a,(player_collided) ;Check if we hit an enemy
0358 a7 and a
0359 c8 ret z
;-----
035a 3e03 ld a,$03 ;If so, mode is now "DEAD" or flashing.
035c 320886 ld (ingame_mode),a
035f 210109 ld hl,$0901
0362 22cf86 ld (wait_counter),hl ;"01" in counter, "09" in next byte.
0365 3e00 ld a,$00 ;Clear messages
0367 320a86 ld (msg_num),a
036a cd4e02 call $024e
036d c9 ret
;===========================================
; if ingame_mode is 3...
036e 21cf86 ld hl,wait_counter
0371 35 dec (hl)
0372 c0 ret nz
0373 3610 ld (hl),$10 ;Wait counter & flash runs for 9 times, I reckon
0375 23 inc hl
0376 35 dec (hl)
0377 cad500 jp z,$00d5 ;Go back to attract mode if flashes all finished.
037a cd4a04 call Flash_Screen_044a
037d c9 ret
;----------------------------------------
Put_Map_On_Screen_037e:
3ea8 ld a,$a8 ;Dot count initialized!
0380 110b86 ld de,DotCount
0383 12 ld (de),a
0384 13 inc de
0385 219507 ld hl,$0795 ;0795- (screen layout) gets written to RAM.
0388 01c000 ld bc,$00c0 ;16 x 12 chars = $C0.
038b edb0 ldir
038d dd210c86 ld ix,dot_wall_map ;Start at RAM dot map
0391 210080 ld hl,$8000 ;Start at screen RAM
0394 0e0c ld c,$0c ;96 pixel lines / 8 characters = 12 ($0C) char lines.
--:
0396 e5 push hl
0397 0610 ld b,$10 ;Do a line of 16 8x8 screen characters
-:
0399 c5 push bc
039a e5 push hl
039b cdc003 call _decode_1_map_tile_03c0
039e e1 pop hl
039f c1 pop bc
03a0 23 inc hl
03a1 dd23 inc ix
03a3 10f4 djnz -
03a5 e1 pop hl
03a6 118000 ld de,$0080 ;Go down 8 lines (1 character)
03a9 19 add hl,de
03aa 0d dec c
03ab 20e9 jr nz,--
03ad c9 ret
;=================================
;Routines used in Player/Enemy graphic masking.
03ae fe79 cp $79 ;This is the YX coord of player/enemy in 1 byte!
03b0 c8 ret z
;---
03b1 fe7a cp $7a ;If not at a certain position, drop down!
03b3 c8 ret z ;$79/$7A are where the Level number is printed.
03b4 dd210c86 ld ix,dot_wall_map ;Point to map
03b8 5f ld e,a ;store our enemy/graphic position(?)
03b9 1600 ld d,$00
03bb dd19 add ix,de ;1 byte per tile on the map, so just add A to map addr.
03bd cdfa03 call Point_Screen_YX_03fa
;------
_decode_1_map_tile_03c0: ;This decodes the map from ROM/RAM (in IX)
;Wall/dot format in dot_wall_map+: 76543210
;(walls use bit CLEAR=wall) ??drRLDU
;d=1 = dot, r=0 = redirect player
111000 ld de,$0010
03c3 dd4600 ld b,(ix+$00)
03c6 0e00 ld c,$00
03c8 cb58 bit 3,b ;if bit 3 cleared, there's a wall?
03ca 2002 jr nz,+
03cc 0e01 ld c,$01 ;Rightmost pixel
+:
03ce cb50 bit 2,b ;bit 2 cleared, another wall...?
03d0 2002 jr nz,+
03d2 cbf9 set 7,c ;Leftmost pixel
+:
03d4 af xor a
03d5 cb40 bit 0,b ;Bit 0 cleared...
03d7 2001 jr nz,+
03d9 3d dec a ;makes a $FF, so entire (top?) row of pixels set.
+:
03da b1 or c
03db 77 ld (hl),a ;Do top wall, plus contiguous L,R walls.
03dc 19 add hl,de ;Go down 1 line
03dd 71 ld (hl),c ;put in L/R walls
03de 19 add hl,de
03df 71 ld (hl),c
03e0 19 add hl,de
03e1 af xor a
03e2 cb68 bit 5,b ;Now check if dot is present
03e4 2802 jr z,+
03e6 3e18 ld a,$18 ;if bit set, dot is present, so do pixel value
+:
03e8 b1 or c ;OR with walls
03e9 77 ld (hl),a ; one
03ea 19 add hl,de
03eb 77 ld (hl),a ; two lines tall
03ec 19 add hl,de
03ed 71 ld (hl),c
03ee 19 add hl,de
03ef 71 ld (hl),c
03f0 19 add hl,de
03f1 af xor a
03f2 cb48 bit 1,b ;if bit 1 cleared, bottom wall
03f4 2001 jr nz,$03f7
03f6 3d dec a
03f7 b1 or c
03f8 77 ld (hl),a ;Save that finally.
03f9 c9 ret
;======================================
Point_Screen_YX_03fa:
f5 push af
03fb e6f0 and $f0 ;Isolate Y-Value
03fd 6f ld l,a
03fe 2600 ld h,$00
0400 29 add hl,hl
0401 29 add hl,hl
0402 29 add hl,hl ;Multiply by 8
0403 f1 pop af
0404 e60f and $0f ;Isolate X-value
0406 110080 ld de,$8000
0409 5f ld e,a
040a 19 add hl,de ;combine them
040b c9 ret
;---------------------------------------------
Fill_PlayerMonster_Defs_040c:
dd215508 ld ix,$0855 ;get 4 pointers from here: 85D, 865, 86D, 875
0410 110087 ld de,$8700 ;Starting positions for player, monsters.
0413 0604 ld b,$04
-:
0415 c5 push bc
0416 dd6e00 ld l,(ix+$00)
0419 dd6601 ld h,(ix+$01)
041c 012000 ld bc,$0020 ;$085d -> $8700 x $20 bytes
041f edb0 ldir
0421 c1 pop bc
0422 dd23 inc ix
0424 dd23 inc ix
0426 10ed djnz -
0428 3acc86 ld a,(LevelNum) ;Levels 0..$B only supported
042b 87 add a,a
042c 87 add a,a
042d 87 add a,a
042e 217d08 ld hl,$087d ;Load blocks of monster speed & existence bytes...
0431 cf rst 08_Get_HL+A
0432 dd210887 ld ix,$8708
0436 112000 ld de,$0020
0439 0604 ld b,$04
-:
043b 7e ld a,(hl)
043c dd7700 ld (ix+$00),a ;Save speed for character(?) and up to 3 monsters.
043f 23 inc hl
0440 7e ld a,(hl)
0441 dd7701 ld (ix+$01),a
0444 23 inc hl
0445 dd19 add ix,de
0447 10f2 djnz -
0449 c9 ret
;=====================================
Flash_Screen_044a:
210080 ld hl,$8000
044d 010006 ld bc,$0600
-:
0450 7e ld a,(hl)
0451 2f cpl ;Complement all bytes on-screen. Simple.
0452 77 ld (hl),a
0453 23 inc hl
0454 0b dec bc
0455 78 ld a,b
0456 b1 or c
0457 20f7 jr nz,-
0459 c9 ret
;----------------------
Player_Movement_045a:
3a0886 ld a,(ingame_mode)
045d fe02 cp $02 ;If game's not running, exit.
045f c0 ret nz
;----
0460 dd210087 ld ix,$8700
0464 dd7e01 ld a,(ix+$01) ;Check if player's X or Y position is at the edge
0467 e607 and $07
0469 fe04 cp $04
046b 2058 jr nz,+
046d dd7e03 ld a,(ix+$03)
0470 e607 and $07
0472 fe04 cp $04
0474 204f jr nz,+
0476 dd7e00 ld a,(ix+$00) ;$8700/2 are X/Y movement/constraint flags?
0479 ddb602 or (ix+$02)
047c 2047 jr nz,+
047e dd7e07 ld a,(ix+$07)
0481 219507 ld hl,$0795 ;Point to MAP data
0484 cf rst 08_Get_HL+A
0485 3a0486 ld a,(Joy_Press)
0488 4f ld c,a
0489 dd7e06 ld a,(ix+$06) ;$8706 is player's direction, I think
048c 47 ld b,a
048d e603 and $03 ;Test U/D direction
048f 3e03 ld a,$03
0491 2802 jr z,++ ;and react HERE
0493 3e0c ld a,$0c
++:
0495 a6 and (hl) ;MASK with map
0496 a1 and c ;And MASK with Joypad presses, clever!
0497 2021 jr nz,++ ;If possible joy presses remain, jump down
0499 78 ld a,b ;Direction back in A
049a a6 and (hl) ;Mask out map impossibilities
049b a1 and c ;This may or may not be zero
049c 2027 jr nz,+ ;if something remains, jump down
049e 78 ld a,b ;Direction again
049f a6 and (hl) ;Mask out ONLY with map
04a0 2023 jr nz,+ ;Jump down again if something remains
04a2 cb66 bit 4,(hl) ;Hmm... bit 4 is.... auto player redirection (Right?)
04a4 280a jr z,+++
04a6 dd360400 ld (ix+$04),$00 ;If bit 4 is set, player can STOP there...(?)
04aa dd360500 ld (ix+$05),$00
04ae 181b jr _skip_new_posn
+++:
04b0 78 ld a,b ;Direction again
04b1 e603 and $03 ;Up/Down only
04b3 3e03 ld a,$03
04b5 2802 jr z,++++ ;If not going U/D, then default to L/R.
04b7 3e0c ld a,$0c
++++:
04b9 a6 and (hl) ;Mask out with map directions
++:
04ba dd7706 ld (ix+$06),a ;New direction set.
04bd dd360000 ld (ix+$00),$00 ;Clear partial positions
04c1 dd360200 ld (ix+$02),$00 ;" " "
+:
04c5 cdcf04 call Player_Speed_04cf
04c8 cdeb04 call Plr_or_Enemy_New_Posn_04eb
_skip_new_posn:
04cb cd3705 call Check_Dot_Eaten_0537
04ce c9 ret
;===========================
Player_Speed_04cf:
218000 ld hl,$0080 ;Usual player speed
04d2 dd7e00 ld a,(ix+$00) ;is player moving/constrained?
04d5 ddb602 or (ix+$02)
04d8 200a jr nz,+
04da 3a0486 ld a,(Joy_Press)
04dd cb67 bit 4,a ;Button 1 (Speed)
04df 2803 jr z,+
04e1 210001 ld hl,$0100 ;Make player move twice as fast if button 1 pressed
+:
04e4 dd7504 ld (ix+$04),l ;Save current player speed temporarily (?)
04e7 dd7405 ld (ix+$05),h
04ea c9 ret
;------------------------
Plr_or_Enemy_New_Posn_04eb:
dd6e04 ld l,(ix+$04)
04ee dd6605 ld h,(ix+$05) ;Player speed
04f1 dd7e06 ld a,(ix+$06) ;Direction we're facing
04f4 4f ld c,a
04f5 e605 and $05 ;if either Up or Left facing, reverse speed
04f7 2807 jr z,+
04f9 7d ld a,l
04fa 2f cpl
04fb 6f ld l,a
04fc 7c ld a,h
04fd 2f cpl
04fe 67 ld h,a
04ff 23 inc hl
+:
0500 110000 ld de,$0000
0503 79 ld a,c
0504 e60c and $0c ;Any Right or Left movement?
0506 2003 jr nz,+
0508 110200 ld de,$0002 ;If Y-movement only, do that.
+:
050b dde5 push ix
050d dd19 add ix,de ;Point to EITHER X or Y position
050f dd5e00 ld e,(ix+$00)
0512 dd5601 ld d,(ix+$01)
0515 19 add hl,de
0516 dd7500 ld (ix+$00),l
0519 dd7401 ld (ix+$01),h ;Set new position after adding speed.
051c dde1 pop ix
051e cd2205 call Obj_New_Char_Posn_0522
0521 c9 ret
;----------------------------
Obj_New_Char_Posn_0522:
dd7e01 ld a,(ix+$01) ;Get X-pos
0525 cb3f srl a
0527 cb3f srl a
0529 cb3f srl a ;*8
052b 4f ld c,a
052c dd7e03 ld a,(ix+$03) ;Get coarse Y-pos
052f e6f8 and $f8
0531 87 add a,a
0532 81 add a,c ;Combine them
0533 dd7707 ld (ix+$07),a ;This is the objects' Character Position.
0536 c9 ret
;=================================
Check_Dot_Eaten_0537:
dd7e01 ld a,(ix+$01) ;Get X-pos
053a d602 sub $02
053c e607 and $07
053e fe05 cp $05 ;Check if right OVER dot.
0540 d0 ret nc
;--------
0541 dd7e07 ld a,(ix+$07) ;Get character position
0544 210c86 ld hl,dot_wall_map
0547 cf rst 08_Get_HL+A
0548 cb6e bit 5,(hl) ;Check if dot is under player
054a c8 ret z
;------
054b cbae res 5,(hl) ;Delete that dot.
054d 210b86 ld hl,DotCount
0550 35 dec (hl) ;Decrease dot count too!
0551 c9 ret
;==========================
Enemy_Movement_0552:
dd212087 ld ix,$8720 ;Up to 3 enemies at $8720/40/60
0556 0603 ld b,$03 ;Do 3 loops of this movement
-:
0558 c5 push bc
0559 cd6505 call _enemy_movement_0565
055c c1 pop bc
055d 112000 ld de,$0020
0560 dd19 add ix,de
0562 10f4 djnz -
0564 c9 ret
;-------------------