Move 'source' asm files to src
This commit is contained in:
-240
@@ -1,240 +0,0 @@
|
||||
.include "constants/gba_constants.inc"
|
||||
.include "constants/misc_constants.inc"
|
||||
.include "constants/version.inc"
|
||||
|
||||
.syntax unified
|
||||
|
||||
.global Start
|
||||
|
||||
.text
|
||||
|
||||
.arm
|
||||
|
||||
_start: @ 8000000
|
||||
b start_vector
|
||||
|
||||
.include "asm/rom_header.inc"
|
||||
|
||||
@ 80000C0
|
||||
.word 0
|
||||
|
||||
.global GPIOPortData
|
||||
GPIOPortData: @ 80000C4
|
||||
.hword 0
|
||||
|
||||
.global GPIOPortDirection
|
||||
GPIOPortDirection: @ 80000C6
|
||||
.hword 0
|
||||
|
||||
.global GPIOPortReadEnable
|
||||
GPIOPortReadEnable: @ 80000C8
|
||||
.hword 0
|
||||
|
||||
.space 6
|
||||
|
||||
@ 80000D0
|
||||
|
||||
.4byte 0xFFFFFFFF
|
||||
.4byte 0xFFFFFFFF
|
||||
.4byte 0xFFFFFFFF
|
||||
.4byte 0xFFFFFFFF
|
||||
.4byte 0xFFFFFFFF
|
||||
.4byte 0xFFFFFFFF
|
||||
.4byte 0xFFFFFFFF
|
||||
.4byte 0xFFFFFFFF
|
||||
.4byte 0xFFFFFFFF
|
||||
.4byte 0xFFFFFFFF
|
||||
.4byte 0xFFFFFFFF
|
||||
.4byte 0xFFFFFFFF
|
||||
|
||||
@ 8000100
|
||||
.global CartIdent
|
||||
CartIdent:
|
||||
.4byte GAME_VERSION
|
||||
.4byte GAME_LANGUAGE
|
||||
.game_name:
|
||||
.ifdef FIRERED
|
||||
.ascii "pokemon red version"
|
||||
.else
|
||||
.ifdef LEAFGREEN
|
||||
.ascii "pokemon green version"
|
||||
.endif
|
||||
.endif
|
||||
.space .game_name+0x20-.
|
||||
.4byte gMonFrontPicTable
|
||||
.4byte gMonBackPicTable
|
||||
.4byte gMonPaletteTable
|
||||
.4byte gMonShinyPaletteTable
|
||||
.4byte gMonIconTable
|
||||
.4byte gMonIconPaletteIndices
|
||||
.4byte gMonIconPaletteTable
|
||||
.4byte gSpeciesNames
|
||||
.4byte gMoveNames
|
||||
.4byte gDecorations
|
||||
.4byte 0xEE0 @ offsetof(struct SaveBlock1, flags)
|
||||
.4byte 0x1000 @ offsetof(struct SaveBlock1, vars)
|
||||
.4byte 0x18 @ offsetof(struct SaveBlock2, pokedex)
|
||||
.4byte 0x5F8 @ offsetof(struct SaveBlock1, seen1)
|
||||
.4byte 0x3A18 @ offsetof(struct SaveBlock1, seen2)
|
||||
.4byte 0x3C
|
||||
.4byte 0x838
|
||||
.4byte 0x839
|
||||
.4byte 0x182
|
||||
.4byte 0xA0A0A07
|
||||
.4byte 0xC060C0C
|
||||
.4byte 0xC121006
|
||||
.4byte 0x8010B0F
|
||||
.4byte 0xC
|
||||
.4byte 0xF24 @ sizeof(struct SaveBlock2)
|
||||
.4byte 0x3D68 @ sizeof(struct SaveBlock1)
|
||||
.4byte 0x34 @ offsetof(struct SaveBlock1, playerPartyCount)
|
||||
.4byte 0x38 @ offsetof(struct SaveBlock1, playerParty)
|
||||
.4byte 9 @ offsetof(struct SaveBlock2, specialSaveWarp)
|
||||
.4byte 0xA @ offsetof(struct SaveBlock2, playerTrainerId)
|
||||
.4byte 0 @ offsetof(struct SaveBlock2, playerName)
|
||||
.4byte 8 @ offsetof(struct SaveBlock2, playerGender)
|
||||
|
||||
.4byte 0xAD @ offsetof(struct SaveBlock2, ?????? (0xAD))
|
||||
.4byte 0xAD @ offsetof(struct SaveBlock2, ?????? (0xAD))
|
||||
.4byte 0x30BB
|
||||
.4byte 0x30A7
|
||||
.4byte 0
|
||||
.4byte gBaseStats
|
||||
.4byte gAbilityNames
|
||||
.4byte gAbilityDescriptionPointers
|
||||
.4byte gItems
|
||||
.4byte gBattleMoves
|
||||
.4byte gBallSpriteSheets
|
||||
.4byte gBallSpritePalettes
|
||||
.4byte 0xA8
|
||||
.4byte 0x82C
|
||||
.4byte 0x83B
|
||||
.4byte 0x3A0D1E2A
|
||||
.4byte 0x1E2B
|
||||
.4byte 0x298 @ offsetof(struct SaveBlock1, pcItems) // maybe all items were in a struct together?
|
||||
.4byte 0x309C @ offsetof(struct SaveBlock1, giftRibbons)
|
||||
.4byte 0x30EC @ offsetof(struct SaveBlock1, enigmaBerry)
|
||||
.4byte 0x34 @ size of SaveBlock1 map header reconstruction data?
|
||||
.4byte 0
|
||||
.4byte 0xFFFFFFFF
|
||||
|
||||
.arm
|
||||
.align 2, 0
|
||||
.global start_vector
|
||||
start_vector:
|
||||
mov r0, #PSR_IRQ_MODE
|
||||
msr cpsr_cf, r0
|
||||
ldr sp, sp_irq
|
||||
mov r0, #PSR_SYS_MODE
|
||||
msr cpsr_cf, r0
|
||||
ldr sp, sp_usr
|
||||
ldr r1, =INTR_VECTOR
|
||||
adr r0, intr_main
|
||||
str r0, [r1]
|
||||
ldr r1, =AgbMain
|
||||
mov lr, pc
|
||||
bx r1
|
||||
b start_vector
|
||||
|
||||
.align 2, 0
|
||||
sp_usr: .word IWRAM_END - 0x1C0
|
||||
sp_irq: .word IWRAM_END - 0x60
|
||||
|
||||
.pool
|
||||
|
||||
.arm
|
||||
.align 2, 0
|
||||
.global intr_main
|
||||
intr_main:
|
||||
mov r3, #REG_BASE
|
||||
add r3, r3, #OFFSET_REG_IE
|
||||
ldr r2, [r3]
|
||||
ldrh r1, [r3, #REG_IME - REG_IE]
|
||||
mrs r0, spsr
|
||||
stmdb sp!, {r0-r3,lr}
|
||||
mov r0, #0
|
||||
strh r0, [r3, #REG_IME - REG_IE]
|
||||
and r1, r2, r2, lsr #16
|
||||
mov r12, #0
|
||||
ands r0, r1, #INTR_FLAG_VCOUNT
|
||||
bne jump_intr
|
||||
add r12, r12, 0x4
|
||||
mov r0, 0x1
|
||||
strh r0, [r3, #REG_IME - REG_IE]
|
||||
ands r0, r1, #INTR_FLAG_SERIAL
|
||||
bne jump_intr
|
||||
add r12, r12, 0x4
|
||||
ands r0, r1, #INTR_FLAG_TIMER3
|
||||
bne jump_intr
|
||||
add r12, r12, 0x4
|
||||
ands r0, r1, #INTR_FLAG_HBLANK
|
||||
bne jump_intr
|
||||
add r12, r12, 0x4
|
||||
ands r0, r1, #INTR_FLAG_VBLANK
|
||||
bne jump_intr
|
||||
add r12, r12, 0x4
|
||||
ands r0, r1, #INTR_FLAG_TIMER0
|
||||
bne jump_intr
|
||||
add r12, r12, 0x4
|
||||
ands r0, r1, #INTR_FLAG_TIMER1
|
||||
bne jump_intr
|
||||
add r12, r12, 0x4
|
||||
ands r0, r1, #INTR_FLAG_TIMER2
|
||||
bne jump_intr
|
||||
add r12, r12, 0x4
|
||||
ands r0, r1, #INTR_FLAG_DMA0
|
||||
bne jump_intr
|
||||
add r12, r12, 0x4
|
||||
ands r0, r1, #INTR_FLAG_DMA1
|
||||
bne jump_intr
|
||||
add r12, r12, 0x4
|
||||
ands r0, r1, #INTR_FLAG_DMA2
|
||||
bne jump_intr
|
||||
add r12, r12, 0x4
|
||||
ands r0, r1, #INTR_FLAG_DMA3
|
||||
bne jump_intr
|
||||
add r12, r12, 0x4
|
||||
ands r0, r1, #INTR_FLAG_KEYPAD
|
||||
bne jump_intr
|
||||
add r12, r12, 0x4
|
||||
ands r0, r1, #INTR_FLAG_GAMEPAK
|
||||
strbne r0, [r3, #REG_SOUNDCNT_X - REG_IE]
|
||||
loop:
|
||||
bne loop @ spin
|
||||
jump_intr:
|
||||
strh r0, [r3, #REG_IF - REG_IE]
|
||||
bic r2, r2, r0
|
||||
ldr r0, =gSTWIStatus
|
||||
ldr r0, [r0]
|
||||
ldrb r0, [r0, 0xA]
|
||||
mov r1, #INTR_FLAG_TIMER0
|
||||
lsl r0, r1, r0
|
||||
orr r0, r0, #INTR_FLAG_GAMEPAK
|
||||
orr r1, r0, #INTR_FLAG_SERIAL | INTR_FLAG_TIMER3 | INTR_FLAG_VCOUNT | INTR_FLAG_HBLANK
|
||||
and r1, r1, r2
|
||||
strh r1, [r3, #0]
|
||||
mrs r3, cpsr
|
||||
bic r3, r3, #PSR_I_BIT | PSR_F_BIT | PSR_MODE_MASK
|
||||
orr r3, r3, #PSR_SYS_MODE
|
||||
msr cpsr_cf, r3
|
||||
ldr r1, =gIntrTable
|
||||
add r1, r1, r12
|
||||
ldr r0, [r1]
|
||||
stmdb sp!, {lr}
|
||||
adr lr, intr_return
|
||||
bx r0
|
||||
intr_return:
|
||||
ldmia sp!, {lr}
|
||||
mrs r3, cpsr
|
||||
bic r3, r3, #PSR_I_BIT | PSR_F_BIT | PSR_MODE_MASK
|
||||
orr r3, r3, #PSR_I_BIT | PSR_IRQ_MODE
|
||||
msr cpsr_cf, r3
|
||||
ldmia sp!, {r0-r3,lr}
|
||||
strh r2, [r3, #0]
|
||||
strh r1, [r3, #REG_IME - REG_IE]
|
||||
msr spsr_cf, r0
|
||||
bx lr
|
||||
|
||||
.pool
|
||||
|
||||
.align 2, 0 @ Don't pad with nop.
|
||||
@@ -1,94 +0,0 @@
|
||||
.include "constants/gba_constants.inc"
|
||||
.include "asm/macros.inc"
|
||||
|
||||
.syntax unified
|
||||
|
||||
.text
|
||||
|
||||
thumb_func_start ArcTan2
|
||||
ArcTan2: @ 81E3B58
|
||||
svc 0xA
|
||||
bx lr
|
||||
thumb_func_end ArcTan2
|
||||
|
||||
thumb_func_start BgAffineSet
|
||||
BgAffineSet: @ 81E3B5C
|
||||
svc 0xE
|
||||
bx lr
|
||||
thumb_func_end BgAffineSet
|
||||
|
||||
thumb_func_start CpuFastSet
|
||||
CpuFastSet: @ 81E3B60
|
||||
svc 0xC
|
||||
bx lr
|
||||
thumb_func_end CpuFastSet
|
||||
|
||||
thumb_func_start CpuSet
|
||||
CpuSet: @ 81E3B64
|
||||
svc 0xB
|
||||
bx lr
|
||||
thumb_func_end CpuSet
|
||||
|
||||
thumb_func_start Div
|
||||
Div: @ 81E3B68
|
||||
svc 0x6
|
||||
bx lr
|
||||
thumb_func_end Div
|
||||
|
||||
thumb_func_start LZ77UnCompVram
|
||||
LZ77UnCompVram: @ 81E3B6C
|
||||
svc 0x12
|
||||
bx lr
|
||||
thumb_func_end LZ77UnCompVram
|
||||
|
||||
thumb_func_start LZ77UnCompWram
|
||||
LZ77UnCompWram: @ 81E3B70
|
||||
svc 0x11
|
||||
bx lr
|
||||
thumb_func_end LZ77UnCompWram
|
||||
|
||||
thumb_func_start MultiBoot
|
||||
MultiBoot: @ 81E3B74
|
||||
movs r1, 0x1
|
||||
svc 0x25
|
||||
bx lr
|
||||
thumb_func_end MultiBoot
|
||||
|
||||
thumb_func_start ObjAffineSet
|
||||
ObjAffineSet: @ 81E3B7C
|
||||
svc 0xF
|
||||
bx lr
|
||||
thumb_func_end ObjAffineSet
|
||||
|
||||
thumb_func_start RegisterRamReset
|
||||
RegisterRamReset: @ 81E3B80
|
||||
svc 0x1
|
||||
bx lr
|
||||
thumb_func_end RegisterRamReset
|
||||
|
||||
thumb_func_start SoftReset
|
||||
SoftReset: @ 81E3B84
|
||||
ldr r3, =REG_IME
|
||||
movs r2, 0
|
||||
strb r2, [r3]
|
||||
ldr r1, =0x03007f00 @ User Stack
|
||||
mov sp, r1
|
||||
svc 0x1
|
||||
svc 0
|
||||
.pool
|
||||
thumb_func_end SoftReset
|
||||
|
||||
thumb_func_start Sqrt
|
||||
Sqrt: @ 81E3B9C
|
||||
svc 0x8
|
||||
bx lr
|
||||
thumb_func_end Sqrt
|
||||
|
||||
thumb_func_start VBlankIntrWait
|
||||
VBlankIntrWait: @ 81E3BA0
|
||||
movs r2, 0
|
||||
svc 0x5
|
||||
bx lr
|
||||
thumb_func_end VBlankIntrWait
|
||||
|
||||
.align 2, 0 @ Don't pad with nop.
|
||||
@@ -1,641 +0,0 @@
|
||||
@ This library can be used to download and execute a multi-boot image from
|
||||
@ a GameCube using the JOY Bus protocol over the link cable.
|
||||
|
||||
.include "asm/macros.inc"
|
||||
.include "constants/constants.inc"
|
||||
|
||||
.equiv GCMB_STRUCT_COUNTER1, 0x00
|
||||
.equiv GCMB_STRUCT_COUNTER2, 0x01
|
||||
.equiv GCMB_STRUCT_MBPROGRESS, 0x02
|
||||
.equiv GCMB_STRUCT_SAVEDVCOUNT, 0x03
|
||||
.equiv GCMB_STRUCT_KEYA, 0x04
|
||||
.equiv GCMB_STRUCT_KEYB, 0x08
|
||||
.equiv GCMB_STRUCT_KEYC, 0x0C
|
||||
.equiv GCMB_STRUCT_BOOT_KEY, 0x10
|
||||
.equiv GCMB_STRUCT_IMAGE_SIZE, 0x12
|
||||
.equiv GCMB_STRUCT_SESSION_KEY, 0x14
|
||||
.equiv GCMB_STRUCT_HASH_VAL, 0x18
|
||||
.equiv GCMB_STRUCT_KEYC_DERIVATION, 0x1C
|
||||
.equiv GCMB_STRUCT_BASE_DEST_PTR, 0x20
|
||||
.equiv GCMB_STRUCT_CUR_DEST_PTR, 0x24
|
||||
.equiv GCMB_STRUCT_SERIAL_INTR_HANDLER, 0x28
|
||||
|
||||
.equiv ROM_HEADER_NINTENDO_LOGO_OFFSET, 0x04
|
||||
.equiv ROM_HEADER_NINTENDO_LOGO_LENGTH, 0x98
|
||||
.equiv ROM_HEADER_NINTENDO_LOGO_END, 0xA0
|
||||
|
||||
.equiv MBPROGRESS_NONE, 0x00
|
||||
.equiv MBPROGRESS_LOGO_CORRECT, 0x01
|
||||
.equiv MBPROGRESS_READY_TO_BOOT, 0x02
|
||||
|
||||
.equiv GCMB_MAGIC_BOOTKEY_HASHVAL, 0xBB
|
||||
.equiv GCMB_MAGIC_BOOTKEY, 0xBB
|
||||
.equiv GCMB_MAGIC_COUNTER2, 0xCC
|
||||
.equiv GCMB_MAGIC_KEYA, 0xDD
|
||||
.equiv GCMB_MAGIC_KEYB, 0xEE
|
||||
.equiv GCMB_MAGIC_KEYCDERIVATION, 0xFF
|
||||
|
||||
.syntax unified
|
||||
|
||||
.text
|
||||
|
||||
thumb_func_start GameCubeMultiBoot_Hash
|
||||
GameCubeMultiBoot_Hash: @ 81DCB38
|
||||
push {r4,lr}
|
||||
ldr r4, pool_HashVal
|
||||
eors r3, r1
|
||||
movs r2, 0x20
|
||||
|
||||
GameCubeMultiBoot_Hash_Loop:
|
||||
lsrs r3, 1
|
||||
bcc GameCubeMultiBoot_Hash_SkipEor
|
||||
|
||||
eors r3, r4
|
||||
|
||||
GameCubeMultiBoot_Hash_SkipEor:
|
||||
subs r2, 0x1
|
||||
bne GameCubeMultiBoot_Hash_Loop
|
||||
|
||||
pop {r4,pc}
|
||||
thumb_func_end GameCubeMultiBoot_Hash
|
||||
|
||||
thumb_func_start GameCubeMultiBoot_Main
|
||||
@ void GameCubeMultiBoot_Main(struct GameCubeMultiBoot *mb)@
|
||||
GameCubeMultiBoot_Main: @ 81DCB4C
|
||||
@ If there is no interrupt handler, skip counter manipulation
|
||||
ldr r1, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
|
||||
cmp r1, 0
|
||||
beq GameCubeMultiBoot_Main_SkipCounters
|
||||
@ Increment the second counter
|
||||
ldrb r1, [r0, GCMB_STRUCT_COUNTER2]
|
||||
adds r1, 0x1
|
||||
strb r1, [r0, GCMB_STRUCT_COUNTER2]
|
||||
@ If there is nothing more to do, bail out
|
||||
ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
|
||||
cmp r1, MBPROGRESS_READY_TO_BOOT
|
||||
beq GameCubeMultiBoot_Main_Return
|
||||
@ Save current interrupt master register value
|
||||
ldr r3, pool_InterruptRegs
|
||||
ldrh r2, [r3, OFFSET_REG_IME - 0x200]
|
||||
@ Disable all interrupts
|
||||
movs r1, 0
|
||||
strh r1, [r3, OFFSET_REG_IME - 0x200]
|
||||
@ Increment the first counter, if it's less than or equal to 10.
|
||||
ldrb r1, [r0, GCMB_STRUCT_COUNTER1]
|
||||
cmp r1, 0xA
|
||||
bgt GameCubeMultiBoot_Main_SkipCounter1Inc
|
||||
adds r1, 0x1
|
||||
strb r1, [r0, GCMB_STRUCT_COUNTER1]
|
||||
GameCubeMultiBoot_Main_SkipCounter1Inc:
|
||||
@ Load the saved interrupt master register value (re-enables interrupts if they were enabled before)
|
||||
strh r2, [r3, OFFSET_REG_IME - 0x200]
|
||||
GameCubeMultiBoot_Main_SkipCounters:
|
||||
@ Initialise multiboot structures if required
|
||||
bcs GameCubeMultiBoot_Init
|
||||
@ Skip this section (check Nintendo logo) if the check has already passed
|
||||
ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
|
||||
cmp r1, MBPROGRESS_NONE
|
||||
bne GameCubeMultiBoot_Main_SkipLogoCheck
|
||||
@ Bail out if no multiboot image data has been transferred yet
|
||||
ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
|
||||
ldr r2, [r0, GCMB_STRUCT_BASE_DEST_PTR]
|
||||
subs r1, r2
|
||||
beq GameCubeMultiBoot_Main_Return2
|
||||
@ Also bail out if not enough data has been transferred
|
||||
cmp r1, ROM_HEADER_NINTENDO_LOGO_END
|
||||
bcc GameCubeMultiBoot_Main_Return2
|
||||
@ Compare the Nintendo logo of the transferred multiboot image header, with the one in the ROM image of the inserted cart
|
||||
push {r4-r6}
|
||||
movs r1, ROM_HEADER_NINTENDO_LOGO_LENGTH
|
||||
adds r2, ROM_HEADER_NINTENDO_LOGO_OFFSET
|
||||
ldr r4, pool_NintendoLogo
|
||||
GameCubeMultiBoot_Main_LogoCmpLoop:
|
||||
ldm r2!, {r5}
|
||||
ldm r4!, {r6}
|
||||
cmp r5, r6
|
||||
bne GameCubeMultiBoot_Main_LogoCmpEnd
|
||||
subs r1, 0x4
|
||||
bne GameCubeMultiBoot_Main_LogoCmpLoop
|
||||
ldm r2!, {r5}
|
||||
ldm r4!, {r6}
|
||||
eors r5, r6
|
||||
lsrs r5, 8
|
||||
str r2, [r0, GCMB_STRUCT_BASE_DEST_PTR]
|
||||
GameCubeMultiBoot_Main_LogoCmpEnd:
|
||||
pop {r4-r6}
|
||||
@ Throw everything away if the logo data didn't match
|
||||
bne GameCubeMultiBoot_Init
|
||||
@ Logo matched, set the relevent multiboot progress bit
|
||||
movs r1, MBPROGRESS_LOGO_CORRECT
|
||||
strb r1, [r0, GCMB_STRUCT_MBPROGRESS]
|
||||
@ XOR together KeyA and KeyB to get the initial multiboot image checksum value
|
||||
ldr r1, [r0, GCMB_STRUCT_KEYA]
|
||||
ldr r2, [r0, GCMB_STRUCT_KEYB]
|
||||
eors r1, r2
|
||||
str r1, [r0, GCMB_STRUCT_HASH_VAL]
|
||||
@ ...also use it as the initial value for the image encryption session key. Algorithm is the same as the GBA BIOS multiboot: sessionkey = (initialvalue * 0x6177614b) + 1
|
||||
ldr r2, pool_Kawa
|
||||
muls r1, r2
|
||||
adds r1, 0x1
|
||||
str r1, [r0, GCMB_STRUCT_SESSION_KEY]
|
||||
GameCubeMultiBoot_Main_Return:
|
||||
bx lr
|
||||
GameCubeMultiBoot_Main_SkipLogoCheck:
|
||||
@ If this code is executed, then the logo check has passed, and the data being transferred in is encrypted.
|
||||
@ Set up registers.
|
||||
ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
|
||||
mov r12, r1
|
||||
ldr r3, [r0, GCMB_STRUCT_HASH_VAL]
|
||||
push {r4-r7}
|
||||
ldr r4, [r0, GCMB_STRUCT_BASE_DEST_PTR]
|
||||
ldr r5, pool_Kawa
|
||||
ldr r6, [r0, GCMB_STRUCT_SESSION_KEY]
|
||||
ldr r7, pool_HashVal
|
||||
GameCubeMultiBoot_Main_ImageDecryptHashLoop:
|
||||
@ If there's no more data, break out of the loop
|
||||
cmp r4, r12
|
||||
bcs GameCubeMultiBoot_Main_ImageDecryptHashEnd
|
||||
@ Get the next uint32
|
||||
ldr r1, [r4]
|
||||
@ Decrypt the ciphertext: plaintext = (ciphertext ^ sessionkey) + hashval
|
||||
eors r1, r6
|
||||
adds r1, r3
|
||||
@ Save the current uint32 of plaintext and advance the pointer
|
||||
stm r4!, {r1}
|
||||
@ Advance the hashval with this uint32 of plaintext -- this is the same code as GameCubeMultiBoot_Hash.
|
||||
eors r3, r1
|
||||
movs r2, 0x20
|
||||
GameCubeMultiBoot_Main_HashLoop:
|
||||
lsrs r3, 1
|
||||
bcc GameCubeMultiBoot_Main_HashSkipEor
|
||||
eors r3, r7
|
||||
GameCubeMultiBoot_Main_HashSkipEor:
|
||||
subs r2, 0x1
|
||||
bne GameCubeMultiBoot_Main_HashLoop
|
||||
@ Advance the sessionkey with the usual algorithm: sessionkey = (sessionkey * 0x6177614b) + 1
|
||||
muls r6, r5
|
||||
adds r6, 0x1
|
||||
b GameCubeMultiBoot_Main_ImageDecryptHashLoop
|
||||
GameCubeMultiBoot_Main_ImageDecryptHashEnd:
|
||||
@ Save the new pointer, sessionkey, hashval
|
||||
str r4, [r0, GCMB_STRUCT_BASE_DEST_PTR]
|
||||
str r6, [r0, GCMB_STRUCT_SESSION_KEY]
|
||||
pop {r4-r7}
|
||||
str r3, [r0, GCMB_STRUCT_HASH_VAL]
|
||||
@ Bail out if the image size is unknown
|
||||
ldrh r1, [r0, GCMB_STRUCT_IMAGE_SIZE]
|
||||
cmp r1, 0
|
||||
bne GameCubeMultiBoot_Main_Return2
|
||||
@ Bail out if no image data has been transferred
|
||||
ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
|
||||
ldr r2, [r0, GCMB_STRUCT_BASE_DEST_PTR]
|
||||
cmp r1, r2
|
||||
bne GameCubeMultiBoot_Main_Return2
|
||||
@ If KeyC hasn't been generated yet, go generate it
|
||||
ldr r1, [r0, GCMB_STRUCT_KEYC]
|
||||
cmp r1, 0
|
||||
beq GameCubeMultiBoot_Main_GenerateKeyC
|
||||
@ If the other side hasn't sent its boot key yet, bail out
|
||||
ldrh r1, [r0, GCMB_STRUCT_BOOT_KEY]
|
||||
cmp r1, 0
|
||||
beq GameCubeMultiBoot_Main_Return
|
||||
@ Save off LR so it doesn't get clobbered by the upcoming function call
|
||||
mov r12, lr
|
||||
@ Generate the real boot key, which is the checksum of a hardcoded value and KeyC
|
||||
movs r1, GCMB_MAGIC_BOOTKEY_HASHVAL
|
||||
ldr r3, [r0, GCMB_STRUCT_KEYC]
|
||||
bl GameCubeMultiBoot_Hash
|
||||
ldrh r1, [r0, GCMB_STRUCT_BOOT_KEY]
|
||||
@ Restore the saved LR value
|
||||
mov lr, r12
|
||||
@ Compare the two boot keys (real and passed in), if they don't match then throw everything away
|
||||
subs r1, r3
|
||||
bne GameCubeMultiBoot_Init
|
||||
@ The two boot keys matched, tell the caller that the image is ready to boot
|
||||
movs r1, MBPROGRESS_READY_TO_BOOT
|
||||
strb r1, [r0, GCMB_STRUCT_MBPROGRESS]
|
||||
@ Nothing more to do, return.
|
||||
bx lr
|
||||
GameCubeMultiBoot_Main_GenerateKeyC:
|
||||
@ Save off LR so it doesn't get clobbered by the upcoming function call
|
||||
mov r12, lr
|
||||
@ KeyC = (SavedVCount << 24) - 1
|
||||
ldrb r1, [r0, GCMB_STRUCT_SAVEDVCOUNT]
|
||||
lsls r1, 24
|
||||
subs r1, 0x1
|
||||
str r1, [r0, GCMB_STRUCT_KEYC]
|
||||
@ Hash the KeyC with the multiboot image checksum to generate the KeyC derivation material to be sent to the other side of the link
|
||||
bl GameCubeMultiBoot_Hash
|
||||
@ Make sure the sent KeyC derivation material contains a magic value so that the other side can detect it
|
||||
lsls r3, 8
|
||||
adds r3, GCMB_MAGIC_KEYCDERIVATION
|
||||
@ Save off the KeyC derivation material and return to caller
|
||||
str r3, [r0, GCMB_STRUCT_KEYC_DERIVATION]
|
||||
bx r12
|
||||
GameCubeMultiBoot_Main_Return2:
|
||||
bx lr
|
||||
thumb_func_end GameCubeMultiBoot_Main
|
||||
|
||||
.align 2, 0
|
||||
|
||||
pool_HashVal: .4byte 0xa1c1
|
||||
|
||||
pool_Kawa: .ascii "Kawa" @ name of BIOS developer
|
||||
|
||||
pool_NintendoLogo: .4byte RomHeaderNintendoLogo
|
||||
|
||||
thumb_func_start GameCubeMultiBoot_ExecuteProgram
|
||||
@ void GameCubeMultiBoot_ExecuteProgram(struct GameCubeMultiBoot *mb)@
|
||||
GameCubeMultiBoot_ExecuteProgram: @ 81DCC4C
|
||||
@ If there's no multiboot image ready, just return to caller
|
||||
ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
|
||||
cmp r1, MBPROGRESS_READY_TO_BOOT
|
||||
bne GameCubeMultiBoot_ExecuteProgram_Fail
|
||||
@ Disable interrupts
|
||||
ldr r3, pool_InterruptRegs
|
||||
movs r1, 0
|
||||
strh r1, [r3, OFFSET_REG_IME - 0x200]
|
||||
@ Jump to the real entry point of the multiboot image (past the image header), in ARM mode
|
||||
ldr r1, pool_MultiBootLoadAddr
|
||||
adds r1, 0xC0
|
||||
bx r1
|
||||
GameCubeMultiBoot_ExecuteProgram_Fail:
|
||||
bx lr
|
||||
thumb_func_end GameCubeMultiBoot_ExecuteProgram
|
||||
|
||||
thumb_func_start GameCubeMultiBoot_Init
|
||||
@ void GameCubeMultiBoot_Init(struct GameCubeMultiBoot *mb)@
|
||||
GameCubeMultiBoot_Init: @ 81DCC60
|
||||
ldr r3, pool_InterruptRegs
|
||||
|
||||
@ Save IME register.
|
||||
ldrh r2, [r3, OFFSET_REG_IME - 0x200]
|
||||
|
||||
@ Disable interrupts.
|
||||
movs r1, 0
|
||||
strh r1, [r3, OFFSET_REG_IME - 0x200]
|
||||
|
||||
@ Set the handler to the "Stop" routine.
|
||||
@ Unless the first command that is received is a device reset command, the
|
||||
@ "Stop" routine will be executed and no further commands will be processed.
|
||||
adr r3, GcMbIntrHandler_Stop
|
||||
str r3, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
|
||||
|
||||
ldrb r3, [r0, 0x3]
|
||||
push {r3}
|
||||
ldrb r3, [r0, 0x1]
|
||||
push {r0,r3}
|
||||
|
||||
adds r3, r0, 0
|
||||
adds r3, GCMB_STRUCT_BASE_DEST_PTR
|
||||
|
||||
@ clear all but the last 3 fields of the struct
|
||||
GameCubeMultiBoot_Init_ClearStructLoop:
|
||||
stm r0!, {r1}
|
||||
cmp r0, r3
|
||||
blo GameCubeMultiBoot_Init_ClearStructLoop
|
||||
|
||||
pop {r0,r3}
|
||||
lsrs r3, 1
|
||||
strb r3, [r0, 0x3]
|
||||
pop {r3}
|
||||
strb r3, [r0, 0x1]
|
||||
|
||||
ldr r3, pool_SerialRegs
|
||||
|
||||
@ Turn off JOY Bus mode.
|
||||
lsls r0, r3, 10
|
||||
strh r0, [r3, OFFSET_REG_RCNT - 0x120]
|
||||
|
||||
@ Turn on JOY Bus mode.
|
||||
movs r0, 0xC0
|
||||
lsls r0, 8
|
||||
strh r0, [r3, OFFSET_REG_RCNT - 0x120]
|
||||
|
||||
@ Init JOY Bus registers.
|
||||
movs r0, 0x47
|
||||
strh r0, [r3, OFFSET_REG_JOYCNT - 0x120]
|
||||
strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
|
||||
|
||||
ldr r3, pool_InterruptRegs
|
||||
|
||||
@ Acknowledge serial interrupt.
|
||||
movs r0, INTR_FLAG_SERIAL
|
||||
strh r0, [r3, OFFSET_REG_IF - 0x200]
|
||||
|
||||
@ Enable serial interrupt.
|
||||
ldrh r1, [r3, OFFSET_REG_IE - 0x200]
|
||||
orrs r1, r0
|
||||
strh r1, [r3, OFFSET_REG_IE - 0x200]
|
||||
|
||||
@ Restore IME register.
|
||||
strh r2, [r3, OFFSET_REG_IME - 0x200]
|
||||
|
||||
bx lr
|
||||
thumb_func_end GameCubeMultiBoot_Init
|
||||
|
||||
non_word_aligned_thumb_func_start GameCubeMultiBoot_HandleSerialInterrupt
|
||||
@ void GameCubeMultiBoot_HandleSerialInterrupt(struct GameCubeMultiBoot *mb)@
|
||||
GameCubeMultiBoot_HandleSerialInterrupt: @ 81DCCAA
|
||||
ldr r3, pool_SerialRegs
|
||||
|
||||
@ Acknowledge reset/receive/send flags.
|
||||
ldrh r1, [r3, OFFSET_REG_JOYCNT - 0x120]
|
||||
strh r1, [r3, OFFSET_REG_JOYCNT - 0x120]
|
||||
|
||||
movs r2, 0
|
||||
strb r2, [r0]
|
||||
|
||||
ldr r2, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
|
||||
cmp r2, 0
|
||||
beq GameCubeMultiBoot_HandleSerialInterruptDone
|
||||
|
||||
lsrs r1, 1 @ was a device reset command received?
|
||||
bcs GameCubeMultiBoot_BeginHandshake @ branch if so
|
||||
|
||||
mov pc, r2
|
||||
|
||||
.align 2, 0
|
||||
|
||||
@ Zero the status and the interrupt handler pointer.
|
||||
@ Commands from the GameCube will not be processed after this is executed
|
||||
@ unless GameCubeMultiBoot_Init() is called again.
|
||||
GcMbIntrHandler_Stop:
|
||||
movs r2, 0
|
||||
strh r2, [r3, OFFSET_REG_JOYSTAT - 0x120]
|
||||
|
||||
GameCubeMultiBoot_SetInterruptHandler:
|
||||
str r2, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
|
||||
|
||||
GameCubeMultiBoot_ReadVCount:
|
||||
ldr r3, pool_RegDispstat
|
||||
ldrh r1, [r3, OFFSET_REG_VCOUNT - OFFSET_REG_DISPSTAT]
|
||||
strb r1, [r0, 0x3]
|
||||
|
||||
GameCubeMultiBoot_HandleSerialInterruptDone:
|
||||
bx lr
|
||||
|
||||
GameCubeMultiBoot_BeginHandshake:
|
||||
@ Throw away anything that got sent
|
||||
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
|
||||
@ Send the game code, the other side of the link must send back the same game code
|
||||
ldr r1, pool_RubyUSAGameCode
|
||||
str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
|
||||
movs r1, 0x10
|
||||
strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
|
||||
@ Use the saved VCount value to provide 8 bits of entropy for KeyB
|
||||
ldrb r1, [r0, GCMB_STRUCT_SAVEDVCOUNT]
|
||||
strb r1, [r0, GCMB_STRUCT_KEYB + 1]
|
||||
@ If a multiboot image has been transferred at least enough such that the Nintendo logo check has passed, stop everything.
|
||||
ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
|
||||
cmp r1, 0
|
||||
bne GcMbIntrHandler_Stop
|
||||
@ Set the image destination pointers.
|
||||
ldr r1, pool_MultiBootLoadAddr
|
||||
str r1, [r0, GCMB_STRUCT_BASE_DEST_PTR]
|
||||
str r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
|
||||
@ Set the new interrupt handler.
|
||||
adr r2, GcMbIntrHandler_CheckGameCodeSent
|
||||
b GameCubeMultiBoot_SetInterruptHandler
|
||||
|
||||
.align 2, 0
|
||||
|
||||
GcMbIntrHandler_CheckGameCodeSent: @ 81DCCEC
|
||||
lsls r1, 31
|
||||
bcc GcMbIntrHandler_Stop @ stop if send failed
|
||||
bmi GameCubeMultiBoot_CheckHandshakeResponse @ branch if receive is complete
|
||||
|
||||
@ If the response hasn't been fully received yet,
|
||||
@ check again upon the next interrupt.
|
||||
adr r2, GcMbIntrHandler_CheckHandshakeResponse
|
||||
b GameCubeMultiBoot_SetInterruptHandler
|
||||
|
||||
.align 2, 0
|
||||
|
||||
GcMbIntrHandler_CheckHandshakeResponse: @ 81DCCF8
|
||||
lsrs r1, 1 @ is receive complete?
|
||||
bcc GcMbIntrHandler_Stop @ stop if not
|
||||
|
||||
GameCubeMultiBoot_CheckHandshakeResponse:
|
||||
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
|
||||
ldr r2, pool_RubyUSAGameCode
|
||||
cmp r1, r2
|
||||
bne GcMbIntrHandler_Stop @ stop if the GameCube didn't reply with the same game code
|
||||
@ Use the saved VCount value to provide another 8 bits of entropy for KeyB.
|
||||
ldrb r1, [r0, GCMB_STRUCT_SAVEDVCOUNT]
|
||||
strb r1, [r0, GCMB_STRUCT_KEYB + 3]
|
||||
adr r2, GcMbIntrHandler_ReceiveKeyA
|
||||
b GameCubeMultiBoot_SetInterruptHandler
|
||||
|
||||
.align 2, 0
|
||||
|
||||
GcMbIntrHandler_ReceiveKeyA: @ 81DCD0C
|
||||
lsrs r1, 1 @ is receive complete?
|
||||
bcc GcMbIntrHandler_Stop @ branch if not
|
||||
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
|
||||
@ make sure top 8 bits of the received value is the KeyA magic number, stop if KeyA is invalid
|
||||
lsrs r2, r1, 24
|
||||
cmp r2, GCMB_MAGIC_KEYA
|
||||
bne GcMbIntrHandler_Stop
|
||||
@ save received KeyA
|
||||
str r1, [r0, GCMB_STRUCT_KEYA]
|
||||
@ use the second GameCubeMultiBoot_Main() counter as another 8 bits of entropy for KeyB
|
||||
ldrb r1, [r0, GCMB_STRUCT_COUNTER2]
|
||||
strb r1, [r0, GCMB_STRUCT_KEYB + 2]
|
||||
movs r2, 0
|
||||
movs r3, 0
|
||||
ldr r1, [r0, GCMB_STRUCT_KEYB]
|
||||
lsrs r1, 8
|
||||
@ make sure KeyB is valid (other side of the link is supposed to check KeyB too), if it's not then change the byte that was just set so it is
|
||||
GameCubeMultiBoot_KeyBCheckLoop:
|
||||
lsrs r1, 1
|
||||
adcs r2, r3
|
||||
cmp r1, 0
|
||||
bne GameCubeMultiBoot_KeyBCheckLoop
|
||||
cmp r2, 0xE
|
||||
bgt GameCubeMultiBoot_KeyBSaveNewByte
|
||||
cmp r2, 0x7
|
||||
bge GameCubeMultiBoot_KeyBCheckEnd
|
||||
movs r1, 0xFF
|
||||
GameCubeMultiBoot_KeyBSaveNewByte:
|
||||
strb r1, [r0, GCMB_STRUCT_KEYB + 2]
|
||||
GameCubeMultiBoot_KeyBCheckEnd:
|
||||
@ add in the KeyB magic number and send off KeyB
|
||||
ldr r1, [r0, GCMB_STRUCT_KEYB]
|
||||
adds r1, GCMB_MAGIC_KEYB
|
||||
ldr r3, pool_SerialRegs
|
||||
str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
|
||||
movs r1, 0x30
|
||||
strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
|
||||
@ set new interrupt handler
|
||||
adr r2, GcMbIntrHandler_CheckKeyBSent
|
||||
b GameCubeMultiBoot_SetInterruptHandler
|
||||
|
||||
.align 2, 0
|
||||
|
||||
GcMbIntrHandler_CheckKeyBSent: @ 81DCD4C
|
||||
lsls r1, 31
|
||||
bcc GcMbIntrHandler_Stop @ stop if send failed
|
||||
bmi GameCubeMultiBoot_CheckImageSizeResponse @ branch if receive is complete
|
||||
adr r2, GcMbIntrHandler_CheckImageSizeResponse
|
||||
b GameCubeMultiBoot_SetInterruptHandler
|
||||
|
||||
.align 2, 0
|
||||
|
||||
GcMbIntrHandler_CheckImageSizeResponse: @ 81DCD58
|
||||
lsrs r1, 1 @ is receive complete?
|
||||
bcc GcMbIntrHandler_Stop @ branch if not
|
||||
GameCubeMultiBoot_CheckImageSizeResponse:
|
||||
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
|
||||
ldr r2, GameCubeMultiBoot_MaximumImageSizeUInt32s
|
||||
cmp r1, r2
|
||||
bhs GcMbIntrHandler_Stop
|
||||
adds r1, 0x1
|
||||
adds r1, r1
|
||||
strh r1, [r0, GCMB_STRUCT_IMAGE_SIZE]
|
||||
ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
|
||||
cmp r1, 0
|
||||
GcMbIntrHandler_StopIfNotEqual:
|
||||
bne GcMbIntrHandler_Stop
|
||||
ldr r1, pool_MultiBootLoadAddr
|
||||
str r1, [r0, GCMB_STRUCT_BASE_DEST_PTR]
|
||||
str r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
|
||||
adr r2, GcMbIntrHandler_CheckImageResponse
|
||||
b GameCubeMultiBoot_SetInterruptHandler
|
||||
|
||||
.align 2, 0
|
||||
|
||||
GcMbIntrHandler_CheckImageResponse: @ 81DCD7C
|
||||
lsrs r1, 1 @ is receive complete?
|
||||
bcc GcMbIntrHandler_Stop @ branch if not
|
||||
ldr r2, [r0, GCMB_STRUCT_CUR_DEST_PTR]
|
||||
movs r1, 0x4
|
||||
ands r1, r2
|
||||
adds r1, 0x8
|
||||
lsls r1, 2
|
||||
strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
|
||||
@ get the recieved uint32
|
||||
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
|
||||
@ put it in the current destination pointer and advance that pointer
|
||||
stm r2!, {r1}
|
||||
@ save off the advanced pointer
|
||||
str r2, [r0, GCMB_STRUCT_CUR_DEST_PTR]
|
||||
@ decrease the image size (in uint32s)
|
||||
ldrh r1, [r0, GCMB_STRUCT_IMAGE_SIZE]
|
||||
subs r1, 0x1
|
||||
strh r1, [r0, GCMB_STRUCT_IMAGE_SIZE]
|
||||
@ branch away if the transfer is not yet complete
|
||||
bne GameCubeMultiBoot_ReadVCount
|
||||
|
||||
GcMbIntrHandler_SendCounter2:
|
||||
@ send counter2 with magic number
|
||||
ldrb r1, [r0, GCMB_STRUCT_COUNTER2]
|
||||
lsls r1, 8
|
||||
adds r1, GCMB_MAGIC_COUNTER2
|
||||
str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
|
||||
adr r2, GcMbIntrHandler_CheckCounter2Sent
|
||||
b GameCubeMultiBoot_SetInterruptHandler
|
||||
|
||||
.align 2, 0
|
||||
|
||||
GcMbIntrHandler_CheckCounter2Sent:
|
||||
lsls r1, 31
|
||||
|
||||
GcMbIntrHandler_StopIfSendFailed:
|
||||
bcc GcMbIntrHandler_Stop @ stop if send failed
|
||||
@ if KeyC derivation value has not yet been generated, send Counter2 again, otherwise, send KeyC derivation
|
||||
ldr r1, [r0, GCMB_STRUCT_KEYC_DERIVATION]
|
||||
cmp r1, 0
|
||||
beq GcMbIntrHandler_SendCounter2
|
||||
str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
|
||||
adr r2, GcMbIntrHandler_CheckKeyCDerivationSent
|
||||
b GameCubeMultiBoot_SetInterruptHandler
|
||||
|
||||
.align 2, 0
|
||||
|
||||
GcMbIntrHandler_CheckKeyCDerivationSent: @ 81DCDB8
|
||||
lsls r1, 31
|
||||
bcc GcMbIntrHandler_StopIfSendFailed @ branch if send failed
|
||||
bmi GameCubeMultiBoot_CheckBootKeyResponse @ branch if receive is complete
|
||||
adr r2, GcMbIntrHandler_CheckBootKeyResponse
|
||||
b GameCubeMultiBoot_SetInterruptHandler
|
||||
|
||||
.align 2, 0
|
||||
|
||||
GcMbIntrHandler_CheckBootKeyResponse: @ 81DCDC4
|
||||
lsrs r1, 1 @ is receive complete?
|
||||
bcc GcMbIntrHandler_StopIfSendFailed @ branch if not
|
||||
|
||||
GameCubeMultiBoot_CheckBootKeyResponse:
|
||||
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
|
||||
@ make sure received boot key contains expected magic number, stop if not
|
||||
lsrs r2, r1, 24
|
||||
cmp r2, GCMB_MAGIC_BOOTKEY
|
||||
bne GcMbIntrHandler_StopIfNotEqual
|
||||
@ save received bootkey to be checked in GameCubeMultiBoot_Main()
|
||||
strh r1, [r0, GCMB_STRUCT_BOOT_KEY]
|
||||
@ stop if anything more gets sent
|
||||
adr r2, GcMbIntrHandler_StopUnconditionally
|
||||
b GameCubeMultiBoot_SetInterruptHandler
|
||||
|
||||
.align 2, 0
|
||||
|
||||
GcMbIntrHandler_StopUnconditionally: @ 81DCDD8
|
||||
b GcMbIntrHandler_Stop
|
||||
|
||||
thumb_func_end GameCubeMultiBoot_HandleSerialInterrupt
|
||||
|
||||
non_word_aligned_thumb_func_start GameCubeMultiBoot_Quit
|
||||
@ void GameCubeMultiBoot_Quit()@
|
||||
GameCubeMultiBoot_Quit: @ 81DCDDA
|
||||
ldr r3, pool_InterruptRegs
|
||||
|
||||
@ Save IME register.
|
||||
ldrh r2, [r3, OFFSET_REG_IME - 0x200]
|
||||
|
||||
@ Disable interrupts.
|
||||
movs r1, 0
|
||||
strh r1, [r3, OFFSET_REG_IME - 0x200]
|
||||
|
||||
ldr r3, pool_SerialRegs
|
||||
|
||||
@ Acknowledge all JOYCNT flags.
|
||||
movs r0, 0x7
|
||||
strh r0, [r3, OFFSET_REG_JOYCNT - 0x120]
|
||||
|
||||
@ Turn off JOY Bus mode.
|
||||
lsls r0, r3, 10
|
||||
strh r0, [r3, OFFSET_REG_RCNT - 0x120] @ store 0x8000
|
||||
|
||||
ldr r3, pool_InterruptRegs
|
||||
|
||||
@ Acknowledge serial interrupt.
|
||||
movs r0, INTR_FLAG_SERIAL
|
||||
strh r0, [r3, OFFSET_REG_IF - 0x200]
|
||||
|
||||
@ Disable serial interrupt.
|
||||
ldrh r1, [r3, OFFSET_REG_IE - 0x200]
|
||||
bics r1, r0
|
||||
strh r1, [r3, OFFSET_REG_IE - 0x200]
|
||||
|
||||
@ Restore IME register.
|
||||
strh r2, [r3, OFFSET_REG_IME - 0x200]
|
||||
|
||||
bx lr
|
||||
thumb_func_end GameCubeMultiBoot_Quit
|
||||
|
||||
.align 2, 0
|
||||
|
||||
GameCubeMultiBoot_MaximumImageSizeUInt32s: .4byte 0x00004000
|
||||
|
||||
pool_InterruptRegs: .4byte REG_BASE + 0x200
|
||||
|
||||
pool_SerialRegs: .4byte REG_BASE + 0x120
|
||||
|
||||
pool_RegDispstat: .4byte REG_DISPSTAT
|
||||
|
||||
pool_RubyUSAGameCode: .ascii "AXVE"
|
||||
|
||||
pool_MultiBootLoadAddr: .4byte EWRAM_START
|
||||
|
||||
.align 2, 0 @ Don't pad with nop.
|
||||
-1935
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user