-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRAM map.asm
4535 lines (4350 loc) · 206 KB
/
RAM map.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
.*(\[\$....\]|RT[LS]|JM[LP]).*
$00..50: Miscellaneous temporary variables
{
$0E: Unused (one byte)
$11: Unused (one byte)
$36: Long address of blocks to update in $80:A9DE/AB78
$39..3B: Unused
$3C: Samus tiles definition in $80:9376 (copy of $071F/$0721)
$3E..43: Unused
$44: Pointer to return address relative parameter in $80:B0FF
$47: Decompression source parameter for $80:B0FF/B119/B271
$4A: Decompression variable (size/command byte, word fill value, dictionary copy source address) in $80:B119/B271
$4C: Decompression destination parameter for $80:B119/B271
$4F: Decompression dictionary copy inversion bit in $80:B119/B271
}
$51..86: Regular IO registers (according to $81:8D0F)
{
$51: Forced blank and screen brightness ($2100). Updated during NMI
{
v = f000bbbb
If b = 0:
Brightness = 0
Else:
Brightness = (b + 1) / 10h
f: Forced blank
}
$52: Sprite size and sprite tiles base address ($2101). Updated during NMI
{
v = sssggbbb
Base address for sprite tiles 0..FFh = b * 2000h
Base address for sprite tiles 100..1FFh = b * 2000h + (g + 1) * 1000h
s: Sprite sizes
Small Large
0: 8x8, 16x16
1: 8x8, 32x32
2: 8x8, 64x64
3: 16x16, 32x32
4: 16x16, 64x64
5: 32x32, 64x64
}
$53: OAM address and OAM priority rotation ($2102). Updated during NMI
{
To set the OAM priority rotation:
Write 80h to $54
Write the highest priority OAM index (0..7Fh) << 1 to $53
To set the OAM address:
Write the (word) address ($00..$01FF) to $53
}
$55: Mode and BG tile size ($2105). Updated during NMI
{
v = dcbapmmm
mmm: Mode (0..7)
p: BG3 priority in mode 1
a: BG1 tile size. 0: 8x8, 1: 16x16
b: BG2 tile size. 0: 8x8, 1: 16x16
c: BG3 tile size. 0: 8x8, 1: 16x16
d: BG4 tile size. 0: 8x8, 1: 16x16
}
$56: Fake mode and BG tile size. Checked by $80:91EE to update mode 7 registers and during NMI to process mode 7 transfers. Value for $07EC. Updated during NMI. Written to by Ceres elevator shaft door ASM and Ceres Ridley
$57: Mosaic size and enable ($2106). Updated during NMI
{
v = ssssdcba
a: BG1 enable
b: BG2 enable
c: BG3 enable
d: BG4 enable
s: Block size = (s+1)x(s+1)
}
$58: BG1 tilemap base address and size ($2107). Updated during NMI
$59: BG2 tilemap base address and size ($2108). Updated during NMI
$5A: BG3 tilemap base address and size ($2109). Updated during NMI
$5B: Gameplay BG3 tilemap base address and size ($2109). Updated during IRQ 6/Eh (gameplay, status bar drawn)
$5C: BG4 tilemap base address and size ($210A). Updated during NMI
{
v = bbbbbbss
s: BG tilemap size
0: 32x32
1: 64x32
2: 32x64
3: 64x64
BG tilemap base address = b * 400h = v * 100h & FC00h
}
$5D: BG tiles base address ($210B). Updated during NMI
{
v = ddddccccbbbbaaaa
BG1 tiles base address = a * 1000h
BG2 tiles base address = b * 1000h
BG3 tiles base address = c * 1000h
BG4 tiles base address = d * 1000h
}
$5F: Mode 7 settings ($211A). Updated during NMI
{
v = oo0000yx
x: Screen X flip
y: Screen Y flip
o: BG map overflow
0/1: Wrap within 128x128 tile area
2: Overflowing tiles are transparent
3: Overflowing tiles are tile 0
}
$60: Window BG1/BG2 mask settings ($2123). Updated during NMI
{
v = ddccbbaa
a: BG1 window 1 mask
b: BG1 window 2 mask
c: BG2 window 1 mask
d: BG2 window 2 mask
a/b/c/d:
0/1: Disable mask
2: Enable inclusive mask
3: Enable exclusive mask
}
$61: Window BG3/BG4 mask settings ($2124). Updated during NMI
{
v = ddccbbaa
a: BG3 window 1 mask
b: BG3 window 2 mask
c: BG4 window 1 mask
d: BG4 window 2 mask
a/b/c/d:
0/1: Disable mask
2: Enable inclusive mask
3: Enable exclusive mask
}
$62: Window sprites/math mask settings ($2125). Updated during NMI
{
v = ddccbbaa
a: Sprite window 1 mask
b: Sprite window 2 mask
c: Colour math window 1 mask
d: Colour math window 2 mask
a/b/c/d:
0/1: Disable mask
2: Enable inclusive mask
3: Enable exclusive mask
}
$63: Window 1 left position ($2126). Updated during NMI
$64: Window 1 right position ($2127). Updated during NMI
$65: Window 2 left position ($2128). Updated during NMI
$66: Window 2 right position ($2129). Updated during NMI
$67: Window 1/2 BG mask logic ($212A). Updated during NMI
{
v = ddccbbaa
a: Window 1/2 BG1 mask logic
b: Window 1/2 BG2 mask logic
c: Window 1/2 BG3 mask logic
d: Window 1/2 BG4 mask logic
a/b/c/d:
0: OR (mask is enabled anywhere window 1 or 2 or both is)
1: AND (mask is enabled only where both window 1 and 2 are)
2: XOR (mask is enabled only where either window 1 or 2 is, but not both)
3: XNOR (mask is enabled where both or neither of window 1 and 2 are)
}
$68: Window 1/2 sprites/colour math mask logic ($212B). Updated during NMI
{
v = 0000bbaa
a: Window 1/2 sprites mask logic
b: Window 1/2 colour math mask logic
a/b:
0: OR (mask is enabled anywhere window 1 or 2 or both is)
1: AND (mask is enabled only where both window 1 and 2 are)
2: XOR (mask is enabled only where either window 1 or 2 is, but not both)
3: XNOR (mask is enabled where both or neither of window 1 and 2 are)
}
$69: Main screen layers ($212C and $6A). Updated during NMI
$6A: Gameplay main screen layers ($212C). Updated during IRQ 6 (main gameplay, status bar drawn). Used exclusively by message boxes (which short-circuit the NMI handler)
$6B: Subscreen layers ($212D). Updated during NMI
{
v = 000edcba
a: Enable BG1
b: Enable BG2
c: Enable BG3
d: Enable BG4
e: Enable sprites
}
$6C: Window area main screen disable ($212E). Updated during NMI
$6D: Window area subscreen disable ($212F). Updated during NMI
{
v = 000edcba
a: Disable BG1 in window area
b: Disable BG2 in window area
c: Disable BG3 in window area
d: Disable BG4 in window area
e: Disable sprites in window area
}
$6E: Next gameplay colour math control register A ($70). Updated during NMI
$6F: Colour math control register A ($2130). Updated during NMI
$70: Gameplay colour math control register A ($2130). Updated during IRQ 6/Eh (gameplay, status bar drawn)
{
v = ffcc00sd
d: Direct colour for 8bpp backgrounds
s: Enable subscreen layers (0 is backdrop only, 1 is BG + sprites too)
c: Colour math mask logic
0: Enable colour math everywhere
1: Restrict colour math to inside window
2: Restrict colour math to outside window
3: Disable colour math
f: Force main screen black
0: Disabled
1: Force main screen black outside window
2: Force main screen black inside window
3: Force main screen black everywhere
}
$71: Next gameplay colour math control register B ($73). Updated during NMI
$72: Colour math control register B ($2131). Updated during NMI
$73: Gameplay colour math control register B ($2131). Updated during IRQ 6/Eh (gameplay, status bar drawn)
{
v = ohfedcba
a: Enable colour math on BG1
b: Enable colour math on BG2
c: Enable colour math on BG3
d: Enable colour math on BG4
e: Enable colour math on sprite palettes 4..7
f: Enable colour math on backdrop
h: Halve result (if not forced black)
o:
0: Add subscreen to main screen
1: Subtract subscreen from main screen
}
$74: Colour math subscreen backdrop colour 0 ($2132). Updated during NMI
$75: Colour math subscreen backdrop colour 1 ($2132). Updated during NMI
$76: Colour math subscreen backdrop colour 2 ($2132). Updated during NMI
{
v = bgriiiii
i: Intensity (0..1Fh)
r: Apply intensity as red (otherwise, no change)
g: Apply intensity as green (otherwise, no change)
b: Apply intensity as blue (otherwise, no change)
}
$77: Display resolution ($2133). Updated during NMI. Always 0
{
v = ex00gbsi
i: Interlacing
s: High Y resolution sprites
b: PAL Y resolution (0: 224, 1: 239)
g: Pseudo high X resolution mode
x: External background mode
e: External synchronisation
}
$78: Mode 7 transformation matrix parameter A. 1/100h pixels ($211B). Updated during NMI
$7A: Mode 7 transformation matrix parameter B. 1/100h pixels ($211C). Updated during NMI
$7C: Mode 7 transformation matrix parameter C. 1/100h pixels ($211D). Updated during NMI
$7E: Mode 7 transformation matrix parameter D. 1/100h pixels ($211E). Updated during NMI
$80: Mode 7 transformation origin co-ordinate X ($211F). Updated during NMI
$82: Mode 7 transformation origin co-ordinate Y ($2120). Updated during NMI
$84: Interrupt and auto-joypad enable ($4200). Updated during NMI
{
v = n0ii000j
n: Enable NMI
i: IRQ mode
0: Disable IRQ
1: Enable h-count IRQ
2: Enable v-count IRQ
3: Enable v-count/h-count IRQ
j: Enable auto-joypad read
}
$85: HDMA channels to enable ($420C). Updated during NMI
$86: ROM access speed ($420D). Never read
}
$87: Auto-press initial delay. Never written
$89: Auto-press subsequent delay. Never written
$8B: Controller 1 input ($4218)
{
8000h: B
4000h: Y
2000h: Select
1000h: Start
800h: Up
400h: Down
200h: Left
100h: Right
80h: A
40h: X
20h: L
10h: R
}
$8D: Debug. Controller 2 input ($421A)
$8F: Newly pressed controller 1 input
$91: Debug. Newly pressed controller 2 input
$93: Fake newly pressed controller 1 input. Never read. Overwritten by controller 1 input if held initially for [$87] frames, then subsequently every [$89] frames
$95: Debug. Fake newly pressed controller 2 input. Never read. Overwritten by controller 2 input if held initially for [$87] frames, then subsequently every [$89] frames
$97: Previous controller 1 input (during controller input processing)
$99: Debug. Previous controller 2 input (during controller input processing)
$9B..A2: Unused
$A3: Controller 1 auto-press timer
$A5: Debug. Controller 2 auto-press timer
$A7: Next interrupt command (after screen is drawn)
$A9: Room loading interrupt command
$AB: Interrupt command
{
0: Nothing
2: Disable h/v-counter interrupts
4: Main gameplay - begin HUD drawing
6: Main gameplay - end HUD drawing
8: Start of room transition - begin HUD drawing
Ah: Start of room transition - end HUD drawing
Ch: Draygon's room - begin HUD drawing
Eh: Draygon's room - end HUD drawing
10h: Vertical room transition - begin HUD drawing
12h: Vertical room transition - end HUD drawing
14h: Vertical room transition - end drawing
16h: Horizontal room transition - begin HUD drawing
18h: Horizontal room transition - end HUD drawing
1Ah: Horizontal room transition - end drawing
}
$AD: Pointer to return address relative parameters in $82:E039
$AF: Current region FX palette FX / animated tiles object table in $89:AB82
$B1: BG1 X scroll ($210D). Updated during NMI. Origin X position in the BG1 layer to draw to screen. Positive direction pans camera rightwards over BG1, or equivalently moves BG1 leftwards on the camera
$B3: BG1 Y scroll ($210E). Updated during NMI. Origin Y position in the BG1 layer to draw to screen. Positive direction pans camera downwards over BG1, or equivalently moves BG1 upwards on the camera
$B5: BG2 X scroll ($210F). Updated during NMI
$B7: BG2 Y scroll ($2110). Updated during NMI
$B9: BG3 X scroll ($2111). Updated during NMI
$BB: BG3 Y scroll ($2112). Updated during NMI
$BD: BG4 X scroll ($2113). Updated during NMI. Pretty pointless, BG4 is never used. Used as backup of BG1 X scroll during equipment screen (strangely...)
$BF: BG4 Y scroll ($2114). Updated during NMI. Pretty pointless, BG4 is never used. Used as backup of BG1 Y scroll during equipment screen (strangely...)
$C1..CF: Unused
$D0..02CF: VRAM write table. 7 byte entries. 2 byte zero-terminator. Table size >= 1FCh bytes = 49h entries according to PLM drawing ($84:8DAA) routine
{
+ 0: Size
+ 2: Source address
+ 5: Destination address. If [destination address] & 8000h: DMA transfer uses 32-byte increment mode (for writing a column in a tilemap)
}
$02D0..032F: Mode 7 transfers. 7 or 9 byte entries. 1 byte zero-terminator. No enforced upper limit (even in mode 7 object handling)
{
+ 0: Control
DMA control = [control] & 1Fh (transfer unit selection and address increment direction)
DMA target = [control] & C0h:
40h: CGRAM data write
80h: VRAM data write low (tilemap)
C0h: VRAM data write high (tiles)
+ 1: Source address
+ 4: Size
+ 6: Destination address (1 byte for CGRAM transfers, 2 bytes for VRAM transfers)
+ 8: VRAM address increment mode (for VRAM transfers only). 0 for tilemap, 2 for tilemap column, 80h for tiles
}
$0330: VRAM write table stack pointer
$0332: Unused
$0334: Mode 7 transfers stack pointer
$0336..3F: Unused
$0340..5C: VRAM read table. 9 byte entries. 2 byte zero-terminator. No enforced upper limit, but only enough space for 3 entries (only 1 ever used in practice). Used by Kraid pausing code ($A7:C325) and x-ray ($91:CB1C/CB57/CB8E/D0D3)
{
+ 0: Source address
+ 2: DMA control (usually 81h)
+ 3: DMA target (usually 39h)
+ 4: Destination address
+ 7: Size
}
$0360: VRAM read table stack pointer
$0362..6F: Unused
$0370..058F: OAM (updated during NMI by $80:933A). 80h entries
{
$0370..056F: Low OAM. 4 byte entries
{
v = xxxxxxxx yyyyyyyy YXPPpppttttttttt
x: X position (lower 8 bits)
y: Y position
t: Tile number
p: Palette
P: Priority
X: X flip
Y: Y flip
}
$0570..8F: High OAM. 2 bit entries
{
ddccbbsx
x: X position (upper 1 bit)
s: Size
b: sx for sprite 4n+1
c: sx for sprite 4n+2
d: sx for sprite 4n+3
}
}
$0590: OAM stack pointer
$0592: Power bomb explosion status
{
4000h: Power bomb explosion is pending (due to Samus dying(?) or auto reserve tanks being active)
8000h: Power bomb is exploding or first part of crystal flash
}
$0594: Unused
$0596: BG3 X scroll HDMA data table size for unused FX type 22h in $88:A673
$0598: Y position on screen in $88:A81C
$059A: Set to E0h by scrolling sky and never read. (Unused) expanding and contracting effect HDMA table update counter, table is updated in 4 parts and this tracks which part is next
$059C: Set to 0 by scrolling sky, otherwise unused
$059E: HUD BG2 X position during scrolling sky (never written to / always zero)
$05A0: Contracting flag. Used by an unused expanding and contracting HDMA effect ($88:B17F)
{
0: Expanding
1: Contracting
}
$05A2..AB: Message box animation variables
{
$05A2: Message box animation Y radius (in units of 1/100h px)
$05A4: Message box animation variable - bottom half. At line y: $05A4 = y + [message box animation Y radius] / 100h
$05A6: Message box animation variable - bottom half. At line y: $05A6 = y + 18h
$05A8: Message box animation variable - top half. At line y: $05A8 = y - [message box animation Y radius] / 100h
$05AA: Message box animation variable - top half. At line y: $05AA = y - 18h
}
$05A2..AB: (Unused) expanding and contracting effect variables. See $88:B17F
{
$05A2: Expansion factor. Scale factor = 1 + [expansion factor] / 8000h
$05A4: HDMA table update destination top base position
$05A6: HDMA table update source top base position
$05A8: HDMA table update destination bottom base position
$05AA: HDMA table update source bottom base position
}
$05A6: Adjusted source Y offset during Crocomire melting. [$0694] + y
$05AC: Map min X scroll
$05AE: Map max X scroll
$05B0: Map min Y scroll
$05B2: Map max Y scroll
$05B4: NMI request flag
$05B5: 8-bit frame counter. Does not include lag frames. Set to 0 during door transitions by a (likely erroneous) 16-bit write to $05B4. Not sure why this exists...
$05B6: Frame counter. Does not include lag frames
$05B8: NMI counter. Includes lag frames (used exclusively by message boxes)
$05BA: Lag counter
$05BB: Maximum lag. Capped at FFh, which happens very quickly if a message box appears. Only useful for measuring the load time of the title sequence (which is 26h frames, or up to 28h frames if returning from the file select screen, guessing audio sync/flush).
$05BC: Door transition VRAM update flag
$05BE: Door transition VRAM update destination
$05C0: Door transition VRAM update source
$05C3: Door transition VRAM update size
$05C5: Debug. Newly pressed controller 1 input when select + L is pressed. Clears $05C7 if non-zero (L has priority over R)
$05C7: Debug. Newly pressed controller 1 input when select + R is pressed
{
8000h: B
4000h: Y
2000h: Select
1000h: Start
800h: Up
400h: Down
200h: Left
100h: Right
80h: A
40h: X
20h: L
10h: R
}
$05C9: Debug. Missiles swap
$05CB: Debug. Super missiles swap
$05CD: Debug. Power bombs swap
$05CF: Debug. Debug options
{
v & 1F40h != 0: draw 3 digits of super missiles
2000h: X is pressed whilst select + R is held ($80:9459)
4000h: Debug controller input processing is disabled ($80:9459)
8000h: Ammo is swapped (B is pressed whilst select + R is held) ($80:9459). Used to show morphed Samus' position in the demo recorder ($90:ED26) and in-game time in unused routine ($90:ED6C)
}
$05D1: Debug. Debug mode. Set to [$80:8004] during boot / soft reset
$05D3: Debug. Saved layer 1 position flag. Toggle with X on controller 2 if $80:8006 is set
$05D5: Debug. Saved layer 1 X position
$05D7: Debug. Saved layer 1 Y position
$05D9: Previous held input
$05DB: Timed held input timer
$05DD: Timed held input timer reset value. Set to 3 (meaning "timed held input" is input held for 4+ frames)
$05DF: Timed held input
$05E1: Newly held down timed held input. This variable is the useful one (used by pause screen). The rest of $05D9..E4 is all helper variables exclusively used in the update routine
$05E3: Previous timed held input
$05E5: Random number. Seeded with 61h during boot / soft reset. Generated by $80:8111. Reseeded by a few enemies
$05E7: Bitmask. In particular, the bitmask result of $80:818E (change nth bit index to byte index and bitmask). Also written by related boss/event set/clear functions in bank $80
$05E9: 16-bit multiplier A. Used by $80:82D6
$05EB: 16-bit multiplier B. Used by $80:82D6
$05ED..F0: Unused
$05F1: 16-bit * 16-bit result registers. Used by routine $80:82D6
$05F5: Disable sounds
$05F7: Disable mini-map
$05F9: Save confirmation selection
{
0: Yes
2: No
}
$05FB: Map scrolling gear switch timer. 0 = free scrolling (hold) 01+ = number of "scrolls" until free scrolling
$05FD: Map scrolling direction
{
0: None
1: Left
2: Right
3: Up
4: Down
}
$05FF: Map scrolling speed index. Indexes the map scrolling speed table $82:92E4
$0601: Pause hook. Executed after fade out is complete and HDMA disabled, but before gameplay state is backed up. Set to $A7:C325 by Kraid, $8F:C8F6 by Draygon
$0604: Unpause hook. Executed after gameplay state is restored, but before HDMAs and screen fade in are enabled. Set to $A7:C24E by Kraid, $8F:C8FC by Draygon, $A9:8763 by Mother Brain
$0607: Earthquake sound effect index
$0609: Earthquake sound effect timer. Earthquake sound effect disabled if negative. Used with rising lava/acid and Tourian entrance reveal FX
$060B:
{
Number of remaining enemy spritemap entries in $A0:944A/9A5A/9B7F/9D23
Loop counter in enemy death item drop routines
Botwoon's spit enemy projectile angle parameter
; Other stuff. TODO
}
$060D:
{
Number of remaining enemy hitbox entries in $A0:9A5A/9B7F/9D23
Number of tiles in $A0:96CA
Loop counter in $B3:9EE0/9F34
}
$060F: Projectile counter is mirrored here in $A0:9B7F. Never read
$0611..16: Unused
$0617: Uploading to APU flag (disables debug soft reset)
$0619..28: Music queue entries. List of words. See $063D
$0629..38: Music queue timers. List of words. Minimum of 8
$0639: Music queue next index. Index of next available queue entry to write to (write position)
$063B: Music queue start index. Index of next queue entry to process (read position)
$063D: Music entry. Processed when the music timer is decremented to 0
{
0: Stop music
1: Samus fanfare
2: Item fanfare
3: Elevator
4: Pre-statue hall (also Ridley pre-fight and game over)
5: Song 0
6: Song 1
7: Song 2
8: Song 3
FF00h: SPC engine
FF03h: Title sequence
{
Song 0: Intro
Song 1: Main theme
Song 2: Unused intro variation
}
FF06h: Empty Crateria
{
Song 0: With thunder (landing site - default, Crateria -> Blue Brinstar elevator - default)
Song 1: Thunder (landing site - Zebes is awake)
Song 2: Without thunder (morph ball room - default)
}
FF09h: Lower Crateria
{
Song 0: Main theme
Song 1: Tourian entrance
}
FF0Ch: Upper Crateria (landing site - power bombs, Wrecked Ship entrances)
FF0Fh: Green Brinstar
FF12h: Red Brinstar
FF15h: Upper Norfair
FF18h: Lower Norfair
FF1Bh: Maridia
{
Song 0: Sandy
Song 1: Sandless
}
FF1Eh: Tourian
{
Song 0: Tourian
Song 1: No music
}
FF21h: Mother Brain
FF24h: Boss fight 1 (and escape music)
{
Song 0: Ridley / Draygon / torizos
Song 1: Pre-fight (Bomb Torizo)
Song 2: Escape music
}
FF27h: Boss fight 2
{
Song 0: Kraid / Phantoon / Crocomire
Song 1: Pre-fight (Kraid / Phantoon / fake Kraid) / post-fight (Crocomire)
}
FF2Ah: Miniboss fight (Spore Spawn / Botwoon)
FF2Dh: Ceres
{
Song 0: Flying to Ceres
Song 1: Ceres
Song 2: Flying to Zebes
Song 3: Ceres time up
}
FF30h: Wrecked Ship
{
Song 0: Power off
Song 1: Power on
}
FF33h: Zebes boom
FF36h: Intro
FF39h: Death
FF3Ch: Credits
FF3Fh: "The last Metroid is in captivity"
FF42h: "The galaxy is at peace"
FF45h: Shitroid (same as boss fight 2)
{
Song 0: Boss music
Song 1: Pre-boss music
Song 2: No music
}
FF48h: Samus theme (same as upper Crateria)
}
$063F: Music timer
$0641: Number of remaining attempts to poll APU for upload request acknowledgement
$0643: Sound queue start index, sound library 1
$0644: Sound queue start index, sound library 2
$0645: Sound queue start index, sound library 3
$0646: Sound queue next index, sound library 1
$0647: Sound queue next index, sound library 2
$0648: Sound queue next index, sound library 3
$0649: Sound state, sound library 1
$064A: Sound state, sound library 2
$064B: Sound state, sound library 3
{
0: Send APU sound request from queue
1: Wait for APU sound request acknowledgement
2: Clear sound request
3: Wait for APU clear request acknowledgement
4: Unused. Reset sound state
}
$064C: Current music track. Never read (see $07F5 instead). FFh means new music data is being uploaded
$064D: Current sound, sound library 1
$064E: Current sound, sound library 2
$064F: Current sound, sound library 3
$0650: Delay before clearing sound
$0651: Delay before clearing sound
$0652: Delay before clearing sound
$0653: Max queued sounds allowed, sound library 1
$0654: Max queued sounds allowed, sound library 2
$0655: Max queued sounds allowed, sound library 3
$0656..65: Sound queue, sound library 1
$0666..75: Sound queue, sound library 2
$0676..85: Sound queue, sound library 3
$0686: Sound handler downtime (set to 8 by music queue handler when music changes)
$0688: Crocomire skeleton loading index. Target number of pixels to erase per column (30h) during Crocomire melting
$068A: Crocomire melting tiles loading table (sub)index
$068C: Number of pixels to erase per column per frame (30h) during Crocomire melting
$068E: Number of words to load (200h) when loading Crocomire melting tiles. Used immediately to initialise a loop counter, no reason for this value to be stored to RAM
$0690: Crocomire melting X offset table index. Index for $A4:9697
$0692: Crocomire melting displacement coefficient. Displacement = y * [$0692] / 10000h. Initialised to 100h. Incremented by 180h up to 5000h, finishing the melting
$0694: Initial adjusted destination Y offset during melting. Initialised to 58h. Decremented by 3 until 10h
$0696: Set to 30h when loading Crocomire melting tiles. Never read
$0698: Max adjusted destination Y offset (58h) during Crocomire melting. HDMA data table is processed until [$0694] + y - displacement(y) >= [$0698]
$069A: Crocomire melting tiles loading table (base) index
$069C..071D: Crocomire melting Y offsets. Only $069C..CC used. Indexed by [$9697 + [$0690]] (melting X offset). Pretty useless, could be replaced by a simple loop counter in $96C8
$071C: Unused. Timer for $80:8577 (wait [A] frames)
$071D: Flag. Transfer Samus' top half tiles to VRAM
$071E: Flag. Transfer Samus' bottom half tiles to VRAM
$071F: Samus' top half tiles definition. Pointer to DMA data (bank 92) for Samus' top sprites (3 byte address, 2 byte part 1 size, 2 byte part 2 size)
$0721: Samus' bottom half tiles definition. Pointer to DMA data (bank 92) for Samus' bottom sprites (3 byte address, 2 byte part 1 size, 2 byte part 2 size)
$0723: Screen fade delay
$0725: Screen fade counter
$0727: Menu index
{
Debug game over menu:
{
0: Fade out and configure graphics for menu
1: Initialise
2: Fade in to main
3: Main
4: Fade in to continue
5: Continue
}
Game over menu:
{
0: Fade out and configure graphics for menu
1: Initialise
2: Play pre-statue hall music track
3: Fade in to main
4: Main
5: Fade out into game map view
6: Load game map view
7: Fade out into soft reset
}
File select menu:
{
0: Title sequence to main - fade out and configure graphics
1: Title sequence to main - load BG2
2: Title sequence to main - initialise
3: Title sequence to main - fade in
4: Main
5: Main to file copy - fade out
6: Main to file copy - initialise
7: Main to file copy - fade in
8: File copy - select source
9: File copy - initialise select destination
Ah: File copy - select destination
Bh: File copy - initialise confirmation
Ch: File copy - confirmation
Dh: File copy - do file copy
Eh: File copy - copy completed
Fh: File copy to main - fade out
10h: File copy to main - reload main
11h: File copy to main - fade in
12h: File copy to main - menu index = main
13h: Main to file clear - fade out
14h: Main to file clear - initialise
15h: Main to file clear - fade in
16h: File clear - select slot
17h: File clear - initialise confirmation
18h: File clear - confirmation
19h: File clear - do file clear
1Ah: File clear - clear completed
1Bh: File clear to main - fade out
1Ch: File clear to main - reload main
1Dh: File clear to main - fade in
1Eh: File clear to main - menu index = main
1Fh: Main to options menu - turn Samus helmet
20h: Main to options menu - fade out
21h: Main to title sequence
}
File select map:
{
0: Game options to area select map - clear BG2 and set up fade out
1: Game options to area select map - fade out and load area palettes
2: Game options to area select map - load foreground tilemap
3: Game options to area select map - load background tilemap
4: Game options to area select map - prepare expanding/contracting square transition
5: Game options to area select map - expanding square transition
6: Area select map
7: Area select map to room select map - prepare expanding square transition
8: Area select map to room select map - expanding square transition
9: Area select map to room select map - initialise
Ah: Room select map
Bh: Room select map to loading game data - wait 2 frames before fade out
Ch: Room select map to loading game data - wait 1 frame before fade out
Dh: Room select map to loading game data - fade out
Eh: Room select map to loading game data - wait
Fh: Room select map to area select map - clear BG1 tilemap
10h: Room select map to area select map - load palettes
11h: Room select map to area select map - load foreground tilemap
12h: Room select map to area select map - load background tilemap
13h: Room select map to area select map - prepare expanding/contracting square transition
14h: Room select map to area select map - prepare contracting square transition
15h: Room select map to area select map - contracting square transition
16h: Area select map to game options
}
Pause menu:
{
0: Map screen
1: Equipment screen
2: Map screen to equipment screen - fading out
3: Map screen to equipment screen - load equipment screen
4: Map screen to equipment screen - fading in
5: Equipment screen to map screen - fading out
6: Equipment screen to map screen - load map screen
7: Equipment screen to map screen - fading in
}
}
$0729..62: Pause menu data
{
$0729: Start / L/R button pressed highlight timer
$072B: L/R highlight animation timer
$072D: Item selector animation timer
$072F: Reserve tank animation timer
$0731: Unused animation timer
$0733: Map scroll up arrow animation timer
$0735: Map scroll down arrow animation timer
$0737: Map scroll right arrow animation timer
$0739: Map scroll left arrow animation timer
$073B: Pause screen palette animation timer
$073D: Unused animation timer
$073F: L/R highlight animation frame
$0741: Item selector animation frame
$0743: Reserve tank animation frame
$0745: Unused animation frame
$0747: Map scroll up arrow animation frame
$0749: Map scroll down arrow animation frame
$074B: Map scroll right arrow animation frame
$074D: Map scroll left arrow animation frame
$074F: Pause screen palette animation frame
$0751: Shoulder button pressed highlight
{
0: None
1: L
2: R
}
$0753: Pause screen button label mode
{
0: Map screen (SAMUS on the right)
1: Unpausing (nothing)
2: Equipment screen (MAP on the left)
}
$0755: Equipment screen category index
{
0: Tanks
1: Weapons
2: Suit/misc
3: Boots
}
$0756: Equipment screen item index
{
Tanks:
0: Mode
1: Reserve tank
Weapons:
0: Charge
1: Ice
2: Wave
3: Spazer
4: Plasma
Suit/misc:
0: Varia suit
1: Gravity suit
2: Morph ball
3: Bombs
4: Spring ball
5: Screw attack
Boots:
0: Hi-jump boots
1: Space jump
2: Speed booster
}
$0757: Delay counter for reserve tank sound
$0759: Unused animation mode (always 0)
$075B: Map scroll up arrow animation mode (always 0)
$075D: Map scroll down arrow animation mode (always 0)
$075F: Map scroll right arrow animation mode (always 0)
$0761: Map scroll left arrow animation mode (always 0)
}
$0763: Pause screen mode
{
0: Map screen
1: Equipment screen
}
$0765: Backup of $58 during pause menu (BG1 tilemap base address and size)
$0766: Backup of $59 during pause menu (BG2 tilemap base address and size)
$0767: Backup of $5A during pause menu (BG3 tilemap base address and size)
$0768: Backup of $5D during pause menu (BG tiles base address)
$076A: Backup of $52 during pause menu (sprite size and sprite tiles base address)
$076B: Backup of $B1 during pause menu (BG1 X scroll)
$076C: Backup of $B5 during pause menu (BG2 X scroll)
$076D: Backup of $B9 during pause menu (BG3 X scroll)
$076E: Backup of $B3 during pause menu (BG1 Y scroll)
$076F: Backup of $B7 during pause menu (BG2 Y scroll)
$0770: Backup of $BB during pause menu (BG3 Y scroll)
$0771: Backup of $55 during pause menu (mode and BG tile size)
$0772: Backup of $091B during pause menu (layer 2 scroll X)
$0773: Backup of $091C during pause menu (layer 2 scroll Y)
$0774: Backup of $57 during pause menu (mosaic size and enable)
$0775: Backup of $71 during pause menu (next gameplay colour math control register B)
$0776: Samus position indicator animation frame
$0778: Samus position indicator animation timer
$077A: Samus position indicator animation loop counter. Bit 0 is used to toggle Samus icon display in file select map
$077C..0997: Main gameplay RAM (according to $82:8593)
{
$077C: HUD item tilemap palette bits in $80:9CEA
$0783: Mode 7 flag
$0785: Unused. Mode 7 rotation angle in $80:B032/B0C2 (in units of 2pi/100h radians)
$0787: Set to 0 when loading file select map foreground tilemap. Never read
$0789: Current area map collected flag. Effectively a mirror of the $7E:D908 byte for the current area, some code checks this variable, some code checks the other one.
$078B: Load station index
$078D: Door pointer
$078F: Door BTS
$0791: Door direction
{
0: Right
1: Left
2: Down
3: Up
+4: Close a door on next screen
}
$0793: Elevator door properties. The high byte is incidentally set to door direction, but never read
{
0ih: Marks debug elevator index i as used (always 0)
40h: Switch map to new area
80h: Door is an elevator
}
$0795: Door transition flag (used by elevators and zebetites)
$0797: Door transition flag (used by other enemies and pause check)
$0799: Elevator direction
{
0: Down
8000h: Up
}
$079B: Room pointer
$079D: Room index
$079F: Area index
{
0: Crateria
1: Brinstar
2: Norfair
3: Wrecked Ship
4: Maridia
5: Tourian
6: Ceres
7: Debug
}
$07A1: Room X co-ordinate (on map)
$07A3: Room Y co-ordinate (on map)
$07A5: Room width in blocks
$07A7: Room height in blocks
$07A9: Room width in scrolls (XBA to get room width in pixels)
$07AB: Room height in scrolls (XBA to get room height in pixels)
$07AD: Up scroller
$07AF: Down scroller
$07B1: Previous CRE bitset
$07B3: CRE bitset
{
1: Disable BG1 during door transitions both into and out of the room
2: Reload CRE (decompress CRE tiles and CRE tile table, transfer CRE tiles and BG3 tiles to VRAM)
4: Load extra large tileset (transfer custom tiles and BG3 tiles to VRAM)
}
$07B5: Door list pointer
$07B7: Event pointer (used when testing room state conditions)
$07B9: Level data size
$07BB: Room state pointer
$07BD: Level data pointer
$07C0: Tileset tile table pointer
$07C3: Tileset tiles pointer
$07C6: Tileset palette pointer
$07C9: Room music track index
$07CB: Room music data index
$07CD: FX pointer
$07CF: Enemy population pointer
$07D1: Enemy set pointer
$07D3..DE: Unused
$07DF: Room main ASM pointer
$07E1..E8: Room main ASM variables
{
$07E1:
{
Diagonal quake timer for escape room 2/4
Elevatube subposition
Rotation matrix index for Ceres escape elevator shaft
Debris delay timer for Ceres pre-elevator hall
}
$07E3:
{
Earthquake type for escape room 2/4
Elevatube position
Rotation matrix timer for Ceres escape elevator shaft
}
$07E5: Elevatube velocity. Unit 1/100h px/frame
$07E7: Elevatube acceleration. Unit 1/100h px/frame²
}
$07E9: Scrolling finished hook. Bank $90. Set to $9589 during the Spore Spawn fight to keep the camera from moving up
$07EB..EC: HDMA data table during Ceres elevator and Ceres Ridley mode 7 sections
{
$07EB: Video mode for HUD and floor (mode 1)
$07EC: Video mode for mode 7 section (mode 7)
}
$07ED..F2: Unused
$07F3: Music data index. Used to compare with new room music track index in door transition for loading music.
$07F5: Music track index. Used as music track to restore after item/Samus fanfare, and to compare with new room music track index in door transition for loading music.
$07F7..08F6: Map tiles explored (for current area). One bit per room. Laid out like a 64x32 1bpp VRAM tilemap: 2x1 pages of 32x32 map tiles (80h bytes per page, 4 bytes per row, 1 bit per tile), each byte is 8 map tiles where the most significant bit is the leftmost tile. The first row is padding and skipped during index calculation ($90:A8A6), that is, room (0, 0) maps to $07FB rather than $07F7
$08F7: Layer 1 X block (layer 1 X position / 10h)
$08F9: Layer 1 Y block
$08FB: Layer 2 X block
$08FD: Layer 2 Y block
$08FF: Previous layer 1 X block
$0901: Previous layer 1 Y block
$0903: Previous layer 2 X block
$0905: Previous layer 2 Y block
$0907: BG1 X block
$0909: BG1 Y block
$090B: BG2 X block
$090D: BG2 Y block
$090F: Layer 1 X subposition
$0911: Layer 1 X position
$0913: Layer 1 Y subposition
$0915: Layer 1 Y position
$0917: Layer 2 X position
$0919: Layer 2 Y position
$091B: Layer 2 scroll X (bit 0 set means library background is used)
$091C: Layer 2 scroll Y (bit 0 set means library background is used)
$091D: BG1 X offset. Base translation between BG and layer positions, [BG1 X scroll] = [layer 1 X position] + [BG1 X offset]. Doesn't account for earthquake or layer 2 bosses.
$091F: BG1 Y offset. Base translation between BG and layer positions, [BG1 Y scroll] = [layer 1 Y position] + [BG1 Y offset]. Doesn't account for earthquake or layer 2 bosses.
$0921: BG2 X offset. Base translation between BG and layer positions, [BG2 X scroll] = [layer 2 X position] + [BG2 X offset]. Doesn't account for earthquake or layer 2 bosses.
$0923: BG2 Y offset. Base translation between BG and layer positions, [BG2 Y scroll] = [layer 2 Y position] + [BG2 Y offset]. Doesn't account for earthquake or layer 2 bosses.
$0925: Door transition frame counter. Stops at 40h for horizontal doors, 39h for vertical doors
$0927: Door destination X position. Multiple of 100h (screens)
$0929: Door destination Y position. Multiple of 100h (screens). Adjusted by 20h when moving up
$092B: Samus subspeed during door transition
$092D: Samus speed during door transition. Defaults to 0.C8h for horizontal and 1.80h for vertical, but can be overridden by "distance from door" in door header
$092F: Downwards elevator delay timer. Initialised to 30h. This is what lets Samus scroll off-screen before performing door transition on downwards elevators
$0931: Flag. 8000h = door transition has finished scrolling
$0933:
{
Position of right/left scroll boundary in $80:A528
VRAM offset of blocks to update in $80:A9DE/$80:AB75
[VRAM blocks to update X block] & 0Fh in $80:AB75
}
$0935: X block of VRAM blocks to update (after masking with 1Fh) in $80:A9DE/$80:AB75
$0937:
{
Base address of VRAM tilemap screen in $80:A9DE
Index of VRAM tilemap source data in $80:A9DE
Base address of wrapped VRAM tilemap screen in $80:AB75
}
$0939:
{
Proposed scrolled layer 1 X position in $80:A528/A641/A6BB. [layer 1 X position] ± (X distance Samus moved + 1/3)
Loop counter in $80:A9DE
}
$093B: Block to update (in $7F) in $80:A9DE/$80:AB75
$093D: Unused
$093F: Ceres status
{
0: Before Ridley escape
1: During Ridley escape cutscene
2: During escape sequence
8000h: When elevator room rotates
}