Link CARDUnlock.c, CARDBios.c matches, but can't be linked due to frank issues

Former-commit-id: 58d5c4a816
This commit is contained in:
Phillip Stephens 2022-09-10 13:32:26 -07:00
parent feff8c6ec3
commit 57d8500376
17 changed files with 1295 additions and 160 deletions

View File

@ -125,8 +125,6 @@ ifeq ($(VERBOSE),0)
ASFLAGS += -W
endif
$(INIT_O_FILES): MWCC_VERSION := 1.2.5
$(INIT_O_FILES): CFLAGS := $(CFLAGS_BASE)
$(METROTRK_FILES): MWCC_VERSION := 1.2.5
$(METROTRK_FILES): CFLAGS := $(CFLAGS_BASE)
$(BASE_FILES): MWCC_VERSION := 1.2.5
@ -135,6 +133,8 @@ $(AI_FILES): MWCC_VERSION := 1.2.5
$(AI_FILES): CFLAGS := $(CFLAGS_BASE)
$(OS_FILES): MWCC_VERSION := 1.2.5
$(OS_FILES): CFLAGS := $(CFLAGS_BASE)
$(CARD_FILES): MWCC_VERSION := 1.2.5
$(CARD_FILES): CFLAGS := $(CFLAGS_BASE)
$(DSP_FILES): MWCC_VERSION := 1.2.5
$(DSP_FILES): CFLAGS := $(CFLAGS_BASE)
$(MUSYX_FILES): CFLAGS := $(CFLAGS_MUSYX)

View File

@ -5,15 +5,17 @@
.global __CARDBlock
__CARDBlock:
.skip 0x220
.global __CARDDiskNone
__CARDDiskNone:
.skip 0x20
.section .data, "wa"
.balign 8
lbl_803F6C90:
__CARDVersionStr:
.asciz "<< Dolphin SDK - CARD\trelease build: Sep 5 2002 05:35:20 (0x2301) >>"
.balign 4
.global lbl_803F6CD8
lbl_803F6CD8:
ResetFunctionInfo:
.4byte OnReset
.4byte 0x0000007f
@ -22,9 +24,9 @@ lbl_803F6CD8:
.section .sdata, "wa"
.balign 8
.global lbl_805A8BF0
lbl_805A8BF0:
.4byte lbl_803F6C90
.global __CARDVersion
__CARDVersion:
.4byte __CARDVersionStr
.skip 4
.section .sbss, "wa"
@ -1080,7 +1082,7 @@ CARDInit:
lbl_803B8CEC:
/* 803B8CEC 003B5C4C 4B FC 82 59 */ bl OSGetFontEncode
/* 803B8CF0 003B5C50 B0 6D B0 08 */ sth r3, __CARDEncode@sda21(r13)
/* 803B8CF4 003B5C54 80 6D A0 30 */ lwz r3, lbl_805A8BF0@sda21(r13)
/* 803B8CF4 003B5C54 80 6D A0 30 */ lwz r3, __CARDVersion@sda21(r13)
/* 803B8CF8 003B5C58 4B FC 53 41 */ bl OSRegisterVersion
/* 803B8CFC 003B5C5C 4B FB 6D 09 */ bl DSPInit
/* 803B8D00 003B5C60 4B FC 53 65 */ bl OSInitAlarm
@ -1098,8 +1100,8 @@ lbl_803B8D0C:
/* 803B8D2C 003B5C8C 41 80 FF E0 */ blt lbl_803B8D0C
/* 803B8D30 003B5C90 3C 60 80 00 */ lis r3, 0x8000
/* 803B8D34 003B5C94 48 00 00 35 */ bl __CARDSetDiskID
/* 803B8D38 003B5C98 3C 60 80 3F */ lis r3, lbl_803F6CD8@ha
/* 803B8D3C 003B5C9C 38 63 6C D8 */ addi r3, r3, lbl_803F6CD8@l
/* 803B8D38 003B5C98 3C 60 80 3F */ lis r3, ResetFunctionInfo@ha
/* 803B8D3C 003B5C9C 38 63 6C D8 */ addi r3, r3, ResetFunctionInfo@l
/* 803B8D40 003B5CA0 4B FC A2 ED */ bl OSRegisterResetFunction
lbl_803B8D44:
/* 803B8D44 003B5CA4 80 01 00 1C */ lwz r0, 0x1c(r1)

View File

@ -1,10 +1,5 @@
.include "macros.inc"
.section .bss
.balign 8
lbl_80569C78:
.skip 0x20
.section .text, "ax"
.global __CARDCompareFileName
@ -55,9 +50,9 @@ __CARDAccess:
/* 803BCDFC 003B9D5C 38 60 FF FC */ li r3, -4
/* 803BCE00 003B9D60 48 00 00 54 */ b lbl_803BCE54
lbl_803BCE04:
/* 803BCE04 003B9D64 3C 60 80 57 */ lis r3, lbl_80569C78@ha
/* 803BCE04 003B9D64 3C 60 80 57 */ lis r3, __CARDDiskNone@ha
/* 803BCE08 003B9D68 80 9E 01 0C */ lwz r4, 0x10c(r30)
/* 803BCE0C 003B9D6C 38 03 9C 78 */ addi r0, r3, lbl_80569C78@l
/* 803BCE0C 003B9D6C 38 03 9C 78 */ addi r0, r3, __CARDDiskNone@l
/* 803BCE10 003B9D70 7C 04 00 40 */ cmplw r4, r0
/* 803BCE14 003B9D74 41 82 00 34 */ beq lbl_803BCE48
/* 803BCE18 003B9D78 38 7F 00 00 */ addi r3, r31, 0
@ -119,9 +114,9 @@ sub_803bce9c:
lbl_803BCECC:
/* 803BCECC 003B9E2C 7F 63 DB 78 */ mr r3, r27
/* 803BCED0 003B9E30 4B FF DA A1 */ bl __CARDGetDirBlock
/* 803BCED4 003B9E34 3C 80 80 57 */ lis r4, lbl_80569C78@ha
/* 803BCED4 003B9E34 3C 80 80 57 */ lis r4, __CARDDiskNone@ha
/* 803BCED8 003B9E38 3B E3 00 00 */ addi r31, r3, 0
/* 803BCEDC 003B9E3C 3B 44 9C 78 */ addi r26, r4, lbl_80569C78@l
/* 803BCEDC 003B9E3C 3B 44 9C 78 */ addi r26, r4, __CARDDiskNone@l
/* 803BCEE0 003B9E40 3B C0 00 00 */ li r30, 0
lbl_803BCEE4:
/* 803BCEE4 003B9E44 88 1F 00 00 */ lbz r0, 0(r31)
@ -228,9 +223,9 @@ lbl_803BD024:
lbl_803BD03C:
/* 803BD03C 003B9F9C 7F E3 FB 78 */ mr r3, r31
/* 803BD040 003B9FA0 4B FF D9 31 */ bl __CARDGetDirBlock
/* 803BD044 003B9FA4 3C 80 80 57 */ lis r4, lbl_80569C78@ha
/* 803BD044 003B9FA4 3C 80 80 57 */ lis r4, __CARDDiskNone@ha
/* 803BD048 003B9FA8 3A E3 00 00 */ addi r23, r3, 0
/* 803BD04C 003B9FAC 3B 44 9C 78 */ addi r26, r4, lbl_80569C78@l
/* 803BD04C 003B9FAC 3B 44 9C 78 */ addi r26, r4, __CARDDiskNone@l
/* 803BD050 003B9FB0 3B 20 00 00 */ li r25, 0
lbl_803BD054:
/* 803BD054 003B9FB4 88 17 00 00 */ lbz r0, 0(r23)

