mirror of https://github.com/PrimeDecomp/prime.git
parent
9bf0ca2b26
commit
bb45a64b7b
|
@ -10,8 +10,6 @@
|
||||||
"editor.tabSize": 2,
|
"editor.tabSize": 2,
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"source_location": "cpp",
|
"source_location": "cpp",
|
||||||
"dtk.h": "c",
|
|
||||||
"dvd.h": "c"
|
|
||||||
},
|
},
|
||||||
"files.autoSave": "onFocusChange",
|
"files.autoSave": "onFocusChange",
|
||||||
"files.insertFinalNewline": true,
|
"files.insertFinalNewline": true,
|
||||||
|
|
3
Makefile
3
Makefile
|
@ -149,7 +149,8 @@ $(PAD_FILES): MWCC_VERSION := 1.2.5
|
||||||
$(PAD_FILES): CFLAGS := $(CFLAGS_BASE)
|
$(PAD_FILES): CFLAGS := $(CFLAGS_BASE)
|
||||||
$(DTK_FILES): MWCC_VERSION := 1.2.5
|
$(DTK_FILES): MWCC_VERSION := 1.2.5
|
||||||
$(DTK_FILES): CFLAGS := $(CFLAGS_BASE)
|
$(DTK_FILES): CFLAGS := $(CFLAGS_BASE)
|
||||||
|
$(SI_FILES): MWCC_VERSION := 1.2.5
|
||||||
|
$(SI_FILES): CFLAGS := $(CFLAGS_BASE)
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# Recipes
|
# Recipes
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1781,9 +1781,6 @@ lbl_803BFE10:
|
||||||
/* 803BFE24 003BCD84 7C 03 00 00 */ cmpw r3, r0
|
/* 803BFE24 003BCD84 7C 03 00 00 */ cmpw r3, r0
|
||||||
/* 803BFE28 003BCD88 4D 82 00 20 */ beqlr
|
/* 803BFE28 003BCD88 4D 82 00 20 */ beqlr
|
||||||
/* 803BFE2C 003BCD8C 48 00 00 08 */ b lbl_803BFE34
|
/* 803BFE2C 003BCD8C 48 00 00 08 */ b lbl_803BFE34
|
||||||
|
|
||||||
.global sub_803bfe30
|
|
||||||
sub_803bfe30:
|
|
||||||
/* 803BFE30 003BCD90 4E 80 00 20 */ blr
|
/* 803BFE30 003BCD90 4E 80 00 20 */ blr
|
||||||
lbl_803BFE34:
|
lbl_803BFE34:
|
||||||
/* 803BFE34 003BCD94 38 60 00 40 */ li r3, 0x40
|
/* 803BFE34 003BCD94 38 60 00 40 */ li r3, 0x40
|
||||||
|
@ -1804,9 +1801,6 @@ lbl_803BFE50:
|
||||||
/* 803BFE68 003BCDC8 7C 03 00 00 */ cmpw r3, r0
|
/* 803BFE68 003BCDC8 7C 03 00 00 */ cmpw r3, r0
|
||||||
/* 803BFE6C 003BCDCC 4D 82 00 20 */ beqlr
|
/* 803BFE6C 003BCDCC 4D 82 00 20 */ beqlr
|
||||||
/* 803BFE70 003BCDD0 48 00 00 08 */ b lbl_803BFE78
|
/* 803BFE70 003BCDD0 48 00 00 08 */ b lbl_803BFE78
|
||||||
|
|
||||||
.global sub_803bfe74
|
|
||||||
sub_803bfe74:
|
|
||||||
/* 803BFE74 003BCDD4 4E 80 00 20 */ blr
|
/* 803BFE74 003BCDD4 4E 80 00 20 */ blr
|
||||||
lbl_803BFE78:
|
lbl_803BFE78:
|
||||||
/* 803BFE78 003BCDD8 54 A3 00 14 */ rlwinm r3, r5, 0, 0, 0xa
|
/* 803BFE78 003BCDD8 54 A3 00 14 */ rlwinm r3, r5, 0, 0, 0xa
|
||||||
|
|
|
@ -136,7 +136,9 @@ void OSFatal(GXColor fg, GXColor bg, const char* msg);
|
||||||
#include <dolphin/os/OSCache.h>
|
#include <dolphin/os/OSCache.h>
|
||||||
#include <dolphin/os/OSContext.h>
|
#include <dolphin/os/OSContext.h>
|
||||||
#include <dolphin/os/OSError.h>
|
#include <dolphin/os/OSError.h>
|
||||||
|
#include <dolphin/os/OSException.h>
|
||||||
#include <dolphin/os/OSFont.h>
|
#include <dolphin/os/OSFont.h>
|
||||||
|
#include <dolphin/os/OSInterrupt.h>
|
||||||
#include <dolphin/os/OSReset.h>
|
#include <dolphin/os/OSReset.h>
|
||||||
#include <dolphin/os/OSSerial.h>
|
#include <dolphin/os/OSSerial.h>
|
||||||
#include <dolphin/os/OSThread.h>
|
#include <dolphin/os/OSThread.h>
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
|
||||||
|
#ifndef __OSEXCEPTION_H__
|
||||||
|
#define __OSEXCEPTION_H__
|
||||||
|
|
||||||
|
#include <dolphin/os/OSContext.h>
|
||||||
|
#include <dolphin/types.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
typedef u8 __OSException;
|
||||||
|
typedef void (*__OSExceptionHandler)(__OSException exception, OSContext* context);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __OSEXCEPTION_H__
|
|
@ -0,0 +1,116 @@
|
||||||
|
#ifndef __OSINTERRUPT_H__
|
||||||
|
#define __OSINTERRUPT_H__
|
||||||
|
|
||||||
|
#include <dolphin/os/OSContext.h>
|
||||||
|
#include <dolphin/types.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __OS_INTERRUPT_MEM_0 0
|
||||||
|
#define __OS_INTERRUPT_MEM_1 1
|
||||||
|
#define __OS_INTERRUPT_MEM_2 2
|
||||||
|
#define __OS_INTERRUPT_MEM_3 3
|
||||||
|
#define __OS_INTERRUPT_MEM_ADDRESS 4
|
||||||
|
#define __OS_INTERRUPT_DSP_AI 5
|
||||||
|
#define __OS_INTERRUPT_DSP_ARAM 6
|
||||||
|
#define __OS_INTERRUPT_DSP_DSP 7
|
||||||
|
#define __OS_INTERRUPT_AI_AI 8
|
||||||
|
#define __OS_INTERRUPT_EXI_0_EXI 9
|
||||||
|
#define __OS_INTERRUPT_EXI_0_TC 10
|
||||||
|
#define __OS_INTERRUPT_EXI_0_EXT 11
|
||||||
|
#define __OS_INTERRUPT_EXI_1_EXI 12
|
||||||
|
#define __OS_INTERRUPT_EXI_1_TC 13
|
||||||
|
#define __OS_INTERRUPT_EXI_1_EXT 14
|
||||||
|
#define __OS_INTERRUPT_EXI_2_EXI 15
|
||||||
|
#define __OS_INTERRUPT_EXI_2_TC 16
|
||||||
|
#define __OS_INTERRUPT_PI_CP 17
|
||||||
|
#define __OS_INTERRUPT_PI_PE_TOKEN 18
|
||||||
|
#define __OS_INTERRUPT_PI_PE_FINISH 19
|
||||||
|
#define __OS_INTERRUPT_PI_SI 20
|
||||||
|
#define __OS_INTERRUPT_PI_DI 21
|
||||||
|
#define __OS_INTERRUPT_PI_RSW 22
|
||||||
|
#define __OS_INTERRUPT_PI_ERROR 23
|
||||||
|
#define __OS_INTERRUPT_PI_VI 24
|
||||||
|
#define __OS_INTERRUPT_PI_DEBUG 25
|
||||||
|
#define __OS_INTERRUPT_PI_HSP 26
|
||||||
|
#define __OS_INTERRUPT_MAX 32
|
||||||
|
|
||||||
|
#define OS_INTERRUPTMASK(interrupt) (0x80000000u >> (interrupt))
|
||||||
|
|
||||||
|
#define OS_INTERRUPTMASK_MEM_0 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0)
|
||||||
|
#define OS_INTERRUPTMASK_MEM_1 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_1)
|
||||||
|
#define OS_INTERRUPTMASK_MEM_2 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_2)
|
||||||
|
#define OS_INTERRUPTMASK_MEM_3 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_3)
|
||||||
|
#define OS_INTERRUPTMASK_MEM_ADDRESS OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_ADDRESS)
|
||||||
|
#define OS_INTERRUPTMASK_MEM \
|
||||||
|
(OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | \
|
||||||
|
OS_INTERRUPTMASK_MEM_3 | OS_INTERRUPTMASK_MEM_ADDRESS)
|
||||||
|
#define OS_INTERRUPTMASK_DSP_AI OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_AI)
|
||||||
|
#define OS_INTERRUPTMASK_DSP_ARAM OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_ARAM)
|
||||||
|
#define OS_INTERRUPTMASK_DSP_DSP OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_DSP)
|
||||||
|
#define OS_INTERRUPTMASK_DSP \
|
||||||
|
(OS_INTERRUPTMASK_DSP_AI | OS_INTERRUPTMASK_DSP_ARAM | OS_INTERRUPTMASK_DSP_DSP)
|
||||||
|
#define OS_INTERRUPTMASK_AI_AI OS_INTERRUPTMASK(__OS_INTERRUPT_AI_AI)
|
||||||
|
#define OS_INTERRUPTMASK_AI (OS_INTERRUPTMASK_AI_AI)
|
||||||
|
#define OS_INTERRUPTMASK_EXI_0_EXI OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_EXI)
|
||||||
|
#define OS_INTERRUPTMASK_EXI_0_TC OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_TC)
|
||||||
|
#define OS_INTERRUPTMASK_EXI_0_EXT OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_EXT)
|
||||||
|
#define OS_INTERRUPTMASK_EXI_0 \
|
||||||
|
(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | OS_INTERRUPTMASK_EXI_0_EXT)
|
||||||
|
#define OS_INTERRUPTMASK_EXI_1_EXI OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_EXI)
|
||||||
|
#define OS_INTERRUPTMASK_EXI_1_TC OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_TC)
|
||||||
|
#define OS_INTERRUPTMASK_EXI_1_EXT OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_EXT)
|
||||||
|
#define OS_INTERRUPTMASK_EXI_1 \
|
||||||
|
(OS_INTERRUPTMASK_EXI_1_EXI | OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT)
|
||||||
|
#define OS_INTERRUPTMASK_EXI_2_EXI OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_2_EXI)
|
||||||
|
#define OS_INTERRUPTMASK_EXI_2_TC OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_2_TC)
|
||||||
|
#define OS_INTERRUPTMASK_EXI_2 (OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC)
|
||||||
|
#define OS_INTERRUPTMASK_EXI \
|
||||||
|
(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)
|
||||||
|
#define OS_INTERRUPTMASK_PI_PE_TOKEN OS_INTERRUPTMASK(__OS_INTERRUPT_PI_PE_TOKEN)
|
||||||
|
#define OS_INTERRUPTMASK_PI_PE_FINISH OS_INTERRUPTMASK(__OS_INTERRUPT_PI_PE_FINISH)
|
||||||
|
#define OS_INTERRUPTMASK_PI_PE (OS_INTERRUPTMASK_PI_PE_TOKEN | OS_INTERRUPTMASK_PI_PE_FINISH)
|
||||||
|
#define OS_INTERRUPTMASK_PI_CP OS_INTERRUPTMASK(__OS_INTERRUPT_PI_CP)
|
||||||
|
#define OS_INTERRUPTMASK_PI_SI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_SI)
|
||||||
|
#define OS_INTERRUPTMASK_PI_DI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_DI)
|
||||||
|
#define OS_INTERRUPTMASK_PI_RSW OS_INTERRUPTMASK(__OS_INTERRUPT_PI_RSW)
|
||||||
|
#define OS_INTERRUPTMASK_PI_ERROR OS_INTERRUPTMASK(__OS_INTERRUPT_PI_ERROR)
|
||||||
|
#define OS_INTERRUPTMASK_PI_VI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_VI)
|
||||||
|
#define OS_INTERRUPTMASK_PI_DEBUG OS_INTERRUPTMASK(__OS_INTERRUPT_PI_DEBUG)
|
||||||
|
#define OS_INTERRUPTMASK_PI_HSP OS_INTERRUPTMASK(__OS_INTERRUPT_PI_HSP)
|
||||||
|
#define OS_INTERRUPTMASK_PI \
|
||||||
|
(OS_INTERRUPTMASK_PI_CP | OS_INTERRUPTMASK_PI_SI | OS_INTERRUPTMASK_PI_DI | \
|
||||||
|
OS_INTERRUPTMASK_PI_RSW | OS_INTERRUPTMASK_PI_ERROR | OS_INTERRUPTMASK_PI_VI | \
|
||||||
|
OS_INTERRUPTMASK_PI_PE_TOKEN | OS_INTERRUPTMASK_PI_PE_FINISH | OS_INTERRUPTMASK_PI_DEBUG | \
|
||||||
|
OS_INTERRUPTMASK_PI_HSP)
|
||||||
|
|
||||||
|
|
||||||
|
typedef s16 __OSInterrupt;
|
||||||
|
typedef void (*__OSInterruptHandler)(__OSInterrupt interrupt, OSContext* context);
|
||||||
|
|
||||||
|
typedef u32 OSInterruptMask;
|
||||||
|
|
||||||
|
extern volatile __OSInterrupt __OSLastInterrupt;
|
||||||
|
extern volatile u32 __OSLastInterruptSrr0;
|
||||||
|
extern volatile OSTime __OSLastInterruptTime;
|
||||||
|
|
||||||
|
__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler);
|
||||||
|
|
||||||
|
__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt);
|
||||||
|
|
||||||
|
void __OSDispatchInterrupt(__OSException exception, OSContext* context);
|
||||||
|
|
||||||
|
OSInterruptMask OSGetInterruptMask(void);
|
||||||
|
OSInterruptMask OSSetInterruptMask(OSInterruptMask mask);
|
||||||
|
OSInterruptMask __OSMaskInterrupts(OSInterruptMask mask);
|
||||||
|
OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask mask);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __OSINTERRUPT_H__
|
|
@ -9,12 +9,41 @@ extern "C" {
|
||||||
typedef void (*SICallback)(s32 chan, u32 sr, OSContext* context);
|
typedef void (*SICallback)(s32 chan, u32 sr, OSContext* context);
|
||||||
typedef void (*SITypeAndStatusCallback)(s32 chan, u32 type);
|
typedef void (*SITypeAndStatusCallback)(s32 chan, u32 type);
|
||||||
|
|
||||||
BOOL SIGetResponse(s32 chan, void* data);
|
typedef struct SIPacket {
|
||||||
void SISetCommand(s32 chan, u32 cmd);
|
s32 chan;
|
||||||
|
void* output;
|
||||||
|
u32 outputBytes;
|
||||||
|
void* input;
|
||||||
|
u32 inputBytes;
|
||||||
|
SICallback callback;
|
||||||
|
OSTime fire;
|
||||||
|
} SIPacket;
|
||||||
|
|
||||||
|
|
||||||
|
void SIInit(void);
|
||||||
|
u32 SIGetStatus(s32 chan);
|
||||||
|
|
||||||
|
BOOL SIBusy(void);
|
||||||
|
BOOL SIIsChanBusy(s32 chan);
|
||||||
|
|
||||||
BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes,
|
BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes,
|
||||||
SICallback callback, OSTime delay);
|
SICallback callback, OSTime delay);
|
||||||
void SIEnablePolling(s32 bits);
|
u32 SISync(void);
|
||||||
void SIDisablePolling(s32 bits);
|
|
||||||
|
void SISetCommand(s32 chan, u32 command);
|
||||||
|
u32 SIGetCommand(s32 chan);
|
||||||
|
void SITransferCommands(void);
|
||||||
|
u32 SISetXY(u32 x, u32 y);
|
||||||
|
u32 SIEnablePolling(u32 poll);
|
||||||
|
u32 SIDisablePolling(u32 poll);
|
||||||
|
BOOL SIGetResponse(s32 chan, void* data);
|
||||||
|
|
||||||
|
BOOL SIRegisterPollingHandler(__OSInterruptHandler handler);
|
||||||
|
BOOL SIUnregisterPollingHandler(__OSInterruptHandler handler);
|
||||||
|
|
||||||
|
u32 SIGetType(s32 chan);
|
||||||
|
u32 SIGetTypeAsync(s32 chan, SITypeAndStatusCallback callback);
|
||||||
|
u32 SIDecodeType(u32 type);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,289 @@
|
||||||
|
#include <dolphin/os.h>
|
||||||
|
#include <dolphin/sipriv.h>
|
||||||
|
|
||||||
|
vu32 __SIRegs[64] : 0xCC006400;
|
||||||
|
|
||||||
|
extern OSTime __OSGetSystemTime();
|
||||||
|
|
||||||
|
const char* __SIVersion = "<< Dolphin SDK - SI\trelease build: Sep 5 2002 05:33:08 (0x2301) >>";
|
||||||
|
|
||||||
|
typedef struct SIControl {
|
||||||
|
s32 chan;
|
||||||
|
u32 poll;
|
||||||
|
u32 inputBytes;
|
||||||
|
void* input;
|
||||||
|
SICallback callback;
|
||||||
|
} SIControl;
|
||||||
|
|
||||||
|
static SIControl Si = {
|
||||||
|
-1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static SIPacket Packet[SI_MAX_CHAN];
|
||||||
|
static OSAlarm Alarm[SI_MAX_CHAN];
|
||||||
|
static u32 Type[SI_MAX_CHAN] = {
|
||||||
|
SI_ERROR_NO_RESPONSE,
|
||||||
|
SI_ERROR_NO_RESPONSE,
|
||||||
|
SI_ERROR_NO_RESPONSE,
|
||||||
|
SI_ERROR_NO_RESPONSE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static OSTime TypeTime[SI_MAX_CHAN];
|
||||||
|
static OSTime XferTime[SI_MAX_CHAN];
|
||||||
|
|
||||||
|
static SITypeAndStatusCallback TypeCallback[SI_MAX_CHAN][4];
|
||||||
|
static __OSInterruptHandler RDSTHandler[4];
|
||||||
|
|
||||||
|
u32 __PADFixBits;
|
||||||
|
|
||||||
|
static BOOL __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes,
|
||||||
|
SICallback callback);
|
||||||
|
|
||||||
|
static BOOL InputBufferValid[SI_MAX_CHAN];
|
||||||
|
static u32 InputBuffer[SI_MAX_CHAN][2];
|
||||||
|
static vu32 InputBufferVcount[SI_MAX_CHAN];
|
||||||
|
|
||||||
|
static BOOL SIGetResponseRaw(s32 chan);
|
||||||
|
static void GetTypeCallback(s32 chan, u32 error, OSContext* context);
|
||||||
|
|
||||||
|
BOOL SIBusy() { return Si.chan != -1 ? TRUE : FALSE; }
|
||||||
|
|
||||||
|
BOOL SIIsChanBusy(s32 chan) { return (Packet[chan].chan != -1 || Si.chan == chan); }
|
||||||
|
|
||||||
|
static void SIClearTCInterrupt() {
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
reg = __SIRegs[13];
|
||||||
|
reg |= 0x80000000;
|
||||||
|
reg &= ~0x00000001;
|
||||||
|
__SIRegs[13] = reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 CompleteTransfer() {
|
||||||
|
u32 sr;
|
||||||
|
u32 i;
|
||||||
|
u32 rLen;
|
||||||
|
u8* input;
|
||||||
|
|
||||||
|
sr = __SIRegs[14];
|
||||||
|
|
||||||
|
SIClearTCInterrupt();
|
||||||
|
|
||||||
|
if (Si.chan != -1) {
|
||||||
|
XferTime[Si.chan] = __OSGetSystemTime();
|
||||||
|
|
||||||
|
input = Si.input;
|
||||||
|
|
||||||
|
rLen = Si.inputBytes / 4;
|
||||||
|
for (i = 0; i < rLen; i++) {
|
||||||
|
*(u32*)input = __SIRegs[32 + i];
|
||||||
|
input += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
rLen = Si.inputBytes & 3;
|
||||||
|
if (rLen) {
|
||||||
|
u32 temp = __SIRegs[32 + i];
|
||||||
|
for (i = 0; i < rLen; i++) {
|
||||||
|
*input++ = (u8)((temp >> ((3 - i) * 8)) & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__SIRegs[13] & 0x20000000) {
|
||||||
|
sr >>= 8 * (3 - Si.chan);
|
||||||
|
sr &= 0xf;
|
||||||
|
|
||||||
|
if ((sr & SI_ERROR_NO_RESPONSE) && !(Type[Si.chan] & SI_ERROR_BUSY)) {
|
||||||
|
Type[Si.chan] = SI_ERROR_NO_RESPONSE;
|
||||||
|
}
|
||||||
|
if (sr == 0) {
|
||||||
|
sr = SI_ERROR_COLLISION;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TypeTime[Si.chan] = __OSGetSystemTime();
|
||||||
|
sr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Si.chan = -1;
|
||||||
|
}
|
||||||
|
return sr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SITransferNext(s32 chan) {
|
||||||
|
int i;
|
||||||
|
SIPacket* packet;
|
||||||
|
|
||||||
|
for (i = 0; i < SI_MAX_CHAN; ++i) {
|
||||||
|
++chan;
|
||||||
|
chan %= SI_MAX_CHAN;
|
||||||
|
packet = &Packet[chan];
|
||||||
|
if (packet->chan != -1 && packet->fire <= __OSGetSystemTime()) {
|
||||||
|
if (__SITransfer(packet->chan, packet->output, packet->outputBytes, packet->input,
|
||||||
|
packet->inputBytes, packet->callback)) {
|
||||||
|
OSCancelAlarm(&Alarm[chan]);
|
||||||
|
packet->chan = -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SIInterruptHandler(__OSInterrupt interrupt, OSContext* context) {
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
reg = __SIRegs[13];
|
||||||
|
|
||||||
|
if ((reg & 0xc0000000) == 0xc0000000) {
|
||||||
|
s32 chan;
|
||||||
|
u32 sr;
|
||||||
|
SICallback callback;
|
||||||
|
|
||||||
|
chan = Si.chan;
|
||||||
|
sr = CompleteTransfer();
|
||||||
|
callback = Si.callback;
|
||||||
|
Si.callback = 0;
|
||||||
|
|
||||||
|
SITransferNext(chan);
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
callback(chan, sr, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
sr = __SIRegs[14];
|
||||||
|
sr &= 0xf000000 >> (8 * chan);
|
||||||
|
__SIRegs[14] = sr;
|
||||||
|
|
||||||
|
if (Type[chan] == SI_ERROR_BUSY && !SIIsChanBusy(chan)) {
|
||||||
|
static u32 cmdTypeAndStatus = 0 << 24;
|
||||||
|
SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, GetTypeCallback,
|
||||||
|
OSMicrosecondsToTicks(65));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((reg & 0x18000000) == 0x18000000) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
u32 vcount;
|
||||||
|
u32 x;
|
||||||
|
|
||||||
|
vcount = VIGetCurrentLine() + 1;
|
||||||
|
x = (Si.poll & 0x03ff0000) >> 16;
|
||||||
|
|
||||||
|
for (i = 0; i < SI_MAX_CHAN; ++i) {
|
||||||
|
if (SIGetResponseRaw(i)) {
|
||||||
|
InputBufferVcount[i] = vcount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < SI_MAX_CHAN; ++i) {
|
||||||
|
if (!(Si.poll & (SI_CHAN0_BIT >> (31 - 7 + i)))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (InputBufferVcount[i] == 0 || InputBufferVcount[i] + (x / 2) < vcount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < SI_MAX_CHAN; ++i) {
|
||||||
|
InputBufferVcount[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
if (RDSTHandler[i]) {
|
||||||
|
RDSTHandler[i](interrupt, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL SIEnablePollingInterrupt(BOOL enable) {
|
||||||
|
BOOL enabled;
|
||||||
|
BOOL rc;
|
||||||
|
u32 reg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
enabled = OSDisableInterrupts();
|
||||||
|
reg = __SIRegs[13];
|
||||||
|
rc = (reg & 0x08000000) ? TRUE : FALSE;
|
||||||
|
if (enable) {
|
||||||
|
reg |= 0x08000000;
|
||||||
|
for (i = 0; i < SI_MAX_CHAN; ++i) {
|
||||||
|
InputBufferVcount[i] = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reg &= ~0x08000000;
|
||||||
|
}
|
||||||
|
reg &= ~0x80000001;
|
||||||
|
__SIRegs[13] = reg;
|
||||||
|
OSRestoreInterrupts(enabled);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL SIRegisterPollingHandler(__OSInterruptHandler handler) {
|
||||||
|
BOOL enabled;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
enabled = OSDisableInterrupts();
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
if (RDSTHandler[i] == handler) {
|
||||||
|
OSRestoreInterrupts(enabled);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
if (RDSTHandler[i] == 0) {
|
||||||
|
RDSTHandler[i] = handler;
|
||||||
|
SIEnablePollingInterrupt(TRUE);
|
||||||
|
OSRestoreInterrupts(enabled);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OSRestoreInterrupts(enabled);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL SIUnregisterPollingHandler(__OSInterruptHandler handler) {
|
||||||
|
BOOL enabled;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
enabled = OSDisableInterrupts();
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
if (RDSTHandler[i] == handler) {
|
||||||
|
RDSTHandler[i] = 0;
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
if (RDSTHandler[i]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == 4) {
|
||||||
|
SIEnablePollingInterrupt(FALSE);
|
||||||
|
}
|
||||||
|
OSRestoreInterrupts(enabled);
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OSRestoreInterrupts(enabled);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SIInit(void) {
|
||||||
|
OSRegisterVersion(__SIVersion);
|
||||||
|
|
||||||
|
Packet[0].chan = Packet[1].chan = Packet[2].chan = Packet[3].chan = -1;
|
||||||
|
|
||||||
|
Si.poll = 0;
|
||||||
|
SISetSamplingRate(0);
|
||||||
|
|
||||||
|
while (__SIRegs[13] & 1)
|
||||||
|
;
|
||||||
|
|
||||||
|
__SIRegs[13] = 0x80000000;
|
||||||
|
|
||||||
|
__OSSetInterruptHandler(__OS_INTERRUPT_PI_SI, SIInterruptHandler);
|
||||||
|
__OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_SI);
|
||||||
|
|
||||||
|
SIGetType(0);
|
||||||
|
SIGetType(1);
|
||||||
|
SIGetType(2);
|
||||||
|
SIGetType(3);
|
||||||
|
}
|
Loading…
Reference in New Issue