Edit: See our level scripts wiki page here
https://wiki.origami64.net/super_mario_64/level_commands
We could use a level script engine thread
Commands: (with dirty pseudo code notes)
0x00 (8037E2C4): Load raw data to RAM segment and jump
00 10 00 [XX] [YY YY YY YY] [ZZ ZZ ZZ ZZ] [AA AA AA AA]
X = RAM segment number
Y = ROM address start
Z = ROM address end
A = Segment offset of jump target
Used for loading level scripts and then jumping to an offset in them
Does stuff with 8039b8b0,b8b4
Call 802783E8
Call 8027868C (A0 = X, A1 = Y, A2 = Z, A3 = 0)
Call 80277F50 (A0 = A)
Command pointer = return value
______________________________________________________________________________________________________
0x01 (8037E388): Load raw data to RAM segment and jump
01 10 00 [XX] [YY YY YY YY] [ZZ ZZ ZZ ZZ] [AA AA AA AA]
X = RAM segment number
Y = ROM address start
Z = ROM address end
A = Segment offset of jump target
The only difference between this command and 0x00 is a call to 0x80278498
Does stuff with 8039b8b0,b8b4
Call 80278498
Call 802783E8
Call 8027868C (A0 = X, A1 = Y, A2 = Z, A3 = 0)
Call 80277F50 (A0 = A)
Command pointer = return value
______________________________________________________________________________________________________
0x02 (8037E404): ?
02 04 00 00
Always followed by null padding, last command in a script?
performs a jump using 8038b8a0,b8b4
______________________________________________________________________________________________________
0x03 (8037E47C): ?
0x04 (8037E4FC): ?
0x05 (8037E580): ?
0x06 (8037E5B8): ?
______________________________________________________________________________________________________
0x07 (8037E620): ?
t6 = w@ 8038B8B0
t7 = (t6 - 4)
w@ 8038B8B0 = t7
Command pointer = w@ t7
______________________________________________________________________________________________________
0x08 (8037E650): ?
0x09 (8037E6D4): ?
0x0A (8037E780): ?
0x0B (8037E7F8): ?
0x0C (8037E878): ?
0x0D (8037E8E8): ?
______________________________________________________________________________________________________
0x0E (8037E988): ?
0E 08 [XX] 00 [YY YY YY YY]
______________________________________________________________________________________________________
0x0F (8037EA18): Skip next command ??
0F [XX] ...
Increment command pointer by X
If next command is 0x10, recurse
Else, skip next command
______________________________________________________________________________________________________
0x10 (8037EA70): No operation
10 [XX] ...
Increment command pointer by X
______________________________________________________________________________________________________
0x11 (8037EA98): Call assembly routine once
11 08 [XX XX] [YY YY YY YY]
Call assembly routine Y (A0 = word from 0x8038BE24, A1 = halfword X)
Store return value at 0x8038BE24
Game startup: 8016F5B0
File select: 801766DC
File select -> Castle grounds: 8024BD5C
Other levels: 8024BE14, 8024BCD8
______________________________________________________________________________________________________
0x12 (8037EB04): Actively call assembly routine
12 08 [XX XX] [YY YY YY YY]
Call assembly routine Y (A0 = word from 0x8038BE24, A1 = halfword X)
Store return value at 0x8038BE24
If return value is 0, set upper halfword @ 0x8039BE20 = 0 and do not continue to next command
Else, set upper halfword @ 0x8039BE20 = 1 and continue to the next command
Demo screen: 8016F5B0
File select: 801768A0
Other levels: 8024BCD8
______________________________________________________________________________________________________
0x13 (8037EB98): Set accumulator value
13 04 [XX XX]
Store X at 0x8038BE24 (32bit)
______________________________________________________________________________________________________
0x14 (8037EBD4): ?
14 04 00 00
Call 0x802783E8
______________________________________________________________________________________________________
0x15 (8037EC14): ?
15 04 00 00
Call 0x80278498
______________________________________________________________________________________________________
0x16 (8037EC54): Load raw data from ROM to absolute RAM address
16 10 00 00 [XX XX XX XX] [YY YY YY YY] [ZZ ZZ ZZ ZZ]
X = RAM address
Y = ROM address start
Z = ROM address end
Call 0x802786F0 (A0 = X, A1 = Y, A2 = Z)
______________________________________________________________________________________________________
0x17 (8037ECA4): Load raw data from ROM to RAM segment (The segment table is at 8033B400 in RAM)
17 0C 00 [XX] [YY YY YY YY] [ZZ ZZ ZZ ZZ]
X = RAM segment number
Y = ROM address start
Z = ROM address end
______________________________________________________________________________________________________
0x18 (8037ECF8): Load and decompress MIO0 data from ROM to RAM segment
18 0C 00 [XX] [YY YY YY YY] [ZZ ZZ ZZ ZZ]
X = RAM segment number
Y = ROM address start
Z = ROM address end
______________________________________________________________________________________________________
0x19 (8037ED48): Create Mario face for the demo screen
19 04 00 [XX]
X Settings: 01 No face, 02 Regular face, 03 Game over face
Call 0x80278120 (A0 = 0x000E1000, A1 = 0); allocate 0xE1000 bytes for mario face settings
If allocation was successful:
Call 0x8019C450(A0 = 0x000E1000, A1 = pointer to allocated area in ram)
Call 0x8019C418(A0 = 0x80000400, A1 = 0x00025800)
Call 0x8019C418(A0 = 0x8039F800, A1 = 0x00070800)
Call 0x8019C4EC ; data gets loaded into 80000400 and 8039F800 after this call
Call 0x8019C684(A0 = X)
______________________________________________________________________________________________________
0x1A (8037EDF8): Load and decompress MIO0 data from ROM to RAM segment (level terrain textures)
1A 0C 00 [XX] [YY YY YY YY] [ZZ ZZ ZZ ZZ]
X = RAM segment number
Y = ROM address start
Z = ROM address end
______________________________________________________________________________________________________
0x1B (8037EE48): Start load sequence
1B 04 00 00
Used before a chain of load commands
Call 0x8037B448 (A0 = 0, A1 = 0x8038BD88)
Call 0x8029D1E8
Call 0x8027AB04
Call 0x802783E8
______________________________________________________________________________________________________
0x1C (8037EEA8): ?? always follows 0x12 command
1C 04 00 00
Call 0x8029D1E8
Call 0x8027AD74
Call 0x80278498
______________________________________________________________________________________________________
0x1D (8037EF00): End load sequence
1D 04 00 00
Used after a chain of load commands
If word @ 0x8038B8A0 is not 0 then:
Call 0x802783C8
S0 = return value
Call 0x80278A14 (A0 = S0+0xFFF0, A1 = 0)
Store return value at 0x8038B8A0
______________________________________________________________________________________________________
0x1E (8037EF70):
______________________________________________________________________________________________________
0x1F (8037F010): Start of an area
1F 08 [XX] 00 [YY YY YY YY]
XX = Area number
YY = Segment offset address of geometry layout
______________________________________________________________________________________________________
0x20 (8037F130): End of an area
Set upper halfword @ 8038B8AC = 0xFFFF
______________________________________________________________________________________________________
0x21 (8037F164): Load polygon data without a geometry layout
21 08 [??] [ID] [XX XX XX XX]
?? = Unknown use. I've seen it so far as: 0x10, 0x40, 0x50, and 0x60.
ID = Id of the model to be used with 3D objects.
XX = Segment offset address
______________________________________________________________________________________________________
0x22 (8037F214): Loads polygon data with a geometry layout
22 08 00 [ID] [XX XX XX XX]
ID = Id of the model to be used with 3D objects.
XX = Segment offset address
______________________________________________________________________________________________________
0x23 (8037F2A4):
______________________________________________________________________________________________________
0x24 (8037F45C): Places a 3D object in the level
24 18 [AA] [ID] [XX XX] [YY YY] [ZZ ZZ] [RX RX] [RY RY] [RZ RZ] [B1 B1] [B2 B2] [BS] [BO BO BO]
AA = Act(s) in which this object will appear in (Binary value)
ID = Id of the model to use for this object. (Defined by commands 0x21 and 0x22)
XX = X position of object (Signed 16-bits)
YY = Y position of object (Signed 16-bits)
ZZ = Z position of object (Signed 16-bits)
RX = Rotation across X axis (Signed 16-bits)
RY = Rotation across Y axis (Signed 16-bits)
RZ = Rotation across Z axis (Signed 16-bits)
B1 = Behavior parameter 1
B2 = Behavior parameter 2
BS = Ram segment for behavior script
BO = Offset of the ram segment
______________________________________________________________________________________________________
0x25 (8037F36C): Loads the Mario Object
Always: 25 0C 00 01 00 00 00 01 13 00 2E C0
25 0C 00 [ID] [?? ?? ?? ??] [XX XX XX XX]
ID = Id of the model to use for Mario. (Defined by commands 0x21 and 0x22)
?? = Some parameters, not sure what they do.
XX = Segment offset address of behavior script
______________________________________________________________________________________________________
0x26 (8037F67C): Connect warps
26 08 [AA] [BB] [CC] [DD] 00 00
AA = Warp ID to jump from (warp ID's are defined with some previous 0x24 commands using specific behaviors)
BB = Course ID number to warp to (Course ID's are defined from previous 0x0C commands)
CC = Course area to jump to
DD = Warp ID number in destination level area
______________________________________________________________________________________________________
0x27 (8037F994): Define level warps for paintings inside the Castle
27 08 [AA] [BB] [CC] [DD] 00 00
AA = Warp ID to jump from (warp ID's are defined with some previous 0x24 commands using specific behaviors)
BB = Course ID number to warp to (Course ID's are defined from previous 0x0C commands)
CC = Course area to jump to
DD = Warp ID number in destination level area
______________________________________________________________________________________________________
0x28 (8037F790): Transport Mario to an area
28 0C [??] [AA] [XX XX] [YY YY] [ZZ ZZ] 00 00
?? = I don't know what this byte does exactly.
AA = Course area # to go to
XX = Teleport Mario by this amount on the X axis (Signed 16-bits)
YY = Teleport Mario by this amount on the Y axis (Signed 16-bits)
ZZ = Teleport Mario by this amount on the Z axis (Signed 16-bits)
______________________________________________________________________________________________________
0x29 (80380014):
______________________________________________________________________________________________________
0x2A (8038007C):
2A 04 00 00
Call 0x8027AF48
______________________________________________________________________________________________________
0x2B (803800BC):
______________________________________________________________________________________________________
0x2C (80380160):
2C 04 00 00
Call 0x8027B038
______________________________________________________________________________________________________
0x2D (803801A0):
2D 04 00 00
Call 0x8027B164
______________________________________________________________________________________________________
0x2E (8037FE94):
______________________________________________________________________________________________________
0x2F (8037FF14): Decides which area of the level geometry to render
2F 08 00 00 [XX XX XX XX]
XX = Segment offset pointer to ??
______________________________________________________________________________________________________
0x30 (80380274):
______________________________________________________________________________________________________
0x31 (8037F920): Set default terrain
31 04 00 [XX]
XX = 00 Normal A, 01 Normal B, 02 Snow, 03 Sand, 04 Haunted house, 05 Water levels, 06 Slippery Slide
If 0x8038B8AC is 0xFFFF continue to next command
______________________________________________________________________________________________________
0x32 (8038024C): No operation
32 [XX] ...
Increment command pointer by X
______________________________________________________________________________________________________
0x33 (803801E0): Fade/overlay screen with color
33 08 [XX] [YY] [RR] [GG] [BB] 00
X = 01 Enable, 00 Disable
Y = Controls duration? usually 0x10
R,G,B = rgb colors
Call 0x8027B1A0 (A0 = X, A1 = Y, A2 = Z, A3 = A, sp_x10 = B)
______________________________________________________________________________________________________
0x34 (8037FDE4):
34 04 [XX] 00
Call 0x80323340 (A0 = X)
______________________________________________________________________________________________________
0x35 (8037FE2C):
35 04 [XX] 00
If X is 0, call 0x803733B0 (A0 = 2)
Else, call 0x803733B0 (A0 = 1)
______________________________________________________________________________________________________
0x36 (80380300): Set music
t0 = w@ 8038B8AC
t7 = w@ 8038BE28
t9 = w@ 8032DDC8
______________________________________________________________________________________________________
0x37 (8038039C): Set music
37 04 00 [XX]
X = Song ID
Call 0x80249178 (A0 = 0, A1 = X, A2 = 0)
______________________________________________________________________________________________________
0x38 (803803EC):
38 04 [XX XX]
Call 0x8024922C (A0 = X)
______________________________________________________________________________________________________
0x39 (8037FF94): Place macro objects
39 08 00 00 [XX XX XX XX]
X = Segment offset pointer to object placement list
List format: (each entry is 10 bytes)
[BB BB] [XX XX] [YY YY] [ZZ ZZ] [?? ??]
B = Object type ID (behavior, model, etc)
X,Y,Z = Coordinates
?? = Always 00 00 ?
______________________________________________________________________________________________________
0x3A (8037FB18):
0x3B (8037FC38):
0x3C (80380434):
Engine variables:
8038BE20: Statuses?
8038BE24: Accumulator
8038BE28: Pointer to current command
8038B8A0: ?
8038B8AC: ?
8038B8B0: Primary stack pointer
8038B8B4: Secondary stack pointer?
Relevant functions:
803805C8: Command interpreter
Arguments (A0 = pointer to command) ; uses the jump table at 8038B8B0
~~~~
80277F50: Uses the segments table to convert a given segment offset address to a RAM address
Arguments (A0 = segment offset address)
Returns (V0 = RAM address)
802783E8: () ?
80278498: () ?
802786F0: Load raw data to RAM address
Arguments (A0 = RAM address, A1 = ROM address start, A2 = ROM address end)