Custom 0x12 Behavior Command

JAL to value inside a level bank using the virtual_to_segmented Function:

0x0C Behavior Command:

80384678: ADDIU SP, SP, 0xFFE0
8038467C: SW RA, 0x0014 (SP)
80384680: LUI T6, 0x8036
80384684: LW T6, 0x1164 (T6)
80384688: LW T7, 0x0004 (T6) <-- Load argument from 0x0C command = RAM Pointer
8038468C: SW T7, 0x001C (SP) <-- Store in Stack
80384690: LW T9, 0x001C (SP) <-- Copy to T9
80384694: JALR RA, T9        <-- JAL to Register T9
80384698: NOP
8038469C: LUI T8, 0x8036
803846A0: LW T8, 0x1164 (T8)
803846A4: LUI AT, 0x8036
803846A8: ADDIU T0, T8, 0x0008
803846AC: SW T0, 0x1164 (AT)
803846B0: BEQ R0, R0, 0x803846C0
803846B4: OR V0, R0, R0      <--  return 0;
803846B8: BEQ R0, R0, 0x803846C0
803846BC: NOP
803846C0: LW RA, 0x0014 (SP)
803846C4: ADDIU SP, SP, 0x0020
803846C8: JR RA
803846CC: NOP


(from cellar dweller's notes)

/* 0x80277f50 */
void * segmented_to_virtual(uint32 addr)
{
    seg = addr >> 24;
    off = addr & 0x00ffffff;

    return (segment_table[seg] + off) | 0x8000000;
}

A0 = Segmented Address
V0 = Virtual Address (machine address + 0x80000000);

0x12 Custom command
----------------------------------

This replaces an apparently unused behavior function with a modified version of the 0x0C:

80384E04: ADDIU SP, SP, 0xFFE0
80384E08: SW RA, 0x0014 (SP)
80384E0C: LUI T6, 0x8036
80384E10: LW T6, 0x1164 (T6)
80384E14: LW T7, 0x0004 (T6) <-- Load argument from 0x0C command = RAM Pointer
80384E18: SW T7, 0x001C (SP) <-- Store in Stack
80384E1C: LW T9, 0x001C (SP) <-- Copy to T9 [ not needed?]

[modified code]

80384E20: JAL 0x80277F50     <-- Segmented to Virtual function
80384E24: LW A0, 0x001C (SP) <-- Copy argument to register A0
80384E28: SW V0, 0x001C (SP) <-- Save in stack [Not sure if it's necessary needed]
80384E2C: JALR RA, V0        <-- JAL to Register V0

[continues with normal code copied from 0x0C command]

80384E30: NOP
80384E34: LUI T8, 0x8036
80384E38: LW T8, 0x1164 (T8)
80384E3C: LUI AT, 0x8036
80384E40: ADDIU T0, T8, 0x0008
80384E44: SW T0, 0x1164 (AT)
80384E48: BEQ R0, R0, 0x803846C0
80384E4C: OR V0, R0, R0      <--  return 0;
80384E50: BEQ R0, R0, 0x803846C0
80384E54: NOP
80384E58: LW RA, 0x0014 (SP)
80384E5C: ADDIU SP, SP, 0x0020
80384E60: JR RA
80384E64: NOP

in ROM, 0x101B84. Assembled:

27BDFFE0
AFBF0014
3C0E8036
8DCE1164
8DCF0004
AFAF001C
8FB9001C
0C09DFD4
8FA4001C
AFA2001C
0040F809
24000000
3C188036
8F181164
3C018036
27080008
AC281164
10000003
00001025
10000001
24000000
8FBF0014
27BD0020
03E00008
24000000


[original 0x12 unused code:]

80384E04: ADDIU SP, SP, 0xFFF8
80384E08: LUI T6, 0x8036
80384E0C: LW T6, 0x1164 (T6)
80384E10: LW T7, 0x0000 (T6)
80384E14: SRL T8, T7, 0x10
80384E18: ANDI T9, T8, 0x00FF
80384E1C: SB T9, 0x0007 (SP)
80384E20: LUI T0, 0x8036
80384E24: LW T0, 0x1164 (T0)
80384E28: LW T1, 0x0000 (T0)
80384E2C: ANDI T2, T1, 0xFFFF
80384E30: SLL T3, T2, 0x10
80384E34: SRA T4, T3, 0x10
80384E38: SW T4, 0x0000 (SP)
80384E3C: LW T5, 0x0000 (SP)
80384E40: ANDI T6, T5, 0xFFFF
80384E44: XORI T7, T6, 0xFFFF
80384E48: SW T7, 0x0000 (SP)
80384E4C: LBU T9, 0x0007 (SP)
80384E50: LUI T8, 0x8036
80384E54: LW T8, 0x1160 (T8)
80384E58: SLL T0, T9, 0x2
80384E5C: LW T3, 0x0000 (SP)
80384E60: ADDU T1, T8, T0
80384E64: LW T2, 0x0088 (T1)
80384E68: AND T4, T2, T3
80384E6C: SW T4, 0x0088 (T1)
80384E70: LUI T5, 0x8036
80384E74: LW T5, 0x1164 (T5)
80384E78: LUI AT, 0x8036
80384E7C: ADDIU T6, T5, 0x0004
80384E80: SW T6, 0x1164 (AT)
80384E84: BEQ R0, R0, 0x80384E94
80384E88: OR V0, R0, R0
80384E8C: BEQ R0, R0, 0x80384E94
80384E90: NOP
80384E94: JR RA
80384E98: ADDIU SP, SP, 0x0008



Comments