View File

@ -3,8 +3,8 @@
.section .data, "wa"
.balign 8
.global lbl_803F6D00
lbl_803F6D00:
.global CardData
CardData:
# ROM: 0x3F3D00
.4byte 0
.4byte 0
@ -98,13 +98,13 @@ lbl_803F6D00:
.section .sdata, "wa"
.balign 8
.global lbl_805A8BF8
lbl_805A8BF8:
next:
.4byte 1
.skip 4
.section .text, "ax"
.global bitrev
bitrev:
/* 803B908C 003B5FEC 38 00 00 08 */ li r0, 8
/* 803B9090 003B5FF0 7C 09 03 A6 */ mtctr r0
@ -311,14 +311,14 @@ DummyLen:
/* 803B9354 003B62B4 93 A1 00 1C */ stw r29, 0x1c(r1)
/* 803B9358 003B62B8 3B A0 00 00 */ li r29, 0
/* 803B935C 003B62BC 4B FC C0 65 */ bl OSGetTick
/* 803B9360 003B62C0 90 6D A0 38 */ stw r3, lbl_805A8BF8@sda21(r13)
/* 803B9360 003B62C0 90 6D A0 38 */ stw r3, next@sda21(r13)
/* 803B9364 003B62C4 3C 60 41 C6 */ lis r3, 0x41C64E6D@ha
/* 803B9368 003B62C8 3B E3 4E 6D */ addi r31, r3, 0x41C64E6D@l
/* 803B936C 003B62CC 80 0D A0 38 */ lwz r0, lbl_805A8BF8@sda21(r13)
/* 803B936C 003B62CC 80 0D A0 38 */ lwz r0, next@sda21(r13)
/* 803B9370 003B62D0 7C 60 F9 D6 */ mullw r3, r0, r31
/* 803B9374 003B62D4 38 03 30 39 */ addi r0, r3, 0x3039
/* 803B9378 003B62D8 90 0D A0 38 */ stw r0, lbl_805A8BF8@sda21(r13)
/* 803B937C 003B62DC 80 0D A0 38 */ lwz r0, lbl_805A8BF8@sda21(r13)
/* 803B9378 003B62D8 90 0D A0 38 */ stw r0, next@sda21(r13)
/* 803B937C 003B62DC 80 0D A0 38 */ lwz r0, next@sda21(r13)
/* 803B9380 003B62E0 54 03 86 FE */ rlwinm r3, r0, 0x10, 0x1b, 0x1f
/* 803B9384 003B62E4 38 63 00 01 */ addi r3, r3, 1
/* 803B9388 003B62E8 48 00 00 40 */ b lbl_803B93C8
@ -330,13 +330,13 @@ lbl_803B938C:
/* 803B939C 003B62FC 40 81 00 08 */ ble lbl_803B93A4
/* 803B93A0 003B6300 3B C0 00 01 */ li r30, 1
lbl_803B93A4:
/* 803B93A4 003B6304 90 0D A0 38 */ stw r0, lbl_805A8BF8@sda21(r13)
/* 803B93A4 003B6304 90 0D A0 38 */ stw r0, next@sda21(r13)
/* 803B93A8 003B6308 3B BD 00 01 */ addi r29, r29, 1
/* 803B93AC 003B630C 80 0D A0 38 */ lwz r0, lbl_805A8BF8@sda21(r13)
/* 803B93AC 003B630C 80 0D A0 38 */ lwz r0, next@sda21(r13)
/* 803B93B0 003B6310 7C 60 F9 D6 */ mullw r3, r0, r31
/* 803B93B4 003B6314 38 03 30 39 */ addi r0, r3, 0x3039
/* 803B93B8 003B6318 90 0D A0 38 */ stw r0, lbl_805A8BF8@sda21(r13)
/* 803B93BC 003B631C 80 0D A0 38 */ lwz r0, lbl_805A8BF8@sda21(r13)
/* 803B93B8 003B6318 90 0D A0 38 */ stw r0, next@sda21(r13)
/* 803B93BC 003B631C 80 0D A0 38 */ lwz r0, next@sda21(r13)
/* 803B93C0 003B6320 54 03 86 FE */ rlwinm r3, r0, 0x10, 0x1b, 0x1f
/* 803B93C4 003B6324 38 63 00 01 */ addi r3, r3, 1
lbl_803B93C8:
@ -376,16 +376,16 @@ __CARDUnlock:
/* 803B9438 003B6398 3B A3 00 00 */ addi r29, r3, 0
/* 803B943C 003B639C 3A DC 00 20 */ addi r22, r28, 0x20
/* 803B9440 003B63A0 4B FC BF 81 */ bl OSGetTick
/* 803B9444 003B63A4 90 6D A0 38 */ stw r3, lbl_805A8BF8@sda21(r13)
/* 803B9444 003B63A4 90 6D A0 38 */ stw r3, next@sda21(r13)
/* 803B9448 003B63A8 3C 60 41 C6 */ lis r3, 0x41C64E6D@ha
/* 803B944C 003B63AC 3C A0 7F ED */ lis r5, 0x7FEC8000@ha
/* 803B9450 003B63B0 80 8D A0 38 */ lwz r4, lbl_805A8BF8@sda21(r13)
/* 803B9450 003B63B0 80 8D A0 38 */ lwz r4, next@sda21(r13)
/* 803B9454 003B63B4 38 03 4E 6D */ addi r0, r3, 0x41C64E6D@l
/* 803B9458 003B63B8 3B 25 80 00 */ addi r25, r5, 0x7FEC8000@l
/* 803B945C 003B63BC 7C 64 01 D6 */ mullw r3, r4, r0
/* 803B9460 003B63C0 38 03 30 39 */ addi r0, r3, 0x3039
/* 803B9464 003B63C4 90 0D A0 38 */ stw r0, lbl_805A8BF8@sda21(r13)
/* 803B9468 003B63C8 80 0D A0 38 */ lwz r0, lbl_805A8BF8@sda21(r13)
/* 803B9464 003B63C4 90 0D A0 38 */ stw r0, next@sda21(r13)
/* 803B9468 003B63C8 80 0D A0 38 */ lwz r0, next@sda21(r13)
/* 803B946C 003B63CC 54 00 84 7E */ rlwinm r0, r0, 0x10, 0x11, 0x1f
/* 803B9470 003B63D0 7F 39 03 78 */ or r25, r25, r0
/* 803B9474 003B63D4 57 39 00 26 */ rlwinm r25, r25, 0, 0, 0x13
@ -1073,9 +1073,9 @@ lbl_803B9E78:
/* 803B9ED8 003B6E38 38 80 00 10 */ li r4, 0x10
/* 803B9EDC 003B6E3C 4B FC 4B D5 */ bl DCFlushRange
/* 803B9EE0 003B6E40 38 00 00 FF */ li r0, 0xff
/* 803B9EE4 003B6E44 3C 60 80 3F */ lis r3, lbl_803F6D00@ha
/* 803B9EE4 003B6E44 3C 60 80 3F */ lis r3, CardData@ha
/* 803B9EE8 003B6E48 90 1E 00 04 */ stw r0, 4(r30)
/* 803B9EEC 003B6E4C 38 63 6D 00 */ addi r3, r3, lbl_803F6D00@l
/* 803B9EEC 003B6E4C 38 63 6D 00 */ addi r3, r3, CardData@l
/* 803B9EF0 003B6E50 3C 03 80 00 */ addis r0, r3, 0x8000
/* 803B9EF4 003B6E54 90 1E 00 0C */ stw r0, 0xc(r30)
/* 803B9EF8 003B6E58 38 00 01 60 */ li r0, 0x160

