mirror of https://github.com/PrimeDecomp/prime.git
Match and link EXI
This commit is contained in:
parent
2f5676d2e0
commit
4059bf7e3d
|
@ -23,8 +23,8 @@ lbl_803F7050:
|
|||
|
||||
.section .bss
|
||||
.balign 8
|
||||
.global lbl_80569E98
|
||||
lbl_80569E98:
|
||||
.global Ecb
|
||||
Ecb:
|
||||
.skip 0xC8
|
||||
|
||||
.section .sdata, "wa"
|
||||
|
@ -46,8 +46,8 @@ SetExiInterruptMask:
|
|||
/* 803C001C 003BCF7C 94 21 FF E8 */ stwu r1, -0x18(r1)
|
||||
/* 803C0020 003BCF80 93 E1 00 14 */ stw r31, 0x14(r1)
|
||||
/* 803C0024 003BCF84 3B E4 00 00 */ addi r31, r4, 0
|
||||
/* 803C0028 003BCF88 3C 80 80 57 */ lis r4, lbl_80569E98@ha
|
||||
/* 803C002C 003BCF8C 38 84 9E 98 */ addi r4, r4, lbl_80569E98@l
|
||||
/* 803C0028 003BCF88 3C 80 80 57 */ lis r4, Ecb@ha
|
||||
/* 803C002C 003BCF8C 38 84 9E 98 */ addi r4, r4, Ecb@l
|
||||
/* 803C0030 003BCF90 38 84 00 80 */ addi r4, r4, 0x80
|
||||
/* 803C0034 003BCF94 2C 03 00 01 */ cmpwi r3, 1
|
||||
/* 803C0038 003BCF98 41 82 00 5C */ beq lbl_803C0094
|
||||
|
@ -127,8 +127,8 @@ EXIImm:
|
|||
/* 803C0124 003BD084 3B A6 00 00 */ addi r29, r6, 0
|
||||
/* 803C0128 003BD088 3B 27 00 00 */ addi r25, r7, 0
|
||||
/* 803C012C 003BD08C 54 64 30 32 */ slwi r4, r3, 6
|
||||
/* 803C0130 003BD090 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C0134 003BD094 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C0130 003BD090 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C0134 003BD094 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C0138 003BD098 7F E0 22 14 */ add r31, r0, r4
|
||||
/* 803C013C 003BD09C 4B FC 15 25 */ bl OSDisableInterrupts
|
||||
/* 803C0140 003BD0A0 7C 7E 1B 78 */ mr r30, r3
|
||||
|
@ -343,8 +343,8 @@ EXIDma:
|
|||
/* 803C0420 003BD380 3B C6 00 00 */ addi r30, r6, 0
|
||||
/* 803C0424 003BD384 3B 27 00 00 */ addi r25, r7, 0
|
||||
/* 803C0428 003BD388 54 64 30 32 */ slwi r4, r3, 6
|
||||
/* 803C042C 003BD38C 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C0430 003BD390 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C042C 003BD38C 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C0430 003BD390 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C0434 003BD394 7F 40 22 14 */ add r26, r0, r4
|
||||
/* 803C0438 003BD398 4B FC 12 29 */ bl OSDisableInterrupts
|
||||
/* 803C043C 003BD39C 7C 7F 1B 78 */ mr r31, r3
|
||||
|
@ -404,8 +404,8 @@ EXISync:
|
|||
/* 803C04F8 003BD458 94 21 FF D0 */ stwu r1, -0x30(r1)
|
||||
/* 803C04FC 003BD45C BF 61 00 1C */ stmw r27, 0x1c(r1)
|
||||
/* 803C0500 003BD460 54 65 30 32 */ slwi r5, r3, 6
|
||||
/* 803C0504 003BD464 3C 80 80 57 */ lis r4, lbl_80569E98@ha
|
||||
/* 803C0508 003BD468 38 04 9E 98 */ addi r0, r4, lbl_80569E98@l
|
||||
/* 803C0504 003BD464 3C 80 80 57 */ lis r4, Ecb@ha
|
||||
/* 803C0508 003BD468 38 04 9E 98 */ addi r0, r4, Ecb@l
|
||||
/* 803C050C 003BD46C 7F E0 2A 14 */ add r31, r0, r5
|
||||
/* 803C0510 003BD470 3B 80 00 00 */ li r28, 0
|
||||
/* 803C0514 003BD474 1F C3 00 14 */ mulli r30, r3, 0x14
|
||||
|
@ -586,8 +586,8 @@ EXISetExiCallback:
|
|||
/* 803C0780 003BD6E0 3B 43 00 00 */ addi r26, r3, 0
|
||||
/* 803C0784 003BD6E4 3B 64 00 00 */ addi r27, r4, 0
|
||||
/* 803C0788 003BD6E8 54 60 30 32 */ slwi r0, r3, 6
|
||||
/* 803C078C 003BD6EC 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C0790 003BD6F0 3B E3 9E 98 */ addi r31, r3, lbl_80569E98@l
|
||||
/* 803C078C 003BD6EC 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C0790 003BD6F0 3B E3 9E 98 */ addi r31, r3, Ecb@l
|
||||
/* 803C0794 003BD6F4 7F DF 02 14 */ add r30, r31, r0
|
||||
/* 803C0798 003BD6F8 4B FC 0E C9 */ bl OSDisableInterrupts
|
||||
/* 803C079C 003BD6FC 7C 7C 1B 78 */ mr r28, r3
|
||||
|
@ -621,8 +621,8 @@ __EXIProbe:
|
|||
/* 803C07F8 003BD758 BF 61 00 14 */ stmw r27, 0x14(r1)
|
||||
/* 803C07FC 003BD75C 3B 83 00 00 */ addi r28, r3, 0
|
||||
/* 803C0800 003BD760 54 64 30 32 */ slwi r4, r3, 6
|
||||
/* 803C0804 003BD764 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C0808 003BD768 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C0804 003BD764 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C0808 003BD768 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C080C 003BD76C 7F E0 22 14 */ add r31, r0, r4
|
||||
/* 803C0810 003BD770 2C 1C 00 02 */ cmpwi r28, 2
|
||||
/* 803C0814 003BD774 40 82 00 0C */ bne lbl_803C0820
|
||||
|
@ -726,8 +726,8 @@ EXIProbe:
|
|||
/* 803C0970 003BD8D0 93 C1 00 10 */ stw r30, 0x10(r1)
|
||||
/* 803C0974 003BD8D4 3B C3 00 00 */ addi r30, r3, 0
|
||||
/* 803C0978 003BD8D8 54 64 30 32 */ slwi r4, r3, 6
|
||||
/* 803C097C 003BD8DC 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C0980 003BD8E0 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C097C 003BD8DC 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C0980 003BD8E0 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C0984 003BD8E4 7F E0 22 14 */ add r31, r0, r4
|
||||
/* 803C0988 003BD8E8 38 7E 00 00 */ addi r3, r30, 0
|
||||
/* 803C098C 003BD8EC 4B FF FE 61 */ bl __EXIProbe
|
||||
|
@ -763,8 +763,8 @@ EXIProbeEx:
|
|||
/* 803C09F0 003BD950 93 C1 00 10 */ stw r30, 0x10(r1)
|
||||
/* 803C09F4 003BD954 3B C3 00 00 */ addi r30, r3, 0
|
||||
/* 803C09F8 003BD958 54 64 30 32 */ slwi r4, r3, 6
|
||||
/* 803C09FC 003BD95C 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C0A00 003BD960 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C09FC 003BD95C 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C0A00 003BD960 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C0A04 003BD964 7F E0 22 14 */ add r31, r0, r4
|
||||
/* 803C0A08 003BD968 38 7E 00 00 */ addi r3, r30, 0
|
||||
/* 803C0A0C 003BD96C 4B FF FD E1 */ bl __EXIProbe
|
||||
|
@ -816,8 +816,8 @@ EXIAttach:
|
|||
/* 803C0AA4 003BDA04 3B 63 00 00 */ addi r27, r3, 0
|
||||
/* 803C0AA8 003BDA08 3B 84 00 00 */ addi r28, r4, 0
|
||||
/* 803C0AAC 003BDA0C 54 64 30 32 */ slwi r4, r3, 6
|
||||
/* 803C0AB0 003BDA10 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C0AB4 003BDA14 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C0AB0 003BDA10 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C0AB4 003BDA14 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C0AB8 003BDA18 7F C0 22 14 */ add r30, r0, r4
|
||||
/* 803C0ABC 003BDA1C 38 7B 00 00 */ addi r3, r27, 0
|
||||
/* 803C0AC0 003BDA20 4B FF FD 2D */ bl __EXIProbe
|
||||
|
@ -893,8 +893,8 @@ EXIDetach:
|
|||
/* 803C0BB4 003BDB14 93 A1 00 14 */ stw r29, 0x14(r1)
|
||||
/* 803C0BB8 003BDB18 3B A3 00 00 */ addi r29, r3, 0
|
||||
/* 803C0BBC 003BDB1C 54 64 30 32 */ slwi r4, r3, 6
|
||||
/* 803C0BC0 003BDB20 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C0BC4 003BDB24 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C0BC0 003BDB20 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C0BC4 003BDB24 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C0BC8 003BDB28 7F E0 22 14 */ add r31, r0, r4
|
||||
/* 803C0BCC 003BDB2C 4B FC 0A 95 */ bl OSDisableInterrupts
|
||||
/* 803C0BD0 003BDB30 7C 7E 1B 78 */ mr r30, r3
|
||||
|
@ -946,8 +946,8 @@ EXISelect:
|
|||
/* 803C0C70 003BDBD0 3B 84 00 00 */ addi r28, r4, 0
|
||||
/* 803C0C74 003BDBD4 3B A5 00 00 */ addi r29, r5, 0
|
||||
/* 803C0C78 003BDBD8 54 64 30 32 */ slwi r4, r3, 6
|
||||
/* 803C0C7C 003BDBDC 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C0C80 003BDBE0 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C0C7C 003BDBDC 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C0C80 003BDBE0 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C0C84 003BDBE4 7F E0 22 14 */ add r31, r0, r4
|
||||
/* 803C0C88 003BDBE8 4B FC 09 D9 */ bl OSDisableInterrupts
|
||||
/* 803C0C8C 003BDBEC 7C 7E 1B 78 */ mr r30, r3
|
||||
|
@ -1032,8 +1032,8 @@ EXIDeselect:
|
|||
/* 803C0DA0 003BDD00 93 81 00 10 */ stw r28, 0x10(r1)
|
||||
/* 803C0DA4 003BDD04 3B E3 00 00 */ addi r31, r3, 0
|
||||
/* 803C0DA8 003BDD08 54 64 30 32 */ slwi r4, r3, 6
|
||||
/* 803C0DAC 003BDD0C 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C0DB0 003BDD10 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C0DAC 003BDD0C 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C0DB0 003BDD10 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C0DB4 003BDD14 7F C0 22 14 */ add r30, r0, r4
|
||||
/* 803C0DB8 003BDD18 4B FC 08 A9 */ bl OSDisableInterrupts
|
||||
/* 803C0DBC 003BDD1C 7C 7C 1B 78 */ mr r28, r3
|
||||
|
@ -1124,8 +1124,8 @@ EXIIntrruptHandler:
|
|||
/* 803C0EE8 003BDE48 60 00 00 02 */ ori r0, r0, 2
|
||||
/* 803C0EEC 003BDE4C 90 03 00 00 */ stw r0, 0(r3)
|
||||
/* 803C0EF0 003BDE50 57 C4 30 32 */ slwi r4, r30, 6
|
||||
/* 803C0EF4 003BDE54 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C0EF8 003BDE58 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C0EF4 003BDE54 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C0EF8 003BDE58 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C0EFC 003BDE5C 7C 60 22 14 */ add r3, r0, r4
|
||||
/* 803C0F00 003BDE60 80 03 00 00 */ lwz r0, 0(r3)
|
||||
/* 803C0F04 003BDE64 7C 1D 03 78 */ mr r29, r0
|
||||
|
@ -1171,8 +1171,8 @@ TCIntrruptHandler:
|
|||
/* 803C0F94 003BDEF4 54 60 0F FE */ srwi r0, r3, 0x1f
|
||||
/* 803C0F98 003BDEF8 7F C3 02 14 */ add r30, r3, r0
|
||||
/* 803C0F9C 003BDEFC 57 C4 30 32 */ slwi r4, r30, 6
|
||||
/* 803C0FA0 003BDF00 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C0FA4 003BDF04 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C0FA0 003BDF00 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C0FA4 003BDF04 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C0FA8 003BDF08 7F E0 22 14 */ add r31, r0, r4
|
||||
/* 803C0FAC 003BDF0C 3C 00 80 00 */ lis r0, 0x8000
|
||||
/* 803C0FB0 003BDF10 7C 03 2C 30 */ srw r3, r0, r5
|
||||
|
@ -1318,8 +1318,8 @@ EXTIntrruptHandler:
|
|||
/* 803C11BC 003BE11C 7C 63 04 30 */ srw r3, r3, r0
|
||||
/* 803C11C0 003BE120 4B FC 08 69 */ bl __OSMaskInterrupts
|
||||
/* 803C11C4 003BE124 57 C4 30 32 */ slwi r4, r30, 6
|
||||
/* 803C11C8 003BE128 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C11CC 003BE12C 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C11C8 003BE128 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C11CC 003BE12C 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C11D0 003BE130 7F A0 22 14 */ add r29, r0, r4
|
||||
/* 803C11D4 003BE134 83 9D 00 08 */ lwz r28, 8(r29)
|
||||
/* 803C11D8 003BE138 80 1D 00 0C */ lwz r0, 0xc(r29)
|
||||
|
@ -1409,8 +1409,8 @@ EXIInit:
|
|||
/* 803C1318 003BE278 3C 80 80 00 */ lis r4, 0x800030C4@ha
|
||||
/* 803C131C 003BE27C 93 E4 30 C4 */ stw r31, 0x800030C4@l(r4)
|
||||
/* 803C1320 003BE280 93 E4 30 C0 */ stw r31, 0x30c0(r4)
|
||||
/* 803C1324 003BE284 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C1328 003BE288 38 63 9E 98 */ addi r3, r3, lbl_80569E98@l
|
||||
/* 803C1324 003BE284 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C1328 003BE288 38 63 9E 98 */ addi r3, r3, Ecb@l
|
||||
/* 803C132C 003BE28C 93 E3 00 60 */ stw r31, 0x60(r3)
|
||||
/* 803C1330 003BE290 93 E3 00 20 */ stw r31, 0x20(r3)
|
||||
/* 803C1334 003BE294 38 60 00 00 */ li r3, 0
|
||||
|
@ -1437,8 +1437,8 @@ EXILock:
|
|||
/* 803C1378 003BE2D8 3B E4 00 00 */ addi r31, r4, 0
|
||||
/* 803C137C 003BE2DC 3B 85 00 00 */ addi r28, r5, 0
|
||||
/* 803C1380 003BE2E0 54 64 30 32 */ slwi r4, r3, 6
|
||||
/* 803C1384 003BE2E4 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C1388 003BE2E8 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C1384 003BE2E4 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C1388 003BE2E8 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C138C 003BE2EC 7F C0 22 14 */ add r30, r0, r4
|
||||
/* 803C1390 003BE2F0 4B FC 02 D1 */ bl OSDisableInterrupts
|
||||
/* 803C1394 003BE2F4 7C 7D 1B 78 */ mr r29, r3
|
||||
|
@ -1508,8 +1508,8 @@ EXIUnlock:
|
|||
/* 803C1470 003BE3D0 93 81 00 10 */ stw r28, 0x10(r1)
|
||||
/* 803C1474 003BE3D4 3B 83 00 00 */ addi r28, r3, 0
|
||||
/* 803C1478 003BE3D8 54 64 30 32 */ slwi r4, r3, 6
|
||||
/* 803C147C 003BE3DC 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C1480 003BE3E0 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C147C 003BE3DC 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C1480 003BE3E0 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C1484 003BE3E4 7F E0 22 14 */ add r31, r0, r4
|
||||
/* 803C1488 003BE3E8 4B FC 01 D9 */ bl OSDisableInterrupts
|
||||
/* 803C148C 003BE3EC 7C 7E 1B 78 */ mr r30, r3
|
||||
|
@ -1562,8 +1562,8 @@ lbl_803C1514:
|
|||
.global EXIGetState
|
||||
EXIGetState:
|
||||
/* 803C1534 003BE494 54 64 30 32 */ slwi r4, r3, 6
|
||||
/* 803C1538 003BE498 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C153C 003BE49C 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C1538 003BE498 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C153C 003BE49C 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C1540 003BE4A0 7C 60 22 14 */ add r3, r0, r4
|
||||
/* 803C1544 003BE4A4 80 63 00 0C */ lwz r3, 0xc(r3)
|
||||
/* 803C1548 003BE4A8 4E 80 00 20 */ blr
|
||||
|
@ -1591,8 +1591,8 @@ EXIGetID:
|
|||
/* 803C1588 003BE4E8 3B 64 00 00 */ addi r27, r4, 0
|
||||
/* 803C158C 003BE4EC 3B 85 00 00 */ addi r28, r5, 0
|
||||
/* 803C1590 003BE4F0 54 64 30 32 */ slwi r4, r3, 6
|
||||
/* 803C1594 003BE4F4 3C 60 80 57 */ lis r3, lbl_80569E98@ha
|
||||
/* 803C1598 003BE4F8 38 03 9E 98 */ addi r0, r3, lbl_80569E98@l
|
||||
/* 803C1594 003BE4F4 3C 60 80 57 */ lis r3, Ecb@ha
|
||||
/* 803C1598 003BE4F8 38 03 9E 98 */ addi r0, r3, Ecb@l
|
||||
/* 803C159C 003BE4FC 7F E0 22 14 */ add r31, r0, r4
|
||||
/* 803C15A0 003BE500 2C 1A 00 02 */ cmpwi r26, 2
|
||||
/* 803C15A4 003BE504 40 80 00 E0 */ bge lbl_803C1684
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.include "macros.inc"
|
||||
|
||||
.section .bss
|
||||
.balign 8
|
||||
.balign 32
|
||||
.global lbl_80569F60
|
||||
lbl_80569F60:
|
||||
.skip 0x118
|
||||
|
@ -8049,4 +8049,3 @@ THPInit:
|
|||
/* 803C90BC 003C601C 38 21 00 10 */ addi r1, r1, 0x10
|
||||
/* 803C90C0 003C6020 7C 08 03 A6 */ mtlr r0
|
||||
/* 803C90C4 003C6024 4E 80 00 20 */ blr
|
||||
|
||||
|
|
|
@ -1005,8 +1005,8 @@ LIBS = [
|
|||
"cflags": "$cflags_base",
|
||||
"host": False,
|
||||
"objects": [
|
||||
"Dolphin/exi/EXIBios",
|
||||
"Dolphin/exi/EXIUart",
|
||||
["Dolphin/exi/EXIBios", True],
|
||||
["Dolphin/exi/EXIUart", True],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
@ -155,6 +155,7 @@ void OSFatal(GXColor fg, GXColor bg, const char* msg);
|
|||
#include <dolphin/os/OSContext.h>
|
||||
#include <dolphin/os/OSError.h>
|
||||
#include <dolphin/os/OSException.h>
|
||||
#include <dolphin/os/OSExpansion.h>
|
||||
#include <dolphin/os/OSFastCast.h>
|
||||
#include <dolphin/os/OSFont.h>
|
||||
#include <dolphin/os/OSInterrupt.h>
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
#ifndef _DOLPHIN_OSEXPANSION
|
||||
#define _DOLPHIN_OSEXPANSION
|
||||
|
||||
#include <dolphin/os.h>
|
||||
#include <dolphin/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define EXI_MEMORY_CARD_59 0x00000004
|
||||
#define EXI_MEMORY_CARD_123 0x00000008
|
||||
#define EXI_MEMORY_CARD_251 0x00000010
|
||||
#define EXI_MEMORY_CARD_507 0x00000020
|
||||
|
||||
#define EXI_MEMORY_CARD_1019 0x00000040
|
||||
#define EXI_MEMORY_CARD_2043 0x00000080
|
||||
|
||||
#define EXI_MEMORY_CARD_1019A 0x00000140
|
||||
#define EXI_MEMORY_CARD_1019B 0x00000240
|
||||
#define EXI_MEMORY_CARD_1019C 0x00000340
|
||||
#define EXI_MEMORY_CARD_1019D 0x00000440
|
||||
#define EXI_MEMORY_CARD_1019E 0x00000540
|
||||
#define EXI_MEMORY_CARD_1019F 0x00000640
|
||||
#define EXI_MEMORY_CARD_1019G 0x00000740
|
||||
|
||||
#define EXI_MEMORY_CARD_2043A 0x00000180
|
||||
#define EXI_MEMORY_CARD_2043B 0x00000280
|
||||
#define EXI_MEMORY_CARD_2043C 0x00000380
|
||||
#define EXI_MEMORY_CARD_2043D 0x00000480
|
||||
#define EXI_MEMORY_CARD_2043E 0x00000580
|
||||
#define EXI_MEMORY_CARD_2043F 0x00000680
|
||||
#define EXI_MEMORY_CARD_2043G 0x00000780
|
||||
|
||||
#define EXI_USB_ADAPTER 0x01010000
|
||||
#define EXI_NPDP_GDEV 0x01020000
|
||||
|
||||
#define EXI_MODEM 0x02020000
|
||||
#define EXI_ETHER 0x04020200
|
||||
#define EXI_ETHER_VIEWER 0x04220001
|
||||
#define EXI_STREAM_HANGER 0x04130000
|
||||
|
||||
#define EXI_MARLIN 0x03010000
|
||||
|
||||
#define EXI_IS_VIEWER 0x05070000
|
||||
|
||||
#define EXI_FREQ_1M 0
|
||||
#define EXI_FREQ_2M 1
|
||||
#define EXI_FREQ_4M 2
|
||||
#define EXI_FREQ_8M 3
|
||||
#define EXI_FREQ_16M 4
|
||||
#define EXI_FREQ_32M 5
|
||||
|
||||
#define EXI_READ 0
|
||||
#define EXI_WRITE 1
|
||||
|
||||
#define EXI_STATE_IDLE 0x00
|
||||
#define EXI_STATE_DMA 0x01
|
||||
#define EXI_STATE_IMM 0x02
|
||||
#define EXI_STATE_BUSY (EXI_STATE_DMA | EXI_STATE_IMM)
|
||||
#define EXI_STATE_SELECTED 0x04
|
||||
#define EXI_STATE_ATTACHED 0x08
|
||||
#define EXI_STATE_LOCKED 0x10
|
||||
|
||||
BOOL EXIProbe(s32 chan);
|
||||
s32 EXIProbeEx(s32 chan);
|
||||
|
||||
s32 EXIGetType(s32 chan, u32 dev, u32* type);
|
||||
char* EXIGetTypeString(u32 type);
|
||||
u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext);
|
||||
s32 EXIGetID(s32 chan, u32 dev, u32* id);
|
||||
|
||||
typedef void (*EXICallback)(s32 chan, OSContext* context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _DOLPHIN_OSEXPANSION
|
|
@ -0,0 +1,690 @@
|
|||
#include "dolphin/os.h"
|
||||
|
||||
#pragma scheduling off
|
||||
|
||||
vu32 __EXIRegs[16] : 0xCC006800;
|
||||
|
||||
static const char* __EXIVersion =
|
||||
"<< Dolphin SDK - EXI\trelease build: Sep 5 2002 05:33:04 (0x2301) >>";
|
||||
|
||||
#define MAX_DEV 3
|
||||
#define MAX_CHAN 3
|
||||
|
||||
#define REG_MAX 5
|
||||
#define REG(chan, idx) (__EXIRegs[((chan)*REG_MAX) + (idx)])
|
||||
|
||||
#define STATE_IDLE 0x00
|
||||
#define STATE_DMA 0x01
|
||||
#define STATE_IMM 0x02
|
||||
#define STATE_BUSY (STATE_DMA | STATE_IMM)
|
||||
#define STATE_SELECTED 0x04
|
||||
#define STATE_ATTACHED 0x08
|
||||
#define STATE_LOCKED 0x10
|
||||
|
||||
#define EXI_0CR(tstart, dma, rw, tlen) \
|
||||
((((u32)(tstart)) << 0) | (((u32)(dma)) << 1) | (((u32)(rw)) << 2) | (((u32)(tlen)) << 4))
|
||||
|
||||
#define CPR_CS(x) ((1u << (x)) << 7)
|
||||
#define CPR_CLK(x) ((x) << 4)
|
||||
|
||||
typedef struct EXIControl {
|
||||
EXICallback exiCallback;
|
||||
EXICallback tcCallback;
|
||||
EXICallback extCallback;
|
||||
vu32 state;
|
||||
int immLen;
|
||||
u8* immBuf;
|
||||
u32 dev;
|
||||
u32 id;
|
||||
s32 idTime;
|
||||
int items;
|
||||
struct {
|
||||
u32 dev;
|
||||
EXICallback callback;
|
||||
} queue[MAX_DEV];
|
||||
} EXIControl;
|
||||
|
||||
static EXIControl Ecb[MAX_CHAN];
|
||||
|
||||
s32 __EXIProbeStartTime[2] : (OS_BASE_CACHED | 0x30C0);
|
||||
|
||||
static void SetExiInterruptMask(s32 chan, EXIControl* exi) {
|
||||
EXIControl* exi2;
|
||||
|
||||
exi2 = &Ecb[2];
|
||||
switch (chan) {
|
||||
case 0:
|
||||
if ((exi->exiCallback == 0 && exi2->exiCallback == 0) || (exi->state & STATE_LOCKED)) {
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI);
|
||||
} else {
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (exi->exiCallback == 0 || (exi->state & STATE_LOCKED)) {
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI);
|
||||
} else {
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (__OSGetInterruptHandler(__OS_INTERRUPT_PI_DEBUG) == 0 || (exi->state & STATE_LOCKED)) {
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG);
|
||||
} else {
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void CompleteTransfer(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
u8* buf;
|
||||
u32 data;
|
||||
int i;
|
||||
int len;
|
||||
|
||||
if (exi->state & STATE_BUSY) {
|
||||
if ((exi->state & STATE_IMM) && (len = exi->immLen)) {
|
||||
buf = exi->immBuf;
|
||||
data = REG(chan, 4);
|
||||
for (i = 0; i < len; i++) {
|
||||
*buf++ = (u8)((data >> ((3 - i) * 8)) & 0xff);
|
||||
}
|
||||
}
|
||||
exi->state &= ~STATE_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL EXIImm(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exi->tcCallback = callback;
|
||||
if (exi->tcCallback) {
|
||||
EXIClearInterrupts(chan, FALSE, TRUE, FALSE);
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_TC >> (3 * chan));
|
||||
}
|
||||
|
||||
exi->state |= STATE_IMM;
|
||||
|
||||
if (type != EXI_READ) {
|
||||
u32 data;
|
||||
int i;
|
||||
|
||||
data = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
data |= ((u8*)buf)[i] << ((3 - i) * 8);
|
||||
}
|
||||
REG(chan, 4) = data;
|
||||
}
|
||||
|
||||
exi->immBuf = buf;
|
||||
exi->immLen = (type != EXI_WRITE) ? len : 0;
|
||||
|
||||
REG(chan, 3) = EXI_0CR(1, 0, type, len - 1);
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EXIImmEx(s32 chan, void* buf, s32 len, u32 mode) {
|
||||
s32 xLen;
|
||||
|
||||
while (len) {
|
||||
xLen = (len < 4) ? len : 4;
|
||||
if (!EXIImm(chan, buf, xLen, mode, NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!EXISync(chan)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
(u8*)buf += xLen;
|
||||
len -= xLen;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EXIDma(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exi->tcCallback = callback;
|
||||
if (exi->tcCallback) {
|
||||
EXIClearInterrupts(chan, FALSE, TRUE, FALSE);
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_TC >> (3 * chan));
|
||||
}
|
||||
|
||||
exi->state |= STATE_DMA;
|
||||
|
||||
REG(chan, 1) = (u32)buf & 0x3ffffe0;
|
||||
REG(chan, 2) = (u32)len;
|
||||
REG(chan, 3) = EXI_0CR(1, 1, type, 0);
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
extern u32 __OSGetDIConfig(void);
|
||||
|
||||
vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6);
|
||||
|
||||
BOOL EXISync(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL rc = FALSE;
|
||||
BOOL enabled;
|
||||
|
||||
while (exi->state & STATE_SELECTED) {
|
||||
if (((REG(chan, 3) & 1) >> 0) == 0) {
|
||||
enabled = OSDisableInterrupts();
|
||||
if (exi->state & STATE_SELECTED) {
|
||||
CompleteTransfer(chan);
|
||||
if (__OSGetDIConfig() != 0xff || exi->immLen != 4 ||
|
||||
(REG(chan, 0) & 0x00000070) != (EXI_FREQ_1M << 4) ||
|
||||
(REG(chan, 4) != EXI_USB_ADAPTER && REG(chan, 4) != EXI_IS_VIEWER &&
|
||||
REG(chan, 4) != 0x04220001) ||
|
||||
__OSDeviceCode == 0x8200) {
|
||||
rc = TRUE;
|
||||
}
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext) {
|
||||
u32 cpr;
|
||||
u32 prev;
|
||||
|
||||
prev = cpr = REG(chan, 0);
|
||||
cpr &= 0x7f5;
|
||||
if (exi)
|
||||
cpr |= 2;
|
||||
if (tc)
|
||||
cpr |= 8;
|
||||
if (ext)
|
||||
cpr |= 0x800;
|
||||
REG(chan, 0) = cpr;
|
||||
return prev;
|
||||
}
|
||||
|
||||
EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
EXICallback prev;
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
prev = exi->exiCallback;
|
||||
exi->exiCallback = exiCallback;
|
||||
|
||||
if (chan != 2) {
|
||||
SetExiInterruptMask(chan, exi);
|
||||
} else {
|
||||
SetExiInterruptMask(0, &Ecb[0]);
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return prev;
|
||||
}
|
||||
|
||||
void EXIProbeReset(void) {
|
||||
__EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0;
|
||||
Ecb[0].idTime = Ecb[1].idTime = 0;
|
||||
__EXIProbe(0);
|
||||
__EXIProbe(1);
|
||||
}
|
||||
|
||||
static BOOL __EXIProbe(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
BOOL rc;
|
||||
u32 cpr;
|
||||
s32 t;
|
||||
|
||||
if (chan == 2) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
rc = TRUE;
|
||||
enabled = OSDisableInterrupts();
|
||||
cpr = REG(chan, 0);
|
||||
if (!(exi->state & EXI_STATE_ATTACHED)) {
|
||||
if (cpr & 0x00000800) {
|
||||
EXIClearInterrupts(chan, FALSE, FALSE, TRUE);
|
||||
__EXIProbeStartTime[chan] = exi->idTime = 0;
|
||||
}
|
||||
|
||||
if (cpr & 0x00001000) {
|
||||
t = (s32)(OSTicksToMilliseconds(OSGetTime()) / 100) + 1;
|
||||
if (__EXIProbeStartTime[chan] == 0) {
|
||||
__EXIProbeStartTime[chan] = t;
|
||||
}
|
||||
if (t - __EXIProbeStartTime[chan] < 300 / 100) {
|
||||
rc = FALSE;
|
||||
}
|
||||
} else {
|
||||
__EXIProbeStartTime[chan] = exi->idTime = 0;
|
||||
rc = FALSE;
|
||||
}
|
||||
} else if (!(cpr & 0x00001000) || (cpr & 0x00000800)) {
|
||||
__EXIProbeStartTime[chan] = exi->idTime = 0;
|
||||
rc = FALSE;
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
BOOL EXIProbe(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL rc;
|
||||
u32 id;
|
||||
|
||||
rc = __EXIProbe(chan);
|
||||
if (rc && exi->idTime == 0) {
|
||||
rc = EXIGetID(chan, 0, &id) ? TRUE : FALSE;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
s32 EXIProbeEx(s32 chan) {
|
||||
if (EXIProbe(chan)) {
|
||||
return 1;
|
||||
} else if (__EXIProbeStartTime[chan] != 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL __EXIAttach(s32 chan, EXICallback extCallback) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if ((exi->state & EXI_STATE_ATTACHED) || __EXIProbe(chan) == FALSE) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EXIClearInterrupts(chan, TRUE, FALSE, FALSE);
|
||||
|
||||
exi->extCallback = extCallback;
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT >> (3 * chan));
|
||||
exi->state |= STATE_ATTACHED;
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EXIAttach(s32 chan, EXICallback extCallback) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
BOOL rc;
|
||||
|
||||
EXIProbe(chan);
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (exi->idTime == 0) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
rc = __EXIAttach(chan, extCallback);
|
||||
OSRestoreInterrupts(enabled);
|
||||
return rc;
|
||||
}
|
||||
|
||||
BOOL EXIDetach(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (!(exi->state & STATE_ATTACHED)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
if ((exi->state & STATE_LOCKED) && exi->dev == 0) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exi->state &= ~STATE_ATTACHED;
|
||||
__OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan));
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EXISelect(s32 chan, u32 dev, u32 freq) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
u32 cpr;
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if ((exi->state & STATE_SELECTED) ||
|
||||
chan != 2 && (dev == 0 && !(exi->state & STATE_ATTACHED) && !__EXIProbe(chan) ||
|
||||
!(exi->state & STATE_LOCKED) || (exi->dev != dev))) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exi->state |= STATE_SELECTED;
|
||||
cpr = REG(chan, 0);
|
||||
cpr &= 0x405;
|
||||
cpr |= CPR_CS(dev) | CPR_CLK(freq);
|
||||
REG(chan, 0) = cpr;
|
||||
|
||||
if (exi->state & STATE_ATTACHED) {
|
||||
switch (chan) {
|
||||
case 0:
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT);
|
||||
break;
|
||||
case 1:
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EXIDeselect(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
u32 cpr;
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (!(exi->state & STATE_SELECTED)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
exi->state &= ~STATE_SELECTED;
|
||||
cpr = REG(chan, 0);
|
||||
REG(chan, 0) = cpr & 0x405;
|
||||
|
||||
if (exi->state & STATE_ATTACHED) {
|
||||
switch (chan) {
|
||||
case 0:
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT);
|
||||
break;
|
||||
case 1:
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
if (chan != 2 && (cpr & CPR_CS(0))) {
|
||||
return __EXIProbe(chan) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext* context) {
|
||||
s32 chan;
|
||||
EXIControl* exi;
|
||||
EXICallback callback;
|
||||
|
||||
chan = (interrupt - __OS_INTERRUPT_EXI_0_EXI) / 3;
|
||||
exi = &Ecb[chan];
|
||||
EXIClearInterrupts(chan, TRUE, FALSE, FALSE);
|
||||
callback = exi->exiCallback;
|
||||
if (callback) {
|
||||
OSContext exceptionContext;
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(&exceptionContext);
|
||||
|
||||
callback(chan, context);
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
static void TCIntrruptHandler(__OSInterrupt interrupt, OSContext* context) {
|
||||
OSContext exceptionContext;
|
||||
s32 chan;
|
||||
EXIControl* exi;
|
||||
EXICallback callback;
|
||||
|
||||
chan = (interrupt - __OS_INTERRUPT_EXI_0_TC) / 3;
|
||||
exi = &Ecb[chan];
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK(interrupt));
|
||||
EXIClearInterrupts(chan, FALSE, TRUE, FALSE);
|
||||
callback = exi->tcCallback;
|
||||
if (callback) {
|
||||
exi->tcCallback = 0;
|
||||
CompleteTransfer(chan);
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(&exceptionContext);
|
||||
|
||||
callback(chan, context);
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
static void EXTIntrruptHandler(__OSInterrupt interrupt, OSContext* context) {
|
||||
s32 chan;
|
||||
EXIControl* exi;
|
||||
EXICallback callback;
|
||||
|
||||
chan = (interrupt - __OS_INTERRUPT_EXI_0_EXT) / 3;
|
||||
__OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan));
|
||||
exi = &Ecb[chan];
|
||||
callback = exi->extCallback;
|
||||
exi->state &= ~STATE_ATTACHED;
|
||||
if (callback) {
|
||||
OSContext exceptionContext;
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(&exceptionContext);
|
||||
|
||||
exi->extCallback = 0;
|
||||
callback(chan, context);
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
void EXIInit(void) {
|
||||
OSRegisterVersion(__EXIVersion);
|
||||
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC |
|
||||
OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_1_EXI |
|
||||
OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT |
|
||||
OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC);
|
||||
|
||||
REG(0, 0) = 0;
|
||||
REG(1, 0) = 0;
|
||||
REG(2, 0) = 0;
|
||||
|
||||
REG(0, 0) = 0x00002000;
|
||||
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_EXI, EXIIntrruptHandler);
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_TC, TCIntrruptHandler);
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_EXT, EXTIntrruptHandler);
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_EXI, EXIIntrruptHandler);
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_TC, TCIntrruptHandler);
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_EXT, EXTIntrruptHandler);
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_2_EXI, EXIIntrruptHandler);
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_2_TC, TCIntrruptHandler);
|
||||
|
||||
if ((OSGetConsoleType() & 0x10000000) != 0) {
|
||||
__EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0;
|
||||
Ecb[0].idTime = Ecb[1].idTime = 0;
|
||||
__EXIProbe(0);
|
||||
__EXIProbe(1);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
int i;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (exi->state & STATE_LOCKED) {
|
||||
if (unlockedCallback) {
|
||||
for (i = 0; i < exi->items; i++) {
|
||||
if (exi->queue[i].dev == dev) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
exi->queue[exi->items].callback = unlockedCallback;
|
||||
exi->queue[exi->items].dev = dev;
|
||||
exi->items++;
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exi->state |= STATE_LOCKED;
|
||||
exi->dev = dev;
|
||||
SetExiInterruptMask(chan, exi);
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EXIUnlock(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
EXICallback unlockedCallback;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (!(exi->state & STATE_LOCKED)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
exi->state &= ~STATE_LOCKED;
|
||||
SetExiInterruptMask(chan, exi);
|
||||
|
||||
if (0 < exi->items) {
|
||||
unlockedCallback = exi->queue[0].callback;
|
||||
if (0 < --exi->items) {
|
||||
memmove(&exi->queue[0], &exi->queue[1], sizeof(exi->queue[0]) * exi->items);
|
||||
}
|
||||
unlockedCallback(chan, 0);
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
u32 EXIGetState(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
|
||||
return (u32)exi->state;
|
||||
}
|
||||
|
||||
static void UnlockedHandler(s32 chan, OSContext* context) {
|
||||
u32 id;
|
||||
|
||||
EXIGetID(chan, 0, &id);
|
||||
}
|
||||
|
||||
s32 EXIGetID(s32 chan, u32 dev, u32* id) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL err;
|
||||
u32 cmd;
|
||||
s32 startTime;
|
||||
BOOL enabled;
|
||||
|
||||
if (chan < 2 && dev == 0) {
|
||||
if (!__EXIProbe(chan)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (exi->idTime == __EXIProbeStartTime[chan]) {
|
||||
*id = exi->id;
|
||||
return exi->idTime;
|
||||
}
|
||||
|
||||
if (!__EXIAttach(chan, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
startTime = __EXIProbeStartTime[chan];
|
||||
}
|
||||
|
||||
err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? UnlockedHandler : NULL);
|
||||
if (!err) {
|
||||
err = !EXISelect(chan, dev, EXI_FREQ_1M);
|
||||
if (!err) {
|
||||
cmd = 0;
|
||||
err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIImm(chan, id, 4, EXI_READ, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIDeselect(chan);
|
||||
}
|
||||
EXIUnlock(chan);
|
||||
}
|
||||
|
||||
if (chan < 2 && dev == 0) {
|
||||
EXIDetach(chan);
|
||||
enabled = OSDisableInterrupts();
|
||||
err |= (startTime != __EXIProbeStartTime[chan]);
|
||||
if (!err) {
|
||||
exi->id = *id;
|
||||
exi->idTime = startTime;
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return err ? 0 : exi->idTime;
|
||||
}
|
||||
|
||||
return err ? 0 : !0;
|
||||
}
|
||||
|
||||
char* EXIGetTypeString(u32 type) {
|
||||
switch (type) {
|
||||
case EXI_MEMORY_CARD_59:
|
||||
return "Memory Card 59";
|
||||
case EXI_MEMORY_CARD_123:
|
||||
return "Memory Card 123";
|
||||
case EXI_MEMORY_CARD_251:
|
||||
return "Memory Card 251";
|
||||
case EXI_MEMORY_CARD_507:
|
||||
return "Memory Card 507";
|
||||
case EXI_USB_ADAPTER:
|
||||
return "USB Adapter";
|
||||
case 0x80000000 | EXI_MEMORY_CARD_59:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_123:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_251:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_507:
|
||||
return "Net Card";
|
||||
case EXI_ETHER_VIEWER:
|
||||
return "Artist Ether";
|
||||
case EXI_STREAM_HANGER:
|
||||
return "Stream Hanger";
|
||||
case EXI_IS_VIEWER:
|
||||
return "IS Viewer";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
#include "dolphin/os.h"
|
||||
|
||||
#define EXI_TX 0x800400u
|
||||
#define EXI_MAGIC 0xa5ff005a
|
||||
|
||||
static s32 Chan;
|
||||
static u32 Dev;
|
||||
static u32 Enabled = 0;
|
||||
static u32 BarnacleEnabled = 0;
|
||||
|
||||
static BOOL ProbeBarnacle(s32 chan, u32 dev, u32* revision) {
|
||||
BOOL err;
|
||||
u32 cmd;
|
||||
|
||||
if (chan != 2 && dev == 0 && !EXIAttach(chan, NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
err = !EXILock(chan, dev, NULL);
|
||||
if (!err) {
|
||||
err = !EXISelect(chan, dev, EXI_FREQ_1M);
|
||||
if (!err) {
|
||||
cmd = 0x20011300;
|
||||
err = FALSE;
|
||||
err |= !EXIImm(chan, &cmd, 4, EXI_WRITE, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIImm(chan, revision, 4, EXI_READ, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIDeselect(chan);
|
||||
}
|
||||
EXIUnlock(chan);
|
||||
}
|
||||
|
||||
if (chan != 2 && dev == 0) {
|
||||
EXIDetach(chan);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return (*revision != 0xFFFFFFFF) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
void __OSEnableBarnacle(s32 chan, u32 dev) {
|
||||
u32 id;
|
||||
|
||||
if (EXIGetID(chan, dev, &id)) {
|
||||
switch (id) {
|
||||
case 0xffffffff:
|
||||
case EXI_MEMORY_CARD_59:
|
||||
case EXI_MEMORY_CARD_123:
|
||||
case EXI_MEMORY_CARD_251:
|
||||
case EXI_MEMORY_CARD_507:
|
||||
case EXI_USB_ADAPTER:
|
||||
case EXI_NPDP_GDEV:
|
||||
case EXI_MODEM:
|
||||
case EXI_MARLIN:
|
||||
case 0x04220000:
|
||||
case 0x04020100:
|
||||
case 0x04020200:
|
||||
case 0x04020300:
|
||||
case 0x04040404:
|
||||
case 0x04060000:
|
||||
case 0x04120000:
|
||||
case 0x04130000:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_59:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_123:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_251:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_507:
|
||||
break;
|
||||
default:
|
||||
if (ProbeBarnacle(chan, dev, &id)) {
|
||||
Chan = chan;
|
||||
Dev = dev;
|
||||
Enabled = BarnacleEnabled = EXI_MAGIC;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 InitializeUART(u32 baudRate) {
|
||||
if (BarnacleEnabled == EXI_MAGIC) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(OSGetConsoleType() & OS_CONSOLE_DEVELOPMENT)) {
|
||||
Enabled = 0;
|
||||
return 2;
|
||||
} else {
|
||||
Chan = 0;
|
||||
Dev = 1;
|
||||
Enabled = EXI_MAGIC;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 ReadUARTN(void* bytes, unsigned long length) { return 4; }
|
||||
|
||||
static int QueueLength(void) {
|
||||
u32 cmd;
|
||||
|
||||
if (!EXISelect(Chan, Dev, EXI_FREQ_8M))
|
||||
return -1;
|
||||
|
||||
cmd = EXI_TX << 6;
|
||||
EXIImm(Chan, &cmd, 4, EXI_WRITE, NULL);
|
||||
EXISync(Chan);
|
||||
|
||||
EXIImm(Chan, &cmd, 1, EXI_READ, NULL);
|
||||
EXISync(Chan);
|
||||
EXIDeselect(Chan);
|
||||
|
||||
return 16 - (int)((cmd >> 24) & 0xff);
|
||||
}
|
||||
|
||||
u32 WriteUARTN(const void* buf, unsigned long len) {
|
||||
u32 cmd;
|
||||
int qLen;
|
||||
long xLen;
|
||||
char* ptr;
|
||||
BOOL locked;
|
||||
u32 error;
|
||||
|
||||
if (Enabled != EXI_MAGIC)
|
||||
return 2;
|
||||
|
||||
locked = EXILock(Chan, Dev, 0);
|
||||
if (!locked) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (ptr = (char*)buf; ptr - buf < len; ptr++) {
|
||||
if (*ptr == '\n')
|
||||
*ptr = '\r';
|
||||
}
|
||||
|
||||
error = 0;
|
||||
cmd = (EXI_TX | 0x2000000) << 6;
|
||||
while (len) {
|
||||
qLen = QueueLength();
|
||||
if (qLen < 0) {
|
||||
error = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
if (qLen < 12 && qLen < len)
|
||||
continue;
|
||||
|
||||
if (!EXISelect(Chan, Dev, EXI_FREQ_8M)) {
|
||||
error = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
EXIImm(Chan, &cmd, 4, EXI_WRITE, NULL);
|
||||
EXISync(Chan);
|
||||
|
||||
while (qLen && len) {
|
||||
if (qLen < 4 && qLen < len)
|
||||
break;
|
||||
xLen = (len < 4) ? (long)len : 4;
|
||||
EXIImm(Chan, (void*)buf, xLen, EXI_WRITE, NULL);
|
||||
(u8*)buf += xLen;
|
||||
len -= xLen;
|
||||
qLen -= xLen;
|
||||
EXISync(Chan);
|
||||
}
|
||||
EXIDeselect(Chan);
|
||||
}
|
||||
|
||||
EXIUnlock(Chan);
|
||||
return error;
|
||||
}
|
Loading…
Reference in New Issue