diff options
-rw-r--r-- | asm/crt0.s | 3 | ||||
-rw-r--r-- | asm/emerald.s | 133 | ||||
-rw-r--r-- | asm/libagbsyscall.s | 1 | ||||
-rw-r--r-- | asm/libgcnmultiboot.s | 525 | ||||
-rw-r--r-- | asm/rom_header.s | 2 |
5 files changed, 383 insertions, 281 deletions
diff --git a/asm/crt0.s b/asm/crt0.s index 6173a2f1a..b93f6368d 100644 --- a/asm/crt0.s +++ b/asm/crt0.s @@ -1,3 +1,6 @@ +RomBase: ; 8000000 + b Init + .include "asm/rom_header.s" _080000C0: diff --git a/asm/emerald.s b/asm/emerald.s index 7ce518805..aaab7fb54 100644 --- a/asm/emerald.s +++ b/asm/emerald.s @@ -702397,16 +702397,16 @@ load_copyright_graphics: ; 816CC70 .pool thumb_func_end load_copyright_graphics - thumb_func_start sub_816CCB8 -sub_816CCB8: ; 816CCB8 + thumb_func_start SerialCb_CopyrightScreen +SerialCb_CopyrightScreen: ; 816CCB8 push {lr} ldr r0, =0x030062b0 - bl sub_82DEEE2 + bl GameCubeMultiBoot_HandleSerialInterrupt pop {r0} bx r0 .align 2, 0 .pool - thumb_func_end sub_816CCB8 + thumb_func_end SerialCb_CopyrightScreen thumb_func_start do_copyright_screen do_copyright_screen: ; 816CCC8 @@ -702509,10 +702509,10 @@ do_copyright_screen: ; 816CCC8 lsls r2, 1 adds r0, r2, 0 strh r0, [r1] - ldr r0, =sub_816CCB8 + ldr r0, =SerialCb_CopyrightScreen bl set_serial_callback ldr r0, =0x030062b0 - bl sub_82DEE98 + bl GameCubeMultiBoot_Init @0816CDBC: bl fade_and_return_progress_probably ldr r0, =0x030022c0 @@ -702523,14 +702523,14 @@ do_copyright_screen: ; 816CCC8 adds r1, 0x1 strb r1, [r0] ldr r0, =0x030062b0 - bl sub_82DED84 + bl GameCubeMultiBoot_Main b @0816CEA0 .align 2, 0 .pool @0816CE00: ldr r4, =0x030062b0 adds r0, r4, 0 - bl sub_82DED84 + bl GameCubeMultiBoot_Main ldrb r0, [r4, 0x2] cmp r0, 0x1 beq @0816CEA0 @@ -702578,12 +702578,12 @@ do_copyright_screen: ; 816CCC8 str r4, [r6] @0816CE6C: adds r0, r5, 0 - bl sub_82DEE84 + bl GameCubeMultiBoot_ExecuteProgram b @0816CE96 .align 2, 0 .pool @0816CE8C: - bl sub_82DF012 + bl GameCubeMultiBoot_Quit ldr r0, =sub_800BA38 bl set_serial_callback @0816CE96: @@ -853744,8 +853744,9 @@ GetGlyphWidthFont6: ; 81BA6CC bx lr thumb_func_end GetGlyphWidthFont6 - thumb_func_start sub_81BA6D0 -sub_81BA6D0: ; 81BA6D0 + thumb_func_start MultiBootInit +; void MultiBootInit(MultiBootParam *mp) +MultiBootInit: ; 81BA6D0 adds r2, r0, 0 movs r1, 0 strb r1, [r2, 0x1E] @@ -853770,17 +853771,18 @@ sub_81BA6D0: ; 81BA6D0 bx lr .align 2, 0 .pool - thumb_func_end sub_81BA6D0 + thumb_func_end MultiBootInit - thumb_func_start sub_81BA70C -sub_81BA70C: ; 81BA70C + thumb_func_start MultiBootMain +; int MultiBootMain(MultiBootParam *mp) +MultiBootMain: ; 81BA70C push {r4-r7,lr} mov r7, r10 mov r6, r9 mov r5, r8 push {r5-r7} adds r7, r0, 0 - bl sub_81BAC30 + bl MultiBootCheckComplete cmp r0, 0 beq @081BA722 b @081BAAEA @@ -853810,7 +853812,7 @@ sub_81BA70C: ; 81BA70C cmp r5, 0x8 beq @081BA760 adds r0, r7, 0 - bl sub_81BA6D0 + bl MultiBootInit movs r0, 0x8 eors r0, r5 b @081BAAEC @@ -853821,7 +853823,7 @@ sub_81BA70C: ; 81BA70C cmp r0, 0xDF bls @081BA7B2 adds r0, r7, 0 - bl sub_81BAC44 + bl MultiBootHandShake adds r5, r0, 0 cmp r5, 0 beq @081BA774 @@ -853836,13 +853838,13 @@ sub_81BA70C: ; 81BA70C cmp r0, 0xE1 bls @081BA790 adds r0, r7, 0 - bl sub_81BAC30 + bl MultiBootCheckComplete cmp r0, 0 bne @081BA790 b @081BAADA @081BA790: adds r0, r7, 0 - bl sub_81BAC30 + bl MultiBootCheckComplete cmp r0, 0 beq @081BA79C b @081BAAEA @@ -853851,7 +853853,7 @@ sub_81BA70C: ; 81BA70C cmp r0, 0 bne @081BA7AC adds r0, r7, 0 - bl sub_81BA6D0 + bl MultiBootInit movs r0, 0x71 b @081BAAEC @081BA7AC: @@ -853963,7 +853965,7 @@ sub_81BA70C: ; 81BA70C cmp r0, r2 beq @081BA88A adds r0, r7, 0 - bl sub_81BAB48 + bl MultiBootStartProbe b @081BA892 .align 2, 0 .pool @@ -854113,7 +854115,7 @@ sub_81BA70C: ; 81BA70C adds r0, r2, 0 orrs r1, r0 adds r0, r7, 0 - bl sub_81BAAFC + bl MultiBootSend b @081BAAEC .align 2, 0 .pool @@ -854139,7 +854141,7 @@ sub_81BA70C: ; 81BA70C orrs r3, r0 adds r0, r7, 0 adds r1, r3, 0 - bl sub_81BAAFC + bl MultiBootSend b @081BAAEC @081BA9D6: movs r5, 0x3 @@ -854177,7 +854179,7 @@ sub_81BA70C: ; 81BA70C .pool @081BAA18: adds r0, r7, 0 - bl sub_81BA6D0 + bl MultiBootInit movs r0, 0x1E mov r1, r10 strb r0, [r1] @@ -854244,7 +854246,7 @@ sub_81BA70C: ; 81BA70C cmp r0, 0 bne @081BAAA2 adds r0, r7, 0 - bl sub_81BA6D0 + bl MultiBootInit movs r0, 0x50 b @081BAAEC @081BAAA2: @@ -854267,7 +854269,7 @@ sub_81BA70C: ; 81BA70C ldrb r1, [r0] orrs r1, r2 adds r0, r7, 0 - bl sub_81BAAFC + bl MultiBootSend adds r5, r0, 0 cmp r5, 0 bne @081BAAEC @@ -854277,11 +854279,11 @@ sub_81BA70C: ; 81BA70C cmp r0, 0x1 bne @081BAAEA @081BAADA: - bl sub_81BAD48 + bl MultiBootWaitSendDone b @081BA736 @081BAAE0: adds r0, r7, 0 - bl sub_81BA6D0 + bl MultiBootInit movs r0, 0x60 b @081BAAEC @081BAAEA: @@ -854294,10 +854296,11 @@ sub_81BA70C: ; 81BA70C pop {r4-r7} pop {r1} bx r1 - thumb_func_end sub_81BA70C + thumb_func_end MultiBootMain - thumb_func_start sub_81BAAFC -sub_81BAAFC: ; 81BAAFC + thumb_func_start MultiBootSend +; int MultiBootSend(MultiBootParam *mp, u16 data) +MultiBootSend: ; 81BAAFC push {r4,lr} adds r2, r0, 0 lsls r1, 16 @@ -854323,7 +854326,7 @@ sub_81BAAFC: ; 81BAAFC .pool @081BAB34: adds r0, r2, 0 - bl sub_81BA6D0 + bl MultiBootInit movs r0, 0x8 eors r4, r0 adds r0, r4, 0 @@ -854331,17 +854334,18 @@ sub_81BAAFC: ; 81BAAFC pop {r4} pop {r1} bx r1 - thumb_func_end sub_81BAAFC + thumb_func_end MultiBootSend - thumb_func_start sub_81BAB48 -sub_81BAB48: ; 81BAB48 + thumb_func_start MultiBootStartProbe +; void MultiBootStartProbe(MultiBootParam *mp) +MultiBootStartProbe: ; 81BAB48 push {lr} adds r1, r0, 0 ldrb r0, [r1, 0x18] cmp r0, 0 beq @081BAB5A adds r0, r1, 0 - bl sub_81BA6D0 + bl MultiBootInit b @081BAB66 @081BAB5A: adds r2, r1, 0 @@ -854353,10 +854357,11 @@ sub_81BAB48: ; 81BAB48 @081BAB66: pop {r0} bx r0 - thumb_func_end sub_81BAB48 + thumb_func_end MultiBootStartProbe - thumb_func_start sub_81BAB6C -sub_81BAB6C: ; 81BAB6C + thumb_func_start MultiBootStartMaster +; void MultiBootStartMaster(MultiBootParam *mp, u8 *srcp, int length, u8 palette_color, s8 palette_speed) +MultiBootStartMaster: ; 81BAB6C push {r4-r7,lr} adds r4, r0, 0 adds r6, r1, 0 @@ -854389,7 +854394,7 @@ sub_81BAB6C: ; 81BAB6C bls @081BABB4 @081BABA8: adds r0, r4, 0 - bl sub_81BA6D0 + bl MultiBootInit b @081BAC28 .align 2, 0 .pool @@ -854453,10 +854458,11 @@ sub_81BAB6C: ; 81BAB6C pop {r4-r7} pop {r0} bx r0 - thumb_func_end sub_81BAB6C + thumb_func_end MultiBootStartMaster - thumb_func_start sub_81BAC30 -sub_81BAC30: ; 81BAC30 + thumb_func_start MultiBootCheckComplete +; s32 MultiBootCheckComplete(MultiBootParam *mp) +MultiBootCheckComplete: ; 81BAC30 push {lr} ldrb r0, [r0, 0x18] cmp r0, 0xE9 @@ -854468,10 +854474,11 @@ sub_81BAC30: ; 81BAC30 @081BAC3E: pop {r1} bx r1 - thumb_func_end sub_81BAC30 + thumb_func_end MultiBootCheckComplete - thumb_func_start sub_81BAC44 -sub_81BAC44: ; 81BAC44 + thumb_func_start MultiBootHandShake +; int MultiBootHandShake(MultiBootParam *mp) +MultiBootHandShake: ; 81BAC44 push {r4-r6,lr} adds r3, r0, 0 ldrb r0, [r3, 0x18] @@ -854543,7 +854550,7 @@ sub_81BAC44: ; 81BAC44 ldrh r1, [r3] @081BACC2: adds r0, r3, 0 - bl sub_81BAAFC + bl MultiBootSend b @081BAD28 .align 2, 0 .pool @@ -854588,7 +854595,7 @@ sub_81BAC44: ; 81BAC44 .pool @081BAD1C: adds r0, r3, 0 - bl sub_81BA6D0 + bl MultiBootInit movs r0, 0x71 b @081BAD28 @081BAD26: @@ -854597,10 +854604,11 @@ sub_81BAC44: ; 81BAC44 pop {r4-r6} pop {r1} bx r1 - thumb_func_end sub_81BAC44 + thumb_func_end MultiBootHandShake - thumb_func_start sub_81BAD30 -sub_81BAD30: ; 81BAD30 + thumb_func_start MultiBootWaitCycles +; void MultiBootWaitCycles(u32 cycles) +MultiBootWaitCycles: ; 81BAD30 mov r2, pc lsrs r2, 24 movs r1, 0xC @@ -854614,10 +854622,11 @@ sub_81BAD30: ; 81BAD30 subs r0, r1 bgt @081BAD42 bx lr - thumb_func_end sub_81BAD30 + thumb_func_end MultiBootWaitCycles - thumb_func_start sub_81BAD48 -sub_81BAD48: ; 81BAD48 + thumb_func_start MultiBootWaitSendDone +; voidMultiBootWaitSendDone(void) +MultiBootWaitSendDone: ; 81BAD48 push {r4,r5,lr} movs r2, 0 ldr r3, =0x04000128 @@ -854640,13 +854649,13 @@ sub_81BAD48: ; 81BAD48 @081BAD6C: movs r0, 0x96 lsls r0, 2 - bl sub_81BAD30 + bl MultiBootWaitCycles pop {r4,r5} pop {r0} bx r0 .align 2, 0 .pool - thumb_func_end sub_81BAD48 + thumb_func_end MultiBootWaitSendDone thumb_func_start sub_81BAD84 sub_81BAD84: ; 81BAD84 @@ -862975,7 +862984,7 @@ sub_81BF3DC: ; 81BF3DC strb r5, [r0] ldr r0, [r4] adds r0, 0x4 - bl sub_81BA6D0 + bl MultiBootInit ldr r1, [r4] strh r5, [r1, 0x2] movs r0, 0x4 @@ -862986,7 +862995,7 @@ sub_81BF3DC: ; 81BF3DC adds r4, r5, 0 ldr r0, [r4] adds r0, 0x4 - bl sub_81BA70C + bl MultiBootMain ldr r4, [r4] ldrb r0, [r4, 0x1C] cmp r0, 0 @@ -863017,7 +863026,7 @@ sub_81BF3DC: ; 81BF3DC movs r3, 0x1 str r3, [sp] movs r3, 0x4 - bl sub_81BAB6C + bl MultiBootStartMaster ldr r1, [r5] movs r0, 0x5 b @081BF590 @@ -863032,10 +863041,10 @@ sub_81BF3DC: ; 81BF3DC ldr r5, =0x030012b8 ldr r0, [r5] adds r0, 0x4 - bl sub_81BA70C + bl MultiBootMain ldr r0, [r5] adds r0, 0x4 - bl sub_81BAC30 + bl MultiBootCheckComplete cmp r0, 0 beq @081BF540 ldr r1, [r5] diff --git a/asm/libagbsyscall.s b/asm/libagbsyscall.s index 923a7a98e..a0d0726f2 100644 --- a/asm/libagbsyscall.s +++ b/asm/libagbsyscall.s @@ -46,6 +46,7 @@ LZ77UnCompWram: ; 82E7090 thumb_func_end LZ77UnCompWram thumb_func_start MultiBoot +; s32 MultiBoot(struct MultiBootParam *mp) MultiBoot: ; 82E7094 movs r1, 0x1 swi 0x25 diff --git a/asm/libgcnmultiboot.s b/asm/libgcnmultiboot.s index 6270dc9e7..8ca22b587 100644 --- a/asm/libgcnmultiboot.s +++ b/asm/libgcnmultiboot.s @@ -1,22 +1,34 @@ - thumb_func_start sub_82DED70 -sub_82DED70: ; 82DED70 +; 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. + + .set GCMB_STRUCT_BASE_DEST_PTR, 0x20 + .set GCMB_STRUCT_CUR_DEST_PTR, 0x24 + .set GCMB_STRUCT_SERIAL_INTR_HANDLER, 0x28 + + thumb_func_start GameCubeMultiBoot_Hash +GameCubeMultiBoot_Hash: ; 82DED70 push {r4,lr} - ldr r4, _082DEE78 + ldr r4, pool_HashVal eors r3, r1 movs r2, 0x20 -_082DED78: + +@loop: lsrs r3, 1 - bcc _082DED7E + bcc @skipExclusiveOr + eors r3, r4 -_082DED7E: + +@skipExclusiveOr: subs r2, 0x1 - bne _082DED78 + bne @loop + pop {r4,pc} - thumb_func_end sub_82DED70 + thumb_func_end GameCubeMultiBoot_Hash - thumb_func_start sub_82DED84 -sub_82DED84: ; 82DED84 - ldr r1, [r0, 0x28] + thumb_func_start GameCubeMultiBoot_Main +; void GameCubeMultiBoot_Main(struct GameCubeMultiBoot *mb); +GameCubeMultiBoot_Main: ; 82DED84 + ldr r1, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER] cmp r1, 0 beq _082DEDAA ldrb r1, [r0, 0x1] @@ -25,32 +37,32 @@ sub_82DED84: ; 82DED84 ldrb r1, [r0, 0x2] cmp r1, 0x2 beq _082DEDF4 - ldr r3, _082DF038 - ldrh r2, [r3, 0x8] + ldr r3, pool_InterruptRegs + ldrh r2, [r3, OFFSET_REG_IME - 0x200] movs r1, 0 - strh r1, [r3, 0x8] + strh r1, [r3, OFFSET_REG_IME - 0x200] ldrb r1, [r0] cmp r1, 0xA bgt _082DEDA8 adds r1, 0x1 strb r1, [r0] _082DEDA8: - strh r2, [r3, 0x8] + strh r2, [r3, OFFSET_REG_IME - 0x200] _082DEDAA: - bcs sub_82DEE98 + bcs GameCubeMultiBoot_Init ldrb r1, [r0, 0x2] cmp r1, 0 bne _082DEDF6 - ldr r1, [r0, 0x24] - ldr r2, [r0, 0x20] + ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR] + ldr r2, [r0, GCMB_STRUCT_BASE_DEST_PTR] subs r1, r2 beq _082DEE76 cmp r1, 0xA0 bcc _082DEE76 push {r4-r6} movs r1, 0x98 - adds r2, 0x4 - ldr r4, _082DEE80 + adds r2, RomHeaderNintendoLogo - RomBase + ldr r4, pool_NintendoLogo _082DEDC6: ldm r2!, {r5} ldm r4!, {r6} @@ -62,31 +74,31 @@ _082DEDC6: ldm r4!, {r6} eors r5, r6 lsrs r5, 8 - str r2, [r0, 0x20] + str r2, [r0, GCMB_STRUCT_BASE_DEST_PTR] _082DEDDC: pop {r4-r6} - bne sub_82DEE98 + bne GameCubeMultiBoot_Init movs r1, 0x1 strb r1, [r0, 0x2] ldr r1, [r0, 0x4] ldr r2, [r0, 0x8] eors r1, r2 str r1, [r0, 0x18] - ldr r2, _082DEE7C + ldr r2, pool_Kawa muls r1, r2 adds r1, 0x1 str r1, [r0, 0x14] _082DEDF4: bx lr _082DEDF6: - ldr r1, [r0, 0x24] + ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR] mov r12, r1 ldr r3, [r0, 0x18] push {r4-r7} - ldr r4, [r0, 0x20] - ldr r5, _082DEE7C + ldr r4, [r0, GCMB_STRUCT_BASE_DEST_PTR] + ldr r5, pool_Kawa ldr r6, [r0, 0x14] - ldr r7, _082DEE78 + ldr r7, pool_HashVal _082DEE06: cmp r4, r12 bcs _082DEE26 @@ -107,15 +119,15 @@ _082DEE1C: adds r6, 0x1 b _082DEE06 _082DEE26: - str r4, [r0, 0x20] + str r4, [r0, GCMB_STRUCT_BASE_DEST_PTR] str r6, [r0, 0x14] pop {r4-r7} str r3, [r0, 0x18] ldrh r1, [r0, 0x12] cmp r1, 0 bne _082DEE76 - ldr r1, [r0, 0x24] - ldr r2, [r0, 0x20] + ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR] + ldr r2, [r0, GCMB_STRUCT_BASE_DEST_PTR] cmp r1, r2 bne _082DEE76 ldr r1, [r0, 0xC] @@ -127,11 +139,11 @@ _082DEE26: mov r12, lr movs r1, 0xBB ldr r3, [r0, 0xC] - bl sub_82DED70 + bl GameCubeMultiBoot_Hash ldrh r1, [r0, 0x10] mov lr, r12 subs r1, r3 - bne sub_82DEE98 + bne GameCubeMultiBoot_Init movs r1, 0x2 strb r1, [r0, 0x2] bx lr @@ -141,153 +153,205 @@ _082DEE60: lsls r1, 24 subs r1, 0x1 str r1, [r0, 0xC] - bl sub_82DED70 + bl GameCubeMultiBoot_Hash lsls r3, 8 adds r3, 0xFF str r3, [r0, 0x1C] bx r12 _082DEE76: bx lr + thumb_func_end GameCubeMultiBoot_Main + .align 2, 0 -_082DEE78: .4byte 0x0000a1c1 -_082DEE7C: .4byte 0x6177614b -_082DEE80: .4byte RomHeaderNintendoLogo - thumb_func_end sub_82DED84 - thumb_func_start sub_82DEE84 -sub_82DEE84: ; 82DEE84 +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: ; 82DEE84 ldrb r1, [r0, 0x2] cmp r1, 0x2 - bne _082DEE96 - ldr r3, _082DF038 + bne @unableToExecute + ldr r3, pool_InterruptRegs movs r1, 0 - strh r1, [r3, 0x8] - ldr r1, _082DF048 + strh r1, [r3, OFFSET_REG_IME - 0x200] + ldr r1, pool_MultiBootLoadAddr adds r1, 0xC0 bx r1 -_082DEE96: +@unableToExecute: bx lr - thumb_func_end sub_82DEE84 + thumb_func_end GameCubeMultiBoot_ExecuteProgram + + thumb_func_start GameCubeMultiBoot_Init +; void GameCubeMultiBoot_Init(struct GameCubeMultiBoot *mb); +GameCubeMultiBoot_Init: ; 82DEE98 + ldr r3, pool_InterruptRegs + +; Save IME register. + ldrh r2, [r3, OFFSET_REG_IME - 0x200] - thumb_func_start sub_82DEE98 -sub_82DEE98: ; 82DEE98 - ldr r3, _082DF038 - ldrh r2, [r3, 0x8] +; Disable interrupts. movs r1, 0 - strh r1, [r3, 0x8] - adr r3, _082DEEF8 - str r3, [r0, 0x28] + 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, 0x20 -_082DEEB0: + adds r3, GCMB_STRUCT_BASE_DEST_PTR + +; clear all but the last 3 fields of the struct +@clearStructLoop: stm r0!, {r1} cmp r0, r3 - bcc _082DEEB0 + blo @clearStructLoop + pop {r0,r3} lsrs r3, 1 strb r3, [r0, 0x3] pop {r3} strb r3, [r0, 0x1] - ldr r3, _082DF03C + + ldr r3, pool_SerialRegs + +; Turn off JOY Bus mode. lsls r0, r3, 10 - strh r0, [r3, 0x14] + strh r0, [r3, OFFSET_REG_RCNT - 0x120] + +; Turn on JOY Bus mode. movs r0, 0xC0 lsls r0, 8 - strh r0, [r3, 0x14] + strh r0, [r3, OFFSET_REG_RCNT - 0x120] + +; Init JOY Bus registers. movs r0, 0x47 - strh r0, [r3, 0x20] - strh r1, [r3, 0x38] - ldr r3, _082DF038 - movs r0, 0x80 - strh r0, [r3, 0x2] - ldrh r1, [r3] + 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] - strh r2, [r3, 0x8] + strh r1, [r3, OFFSET_REG_IE - 0x200] + +; Restore IME register. + strh r2, [r3, OFFSET_REG_IME - 0x200] + bx lr - thumb_func_end sub_82DEE98 + thumb_func_end GameCubeMultiBoot_Init + + non_word_aligned_thumb_func_start GameCubeMultiBoot_HandleSerialInterrupt +; void GameCubeMultiBoot_HandleSerialInterrupt(struct GameCubeMultiBoot *mb); +GameCubeMultiBoot_HandleSerialInterrupt: ; 82DEEE2 + ldr r3, pool_SerialRegs + +; Acknowledge reset/receive/send flags. + ldrh r1, [r3, OFFSET_REG_JOYCNT - 0x120] + strh r1, [r3, OFFSET_REG_JOYCNT - 0x120] - non_word_aligned_thumb_func_start sub_82DEEE2 -sub_82DEEE2: ; 82DEEE2 - ldr r3, _082DF03C - ldrh r1, [r3, 0x20] - strh r1, [r3, 0x20] movs r2, 0 strb r2, [r0] - ldr r2, [r0, 0x28] + + ldr r2, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER] cmp r2, 0 - beq _082DEF04 - lsrs r1, 1 - bcs _082DEF06 + beq GameCubeMultiBoot_HandleSerialInterruptDone + + lsrs r1, 1 ; was a device reset command received? + bcs GameCubeMultiBoot_BeginHandshake ; branch if so + mov pc, r2 -_082DEEF8: + + .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, 0x38] -_082DEEFC: - str r2, [r0, 0x28] -_082DEEFE: - ldr r3, _082DF040 - ldrh r1, [r3, 0x2] + 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] -_082DEF04: + +GameCubeMultiBoot_HandleSerialInterruptDone: bx lr -_082DEF06: - ldr r1, [r3, 0x30] - ldr r1, _082DF044 - str r1, [r3, 0x34] + +GameCubeMultiBoot_BeginHandshake: + ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] + ldr r1, pool_RubyUSAGameCode + str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120] movs r1, 0x10 - strh r1, [r3, 0x38] + strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120] ldrb r1, [r0, 0x3] strb r1, [r0, 0x9] ldrb r1, [r0, 0x2] cmp r1, 0 - bne _082DEEF8 - ldr r1, _082DF048 - str r1, [r0, 0x20] - str r1, [r0, 0x24] - adr r2, .L082DEF24 - b _082DEEFC - thumb_func_end sub_82DEEE2 - - thumb_func_start sub_82DEF24 -.L082DEF24: -sub_82DEF24: ; 82DEF24 + 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_CheckGameCodeSent + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_CheckGameCodeSent: ; 82DEF24 lsls r1, 31 - bcc _082DEEF8 - bmi _082DEF34 - adr r2, .L082DEF30 - b _082DEEFC - thumb_func_end sub_82DEF24 - - thumb_func_start sub_82DEF30 -.L082DEF30: -sub_82DEF30: ; 82DEF30 - lsrs r1, 1 - bcc _082DEEF8 -_082DEF34: - ldr r1, [r3, 0x30] - ldr r2, _082DF044 + 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: ; 82DEF30 + 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 _082DEEF8 + bne GcMbIntrHandler_Stop ; stop if the GameCube didn't reply with the same game code ldrb r1, [r0, 0x3] strb r1, [r0, 0xB] - adr r2, .L082DEF44 - b _082DEEFC - thumb_func_end sub_82DEF30 + adr r2, GcMbIntrHandler_82DEF44 + b GameCubeMultiBoot_SetInterruptHandler - thumb_func_start sub_82DEF44 -.L082DEF44: -sub_82DEF44: ; 82DEF44 - lsrs r1, 1 - bcc _082DEEF8 - ldr r1, [r3, 0x30] + .align 2, 0 + +GcMbIntrHandler_82DEF44: ; 82DEF44 + lsrs r1, 1 ; is receive complete? + bcc GcMbIntrHandler_Stop ; branch if not + ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] lsrs r2, r1, 24 cmp r2, 0xDD - bne _082DEEF8 + bne GcMbIntrHandler_Stop str r1, [r0, 0x4] ldrb r1, [r0, 0x1] strb r1, [r0, 0xA] @@ -310,139 +374,166 @@ _082DEF70: _082DEF72: ldr r1, [r0, 0x8] adds r1, 0xEE - ldr r3, _082DF03C - str r1, [r3, 0x34] + ldr r3, pool_SerialRegs + str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120] movs r1, 0x30 - strh r1, [r3, 0x38] - adr r2, .L082DEF84 - b _082DEEFC - thumb_func_end sub_82DEF44 - - thumb_func_start sub_82DEF84 -.L082DEF84: -sub_82DEF84: ; 82DEF84 + strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120] + adr r2, GcMbIntrHandler_82DEF84 + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_82DEF84: ; 82DEF84 lsls r1, 31 - bcc _082DEEF8 - bmi _082DEF94 - adr r2, .L082DEF90 - b _082DEEFC - thumb_func_end sub_82DEF84 - - thumb_func_start sub_82DEF90 -.L082DEF90: -sub_82DEF90: ; 82DEF90 - lsrs r1, 1 - bcc _082DEEF8 + bcc GcMbIntrHandler_Stop ; stop if send failed + bmi _082DEF94 ; branch if receive is complete + adr r2, GcMbIntrHandler_82DEF90 + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_82DEF90: ; 82DEF90 + lsrs r1, 1 ; is receive complete? + bcc GcMbIntrHandler_Stop ; branch if not _082DEF94: - ldr r1, [r3, 0x30] + ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] ldr r2, _082DF034 cmp r1, r2 - bcs _082DEEF8 + bhs GcMbIntrHandler_Stop adds r1, 0x1 adds r1, r1 strh r1, [r0, 0x12] ldrb r1, [r0, 0x2] cmp r1, 0 _082DEFA6: - bne _082DEEF8 - ldr r1, _082DF048 - str r1, [r0, 0x20] - str r1, [r0, 0x24] - adr r2, .L082DEFB4 - b _082DEEFC - thumb_func_end sub_82DEF90 - - thumb_func_start sub_82DEFB4 -.L082DEFB4: -sub_82DEFB4: ; 82DEFB4 - lsrs r1, 1 - bcc _082DEEF8 - ldr r2, [r0, 0x24] + 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_82DEFB4 + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_82DEFB4: ; 82DEFB4 + 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, 0x38] - ldr r1, [r3, 0x30] + strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120] + ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] stm r2!, {r1} - str r2, [r0, 0x24] + str r2, [r0, GCMB_STRUCT_CUR_DEST_PTR] ldrh r1, [r0, 0x12] subs r1, 0x1 strh r1, [r0, 0x12] - bne _082DEEFE + bne GameCubeMultiBoot_ReadVCount + _082DEFD2: ldrb r1, [r0, 0x1] lsls r1, 8 adds r1, 0xCC - str r1, [r3, 0x34] + str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120] adr r2, _082DEFE0 - b _082DEEFC + b GameCubeMultiBoot_SetInterruptHandler + .align 2, 0 + _082DEFE0: lsls r1, 31 + _082DEFE2: - bcc _082DEEF8 + bcc GcMbIntrHandler_Stop ldr r1, [r0, 0x1C] cmp r1, 0 beq _082DEFD2 - str r1, [r3, 0x34] - adr r2, .L082DEFF0 - b _082DEEFC - thumb_func_end sub_82DEFB4 - - thumb_func_start sub_82DEFF0 -.L082DEFF0: -sub_82DEFF0: ; 82DEFF0 + str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120] + adr r2, GcMbIntrHandler_82DEFF0 + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_82DEFF0: ; 82DEFF0 lsls r1, 31 - bcc _082DEFE2 - bmi _082DF000 - adr r2, .L082DEFFC - b _082DEEFC + bcc _082DEFE2 ; branch if send failed + bmi _082DF000 ; branch if receive is complete + adr r2, GcMbIntrHandler_82DEFFC + b GameCubeMultiBoot_SetInterruptHandler + .align 2, 0 -.L082DEFFC: -_082DEFFC: - lsrs r1, 1 - bcc _082DEFE2 + +GcMbIntrHandler_82DEFFC: ; 82DEFFC + lsrs r1, 1 ; is receive complete? + bcc _082DEFE2 ; branch if not + _082DF000: - ldr r1, [r3, 0x30] + ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] lsrs r2, r1, 24 cmp r2, 0xBB bne _082DEFA6 strh r1, [r0, 0x10] - adr r2, .L082DF010 - b _082DEEFC - thumb_func_end sub_82DEFF0 - - thumb_func_start sub_82DF010 -.L082DF010: -sub_82DF010: ; 82DF010 - b _082DEEF8 - thumb_func_end sub_82DF010 - - non_word_aligned_thumb_func_start sub_82DF012 -sub_82DF012: ; 82DF012 - ldr r3, _082DF038 - ldrh r2, [r3, 0x8] + adr r2, GcMbIntrHandler_82DF010 + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_82DF010: ; 82DF010 + b GcMbIntrHandler_Stop + + thumb_func_end GameCubeMultiBoot_HandleSerialInterrupt + + non_word_aligned_thumb_func_start GameCubeMultiBoot_Quit +; void GameCubeMultiBoot_Quit(); +GameCubeMultiBoot_Quit: ; 82DF012 + ldr r3, pool_InterruptRegs + +; Save IME register. + ldrh r2, [r3, OFFSET_REG_IME - 0x200] + +; Disable interrupts. movs r1, 0 - strh r1, [r3, 0x8] - ldr r3, _082DF03C + strh r1, [r3, OFFSET_REG_IME - 0x200] + + ldr r3, pool_SerialRegs + +; Acknowledge all JOYCNT flags. movs r0, 0x7 - strh r0, [r3, 0x20] + strh r0, [r3, OFFSET_REG_JOYCNT - 0x120] + +; Turn off JOY Bus mode. lsls r0, r3, 10 - strh r0, [r3, 0x14] - ldr r3, _082DF038 - movs r0, 0x80 - strh r0, [r3, 0x2] - ldrh r1, [r3] + 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] - strh r2, [r3, 0x8] + 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 -_082DF034: .4byte 0x00004000 -_082DF038: .4byte 0x04000200 -_082DF03C: .4byte 0x04000120 -_082DF040: .4byte 0x04000004 -_082DF044: .4byte 0x45565841 -_082DF048: .4byte 0x02000000 - thumb_func_end sub_82DF012 + +_082DF034: .4byte 0x4000 + +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 diff --git a/asm/rom_header.s b/asm/rom_header.s index a9cbf9429..e03b9ceb3 100644 --- a/asm/rom_header.s +++ b/asm/rom_header.s @@ -1,5 +1,3 @@ - b Init - RomHeaderNintendoLogo: .incbin "base_emerald.gba", 0x4, 0xA0 - 0x4 |