forked from samrussell/alexkidd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAlex Kidd in Miracle World.sms.asm
5799 lines (5404 loc) · 134 KB
/
Alex Kidd in Miracle World.sms.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
; Source code created by SMS Examine V1.2a
; Size: 131072 bytes
.MEMORYMAP
SLOTSIZE $4000
SLOT 0 $0000
SLOT 1 $4000
SLOT 2 $8000
DEFAULTSLOT 2
.ENDME
.ROMBANKMAP
BANKSTOTAL 8
BANKSIZE $4000
BANKS 8
.ENDRO
.BANK 0 SLOT 0
.ORG $0000
_START:
; disable interrupts
di
; interrupt mode 1
; interrupt handler is at address 0038
im 1
; set stack at $DFF0
ld sp, $DFF0
; goto _LABEL_85_2
jr _LABEL_85_2
_LABEL_8_10:
; writes de to VDP register
ld a, e
out ($BF), a
ld a, d
out ($BF), a
ret
; Data from F to 1A (12 bytes)
.db $FF, $87, $4F, $06, $00, $09, $7E, $23, $66, $6F, $C9, $FF
_LABEL_1B_39:
; some big long jump based on a having high bit?
bit 7, a
ret z
and $0F
_RST_20H:
; when hl = 0x3B and a = 0x02
add a, a
; a = 0x04
ld e, a
; e = 0x04
ld d, $00
; d = 0x00
; de = 0x0004
add hl, de
; hl = 0x3F
ld a, (hl)
; a = 0xE5
inc hl
ld h, (hl)
; h = 0x09
ld l, a
; could be 0x076D
; hl = 0x09E5
; we get 76d lots but rarely 9e5
; off in some memory bank somewhere, idk how to get to it :/
jp (hl)
; Data from 2A to 2F (6 bytes)
.db $FF, $FF, $FF, $FF, $FF, $FF
_RST_30H:
; used to load palettes
; also appears to be used in the sound loop
rst $8
ld c, $BE
_LABEL_33_112:
outi
jr nz, _LABEL_33_112
ret
; this gets called 140 times per second!!
; at $38 because we set interrupt mode to 1
; called by vsync or scanline
; in any case the video rendering drives this
_IRQ_HANDLER:
jp _LABEL_C0_13
; looks like some function pointers that we hit sometimes
; 76D, 76D, 9E5, 194F, 18CE, 1BC9, 6C0C (doesn't make sense)
; we do hit 76D from $53 - this is a call to executable code
; i reckon there must be a function there
; Data from 3B to 52 (24 bytes)
.db $6D, $07, $6D, $07, $E5, $09, $4F, $19, $CE, $18, $C9, $1B, $0C, $6C, $C9, $7D
.db $50, $16, $88, $0A, $88, $0A, $CD, $1F
_LABEL_53_93:
xor a
ld ($C01F), a
_LABEL_57_147:
; start screen loop
; waits for $C01F to get data
; then goes and does it
; and gets a function pointer from it
; then jumps to it
ld hl, $C01F
; a gets set sometimes to 0 and sometimes to 2
; masked to 0x0F
ld a, (hl)
and $0F
exx
ld hl, $003B
rst $20
jp _LABEL_57_147
; Data from 65 to 65 (1 bytes)
.db $FF
; non-maskable interrupt
; called when the pause button is pushed
; we can postpone this until we care about the menu
_NMI_HANDLER:
push af
ld a, ($C31A)
cp $0F
jp z, _LABEL_82_149
ld a, ($C015)
or a
jp nz, _LABEL_82_149
ld a, ($C01F)
cp $8A
jr c, _LABEL_82_149
ld a, $01
ld ($C093), a
_LABEL_82_149:
pop af
retn
; start of actual game
; this gets things prepped before we load the start screen
_LABEL_85_2:
; set paging register
; in practise this sets to 02
; the game leaves first two registers both at 00 and third at 02
; this might change later?
ld a, $82
ld ($FFFF), a
call _LABEL_9E02_3 ; all 4 channels turned off
; this is kind of cute
; this is a memmove from c000 to c001
; with c000 initialised to 0
; so it's just zeroing out the memory from c000 to dfff
; i.e. all ram
ld hl, $C000
ld de, $C001
ld bc, $1FFF
ld (hl), l
ldir
call _LABEL_341_4 ; some no-op sanity check? warm up the registers before using them?
call _LABEL_350_7 ; some sort of console check, answer is in $C005 (is 0 for us)
_LABEL_9F_14:
; we get sent here in a soft reset
; from hard start/reset we do everything again for some reason
ld a, $82
ld ($FFFF), a
ld sp, $DFF0
call _LABEL_9E02_3 ; all 4 channels turned off
call _LABEL_26B_8 ; initialise graphics to black screen + sane values
ld hl, $0000
ld de, $4000
ld bc, $3800
call _LABEL_184_9 ; this appears to zero out the first 3800 bytes of VRAM (all the sprite/tile patterns)
ei ; enable interrupts
call _LABEL_2F6_92 ; enable display
jp _LABEL_53_93
; interrupt handler
; "video handler" i guess
; called some number of hundreds of times per second
; this probably drives the main event loop - getting user input, time-tick based actions, etc
_LABEL_C0_13:
; push all the registers
push af
push bc
push de
push hl
; swap with shadow registers
exx
ex af, af'
push af
push bc
push de
push hl
push ix
push iy
; i think we're doing a semi-obligatory check of $BF
in a, ($BF) ; video status register, bit 7 is vsync, 6 is line interrupt, 5 is sprite collision
in a, ($DD) ; joypad port 2
and $10 ; mask everything except bit 4, reset button
; store reset button flag in $C096
ld hl, $C096
ld c, (hl)
ld (hl), a
xor c
and c
; jump if reset button has been pressed/released since last interrupt
; looks like this is a soft reset
jp nz, _LABEL_9F_14
; store current memory location in a
ld a, ($FFFF)
; $C008 looks like a bitmap of things to do here
; we zero it at the end here
; save af (a and flags), so we can reload memory at the end
push af
ld a, ($C008)
; rotate right with carry on `a` register
rrca
push af
; call conditional on carry flag - carry flag gets set if `a` from above has lsb set (1)
; bit 0
; sync sprite map from C700 to VRAM 3F00
; $E7
call c, _LABEL_1F7_15
; compare $C200 with $C201
call _LABEL_41B3_24
pop af
rrca
push af
; bit 1
call _LABEL_367_26 ; get joypad buttons pushed
call _LABEL_107C_35 ; ? some magic far jump
pop af
rrca
push af
; bit 2
call _LABEL_264F_36 ; updates sprite colour
pop af
rrca
; bit 3
; this is a conditional "go to $842 via $20"
ld a, ($C01F)
ld hl, $0127
call c, _LABEL_1B_39 ; hits rst $20 but only if a has high bit set, otherwise short circuits
ld a, $82
; this sets it to 02 not 82 ?!
ld ($FFFF), a
call _LABEL_984F_43
xor a
ld ($C008), a
pop af
ld ($FFFF), a
; pop all the registers and shadow registers
pop iy
pop ix
pop hl
pop de
pop bc
pop af
exx
ex af, af'
pop hl
pop de
pop bc
pop af
; enable interrupts (they were disabled because we were in the handler)
ei
ret
; method jumps
; 842 gets used by start screen
; Data from 127 to 13E (24 bytes)
.db $42, $08, $42, $08, $35, $0A, $01, $1A, $CD, $18, $EE, $1B, $AE, $6E, $29, $7F
.db $A6, $16, $B1, $0A, $B1, $0A, $E6, $1F
_LABEL_13F_38:
; set palette value
; 0x00-0x0f = tile
; 0x10-0x1f = sprite
push af
rst $8
pop af
out ($BE), a
ret
; Data from 145 to 17B (55 bytes)
.db $CF, $79, $B7, $28, $01, $04, $78, $41, $0E, $BE, $ED, $A3, $C2, $4F, $01, $3D
.db $C2, $4F, $01, $C9, $CF, $3A, $0A, $C1, $0E, $BE, $ED, $A3, $F5, $F1, $ED, $79
.db $20, $F8, $C9, $CF, $79, $B7, $28, $01, $04, $78, $41, $0E, $BE, $ED, $A2, $C2
.db $72, $01, $3D, $C2, $72, $01, $C9
_LABEL_17C_101:
; clear screen display (set 3800-3EFF to 00)
ld de, $7800
ld bc, $0700
ld l, $00
; set VRAM pointer to 3800 (screen display)
_LABEL_184_9:
; fill vram
; de = 4000 + starting point (so 7800 -> vram 3800)
; bc = size (0700 = 700 bytes)
; l = value (00)
rst $8; writes de to $BF
ld a, c
or a
ld a, l
jr z, _LABEL_18B_11
inc b
_LABEL_18B_11:
out ($BE), a
dec c
jr nz, _LABEL_18B_11
djnz _LABEL_18B_11
ret
_LABEL_193_109:
; print rectangle of tiles to screen
; hl = memory of flattened blob
; de = initial coordinate
; b = height
; c = width (in bytes, twice the number of tiles)
; gets called twice
; hl=$AD9E, de=$788E, bc=$061C
; hl=$AE46, de=$79DA, bc=$071A
; b = number of iterations (whole loop)
; c = number of bytes to copy in each iteration
; $061C = 06 * 1C = 0xA8 (14 tiles)
; $071A = 07 * 1A = 0xB6 (13 tiles)
; we appear to write chunks of 0x1C or 0x1A but then skip hl forward by 0x40 after that
; 0x40 is the width of the screen (32 = 0x20, and 2 bytes per thing)
; 788E = write to 0x388E in VRAM (weird... display mem starts at 0x3800 so we skip a bunch?!)
; 79DA = write to 0x39DA in VRAM (weird... display mem starts at 0x3800 so we skip a bunch?!)
; the idea here is to dump the "ALEX KIDD" logo on the screen
; by passing de=$788E or $79DA we get to start at a certain x,y coordinate and print line at a time
; then we just nudge de forward 0x40 at a time
; in any case this would appear to be syncing (most of) the screen to VRAM
; this is part of the start screen, it dumps a bunch of tiles in two specific chunks
push bc
rst $8; write de to VDP register
ld b, c
ld c, $BE
_LABEL_198_110:
outi
nop
jr nz, _LABEL_198_110
ex de, hl
ld bc, $0040
add hl, bc
ex de, hl
pop bc
djnz _LABEL_193_109
ret
; Data from 1A7 to 1F6 (80 bytes)
.db $32, $0A, $C1, $C5, $CF, $41, $0E, $BE, $ED, $A3, $3A, $0A, $C1, $00, $ED, $79
.db $00, $C2, $AF, $01, $EB, $01, $40, $00, $09, $EB, $C1, $10, $E6, $C9, $21, $40
.db $00, $CF, $C5, $AF, $D3, $BE, $0D, $20, $FB, $19, $EB, $C1, $10, $F0, $C9, $32
.db $0B, $C1, $CF, $7E, $D9, $0E, $BE, $06, $04, $67, $3A, $0B, $C1, $1F, $54, $38
.db $02, $16, $00, $ED, $51, $10, $F6, $D9, $23, $0B, $78, $B1, $C2, $DA, $01, $C9
_LABEL_1F7_15:
; called by video handler
; 2x places kick this off (bit 0)
; am expecting some sort of screen/state update here
; $C01F could be the number of rows to update
ld a, ($C01F)
and $0F
cp $02
jr c, _LABEL_208_16
ld hl, $C10D
inc (hl)
bit 0, (hl)
jr z, _LABEL_224_17
_LABEL_208_16:
; sync sprites from C700 to VRAM
; send 7F00 to VDP register
; this is (0x7000 + 0x3F00) = write to 0x3F00 in VRAM
; Screen display: 32x28 table of tile numbers/attributes
; in other words, update on-screen tiles
; then copy 0x40 bytes from $C700 to port 0xBE
; this is the y position of each of 64 sprites
ld hl, $C700
ld de, $7F00
ld bc, $40BE
rst $8
_LABEL_212_18:
outi
jr nz, _LABEL_212_18
; copy sprite x coordinates and tiles
; these are in (x, tile_id) pairs
; memove(c780_local, 3f80_vram, 0x80)
ld hl, $C780
ld de, $7F80
ld b, $80
rst $8
_LABEL_21F_19:
outi
jr nz, _LABEL_21F_19
ret
_LABEL_224_17:
ld a, ($C009)
cp $13
jr c, _LABEL_208_16
; copy 0x11=17 sprites to 3f80
; memove(c780_local, 3f80_vram, 0x80)
ld hl, $C700
ld bc, $11BE
ld de, $7F00
rst $8
_LABEL_235_20:
outi
jr nz, _LABEL_235_20
ld hl, ($C009)
ld a, l
; accounting, subtract the 0x11 sprites from some counter
dec l
sub $11
ld b, a
_LABEL_241_21:
; send another 0x11 but increment b this time?!
outd
jr nz, _LABEL_241_21
; then 0xD0 - 35 all up at this stage
ld a, $D0
out ($BE), a
; then another 0x22=34 - 39 all up
ld hl, $C780
ld de, $7F80
ld b, $22
rst $8
_LABEL_252_22:
outi
jr nz, _LABEL_252_22
ld hl, ($C009)
sla l
set 7, l
ld a, l
sub $A2
ld b, a
_LABEL_261_23:
; some padding for the rest of the sprite mem?
dec l
dec l
outi
outd
jp nz, _LABEL_261_23
ret
_LABEL_26B_8:
; initialises graphics
; write a string of 0x16 (22 bytes) from $027D to port $BF
; $26, $80, $A0, $81, $FF, $82, $FF, $83, $FF, $84, $FF, $85, $FF, $86, $00, $88, $00, $89, $00, $87, $10, $C0
; sets VDP registers 0-9 as follows:
; 0 = 26 (do not display leftmost column, shift all sprites left, stretch screen - 33 columns wide)
; 1 = A0 (don't display, do start vsync interupts though?!)
; 2 = FF (nametable at $3800, default)
; 3 = FF (??)
; 4 = FF (??)
; 5 = FF (sprite table at $3900, default)
; 6 = FF (sprites are the second lot of tiles - $2000, tile 256 - 511)
; 7 = 00 (use colour 0 for border)
; 8 = 00 (hscroll = 0)
; 9 = 00 (vscroll = 0)
; last set ($10, $C0) sets us up to write to palette ram
ld hl, $027D
ld bc, $16BF
otir
; colour 0 is 000 - guarantees black border
xor a
out ($BE), a
; $C004 = ($27F) = $A0
; we must track $C004 to figure whether display/vsync interrupts are enabled/disabled
ld a, ($027F)
ld ($C004), a
ret
; Data from 27D to 292 (22 bytes)
.db $26, $80, $A0, $81, $FF, $82, $FF, $83, $FF, $84, $FF, $85, $FF, $86, $00, $88
.db $00, $89, $00, $87, $10, $C0
_LABEL_293_104:
;4.times do
ld b, $04
_LABEL_295_108:
push bc
push de
call _LABEL_2A0_105
pop de
; so we do 0+4n
; then 1+4n
; etc etc
; so this is 2 rows at a time (out of 8)
inc de
pop bc
djnz _LABEL_295_108
ret
_LABEL_2A0_105:
; gets called 4 times
ld a, (hl)
inc hl
or a
; 0 terminates
ret z
ld b, a
ld c, a
res 7, b ; make sure it isn't a negative number
_LABEL_2A8_107:
; de is either $4020 or $6400
; these translate to write to $0020 or $2400
; both of these are addresses of sprite/tile defs
; each is 32 bytes (each nybble is a colour)
; looks like we RLE the sprites, and stack them 4 bytes at a time
; presumably this helps with compression?
; important thing is that HL seems fixed - base sprites + some modifiers?
ld a, e
out ($BF), a
ld a, d
out ($BF), a
ld a, (hl)
out ($BE), a
bit 7, c
; repeat the same character if bit 7 is 0
jp z, _LABEL_2B7_106
; if bit 7 is set, then we're dumping characters 1 by 1
inc hl
_LABEL_2B7_106:
inc de
inc de
inc de
inc de
djnz _LABEL_2A8_107
; djnz preserves flags so this is the zero flag from earlier
; in other words, this makes sure we increment hl if we didn't just above
jp nz, _LABEL_2A0_105
inc hl
jp _LABEL_2A0_105
; Data from 2C4 to 2E5 (34 bytes)
.db $CF, $1E, $08, $56, $CB, $22, $1F, $1D, $20, $FA, $D3, $BE, $23, $0B, $78, $B1
.db $20, $EF, $C9, $21, $00, $C7, $11, $01, $C7, $01, $BF, $00, $36, $E0, $ED, $B0
.db $3E, $01
_LABEL_2E6_99:
; this looks like it sets the sync bitmap and busy waits until the interrupt handler has been called
; debugger spends a ton of time here, makes a lot of sense
ld hl, $C008
ld (hl), a
_LABEL_2EA_100:
ld a, (hl)
or a
jr nz, _LABEL_2EA_100
ret
_LABEL_2EF_97:
; disable display
ld a, ($C004)
and $BF
jr _LABEL_2FB_98
_LABEL_2F6_92:
; enable display
ld a, ($C004) ; caches VDP register 1
or $40
_LABEL_2FB_98:
; write a to vdp register 1
ld ($C004), a
ld e, a
ld d, $81
rst $8
ret
; Data from 303 to 310 (14 bytes)
.db $AF, $32, $BE, $C0, $32, $B0, $C0, $5F, $16, $89, $CF, $15, $CF, $C9
_LABEL_311_96:
; called from just before busy wait thing
call _LABEL_2EF_97 ; disable display
; zero a bunch of state (scroll counters?)
ld hl, $0000
ld ($C0AF), hl
ld ($C0BD), hl
ld ($C0AB), hl
ld ($C0B9), hl
; fill from C700 to C7BF with E0
ld hl, $C700
ld de, $C701
ld bc, $00BF
ld (hl), $E0
ldir
; zero out scroll values (registers 8 and 9)
ld de, $8800
rst $8
ld d, $89
rst $8
; enable interrupts
ei
; set bottom-most sync bit, busy wait
; this gets it to sync $C700 to sprite info table (done in interrupt)
ld a, $01
call _LABEL_2E6_99
di
; clear screen display
jp _LABEL_17C_101
_LABEL_341_4:
; this doesn't seem to have any side effects?!
ld b, $0A
_LABEL_343_6:
push bc
ld bc, $3333
_LABEL_347_5:
dec bc
ld a, b
or c
jr nz, _LABEL_347_5
pop bc
djnz _LABEL_343_6
ret
_LABEL_350_7:
; some sort of checking on $DE/$DF, $C005 holds the result (ends up being 1 or 0, is 0 for us)
ld a, $92
out ($DF), a
ld hl, $C005
ld a, (hl)
and $02
or $01
ld (hl), a
xor a
out ($DE), a
in a, ($DE)
or a
ret z
res 0, (hl)
ret
_LABEL_367_26:
; input detection, output in $C006
ld a, ($C005)
bit 0, a
jp nz, _LABEL_374_27
in a, ($DC)
jp _LABEL_3C4_28
_LABEL_374_27:
ld a, $07
out ($DE), a
in a, ($DC)
ld c, a
ld a, $04
out ($DE), a
in a, ($DC)
bit 5, a
jp nz, _LABEL_388_29
res 1, c
_LABEL_388_29:
ld a, $05
out ($DE), a
in a, ($DC)
bit 5, a
jp nz, _LABEL_395_30
res 2, c
_LABEL_395_30:
ld a, $06
out ($DE), a
in a, ($DC)
bit 5, a
jp nz, _LABEL_3A2_31
res 3, c
_LABEL_3A2_31:
bit 6, a
jp nz, _LABEL_3A9_32
res 0, c
_LABEL_3A9_32:
ld a, $02
out ($DE), a
in a, ($DC)
bit 4, a
jp nz, _LABEL_3B6_33
res 4, c
_LABEL_3B6_33:
ld a, $03
out ($DE), a
in a, ($DC)
bit 4, a
jp nz, _LABEL_3C3_34
res 5, c
_LABEL_3C3_34:
ld a, c
_LABEL_3C4_28:
ld hl, $C006
cpl
ld c, a
xor (hl)
ld (hl), c
inc hl
and c
ld (hl), a
ret
; Data from 3CF to 43A (108 bytes)
.db $3A, $05, $C0, $E6, $20, $C0, $01, $30, $C0, $11, $83, $04, $26, $00, $19, $CD
.db $0B, $04, $D0, $21, $30, $C0, $0E, $99, $71, $23, $71, $23, $71, $C9, $3A, $05
.db $C0, $E6, $20, $C0, $01, $20, $C0, $11, $89, $04, $26, $00, $19, $CD, $0B, $04
.db $D0, $21, $00, $C0, $0E, $99, $71, $23, $71, $23, $71, $C9, $0A, $86, $27, $02
.db $03, $23, $0A, $8E, $27, $02, $03, $23, $0A, $8E, $27, $02, $C9, $0A, $96, $27
.db $02, $23, $0C, $0A, $9E, $27, $02, $23, $0C, $0A, $9E, $27, $02, $C9, $0A, $96
.db $27, $23, $0C, $0A, $9E, $27, $23, $0C, $0A, $9E, $27, $C9
_LABEL_43B_102:
; these two hold counters?
; subtract one from the other
ld de, $C020
ld hl, $C000
ld b, $03
or a ; not sure what this does, we override a and the flags should get reset
_LABEL_444_103:
; this checks if ($C020) > ($C000)
ld a, (de)
sbc a, (hl)
inc hl
inc de
djnz _LABEL_444_103
ret c
; if so, copy ($C020) into ($C000)
ex de, hl
dec hl
dec de
ld bc, $0003
lddr
ret
; Data from 454 to 76C (793 bytes)
.db $0E, $03, $CD, $08, $00, $CB, $FB, $3E, $C0, $06, $02, $ED, $6F, $F5, $FE, $C0
.db $20, $08, $CB, $7B, $28, $06, $3E, $00, $18, $02, $CB, $BB, $D3, $BE, $F5, $F1
.db $3A, $0A, $C1, $D3, $BE, $F1, $10, $E3, $ED, $6F, $2B, $0D, $20, $D9, $C9, $01
.db $00, $00, $02, $00, $00, $20, $00, $00, $40, $00, $00, $60, $00, $00, $80, $00
.db $00, $00, $01, $00, $20, $01, $00, $00, $02, $00, $00, $10, $00, $23, $5E, $23
.db $56, $23, $46, $23, $7E, $C9, $46, $C5, $CD, $A1, $04, $23, $E5, $66, $6F, $CD
.db $59, $01, $E1, $C1, $10, $F1, $C9, $08, $3E, $82, $32, $FF, $FF, $08, $11, $00
.db $44, $01, $00, $02, $21, $05, $B3, $C3, $D6, $01, $DD, $6E, $1B, $DD, $7E, $1C
.db $E6, $01, $DD, $77, $1C, $67, $29, $7D, $E6, $7E, $4F, $29, $7C, $87, $5F, $16
.db $00, $21, $EE, $04, $19, $7E, $23, $66, $6F, $E9, $FE, $04, $35, $05, $71, $05
.db $A8, $05, $E4, $05, $1B, $06, $57, $06, $8E, $06, $21, $CA, $06, $06, $00, $09
.db $7E, $D9, $5F, $DD, $6E, $1D, $CD, $4C, $07, $DD, $7E, $1E, $84, $DD, $77, $0E
.db $DD, $7E, $19, $CE, $00, $DD, $77, $0A, $D9, $23, $6E, $DD, $5E, $1D, $CD, $4C
.db $07, $DD, $7E, $1F, $84, $DD, $77, $0C, $DD, $7E, $1A, $DE, $00, $DD, $77, $09
.db $C9, $21, $CC, $06, $79, $2F, $C6, $7F, $4F, $06, $00, $09, $7E, $D9, $5F, $DD
.db $6E, $1D, $CD, $4C, $07, $DD, $7E, $1F, $84, $DD, $77, $0C, $DD, $7E, $1A, $DE
.db $00, $DD, $77, $09, $D9, $23, $6E, $DD, $5E, $1D, $CD, $4C, $07, $DD, $7E, $1E
.db $84, $DD, $77, $0E, $DD, $7E, $19, $CE, $00, $DD, $77, $0A, $C9, $21, $CC, $06
.db $06, $00, $09, $7E, $D9, $5F, $DD, $6E, $1D, $CD, $4C, $07, $DD, $7E, $1F, $94
.db $DD, $77, $0C, $DD, $7E, $1A, $CE, $00, $DD, $77, $09, $D9, $23, $6E, $DD, $5E
.db $1D, $CD, $4C, $07, $DD, $7E, $1E, $84, $DD, $77, $0E, $DD, $7E, $19, $CE, $00
.db $DD, $77, $0A, $C9, $21, $CA, $06, $79, $2F, $C6, $7F, $4F, $06, $00, $09, $7E
.db $D9, $5F, $DD, $6E, $1D, $CD, $4C, $07, $DD, $7E, $1E, $84, $DD, $77, $0E, $DD
.db $7E, $19, $CE, $00, $DD, $77, $0A, $D9, $23, $6E, $DD, $5E, $1D, $CD, $4C, $07
.db $DD, $7E, $1F, $94, $DD, $77, $0C, $DD, $7E, $1A, $CE, $00, $DD, $77, $09, $C9
.db $21, $CA, $06, $06, $00, $09, $7E, $D9, $5F, $DD, $6E, $1D, $CD, $4C, $07, $DD
.db $7E, $1E, $94, $DD, $77, $0E, $DD, $7E, $19, $DE, $00, $DD, $77, $0A, $D9, $23
.db $6E, $DD, $5E, $1D, $CD, $4C, $07, $DD, $7E, $1F, $94, $DD, $77, $0C, $DD, $7E
.db $1A, $CE, $00, $DD, $77, $09, $C9, $21, $CC, $06, $79, $2F, $C6, $7F, $4F, $06
.db $00, $09, $7E, $D9, $5F, $DD, $6E, $1D, $CD, $4C, $07, $DD, $7E, $1F, $94, $DD
.db $77, $0C, $DD, $7E, $1A, $CE, $00, $DD, $77, $09, $D9, $23, $6E, $DD, $5E, $1D
.db $CD, $4C, $07, $DD, $7E, $1E, $94, $DD, $77, $0E, $DD, $7E, $19, $DE, $00, $DD
.db $77, $0A, $C9, $21, $CC, $06, $06, $00, $09, $7E, $D9, $5F, $DD, $6E, $1D, $CD
.db $4C, $07, $DD, $7E, $1F, $84, $DD, $77, $0C, $DD, $7E, $1A, $DE, $00, $DD, $77
.db $09, $D9, $23, $6E, $DD, $5E, $1D, $CD, $4C, $07, $DD, $7E, $1E, $94, $DD, $77
.db $0E, $DD, $7E, $19, $DE, $00, $DD, $77, $0A, $C9, $21, $CA, $06, $79, $2F, $C6
.db $7F, $4F, $06, $00, $09, $7E, $D9, $5F, $DD, $6E, $1D, $CD, $4C, $07, $DD, $7E
.db $1E, $94, $DD, $77, $0E, $DD, $7E, $19, $DE, $00, $DD, $77, $0A, $D9, $23, $6E
.db $DD, $5E, $1D, $CD, $4C, $07, $DD, $7E, $1F, $84, $DD, $77, $0C, $DD, $7E, $1A
.db $DE, $00, $DD, $77, $09, $C9, $00, $FF, $03, $FF, $06, $FF, $09, $FF, $0D, $FF
.db $10, $FF, $13, $FE, $16, $FE, $19, $FE, $1C, $FD, $1F, $FD, $22, $FD, $25, $FC
.db $29, $FC, $2C, $FB, $2F, $FB, $32, $FA, $35, $F9, $38, $F9, $3B, $F8, $3E, $F7
.db $41, $F7, $44, $F6, $47, $F5, $4A, $F4, $4D, $F3, $50, $F2, $53, $F1, $56, $F0
.db $59, $EF, $5C, $EE, $5F, $ED, $62, $EC, $64, $EA, $67, $E9, $6A, $E8, $6D, $E7
.db $70, $E5, $73, $E4, $75, $E2, $78, $E1, $7B, $DF, $7E, $DE, $80, $DC, $83, $DB
.db $86, $D9, $88, $D7, $8B, $D6, $8E, $D4, $90, $D2, $93, $D0, $95, $CF, $98, $CD
.db $9A, $CB, $9D, $C9, $9F, $C7, $A2, $C5, $A4, $C3, $A7, $C1, $A9, $BF, $AB, $BD
.db $AE, $BB, $B0, $B9, $B2, $B7, $B4, $B4, $65, $06, $08, $16, $00, $6A, $29, $30
.db $01, $19, $10, $FA, $C9, $06, $11, $AF, $C3, $68, $07, $8F, $38, $03, $BB, $38
.db $02, $93, $B7, $3F, $ED, $6A, $10, $F3, $C9
; This label is reached with a register jump
; seems to be the default event to go to
; ALEX KIDD start screen
_LABEL_76D_94:
; this appears to just load the start screen and nothing else
exx
bit 7, (hl)
; nothing to do so short circuit to busy wait
jp nz, _LABEL_7EC_95
; set bit ($C01F) and don't come back in here until it gets re-set
set 7, (hl)
; this strikes me as "init everything for the start screen"
; it loads all the sprites, puts the alex kidd logo on screen
; then we're ready to do everything else
xor a
ld ($C10A), a
; disable display and reset a bunch of stuff including scroll
; populates base sprite/tile data (done in interrupt)
; clears screen display
call _LABEL_311_96
ld de, $6000
ld bc, $0020
ld l, $00
; zeroes out first 0x20 bytes from vram 2000
; (first 0x20 sprites are special maybe? all we use?)
; address $784
call _LABEL_184_9
; load memory bank 2
ld a, $82
ld ($FFFF), a
call _LABEL_9DF3_45 ; turns sound channels to 0 volume and fills C111 - C1F5 with 00
call _LABEL_43B_102 ; copies from ($C020) to ($C000) if one is bigger - seems to track which demo is playing
; zero out C020-DDFF
ld hl, $C020
ld de, $C021
ld bc, $1DDF
ld (hl), $00
ldir
ld hl, $C226
ld (hl), $3C
xor a
; zero out $C227 and $C228
ld ($C227), a
ld ($C228), a
; load rom 4 in bank 2
ld a, $84
ld ($FFFF), a
ld hl, $B332
ld de, $4020
; $7b6
; no tiles loaded
call _LABEL_293_104 ; unpack tileset from $B332 (0x13332 in file) and load into VRAM
ld hl, $AD9E ; 12D9E in ROM
ld de, $788E ; start at (7, 2) - (y_coord + x_coord+row_length)*bytes_in_word = (7 + 2*32)*2 = 142 = 8E
ld bc, $061C ; height 6, width 14
; $7c2
; loading screen tiles all loaded
call _LABEL_193_109 ; sync screen display from memory
ld hl, $AE46 ; 12E46 in ROM
ld de, $79DA ; start at (13, 7) - (y_coord + x_coord+row_length)*bytes_in_word = (13 + 7*32)*2 = 474 = 1DA
ld bc, $071A ; height 7, width 13
; $7ce
; word ALEX is loaded in tilemap
call _LABEL_193_109 ; sync screen display from memory
; load palette
ld hl, $08C6 ; palette location
ld de, $C000 ; palette entry 0
ld b, $20
; $7d9
; whole ALEX KIDD in miracle world logo is loaded
rst $30
; 7da
; palette now updated
call _LABEL_8F6_113 ; clears sprite memory ($C300) and loads up sprite tiles (alex/janken etc)
; other sprites loaded (not just logo but the stuff that pops up during loading screen)
call _LABEL_2F6_92 ; enable display
; no change observed to maps
ei
ld hl, $01D0
ld ($C103), hl
ld a, $81
ld ($C110), a
_LABEL_7EC_95:
;set vsync bits 3 and 0 and busy wait
ld a, $09
; this plays out the first chunk of music - we should see where it goes
; a = 0x01 + 0x08
; the 0x08 means we get sent to $842 at the end of the interrupt loop
call _LABEL_2E6_99 ; int whatever... with a=09
; we get to here after the first second of music and first sprite (underwater top right) displayed
call _LABEL_2694_121 ; didn't look too closely, looks to be a bunch of init stuff
ld a, ($C006) ; a = bitmask of joypad buttons
ld b, a
and $30
jr nz, _LABEL_80C_146
ld hl, ($C103)
dec hl
ld ($C103), hl
ld a, h
or l
ret nz
ld a, $02
ld ($C01F), a
ret
_LABEL_80C_146:
ld a, $26
ld ($C05F), a
ld hl, $0824
ld de, $C01F
ld bc, $0019
ldir
xor a
ld ($C10A), a
ld ($C005), a
ret
; Data from 824 to 841 (30 bytes)
.db $03, $00, $00, $00, $01, $01, $03, $00, $00, $00, $00, $00, $00, $00, $00, $00
.db $00, $00, $00, $00, $00, $00, $03, $00, $00, $00, $00, $00, $00, $00
; This label is reached with a register jump
; used by the start screen
; gets called by $20
; then jumps back there?!
_LABEL_842_40:
ld hl, $C226
dec (hl)
ret nz
ld (hl), $20
inc hl
ld a, (hl)
cp $06
jr c, _LABEL_866_41 ; jump if ($C227) is less than 6
; if we haven't jumped then $C227 is 6 or more
; this might be where we pick a demo and start that?
dec hl
ld (hl), $03
inc hl
inc hl
inc (hl)
ld a, (hl)
and $03
ld hl, $08F2
ld e, a
ld d, $00
add hl, de
ld a, (hl)
ld de, $C002
; set palette 02 to colour in a
jp _LABEL_13F_38
_LABEL_866_41:
inc (hl)
ld hl, $FFFF
ld (hl), $84
ld hl, $08E6
jp _RST_20H
; 872-8F5 disassembled
ld hl,$aefc ; 0x12EFC = 77564 in ROM
ld de,$7828 ; start at (20, 0) - (y_coord + x_coord+row_length)*bytes_in_word = (20 + 0*32)*2 = 40 = 0x28
ld bc,$0718 ; height 7, width 12, 7*12*2 = 168 bytes
call $0193
jp $09c2
ld hl,$b0a4 ; 0x130A4 = 77988 in ROM
ld de,$7b98 ; start at (12, 14) - (y_coord + x_coord+row_length)*bytes_in_word = (12 + 14*32)*2 = 920 = 0x398
ld bc,$061c ; height 6, width 14, 6*14*2 = 168 bytes
call $0193
jp $097e
ld hl,$afa4 ; 0x12FA4 = 77732 in ROM
ld de,$7800 ; start at (0, 0)
ld bc,$080e ; height 8, width 7, 8*7*2 = 112 bytes
jp $0193
ld hl,$b014 ; 0x13014 = 77844 in ROM
ld de,$79f4 ; start at (26, 7) - (y_coord + x_coord+row_length)*bytes_in_word = (26 + 7*32)*2 = 500 = 0x1F4
ld bc,$0c0c ; height 12, width 6, 12*6*2 = 144 bytes
call $0193
jp $0967
ld hl,$b1b2 ; 0x131B2 = 78258 in ROM
ld de,$7a00 ; start at (0, 8) - (y_coord + x_coord+row_length)*bytes_in_word = (0 + 8*32)*2 = 512 = 0x200
ld bc,$1018 ; height 16, width 12, 16*12*2 = 384 bytes
call $0193
jp $0995
ld hl,$b14c ; 0x1314C = 78156 in ROM
ld de,$7d1a ; start at (13, 20) - (y_coord + x_coord+row_length)*bytes_in_word = (13 + 20*32)*2 = 1306 = 0x51A
ld bc,$0322 ; height 3, width 17, 3*17*2 = 102 bytes
jp $0193
; $8C6-$8F5 appears to be data
; Data from 872 to 8F5 (132 bytes)
.db $21, $FC, $AE, $11, $28, $78, $01, $18, $07, $CD, $93, $01, $C3, $C2, $09, $21
.db $A4, $B0, $11, $98, $7B, $01, $1C, $06, $CD, $93, $01, $C3, $7E, $09, $21, $A4
.db $AF, $11, $00, $78, $01, $0E, $08, $C3, $93, $01, $21, $14, $B0, $11, $F4, $79