104
include/dolphin/CARDPriv.h Normal file
View File

@ -0,0 +1,104 @@
#ifndef __CARDPRIV_H__
#define __CARDPRIV_H__
#ifdef __cplusplus
extern "C" {
#endif
#define CARD_FAT_CHECKSUM 0x0000u
#define CARD_FAT_CHECKSUMINV 0x0001u
#define CARD_FAT_CHECKCODE 0x0002u
#define CARD_FAT_FREEBLOCKS 0x0003u
#define CARD_FAT_LASTSLOT 0x0004u
#define CARD_NUM_SYSTEM_BLOCK 5
#define CARD_SYSTEM_BLOCK_SIZE (8 * 1024u)
#define CARD_MAX_MOUNT_STEP (CARD_NUM_SYSTEM_BLOCK + 2)
typedef struct CARDDir
{
u8 gameName[4];
u8 company[2];
u8 _padding0;
u8 bannerFormat;
u8 fileName[CARD_FILENAME_MAX];
u32 time; // seconds since 01/01/2000 midnight
u32 iconAddr; // 0xffffffff if not used
u16 iconFormat;
u16 iconSpeed;
u8 permission;
u8 copyTimes;
u16 startBlock;
u16 length;
u8 _padding1[2];
u32 commentAddr; // 0xffffffff if not used
} CARDDir;
typedef struct CARDControl {
BOOL attached;
s32 result;
u16 size;
u16 pageSize;
s32 sectorSize;
u16 cBlock;
u16 vendorID;
s32 latency;
u8 id[12];
int mountStep;
int formatStep;
u32 scramble;
DSPTaskInfo task;
void* workArea;
CARDDir* dir;
u16* currentFat;
OSThreadQueue threadQueue;
u8 cmd[9];
s32 cmdlen;
vu32 mode;
int retry;
int repeat;
u32 addr;
void* buffer;
s32 xferred;
u16 freeNo;
u16 startBlock;
CARDFileInfo* fileInfo;
CARDCallback extCallback;
CARDCallback txCallback;
CARDCallback exiCallback;
CARDCallback apiCallback;
CARDCallback xferCallback;
CARDCallback eraseCallback;
CARDCallback unlockCallback;
OSAlarm alarm;
u32 cid;
const DVDDiskID* diskID;
} CARDControl;
typedef struct CARDID {
u8 serial[32]; // flashID[12] + timebase[8] + counterBias[4] + language[4] + XXX[4]
u16 deviceID;
u16 size;
u16 encode; // character set -- 0: S-JIS, 1: ANSI
u8 padding[512 - 32 - 5 * 2];
u16 checkSum;
u16 checkSumInv;
} CARDID;
CARDDir* __CARDGetDirBlock( CARDControl* card );
u16* __CARDGetFatBlock ( CARDControl* card );
extern CARDControl __CARDBlock[2];
extern DVDDiskID __CARDDiskNone;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -2,6 +2,7 @@
#define __DSP_H__
#include "types.h"
#include <dolphin/os.h>
#ifdef __cplusplus
extern "C" {

24
include/dolphin/dvd.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef __DVD_H__
#define __DVD_H__
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct DVDDiskID {
char gameName[4];
char company[2];
u8 diskNumber;
u8 gameVersion;
u8 streaming;
u8 streamingBufSize; // 0 = default
u8 padding[22]; // 0's are stored
} DVDDiskID;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -8,15 +8,15 @@ extern "C" {
#endif
// TODO OSInerrupt.h
typedef s16 __OSInterrupt;
typedef s16 __OSInterrupt;
// Upper words of the masks, since UIMM is only 16 bits
#define OS_CACHED_REGION_PREFIX 0x8000
#define OS_UNCACHED_REGION_PREFIX 0xC000
#define OS_PHYSICAL_MASK 0x3FFF
#define OS_CACHED_REGION_PREFIX 0x8000
#define OS_UNCACHED_REGION_PREFIX 0xC000
#define OS_PHYSICAL_MASK 0x3FFF
#define OS_BASE_CACHED (OS_CACHED_REGION_PREFIX << 16)
#define OS_BASE_UNCACHED (OS_UNCACHED_REGION_PREFIX << 16)
#define OS_BASE_CACHED (OS_CACHED_REGION_PREFIX << 16)
#define OS_BASE_UNCACHED (OS_UNCACHED_REGION_PREFIX << 16)
#ifdef __MWERKS__
#define AT_ADDRESS(xyz) : (xyz)
@ -25,48 +25,32 @@ typedef s16 __OSInterrupt;
#endif
typedef s64 OSTime;
typedef u32 OSTick;
u32 __OSBusClock AT_ADDRESS(OS_BASE_CACHED | 0x00F8); // sync with OSLoMem.h
u32 __OSCoreClock AT_ADDRESS(OS_BASE_CACHED | 0x00FC); // sync with OSLoMem.h
#define OS_BUS_CLOCK __OSBusClock
#define OS_CORE_CLOCK __OSCoreClock
#define OS_TIMER_CLOCK (OS_BUS_CLOCK/4)
u32 __OSBusClock AT_ADDRESS(OS_BASE_CACHED | 0x00F8); // sync with OSLoMem.h
u32 __OSCoreClock AT_ADDRESS(OS_BASE_CACHED | 0x00FC); // sync with OSLoMem.h
#define OS_BUS_CLOCK __OSBusClock
#define OS_CORE_CLOCK __OSCoreClock
#define OS_TIMER_CLOCK (OS_BUS_CLOCK / 4)
#define OSTicksToCycles( ticks ) (((ticks) * ((OS_CORE_CLOCK * 2) / OS_TIMER_CLOCK)) / 2)
#define OSTicksToSeconds( ticks ) ((ticks) / OS_TIMER_CLOCK)
#define OSTicksToMilliseconds( ticks ) ((ticks) / (OS_TIMER_CLOCK / 1000))
#define OSTicksToMicroseconds( ticks ) (((ticks) * 8) / (OS_TIMER_CLOCK / 125000))
#define OSTicksToNanoseconds( ticks ) (((ticks) * 8000) / (OS_TIMER_CLOCK / 125000))
#define OSSecondsToTicks( sec ) ((sec) * OS_TIMER_CLOCK)
#define OSMillisecondsToTicks( msec ) ((msec) * (OS_TIMER_CLOCK / 1000))
#define OSMicrosecondsToTicks( usec ) (((usec) * (OS_TIMER_CLOCK / 125000)) / 8)
#define OSNanosecondsToTicks( nsec ) (((nsec) * (OS_TIMER_CLOCK / 125000)) / 8000)
#define OSPhysicalToCached(paddr) ((void*) ((u32)(paddr) + OS_BASE_CACHED))
#define OSPhysicalToUncached(paddr) ((void*) ((u32)(paddr) + OS_BASE_UNCACHED))
#define OSCachedToPhysical(caddr) ((u32) ((u8*)(caddr) - OS_BASE_CACHED))
#define OSUncachedToPhysical(ucaddr) ((u32) ((u8*)(ucaddr)- OS_BASE_UNCACHED))
#define OSCachedToUncached(caddr) ((void*) ((u8*)(caddr) + (OS_BASE_UNCACHED - OS_BASE_CACHED)))
#define OSUncachedToCached(ucaddr) ((void*) ((u8*)(ucaddr)- (OS_BASE_UNCACHED - OS_BASE_CACHED)))
#define OSDiffTick(tick1, tick0) ((s32) (tick1) - (s32) (tick0))
#define OSTicksToCycles(ticks) (((ticks) * ((OS_CORE_CLOCK * 2) / OS_TIMER_CLOCK)) / 2)
#define OSTicksToSeconds(ticks) ((ticks) / OS_TIMER_CLOCK)
#define OSTicksToMilliseconds(ticks) ((ticks) / (OS_TIMER_CLOCK / 1000))
#define OSTicksToMicroseconds(ticks) (((ticks)*8) / (OS_TIMER_CLOCK / 125000))
#define OSTicksToNanoseconds(ticks) (((ticks)*8000) / (OS_TIMER_CLOCK / 125000))
#define OSSecondsToTicks(sec) ((sec)*OS_TIMER_CLOCK)
#define OSMillisecondsToTicks(msec) ((msec) * (OS_TIMER_CLOCK / 1000))
#define OSMicrosecondsToTicks(usec) (((usec) * (OS_TIMER_CLOCK / 125000)) / 8)
#define OSNanosecondsToTicks(nsec) (((nsec) * (OS_TIMER_CLOCK / 125000)) / 8000)
#define OSDiffTick(tick1, tick0) ((s32)(tick1) - (s32)(tick0))
typedef struct OSContext {
u32 gpr[32];
u32 cr;
u32 lr;
u32 ctr;
u32 xer;
f64 fpr[32];
u32 fpscr_pad;
u32 fpscr;
u32 srr0;
u32 srr1;
u16 mode;
u16 state;
u32 gqr[8];
u32 psf_pad;
f64 psf[32];
} OSContext;
#define OSRoundUp32B(v) (((u32)(v + 31) & ~31))
OSTime OSGetTime();
@ -74,4 +58,10 @@ OSTime OSGetTime();
}
#endif
#include <dolphin/os/OSAlarm.h>
#include <dolphin/os/OSCache.h>
#include <dolphin/os/OSContext.h>
#include <dolphin/os/OSFont.h>
#include <dolphin/os/OSReset.h>
#include <dolphin/os/OSThread.h>
#endif

View File

@ -0,0 +1,29 @@
#ifndef __OSALARM_H__
#define __OSALARM_H__
#include <types.h>
#include <dolphin/os/OSContext.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct OSAlarm OSAlarm;
typedef void (*OSAlarmHandler)(OSAlarm* alarm, OSContext* context);
struct OSAlarm {
OSAlarmHandler handler;
u32 tag;
OSTime fire;
OSAlarm* prev;
OSAlarm* next;
OSTime period;
OSTime start;
};
void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,40 @@
#ifndef __OSCONTEXT_H__
#define __OSCONTEXT_H__
#include <types.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct OSContext {
u32 gpr[32];
u32 cr;
u32 lr;
u32 ctr;
u32 xer;
f64 fpr[32];
u32 fpscr_pad;
u32 fpscr;
u32 srr0;
u32 srr1;
u16 mode;
u16 state;
u32 gqr[8];
u32 psf_pad;
f64 psf[32];
} OSContext;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,17 @@
#ifndef __OSFONT_H__
#define __OSFONT_H__
#include <types.h>
#ifdef __cplusplus
extern "C" {
#endif
u16 OSGetFontEncode(void);
u16 OSSetFontEncode(u16 encode);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,28 @@
#ifndef __OSRESET_H__
#define __OSRESET_H__
#include <types.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef BOOL (* OSResetFunction )(BOOL final);
typedef struct OSResetFunctionInfo OSResetFunctionInfo;
struct OSResetFunctionInfo
{
// public
OSResetFunction func;
u32 priority;
// private
OSResetFunctionInfo* next;
OSResetFunctionInfo* prev;
};
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,69 @@
#ifndef __OSTHREAD_H__
#define __OSTHREAD_H__
#include <dolphin/os/OSContext.h>
#ifdef __cplusplus
extern "C" {
#endif
#define OS_THREAD_SPECIFIC_MAX 2
typedef struct OSThread OSThread;
typedef struct OSThreadQueue OSThreadQueue;
typedef struct OSThreadLink OSThreadLink;
typedef s32 OSPriority; // 0 highest, 31 lowest
typedef struct OSMutex OSMutex;
typedef struct OSMutexQueue OSMutexQueue;
typedef struct OSMutexLink OSMutexLink;
typedef struct OSCond OSCond;
typedef void (*OSIdleFunction)(void* param);
typedef void (*OSSwitchThreadCallback)(OSThread* from, OSThread* to);
struct OSThreadQueue {
OSThread* head;
OSThread* tail;
};
struct OSThreadLink {
OSThread* next;
OSThread* prev;
};
struct OSMutexQueue {
OSMutex* head;
OSMutex* tail;
};
struct OSMutexLink {
OSMutex* next;
OSMutex* prev;
};
struct OSThread {
OSContext context;
u16 state;
u16 attr;
s32 suspend;
OSPriority priority;
OSPriority base;
void* val;
OSThreadQueue* queue;
OSThreadLink link;
OSThreadQueue queueJoin;
OSMutex* mutex;
OSMutexQueue queueMutex;
OSThreadLink linkActive;
u8* stackBase;
u32* stackEnd;
s32 error;
void* specific[OS_THREAD_SPECIFIC_MAX];
};
#ifdef __cplusplus
}
#endif
#endif

View File

@ -816,7 +816,7 @@ DTK_FILES :=\
CARD_FILES :=\
$(BUILD_DIR)/asm/Dolphin/card/CARDBios.o\
$(BUILD_DIR)/asm/Dolphin/card/CARDUnlock.o\
$(BUILD_DIR)/src/Dolphin/card/CARDUnlock.ep.o\
$(BUILD_DIR)/asm/Dolphin/card/CARDRdwr.o\
$(BUILD_DIR)/asm/Dolphin/card/CARDBlock.o\
$(BUILD_DIR)/asm/Dolphin/card/CARDDir.o\

View File

@ -1,103 +1,549 @@
#include <dolphin/card.h>
#include <dolphin/dsp.h>
#include <dolphin/dvd.h>
#include <dolphin/os.h>
#include <dolphin/CARDPriv.h>
const char* __CARDVersion = "<< Dolphin SDK - CARD\trelease build: Sep 5 2002 05:35:20 (0x2301) >>";
CARDControl __CARDBlock[2];
DVDDiskID __CARDDiskNone;
void __CARDDefaultApiCallback(s32 chan, s32 result) {
}
static u16 __CARDEncode;
s32 __CARDReadStatus(s32 chan, u8* status);
s32 __CARDClearStatus(s32 chan);
void __CARDSetDiskID(const DVDDiskID* id);
static s32 Retry(s32 chan);
BOOL OnReset(BOOL final);
static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 127};
void __CARDDefaultApiCallback(s32 chan, s32 result) {}
void __CARDExtHandler(s32 chan, OSContext* context) {
CARDControl* card;
CARDCallback callback;
CARDControl* card;
CARDCallback callback;
card = &__CARDBlock[chan];
if (card->attached) {
card->attached = FALSE;
EXISetExiCallback(chan, 0);
OSCancelAlarm(&card->alarm);
callback = card->exiCallback;
if (callback) {
card->exiCallback = 0;
callback(chan, CARD_RESULT_NOCARD);
}
if (card->result != CARD_RESULT_BUSY) {
card->result = CARD_RESULT_NOCARD;
}
callback = card->extCallback;
if (callback && CARD_MAX_MOUNT_STEP <= card->mountStep) {
card->extCallback = 0;
callback(chan, CARD_RESULT_NOCARD);
}
card = &__CARDBlock[chan];
if (card->attached) {
card->attached = FALSE;
EXISetExiCallback(chan, 0);
OSCancelAlarm(&card->alarm);
callback = card->exiCallback;
if (callback) {
card->exiCallback = 0;
callback(chan, CARD_RESULT_NOCARD);
}
if (card->result != CARD_RESULT_BUSY) {
card->result = CARD_RESULT_NOCARD;
}
callback = card->extCallback;
if (callback && CARD_MAX_MOUNT_STEP <= card->mountStep) {
card->extCallback = 0;
callback(chan, CARD_RESULT_NOCARD);
}
}
}
void __CARDExiHandler(s32 chan, OSContext* context) {
CARDControl* card;
CARDCallback callback;
u8 status;
s32 result;
CARDControl* card;
CARDCallback callback;
u8 status;
s32 result;
card = &__CARDBlock[chan];
card = &__CARDBlock[chan];
OSCancelAlarm(&card->alarm);
OSCancelAlarm(&card->alarm);
if (!card->attached) {
return;
}
if (!EXILock(chan, 0, 0)) {
result = CARD_RESULT_FATAL_ERROR;
goto fatal;
}
if ((result = __CARDReadStatus(chan, &status)) < 0 || (result = __CARDClearStatus(chan)) < 0) {
goto error;
}
if ((result = (status & 0x18) ? CARD_RESULT_IOERROR : CARD_RESULT_READY) == CARD_RESULT_IOERROR && --card->retry > 0) {
result = Retry(chan);
if (result >= 0) {
return;
}
goto fatal;
if (!card->attached) {
return;
}
if (!EXILock(chan, 0, 0)) {
result = CARD_RESULT_FATAL_ERROR;
goto fatal;
}
if ((result = __CARDReadStatus(chan, &status)) < 0 || (result = __CARDClearStatus(chan)) < 0) {
goto error;
}
if ((result = (status & 0x18) ? CARD_RESULT_IOERROR : CARD_RESULT_READY) == CARD_RESULT_IOERROR && --card->retry > 0) {
result = Retry(chan);
if (result >= 0) {
return;
}
goto fatal;
}
error:
EXIUnlock(chan);
EXIUnlock(chan);
fatal:
callback = card->exiCallback;
if (callback) {
card->exiCallback = 0;
callback(chan, result);
}
callback = card->exiCallback;
if (callback) {
card->exiCallback = 0;
callback(chan, result);
}
}
void __CARDTxHandler(s32 chan, OSContext* context) {
CARDControl* card;
CARDCallback callback;
BOOL err;
CARDControl* card;
CARDCallback callback;
BOOL err;
card = &__CARDBlock[chan];
err = !EXIDeselect(chan);
EXIUnlock(chan);
callback = card->txCallback;
if (callback) {
card->txCallback = 0;
callback(chan, (!err && EXIProbe(chan)) ? CARD_RESULT_READY : CARD_RESULT_NOCARD);
}
card = &__CARDBlock[chan];
err = !EXIDeselect(chan);
EXIUnlock(chan);
callback = card->txCallback;
if (callback) {
card->txCallback = 0;
callback(chan, (!err && EXIProbe(chan)) ? CARD_RESULT_READY : CARD_RESULT_NOCARD);
}
}
void __CARDUnlockedHandler(s32 chan, OSContext* context) {
CARDControl* card;
CARDCallback callback;
CARDControl* card;
CARDCallback callback;
card = &__CARDBlock[chan];
callback = card->unlockCallback;
if (callback) {
card->unlockCallback = 0;
callback(chan, EXIProbe(chan) ? CARD_RESULT_UNLOCKED : CARD_RESULT_NOCARD);
}
card = &__CARDBlock[chan];
callback = card->unlockCallback;
if (callback) {
card->unlockCallback = 0;
callback(chan, EXIProbe(chan) ? CARD_RESULT_UNLOCKED : CARD_RESULT_NOCARD);
}
}
s32 __CARDEnableInterrupt(s32 chan, BOOL enable) {
BOOL err;
u32 cmd;
if (!EXISelect(chan, 0, 4)) {
return CARD_RESULT_NOCARD;
}
cmd = enable ? 0x81010000 : 0x81000000;
err = FALSE;
err |= !EXIImm(chan, &cmd, 2, 1, NULL);
err |= !EXISync(chan);
err |= !EXIDeselect(chan);
return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY;
}
s32 __CARDReadStatus(s32 chan, u8* status) {
BOOL err;
u32 cmd;
if (!EXISelect(chan, 0, 4)) {
return CARD_RESULT_NOCARD;
}
cmd = 0x83000000;
err = FALSE;
err |= !EXIImm(chan, &cmd, 2, 1, NULL);
err |= !EXISync(chan);
err |= !EXIImm(chan, status, 1, 0, NULL);
err |= !EXISync(chan);
err |= !EXIDeselect(chan);
return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY;
}
s32 __CARDClearStatus(s32 chan) {
BOOL err;
u32 cmd;
if (!EXISelect(chan, 0, 4)) {
return CARD_RESULT_NOCARD;
}
cmd = 0x89000000;
err = FALSE;
err |= !EXIImm(chan, &cmd, 1, 1, 0);
err |= !EXISync(chan);
err |= !EXIDeselect(chan);
return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY;
}
static void TimeoutHandler(OSAlarm* alarm, OSContext* context) {
s32 chan;
CARDControl* card;
CARDCallback callback;
for (chan = 0; chan < 2; ++chan) {
card = &__CARDBlock[chan];
if (alarm == &card->alarm) {
break;
}
}
if (!card->attached) {
return;
}
EXISetExiCallback(chan, NULL);
callback = card->exiCallback;
if (callback) {
card->exiCallback = 0;
callback(chan, CARD_RESULT_IOERROR);
}
}
static void SetupTimeoutAlarm(CARDControl* card) {
OSCancelAlarm(&card->alarm);
switch (card->cmd[0]) {
case 0xF2:
OSSetAlarm(&card->alarm, OSMillisecondsToTicks(100), TimeoutHandler);
break;
case 0xF3:
break;
case 0xF4:
case 0xF1:
OSSetAlarm(&card->alarm, OSSecondsToTicks((OSTime)2) * (card->sectorSize / 0x2000), TimeoutHandler);
break;
}
}
static s32 Retry(s32 chan) {
CARDControl* card;
card = &__CARDBlock[chan];
if (!EXISelect(chan, 0, 4)) {
EXIUnlock(chan);
return CARD_RESULT_NOCARD;
}
SetupTimeoutAlarm(card);
if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1)) {
EXIDeselect(chan);
EXIUnlock(chan);
return CARD_RESULT_NOCARD;
}
if (card->cmd[0] == 0x52 && !EXIImmEx(chan, (u8*)card->workArea + sizeof(CARDID), card->latency, 1)) {
EXIDeselect(chan);
EXIUnlock(chan);
return CARD_RESULT_NOCARD;
}
if (card->mode == 0xffffffff) {
EXIDeselect(chan);
EXIUnlock(chan);
return CARD_RESULT_READY;
}
if (!EXIDma(chan, card->buffer, (s32)((card->cmd[0] == 0x52) ? 512 : 128), card->mode, __CARDTxHandler)) {
EXIDeselect(chan);
EXIUnlock(chan);
return CARD_RESULT_NOCARD;
}
return CARD_RESULT_READY;
}
static void UnlockedCallback(s32 chan, s32 result) {
CARDCallback callback;
CARDControl* card;
card = &__CARDBlock[chan];
if (result >= 0) {
card->unlockCallback = UnlockedCallback;
if (!EXILock(chan, 0, __CARDUnlockedHandler)) {
result = CARD_RESULT_READY;
} else {
card->unlockCallback = 0;
result = Retry(chan);
}
}
if (result < 0) {
switch (card->cmd[0]) {
case 0x52:
callback = card->txCallback;
if (callback) {
card->txCallback = 0;
callback(chan, result);
}
break;
case 0xF2:
case 0xF4:
case 0xF1:
callback = card->exiCallback;
if (callback) {
card->exiCallback = 0;
callback(chan, result);
}
break;
}
}
}
static s32 __CARDStart(s32 chan, CARDCallback txCallback, CARDCallback exiCallback) {
BOOL enabled;
CARDControl* card;
s32 result;
enabled = OSDisableInterrupts();
card = &__CARDBlock[chan];
if (!card->attached) {
result = CARD_RESULT_NOCARD;
} else {
if (txCallback) {
card->txCallback = txCallback;
}
if (exiCallback) {
card->exiCallback = exiCallback;
}
card->unlockCallback = UnlockedCallback;
if (!EXILock(chan, 0, __CARDUnlockedHandler)) {
result = CARD_RESULT_BUSY;
} else {
card->unlockCallback = 0;
if (!EXISelect(chan, 0, 4)) {
EXIUnlock(chan);
result = CARD_RESULT_NOCARD;
} else {
SetupTimeoutAlarm(card);
result = CARD_RESULT_READY;
}
}
}
OSRestoreInterrupts(enabled);
return result;
}
#define AD1(x) ((u8)(((x) >> 17) & 0x7f))
#define AD1EX(x) ((u8)(AD1(x) | 0x80));
#define AD2(x) ((u8)(((x) >> 9) & 0xff))
#define AD3(x) ((u8)(((x) >> 7) & 0x03))
#define BA(x) ((u8)((x)&0x7f))
s32 __CARDReadSegment(s32 chan, CARDCallback callback) {
CARDControl* card;
s32 result;
card = &__CARDBlock[chan];
card->cmd[0] = 0x52;
card->cmd[1] = AD1(card->addr);
card->cmd[2] = AD2(card->addr);
card->cmd[3] = AD3(card->addr);
card->cmd[4] = BA(card->addr);
card->cmdlen = 5;
card->mode = 0;
card->retry = 0;
result = __CARDStart(chan, callback, 0);
if (result == CARD_RESULT_BUSY) {
result = CARD_RESULT_READY;
} else if (result >= 0) {
if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1) ||
!EXIImmEx(chan, (u8*)card->workArea + sizeof(CARDID), card->latency, 1) || // XXX use DMA if possible
!EXIDma(chan, card->buffer, 512, card->mode, __CARDTxHandler)) {
card->txCallback = 0;
EXIDeselect(chan);
EXIUnlock(chan);
result = CARD_RESULT_NOCARD;
} else {
result = CARD_RESULT_READY;
}
}
return result;
}
s32 __CARDWritePage(s32 chan, CARDCallback callback) {
CARDControl* card;
s32 result;
card = &__CARDBlock[chan];
card->cmd[0] = 0xF2;
card->cmd[1] = AD1(card->addr);
card->cmd[2] = AD2(card->addr);
card->cmd[3] = AD3(card->addr);
card->cmd[4] = BA(card->addr);
card->cmdlen = 5;
card->mode = 1;
card->retry = 3;
result = __CARDStart(chan, 0, callback);
if (result == CARD_RESULT_BUSY) {
result = CARD_RESULT_READY;
} else if (result >= 0) {
if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1) || !EXIDma(chan, card->buffer, 128, card->mode, __CARDTxHandler)) {
card->exiCallback = 0;
EXIDeselect(chan);
EXIUnlock(chan);
result = CARD_RESULT_NOCARD;
} else {
result = CARD_RESULT_READY;
}
}
return result;
}
/* TODO: Needs frank fix for disconnected stack epilogue */
s32 __CARDEraseSector(s32 chan, u32 addr, CARDCallback callback) {
CARDControl* card;
s32 result;
card = &__CARDBlock[chan];
card->cmd[0] = 0xF1;
card->cmd[1] = AD1(addr);
card->cmd[2] = AD2(addr);
card->cmdlen = 3;
card->mode = -1;
card->retry = 3;
result = __CARDStart(chan, 0, callback);
if (result == CARD_RESULT_BUSY) {
result = CARD_RESULT_READY;
} else if (result >= 0) {
if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1)) {
card->exiCallback = NULL;
result = CARD_RESULT_NOCARD;
} else {
result = CARD_RESULT_READY;
}
EXIDeselect(chan);
EXIUnlock(chan);
}
return result;
}
void CARDInit(void) {
int chan;
if (__CARDBlock[0].diskID && __CARDBlock[1].diskID) {
return;
}
__CARDEncode = OSGetFontEncode();
OSRegisterVersion(__CARDVersion);
DSPInit();
OSInitAlarm();
for (chan = 0; chan < 2; ++chan) {
CARDControl* card = &__CARDBlock[chan];
card->result = CARD_RESULT_NOCARD;
OSInitThreadQueue(&card->threadQueue);
OSCreateAlarm(&card->alarm);
}
__CARDSetDiskID((DVDDiskID*)OSPhysicalToCached(0x0));
OSRegisterResetFunction(&ResetFunctionInfo);
}
u16 __CARDGetFontEncode(s32 chan) { return __CARDEncode; }
void __CARDSetDiskID(const DVDDiskID* id) {
__CARDBlock[0].diskID = id ? id : &__CARDDiskNone;
__CARDBlock[1].diskID = id ? id : &__CARDDiskNone;
}
s32 __CARDGetControlBlock(s32 chan, CARDControl** pcard) {
BOOL enabled;
s32 result;
CARDControl* card;
card = &__CARDBlock[chan];
if (chan < 0 || chan >= 2 || card->diskID == NULL) {
return CARD_RESULT_FATAL_ERROR;
}
enabled = OSDisableInterrupts();
if (!card->attached) {
result = CARD_RESULT_NOCARD;
} else if (card->result == CARD_RESULT_BUSY) {
result = CARD_RESULT_BUSY;
} else {
card->result = CARD_RESULT_BUSY;
result = CARD_RESULT_READY;
card->apiCallback = 0;
*pcard = card;
}
OSRestoreInterrupts(enabled);
return result;
}
/* TODO: Needs frank fix for disconnected stack epilogue */
s32 __CARDPutControlBlock(CARDControl* card, s32 result) {
BOOL enabled;
enabled = OSDisableInterrupts();
if (card->attached) {
card->result = result;
} else if (card->result == CARD_RESULT_BUSY) {
card->result = result;
}
OSRestoreInterrupts(enabled);
return result;
}
s32 CARDGetResultCode(s32 chan) {
CARDControl* card;
if (chan < 0 || chan >= 2) {
return CARD_RESULT_FATAL_ERROR;
}
card = &__CARDBlock[chan];
return card->result;
}
s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed) {
CARDControl* card;
s32 result;
u16* fat;
CARDDir* dir;
CARDDir* ent;
u16 fileNo;
result = __CARDGetControlBlock(chan, &card);
if (result < 0) {
return result;
}
fat = __CARDGetFatBlock(card);
dir = __CARDGetDirBlock(card);
if (fat == 0 || dir == 0) {
return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
}
if (byteNotUsed) {
*byteNotUsed = (s32)(card->sectorSize * fat[CARD_FAT_FREEBLOCKS]);
}
if (filesNotUsed) {
*filesNotUsed = 0;
for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) {
ent = &dir[fileNo];
if (ent->fileName[0] == 0xff) {
++*filesNotUsed;
}
}
}
return __CARDPutControlBlock(card, CARD_RESULT_READY);
}
static BOOL OnReset(BOOL final) {
if (!final) {
if (CARDUnmount(0) == CARD_RESULT_BUSY || CARDUnmount(1) == CARD_RESULT_BUSY) {
return FALSE;
}
}
return TRUE;
}

View File

@ -0,0 +1,390 @@
#include <dolphin/card.h>
#include <dolphin/dsp.h>
#include <dolphin/dvd.h>
#include <dolphin/os.h>
#include <dolphin/CARDPriv.h>
static void InitCallback(void* task);
static void DoneCallback(void* task);
static u8 CardData[] ATTRIBUTE_ALIGN(32) = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x02, 0xFF, 0x00, 0x21, 0x13, 0x06, 0x12, 0x03, 0x12, 0x04, 0x13, 0x05, 0x00, 0x92, 0x00, 0xFF,
0x00, 0x88, 0xFF, 0xFF, 0x00, 0x89, 0xFF, 0xFF, 0x00, 0x8A, 0xFF, 0xFF, 0x00, 0x8B, 0xFF, 0xFF, 0x8F, 0x00, 0x02, 0xBF, 0x00, 0x88,
0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x00, 0x16, 0xFB, 0x00, 0x01, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x03, 0x80, 0xFF, 0x00,
0x02, 0x94, 0x00, 0x27, 0x02, 0xBF, 0x00, 0x8E, 0x1F, 0xDF, 0x24, 0xFF, 0x02, 0x40, 0x0F, 0xFF, 0x00, 0x98, 0x04, 0x00, 0x00, 0x9A,
0x00, 0x10, 0x00, 0x99, 0x00, 0x00, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x94, 0x02, 0xBF, 0x86, 0x44, 0x02, 0xBF, 0x00, 0x88, 0x16, 0xFC,
0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x03, 0x16, 0xFB, 0x00, 0x01, 0x8F, 0x00, 0x02, 0xBF, 0x00, 0x8E, 0x03, 0x80, 0xCD, 0xD1, 0x02, 0x94,
0x00, 0x48, 0x27, 0xFF, 0x03, 0x80, 0x00, 0x01, 0x02, 0x95, 0x00, 0x5A, 0x03, 0x80, 0x00, 0x02, 0x02, 0x95, 0x80, 0x00, 0x02, 0x9F,
0x00, 0x48, 0x00, 0x21, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E,
0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC5, 0xFF, 0xFF, 0x03, 0x40, 0x0F, 0xFF, 0x1C, 0x9F, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC7,
0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC6, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC0, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x8E,
0x20, 0xFF, 0x03, 0x40, 0x0F, 0xFF, 0x1F, 0x5F, 0x02, 0xBF, 0x00, 0x8E, 0x21, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x23, 0xFF, 0x12, 0x05,
0x12, 0x06, 0x02, 0x9F, 0x80, 0xB5, 0x00, 0x21, 0x27, 0xFC, 0x03, 0xC0, 0x80, 0x00, 0x02, 0x9D, 0x00, 0x88, 0x02, 0xDF, 0x27, 0xFE,
0x03, 0xC0, 0x80, 0x00, 0x02, 0x9C, 0x00, 0x8E, 0x02, 0xDF, 0x2E, 0xCE, 0x2C, 0xCF, 0x00, 0xF8, 0xFF, 0xCD, 0x00, 0xF9, 0xFF, 0xC9,
0x00, 0xFA, 0xFF, 0xCB, 0x26, 0xC9, 0x02, 0xC0, 0x00, 0x04, 0x02, 0x9D, 0x00, 0x9C, 0x02, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
typedef struct DecodeParameters {
u8* inputAddr;
u32 inputLength;
u32 aramAddr;
u8* outputAddr;
} DecodeParameters;
static unsigned long int next = 1;
static int CARDRand(void) {
next = next * 1103515245 + 12345;
return (int)((unsigned int)(next / 65536) % 32768);
}
static void CARDSrand(unsigned int seed) { next = seed; }
static u32 GetInitVal(void) {
u32 tmp;
u32 tick;
tick = OSGetTick();
CARDSrand(tick);
tmp = 0x7fec8000;
tmp |= CARDRand();
tmp &= 0xfffff000;
return tmp;
}
static u32 exnor_1st(u32 data, u32 rshift) {
u32 wk;
u32 w;
u32 i;
w = data;
for (i = 0; i < rshift; i++) {
wk = ~(w ^ (w >> 7) ^ (w >> 15) ^ (w >> 23));
w = (w >> 1) | ((wk << 30) & 0x40000000);
}
return w;
}
static u32 exnor(u32 data, u32 lshift) {
u32 wk;
u32 w;
u32 i;
w = data;
for (i = 0; i < lshift; i++) {
// 1bit Left Shift
wk = ~(w ^ (w << 7) ^ (w << 15) ^ (w << 23));
w = (w << 1) | ((wk >> 30) & 0x00000002);
// printf("i=%d, w=%8x\n", i, w);
}
return w;
}
static u32 bitrev(u32 data) {
u32 wk;
u32 i;
u32 k = 0;
u32 j = 1;
wk = 0;
for (i = 0; i < 32; i++) {
if (i > 15) {
if (i == 31) {
wk |= (((data & (0x01 << 31)) >> 31) & 0x01);
} else {
wk |= ((data & (0x01 << i)) >> j);
j += 2;
}
} else {
wk |= ((data & (0x01 << i)) << (31 - i - k));
k++;
}
}
return wk;
}
#define SEC_AD1(x) ((u8)(((x) >> 29) & 0x03))
#define SEC_AD2(x) ((u8)(((x) >> 21) & 0xff))
#define SEC_AD3(x) ((u8)(((x) >> 19) & 0x03))
#define SEC_BA(x) ((u8)(((x) >> 12) & 0x7f))
static s32 ReadArrayUnlock(s32 chan, u32 data, void* rbuf, s32 rlen, s32 mode) {
CARDControl* card;
BOOL err;
u8 cmd[5];
card = &__CARDBlock[chan];
if (!EXISelect(chan, 0, 4)) {
return CARD_RESULT_NOCARD;
}
data &= 0xfffff000;
memset(cmd, 0, 5);
cmd[0] = 0x52;
if (mode == 0) {
cmd[1] = SEC_AD1(data);
cmd[2] = SEC_AD2(data);
cmd[3] = SEC_AD3(data);
cmd[4] = SEC_BA(data);
} else {
cmd[1] = (u8)((data & 0xff000000) >> 24);
cmd[2] = (u8)((data & 0x00ff0000) >> 16);
}
err = FALSE;
err |= !EXIImmEx(chan, cmd, 5, 1);
err |= !EXIImmEx(chan, (u8*)card->workArea + (u32)sizeof(CARDID), card->latency, 1);
err |= !EXIImmEx(chan, rbuf, rlen, 0);
err |= !EXIDeselect(chan);
return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY;
}
// Calculate Dummy Read Length, 4-32Bytes
static s32 DummyLen(void) {
u32 tick;
u32 wk;
s32 tmp;
u32 max;
wk = 1;
max = 0;
tick = OSGetTick();
CARDSrand(tick);
tmp = CARDRand();
tmp &= 0x0000001f;
tmp += 1;
while ((tmp < 4) && (max < 10)) {
tick = OSGetTick();
tmp = (s32)(tick << wk);
wk++;
if (wk > 16) {
wk = 1;
}
CARDSrand((u32)tmp);
tmp = CARDRand();
tmp &= 0x0000001f;
tmp += 1;
max++;
}
if (tmp < 4) {
tmp = 4;
}
return tmp;
}
s32 __CARDUnlock(s32 chan, u8 flashID[12]) {
u32 init_val;
u32 data;
s32 dummy;
s32 rlen;
u32 rshift;
u8 fsts;
u32 wk, wk1;
u32 Ans1 = 0;
u32 Ans2 = 0;
u32* dp;
u8 rbuf[64];
u32 para1A = 0;
u32 para1B = 0;
u32 para2A = 0;
u32 para2B = 0;
CARDControl* card;
DSPTaskInfo* task;
DecodeParameters* param;
u8* input;
u8* output;
card = &__CARDBlock[chan];
task = &card->task;
param = (DecodeParameters*)card->workArea;
input = (u8*)((u8*)param + sizeof(DecodeParameters));
input = (u8*)OSRoundUp32B(input);
output = input + 32;
fsts = 0;
init_val = GetInitVal();
dummy = DummyLen();
rlen = dummy;
if (ReadArrayUnlock(chan, init_val, rbuf, rlen, 0) < 0) {
return CARD_RESULT_NOCARD;
}
rshift = (u32)(dummy * 8 + 1);
wk = exnor_1st(init_val, rshift);
wk1 = ~(wk ^ (wk >> 7) ^ (wk >> 15) ^ (wk >> 23));
card->scramble = (wk | ((wk1 << 31) & 0x80000000));
card->scramble = bitrev(card->scramble);
dummy = DummyLen();
rlen = 20 + dummy;
data = 0;
if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) {
return CARD_RESULT_NOCARD;
}
dp = (u32*)rbuf;
para1A = *dp++;
para1B = *dp++;
Ans1 = *dp++;
para2A = *dp++;
para2B = *dp++;
para1A = (para1A ^ card->scramble);
rshift = 32;
wk = exnor(card->scramble, rshift);
wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
para1B = (para1B ^ card->scramble);
rshift = 32;
wk = exnor(card->scramble, rshift);
wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
Ans1 ^= card->scramble;
rshift = 32;
wk = exnor(card->scramble, rshift);
wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
para2A = (para2A ^ card->scramble);
rshift = 32;
wk = exnor(card->scramble, rshift);
wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
para2B = (para2B ^ card->scramble);
rshift = (u32)(dummy * 8);
wk = exnor(card->scramble, rshift);
wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
rshift = 32 + 1;
wk = exnor(card->scramble, rshift);
wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
*(u32*)&input[0] = para2A;
*(u32*)&input[4] = para2B;
param->inputAddr = input;
param->inputLength = 8;
param->outputAddr = output;
param->aramAddr = 0;
DCFlushRange(input, 8);
DCInvalidateRange(output, 4);
DCFlushRange(param, sizeof(DecodeParameters));
task->priority = 255;
task->iram_mmem_addr = (u16*)OSPhysicalToCached(CardData);
task->iram_length = 0x160;
task->iram_addr = 0;
task->dsp_init_vector = 0x10;
task->init_cb = InitCallback;
task->res_cb = NULL;
task->done_cb = DoneCallback;
task->req_cb = NULL;
DSPAddTask(task);
dp = (u32*)flashID;
*dp++ = para1A;
*dp++ = para1B;
*dp = Ans1;
return CARD_RESULT_READY;
}
static void InitCallback(void* _task) {
s32 chan;
CARDControl* card;
DSPTaskInfo* task;
DecodeParameters* param;
task = _task;
for (chan = 0; chan < 2; ++chan) {
card = &__CARDBlock[chan];
if ((DSPTaskInfo*)&card->task == task) {
break;
}
}
param = (DecodeParameters*)card->workArea;
DSPSendMailToDSP(0xff000000);
while (DSPCheckMailToDSP())
;
DSPSendMailToDSP((u32)param);
while (DSPCheckMailToDSP())
;
}
static void DoneCallback(void* _task) {
u8 rbuf[64];
u32 data;
s32 dummy;
s32 rlen;
u32 rshift;
u8 unk;
u32 wk, wk1;
u32 Ans2;
s32 chan;
CARDControl* card;
s32 result;
DSPTaskInfo* task;
DecodeParameters* param;
u8* input;
u8* output;
task = _task;
for (chan = 0; chan < 2; ++chan) {
card = &__CARDBlock[chan];
if ((DSPTaskInfo*)&card->task == task) {
break;
}
}
param = (DecodeParameters*)card->workArea;
input = (u8*)((u8*)param + sizeof(DecodeParameters));
input = (u8*)OSRoundUp32B(input);
output = input + 32;
Ans2 = *(u32*)output;
dummy = DummyLen();
rlen = dummy;
data = ((Ans2 ^ card->scramble) & 0xffff0000);
if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) {
EXIUnlock(chan);
__CARDMountCallback(chan, CARD_RESULT_NOCARD);
return;
}
rshift = (u32)((dummy + 4 + card->latency) * 8 + 1);
wk = exnor(card->scramble, rshift);
wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
dummy = DummyLen();
rlen = dummy;
data = (((Ans2 << 16) ^ card->scramble) & 0xffff0000);
if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) {
EXIUnlock(chan);
__CARDMountCallback(chan, CARD_RESULT_NOCARD);
return;
}
result = __CARDReadStatus(chan, &unk);
if (!EXIProbe(chan)) {
EXIUnlock(chan);
__CARDMountCallback(chan, CARD_RESULT_NOCARD);
return;
}
if (result == CARD_RESULT_READY && !(unk & 0x40)) {
EXIUnlock(chan);
result = CARD_RESULT_IOERROR;
}
__CARDMountCallback(chan, result);
}