#define Rsp ((char *)PSXM(sp))
typedef struct {
- u32 desc;
- s32 status;
- s32 mode;
+ u32 class;
+ u32 status;
+ u32 spec;
+ u32 mode;
u32 fhandler;
-} EvCB[32];
-
-#define EvStUNUSED 0x0000
-#define EvStWAIT 0x1000
-#define EvStACTIVE 0x2000
-#define EvStALREADY 0x4000
+ u32 unused[2];
+} EvCB;
-#define EvMdINTR 0x1000
-#define EvMdNOINTR 0x2000
+#define EvStUNUSED 0x0000
+#define EvStDISABLED 0x1000
+#define EvStACTIVE 0x2000
+#define EvStALREADY 0x4000
-/*
-typedef struct {
- s32 next;
- s32 func1;
- s32 func2;
- s32 pad;
-} SysRPst;
-*/
+#define EvMdCALL 0x1000
+#define EvMdMARK 0x2000
typedef struct {
u32 status;
} FileDesc;
static int *pad_buf = NULL;
-static char *pad_buf1 = NULL, *pad_buf2 = NULL;
-static int pad_buf1len, pad_buf2len;
-static int pad_stopped = 0;
-
-static u32 regs[35];
-static EvCB *EventCB;
-static EvCB *HwEV; // 0xf0
-static EvCB *EvEV; // 0xf1
-static EvCB *RcEV; // 0xf2
-static EvCB *UeEV; // 0xf3
-static EvCB *SwEV; // 0xf4
-static EvCB *ThEV; // 0xff
static u32 heap_size = 0;
static u32 *heap_addr = NULL;
static u32 *heap_end = NULL;
-static int CardState = -1;
-static int CurThread = 0;
static FileDesc FDesc[32];
static u32 card_active_chan = 0;
#define A_TT_ExCB 0x0100
#define A_TT_PCB 0x0108
#define A_TT_TCB 0x0110
+#define A_TT_EvCB 0x0120
#define A_A0_TABLE 0x0200
#define A_B0_TABLE 0x0874
#define A_C0_TABLE 0x0674
#define A_KMALLOC_PTR 0x7460
#define A_KMALLOC_SIZE 0x7464
#define A_KMALLOC_END 0x7468
+#define A_PADCRD_CHN_E 0x74a8 // pad/card irq chain entry
+#define A_PAD_IRQR_ENA 0x74b8 // pad read on vint irq (nocash 'pad_enable_flag')
+#define A_CARD_IRQR_ENA 0x74bc // same for card
+#define A_PAD_INBUF 0x74c8 // 2x buffers for rx pad data
+#define A_PAD_OUTBUF 0x74d0 // 2x buffers for tx pad data
+#define A_PAD_IN_LEN 0x74d8
+#define A_PAD_OUT_LEN 0x74e0
#define A_EEXIT_PTR 0x75d0
#define A_EXC_STACK 0x85d8 // exception stack top
#define A_RCNT_VBL_ACK 0x8600
+#define A_PAD_ACK_VBL 0x8914 // enable vint ack by pad reading code
+#define A_CD_EVENTS 0xb9b8
#define A_EXC_GP 0xf450
#define HLEOP(n) SWAPu32((0x3b << 26) | (n));
return SWAP32(*((u32 *)psxM + ((addr & 0x1fffff) >> 2)));
}
+static void *castRam8ptr(u32 addr)
+{
+ assert(!(addr & 0x5f800000));
+ return psxM + (addr & 0x1fffff);
+}
+
static void *castRam32ptr(u32 addr)
{
assert(!(addr & 0x5f800003));
return psxM + (addr & 0x1ffffc);
}
+static void *loadRam8ptr(u32 addr)
+{
+ return castRam8ptr(loadRam32(addr));
+}
+
static void *loadRam32ptr(u32 addr)
{
return castRam32ptr(loadRam32(addr));
}
+static void storeRam8(u32 addr, u8 d)
+{
+ assert(!(addr & 0x5f800000));
+ *((u8 *)psxM + (addr & 0x1fffff)) = d;
+}
+
static void storeRam32(u32 addr, u32 d)
{
assert(!(addr & 0x5f800000));
ra = sra;
}
-static inline void DeliverEvent(u32 ev, u32 spec) {
- if (EventCB[ev][spec].status != EvStACTIVE) return;
-
-// EventCB[ev][spec].status = EvStALREADY;
- if (EventCB[ev][spec].mode == EvMdINTR) {
- softCall(EventCB[ev][spec].fhandler);
- } else EventCB[ev][spec].status = EvStALREADY;
-}
+static u32 OpenEvent(u32 class, u32 spec, u32 mode, u32 func);
+static u32 DeliverEvent(u32 class, u32 spec);
+static u32 UnDeliverEvent(u32 class, u32 spec);
+static void CloseEvent(u32 ev);
/* *
// *
ptr = Mcd##mcd##Data + 8192 * FDesc[1 + mcd].mcfile + FDesc[1 + mcd].offset; \
memcpy(Ra1, ptr, length); \
if (FDesc[1 + mcd].mode & 0x8000) { \
- DeliverEvent(0x11, 0x2); /* 0xf0000011, 0x0004 */ \
- DeliverEvent(0x81, 0x2); /* 0xf4000001, 0x0004 */ \
+ DeliverEvent(0xf0000011, 0x0004); \
+ DeliverEvent(0xf4000001, 0x0004); \
v0 = 0; } \
else v0 = length; \
FDesc[1 + mcd].offset += v0; \
FDesc[1 + mcd].offset += length; \
SaveMcd(Config.Mcd##mcd, Mcd##mcd##Data, offset, length); \
if (FDesc[1 + mcd].mode & 0x8000) { \
- DeliverEvent(0x11, 0x2); /* 0xf0000011, 0x0004 */ \
- DeliverEvent(0x81, 0x2); /* 0xf4000001, 0x0004 */ \
+ DeliverEvent(0xf0000011, 0x0004); \
+ DeliverEvent(0xf4000001, 0x0004); \
v0 = 0; } \
else v0 = length; \
}
PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x70]);
#endif
- DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
- DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
+ DeliverEvent(0xf0000011, 0x0004);
+ DeliverEvent(0xf4000001, 0x0004);
pc0 = ra;
}
pc0 = ra;
}
-static void psxBios_SysDeqIntRP_();
+static void write_chain(u32 *d, u32 next, u32 handler1, u32 handler2);
+static void psxBios_SysEnqIntRP_(u32 priority, u32 chain_eptr);
+static void psxBios_SysDeqIntRP_(u32 priority, u32 chain_rm_eptr);
static void psxBios_DequeueCdIntr_() {
- a0 = 0; a1 = 0x91d0;
- psxBios_SysDeqIntRP_();
- a0 = 0; a1 = 0x91e0;
- psxBios_SysDeqIntRP_();
+ psxBios_SysDeqIntRP_(0, 0x91d0);
+ psxBios_SysDeqIntRP_(0, 0x91e0);
use_cycles(16);
}
static void psxBios_CdRemove() { // 56, 72
PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x72]);
- // CloseEvent 0xf1000000
- // CloseEvent 0xf1000001
- // CloseEvent 0xf1000002
- // CloseEvent 0xf1000003
- // CloseEvent 0xf1000004
+ CloseEvent(loadRam32(A_CD_EVENTS + 0x00));
+ CloseEvent(loadRam32(A_CD_EVENTS + 0x04));
+ CloseEvent(loadRam32(A_CD_EVENTS + 0x08));
+ CloseEvent(loadRam32(A_CD_EVENTS + 0x0c));
+ CloseEvent(loadRam32(A_CD_EVENTS + 0x10));
psxBios_DequeueCdIntr_();
// EnterCriticalSection - should be done at the beginning,
switch (port) {
case 0x0:
case 0x1:
- ret = 0x2;
+ ret = 0x0004;
if (McdDisable[port & 1])
- ret = 0x8;
+ ret = 0x0100;
break;
default:
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s: UNKNOWN PORT 0x%x\n", biosA0n[0xab], card_active_chan);
#endif
- ret = 0x11;
+ ret = 0x0302;
break;
}
if (McdDisable[0] && McdDisable[1])
- ret = 0x8;
+ ret = 0x0100;
- DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
-// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
- DeliverEvent(0x81, ret); // 0xf4000001, 0x0004
+ DeliverEvent(0xf0000011, 0x0004);
+// DeliverEvent(0xf4000001, 0x0004);
+ DeliverEvent(0xf4000001, ret);
v0 = 1; pc0 = ra;
}
card_active_chan = a0;
-// DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
- DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
+// DeliverEvent(0xf0000011, 0x0004);
+ DeliverEvent(0xf4000001, 0x0004);
v0 = 1; pc0 = ra;
}
pc0 = ra;
}
+static u32 DeliverEvent(u32 class, u32 spec) {
+ EvCB *ev = (EvCB *)loadRam32ptr(A_TT_EvCB);
+ u32 evcb_len = loadRam32(A_TT_EvCB + 4);
+ u32 ret = loadRam32(A_TT_EvCB) + evcb_len;
+ u32 i, lim = evcb_len / 0x1c;
-/* gets ev for use with EventCB */
-#define GetEv() \
- ev = (a0 >> 24) & 0xf; \
- if (ev == 0xf) ev = 0x5; \
- ev*= 32; \
- ev+= a0&0x1f;
-
-/* gets spec for use with EventCB */
-#define GetSpec() \
- spec = 0; \
- switch (a1) { \
- case 0x0301: spec = 16; break; \
- case 0x0302: spec = 17; break; \
- default: \
- for (i=0; i<16; i++) if (a1 & (1 << i)) { spec = i; break; } \
- break; \
+ for (i = 0; i < lim; i++, ev++) {
+ use_cycles(8);
+ if (SWAP32(ev->status) != EvStACTIVE)
+ continue;
+ use_cycles(4);
+ if (SWAP32(ev->class) != class)
+ continue;
+ use_cycles(4);
+ if (SWAP32(ev->spec) != spec)
+ continue;
+ use_cycles(6);
+ ret = SWAP32(ev->mode);
+ if (ret == EvMdMARK) {
+ ev->status = SWAP32(EvStALREADY);
+ continue;
+ }
+ use_cycles(8);
+ if (ret == EvMdCALL) {
+ ret = SWAP32(ev->fhandler);
+ if (ret) {
+ v0 = ret;
+ softCall(ret);
+ ret = v0;
+ }
+ }
}
+ use_cycles(29);
+ return ret;
+}
-void psxBios_DeliverEvent() { // 07
- int ev, spec;
- int i;
-
- GetEv();
- GetSpec();
-
-#ifdef PSXBIOS_LOG
- PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x07], ev, spec);
-#endif
-
- DeliverEvent(ev, spec);
+static u32 UnDeliverEvent(u32 class, u32 spec) {
+ EvCB *ev = (EvCB *)loadRam32ptr(A_TT_EvCB);
+ u32 evcb_len = loadRam32(A_TT_EvCB + 4);
+ u32 ret = loadRam32(A_TT_EvCB) + evcb_len;
+ u32 i, lim = evcb_len / 0x1c;
- pc0 = ra;
+ for (i = 0; i < lim; i++, ev++) {
+ use_cycles(8);
+ if (SWAP32(ev->status) != EvStALREADY)
+ continue;
+ use_cycles(4);
+ if (SWAP32(ev->class) != class)
+ continue;
+ use_cycles(4);
+ if (SWAP32(ev->spec) != spec)
+ continue;
+ use_cycles(6);
+ if (SWAP32(ev->mode) == EvMdMARK)
+ ev->status = SWAP32(EvStACTIVE);
+ }
+ use_cycles(28);
+ return ret;
}
-void psxBios_OpenEvent() { // 08
- int ev, spec;
- int i;
-
- GetEv();
- GetSpec();
+static void psxBios_DeliverEvent() { // 07
+ u32 ret;
+ PSXBIOS_LOG("psxBios_%s %x %04x\n", biosB0n[0x07], a0, a1);
-#ifdef PSXBIOS_LOG
- PSXBIOS_LOG("psxBios_%s %x,%x (class:%x, spec:%x, mode:%x, func:%x)\n", biosB0n[0x08], ev, spec, a0, a1, a2, a3);
-#endif
+ ret = DeliverEvent(a0, a1);
+ mips_return(ret);
+}
- EventCB[ev][spec].status = EvStWAIT;
- EventCB[ev][spec].mode = a2;
- EventCB[ev][spec].fhandler = a3;
+static s32 get_free_EvCB_slot() {
+ EvCB *ev = (EvCB *)loadRam32ptr(A_TT_EvCB);
+ u32 i, lim = loadRam32(A_TT_EvCB + 4) / 0x1c;
- v0 = ev | (spec << 8);
- pc0 = ra;
+ use_cycles(19);
+ for (i = 0; i < lim; i++, ev++) {
+ use_cycles(8);
+ if (ev->status == SWAP32(EvStUNUSED))
+ return i;
+ }
+ return -1;
}
-void psxBios_CloseEvent() { // 09
- int ev, spec;
-
- ev = a0 & 0xff;
- spec = (a0 >> 8) & 0xff;
+static u32 OpenEvent(u32 class, u32 spec, u32 mode, u32 func) {
+ u32 ret = get_free_EvCB_slot();
+ if ((s32)ret >= 0) {
+ EvCB *ev = (EvCB *)loadRam32ptr(A_TT_EvCB) + ret;
+ ev->class = SWAP32(class);
+ ev->status = SWAP32(EvStDISABLED);
+ ev->spec = SWAP32(spec);
+ ev->mode = SWAP32(mode);
+ ev->fhandler = SWAP32(func);
+ ret |= 0xf1000000u;
+ }
+ return ret;
+}
-#ifdef PSXBIOS_LOG
- PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x09], ev, spec);
-#endif
+static void psxBios_OpenEvent() { // 08
+ u32 ret = OpenEvent(a0, a1, a2, a3);
+ PSXBIOS_LOG("psxBios_%s (class:%x, spec:%04x, mode:%04x, func:%x) -> %x\n",
+ biosB0n[0x08], a0, a1, a2, a3, ret);
+ mips_return_c(ret, 36);
+}
- EventCB[ev][spec].status = EvStUNUSED;
+static void CloseEvent(u32 ev)
+{
+ u32 base = loadRam32(A_TT_EvCB);
+ storeRam32(base + (ev & 0xffff) * sizeof(EvCB) + 4, EvStUNUSED);
+}
- v0 = 1; pc0 = ra;
+static void psxBios_CloseEvent() { // 09
+ PSXBIOS_LOG("psxBios_%s %x (%x)\n", biosB0n[0x09], a0,
+ loadRam32(loadRam32(A_TT_EvCB) + (a0 & 0xffff) * sizeof(EvCB) + 4));
+ CloseEvent(a0);
+ mips_return_c(1, 10);
}
-void psxBios_WaitEvent() { // 0a
- int ev, spec;
+static void psxBios_WaitEvent() { // 0a
+ u32 base = loadRam32(A_TT_EvCB);
+ u32 status = loadRam32(base + (a0 & 0xffff) * sizeof(EvCB) + 4);
+ PSXBIOS_LOG("psxBios_%s %x (status=%x)\n", biosB0n[0x0a], a0, status);
- ev = a0 & 0xff;
- spec = (a0 >> 8) & 0xff;
-#ifdef PSXBIOS_LOG
- PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0a], ev, spec);
-#endif
- if (EventCB[ev][spec].status == EvStUNUSED)
- {
- v0 = 0;
- pc0 = ra;
+ use_cycles(15);
+ if (status == EvStALREADY) {
+ storeRam32(base + (a0 & 0xffff) * sizeof(EvCB) + 4, EvStACTIVE);
+ mips_return(1);
return;
}
-
- if (EventCB[ev][spec].status == EvStALREADY)
+ if (status != EvStACTIVE)
{
- /* Callback events (mode=EvMdINTR) do never set the ready flag (and thus WaitEvent would hang forever). */
- if (!(EventCB[ev][spec].mode == EvMdINTR)) EventCB[ev][spec].status = EvStACTIVE;
- v0 = 1;
- pc0 = ra;
+ mips_return_c(0, 2);
return;
}
- v0 = 0;
- pc0 = ra;
+ // retrigger this hlecall after the next emulation event
+ pc0 -= 4;
+ if ((s32)(next_interupt - psxRegs.cycle) > 0)
+ psxRegs.cycle = next_interupt;
+ psxBranchTest();
}
-void psxBios_TestEvent() { // 0b
- int ev, spec;
-
- ev = a0 & 0xff;
- spec = (a0 >> 8) & 0xff;
-
- if (EventCB[ev][spec].status == EvStALREADY)
- {
- if (!(EventCB[ev][spec].mode == EvMdINTR)) EventCB[ev][spec].status = EvStACTIVE;
- v0 = 1;
- }
- else
- {
- v0 = 0;
+static void psxBios_TestEvent() { // 0b
+ u32 base = loadRam32(A_TT_EvCB);
+ u32 status = loadRam32(base + (a0 & 0xffff) * sizeof(EvCB) + 4);
+ u32 ret = 0;
+ PSXBIOS_LOG("psxBios_%s %x %x\n", biosB0n[0x0b], a0, status);
+ if (status == EvStALREADY) {
+ storeRam32(base + (a0 & 0xffff) * sizeof(EvCB) + 4, EvStACTIVE);
+ ret = 1;
}
-#ifdef PSXBIOS_LOG
- PSXBIOS_LOG("psxBios_%s %x,%x: %x\n", biosB0n[0x0b], ev, spec, v0);
-#endif
-
- pc0 = ra;
+ mips_return_c(ret, 15);
}
-void psxBios_EnableEvent() { // 0c
- int ev, spec;
-
- ev = a0 & 0xff;
- spec = (a0 >> 8) & 0xff;
+static void psxBios_EnableEvent() { // 0c
+ u32 base = loadRam32(A_TT_EvCB);
+ u32 status = loadRam32(base + (a0 & 0xffff) * sizeof(EvCB) + 4);
+ PSXBIOS_LOG("psxBios_%s %x (%x)\n", biosB0n[0x0c], a0, status);
+ if (status != EvStUNUSED)
+ storeRam32(base + (a0 & 0xffff) * sizeof(EvCB) + 4, EvStACTIVE);
-#ifdef PSXBIOS_LOG
- PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0c], ev, spec);
-#endif
-
- EventCB[ev][spec].status = EvStACTIVE;
-
- v0 = 1; pc0 = ra;
+ mips_return_c(1, 15);
}
-void psxBios_DisableEvent() { // 0d
- int ev, spec;
+static void psxBios_DisableEvent() { // 0d
+ u32 base = loadRam32(A_TT_EvCB);
+ u32 status = loadRam32(base + (a0 & 0xffff) * sizeof(EvCB) + 4);
+ PSXBIOS_LOG("psxBios_%s %x: %x\n", biosB0n[0x0d], a0, status);
+ if (status != EvStUNUSED)
+ storeRam32(base + (a0 & 0xffff) * sizeof(EvCB) + 4, EvStDISABLED);
- ev = a0 & 0xff;
- spec = (a0 >> 8) & 0xff;
-
-#ifdef PSXBIOS_LOG
- PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0d], ev, spec);
-#endif
-
- EventCB[ev][spec].status = EvStWAIT;
-
- v0 = 1; pc0 = ra;
+ mips_return_c(1, 15);
}
/*
}
void psxBios_InitPAD() { // 0x12
-#ifdef PSXBIOS_LOG
- PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x12]);
-#endif
+ u32 i, *ram32 = (u32 *)psxM;
+ PSXBIOS_LOG("psxBios_%s %x %x %x %x\n", biosB0n[0x12], a0, a1, a2, a3);
- pad_buf1 = (char*)Ra0;
- pad_buf1len = a1;
- pad_buf2 = (char*)Ra2;
- pad_buf2len = a3;
+ // printf("%s", "PS-X Control PAD Driver Ver 3.0");
+ // PAD_dr_enable = 0;
+ ram32[A_PAD_OUTBUF/4 + 0] = 0;
+ ram32[A_PAD_OUTBUF/4 + 1] = 0;
+ ram32[A_PAD_OUT_LEN/4 + 0] = 0;
+ ram32[A_PAD_OUT_LEN/4 + 1] = 0;
+ ram32[A_PAD_INBUF/4 + 0] = SWAP32(a0);
+ ram32[A_PAD_INBUF/4 + 1] = SWAP32(a2);
+ ram32[A_PAD_IN_LEN/4 + 0] = SWAP32(a1);
+ ram32[A_PAD_IN_LEN/4 + 1] = SWAP32(a3);
- v0 = 1; pc0 = ra;
+ for (i = 0; i < a1; i++) {
+ use_cycles(4);
+ storeRam8(a0 + i, 0);
+ }
+ for (i = 0; i < a3; i++) {
+ use_cycles(4);
+ storeRam8(a2 + i, 0);
+ }
+ write_chain(ram32 + A_PADCRD_CHN_E/4, 0, 0x49bc, 0x4a4c);
+
+ ram32[A_PAD_IRQR_ENA/4] = SWAP32(1);
+
+ mips_return_c(1, 200);
}
void psxBios_StartPAD() { // 13
-#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x13]);
-#endif
- pad_stopped = 0;
- psxHwWrite16(0x1f801074, (unsigned short)(psxHwRead16(0x1f801074) | 0x1));
+
+ psxBios_SysDeqIntRP_(2, A_PADCRD_CHN_E);
+ psxBios_SysEnqIntRP_(2, A_PADCRD_CHN_E);
+ psxHwWrite16(0x1f801070, ~1);
+ psxHwWrite16(0x1f801074, psxHu32(0x1074) | 1);
+ storeRam32(A_PAD_ACK_VBL, 1);
+ storeRam32(A_RCNT_VBL_ACK + (3 << 2), 0);
psxRegs.CP0.n.SR |= 0x401;
- pc0 = ra;
+
+ mips_return_c(1, 300);
}
void psxBios_StopPAD() { // 14
-#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x14]);
-#endif
- pad_stopped = 1;
- pad_buf1 = NULL;
- pad_buf2 = NULL;
- pc0 = ra;
+ storeRam32(A_RCNT_VBL_ACK + (3 << 2), 1);
+ psxBios_SysDeqIntRP_(2, A_PADCRD_CHN_E);
+ psxRegs.CP0.n.SR |= 0x401;
+ mips_return_void_c(200);
}
void psxBios_PAD_init() { // 15
mips_return_void_c(3);
}
-void psxBios_UnDeliverEvent() { // 0x20
- int ev, spec;
- int i;
-
- GetEv();
- GetSpec();
-
-#ifdef PSXBIOS_LOG
- PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x20], ev, spec);
-#endif
-
- if (EventCB[ev][spec].status == EvStALREADY &&
- EventCB[ev][spec].mode == EvMdNOINTR)
- EventCB[ev][spec].status = EvStACTIVE;
+static void psxBios_UnDeliverEvent() { // 0x20
+ u32 ret;
+ PSXBIOS_LOG("psxBios_%s %x %x\n", biosB0n[0x20], a0, a1);
- pc0 = ra;
+ ret = UnDeliverEvent(a0, a1);
+ mips_return(ret);
}
char ffile[64], *pfile;
case 0: // SEEK_SET
FDesc[a0].offset = a1;
v0 = a1;
-// DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
-// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
+// DeliverEvent(0xf0000011, 0x0004);
+// DeliverEvent(0xf4000001, 0x0004);
break;
case 1: // SEEK_CUR
nfile = 0;
if (!strncmp(pa0, "bu00", 4)) {
// firstfile() calls _card_read() internally, so deliver it's event
- DeliverEvent(0x11, 0x2);
+ DeliverEvent(0xf0000011, 0x0004);
bufile(1);
} else if (!strncmp(pa0, "bu10", 4)) {
// firstfile() calls _card_read() internally, so deliver it's event
- DeliverEvent(0x11, 0x2);
+ DeliverEvent(0xf0000011, 0x0004);
bufile(2);
}
}
}
void psxBios_InitCARD() { // 4a
-#ifdef PSXBIOS_LOG
+ u32 *ram32 = (u32 *)psxM;
PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x4a], a0);
-#endif
+ write_chain(ram32 + A_PADCRD_CHN_E/4, 0, 0x49bc, 0x4a4c);
+ // (maybe) todo: early_card_irq, FlushCache etc
- CardState = 0;
+ ram32[A_PAD_IRQR_ENA/4] = SWAP32(a0);
- pc0 = ra;
+ mips_return_c(0, 300);
}
void psxBios_StartCARD() { // 4b
-#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x4b]);
-#endif
+ psxBios_SysDeqIntRP_(2, A_PADCRD_CHN_E);
+ psxBios_SysEnqIntRP_(2, A_PADCRD_CHN_E);
- if (CardState == 0) CardState = 1;
+ psxHwWrite16(0x1f801074, psxHu32(0x1074) | 1);
+ storeRam32(A_PAD_ACK_VBL, 1);
+ storeRam32(A_RCNT_VBL_ACK + (3 << 2), 0);
+ storeRam32(A_CARD_IRQR_ENA, 1);
+ psxRegs.CP0.n.SR |= 0x401;
- pc0 = ra;
+ mips_return_c(1, 200);
}
void psxBios_StopCARD() { // 4c
-#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x4c]);
-#endif
-
- if (CardState == 1) CardState = 0;
-
- pc0 = ra;
+ storeRam32(A_RCNT_VBL_ACK + (3 << 2), 1);
+ psxBios_SysDeqIntRP_(2, A_PADCRD_CHN_E);
+ storeRam32(A_CARD_IRQR_ENA, 0);
+ psxRegs.CP0.n.SR |= 0x401;
+ mips_return_void_c(200);
}
void psxBios__card_write() { // 0x4e
}
}
- DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
-// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
+ DeliverEvent(0xf0000011, 0x0004);
+// DeliverEvent(0xf4000001, 0x0004);
v0 = 1; pc0 = ra;
}
}
}
- DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
-// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
+ DeliverEvent(0xf0000011, 0x0004);
+// DeliverEvent(0xf4000001, 0x0004);
v0 = 1; pc0 = ra;
}
pc0 = ra;
}
-void psxBios_ChangeClearPad() { // 5b
-#ifdef PSXBIOS_LOG
+static void psxBios_ChangeClearPad() { // 5b
+ u32 ret;
PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x5b], a0);
-#endif
+ ret = loadRam32(A_PAD_ACK_VBL);
+ storeRam32(A_PAD_ACK_VBL, a0);
- pc0 = ra;
+ mips_return_c(ret, 6);
}
void psxBios__card_status() { // 5c
/* System calls C0 */
-static void psxBios_SysEnqIntRP();
-
static void psxBios_InitRCnt() { // 00
int i;
PSXBIOS_LOG("psxBios_%s %x\n", biosC0n[0x00], a0);
psxHwWrite16(0x1f801100 + i*0x10 + 8, 0);
psxHwWrite16(0x1f801100 + i*0x10 + 0, 0);
}
- a1 = 0x6d88;
- psxBios_SysEnqIntRP();
+ psxBios_SysEnqIntRP_(a0, 0x6d88);
mips_return_c(0, 9);
}
static void psxBios_InitException() { // 01
PSXBIOS_LOG("psxBios_%s %x\n", biosC0n[0x01], a0);
- a1 = 0x6da8;
- psxBios_SysEnqIntRP();
+ psxBios_SysEnqIntRP_(a0, 0x6da8);
mips_return_c(0, 9);
}
* int SysEnqIntRP(int index , long *queue);
*/
-static void psxBios_SysEnqIntRP() { // 02
+static void psxBios_SysEnqIntRP_(u32 priority, u32 chain_eptr) {
u32 old, base = loadRam32(A_TT_ExCB);
- PSXBIOS_LOG("psxBios_%s %x %x\n", biosC0n[0x02], a0, a1);
- old = loadRam32(base + (a0 << 3));
- storeRam32(base + (a0 << 3), a1);
- storeRam32(a1, old);
+ old = loadRam32(base + (priority << 3));
+ storeRam32(base + (priority << 3), chain_eptr);
+ storeRam32(chain_eptr, old);
mips_return_c(0, 9);
}
+static void psxBios_SysEnqIntRP() { // 02
+ PSXBIOS_LOG("psxBios_%s %x %x\n", biosC0n[0x02], a0, a1);
+ psxBios_SysEnqIntRP_(a0, a1);
+}
+
/*
* int SysDeqIntRP(int index , long *queue);
*/
-static void psxBios_SysDeqIntRP_() { // 03
+static void psxBios_SysDeqIntRP_(u32 priority, u32 chain_rm_eptr) {
u32 ptr, next, base = loadRam32(A_TT_ExCB);
u32 lim = 0, ret = 0;
// as in original: no arg checks of any kind, bug if a1 == 0
- ptr = loadRam32(base + (a0 << 3));
+ ptr = loadRam32(base + (priority << 3));
while (ptr) {
next = loadRam32(ptr);
- if (ptr == a1) {
- storeRam32(base + (a0 << 3), next);
+ if (ptr == chain_rm_eptr) {
+ storeRam32(base + (priority << 3), next);
ret = ptr;
use_cycles(6);
break;
}
- while (next && next != a1 && lim++ < 100) {
+ while (next && next != chain_rm_eptr && lim++ < 100) {
ptr = next;
next = loadRam32(ptr);
use_cycles(8);
}
- if (next == a1) {
+ if (next == chain_rm_eptr) {
next = loadRam32(next);
storeRam32(ptr, next);
ret = ptr;
break;
}
if (lim == 100)
- PSXBIOS_LOG("bad chain %u %x\n", a0, base);
+ PSXBIOS_LOG("bad chain %u %x\n", priority, base);
mips_return_c(ret, 12);
}
static void psxBios_SysDeqIntRP() { // 03
PSXBIOS_LOG("psxBios_%s %x %x\n", biosC0n[0x03], a0, a1);
- psxBios_SysDeqIntRP_();
+ psxBios_SysDeqIntRP_(a0, a1);
}
+static void psxBios_get_free_EvCB_slot() { // 04
+ PSXBIOS_LOG("psxBios_%s\n", biosC0n[0x04]);
+ s32 ret = get_free_EvCB_slot();
+ mips_return_c(ret, 0);
+}
+
static void psxBios_SysInitMemory_(u32 base, u32 size) {
storeRam32(base, 0);
storeRam32(A_KMALLOC_PTR, base);
static void psxBios_InitDefInt() { // 0c
PSXBIOS_LOG("psxBios_%s %x\n", biosC0n[0x0c], a0);
// should also clear the autoack table
- a1 = 0x6d98;
- psxBios_SysEnqIntRP();
+ psxBios_SysEnqIntRP_(a0, 0x6d98);
mips_return_c(0, 20 + 6*2);
}
{ 0x1920, hleop_exc1_3_1 },
{ 0x1794, hleop_exc1_3_2 },
{ 0x2458, hleop_exc3_0_2 },
+ { 0x49bc, hleop_exc_padcard1 },
+ { 0x4a4c, hleop_exc_padcard2 },
};
static int chain_hle_op(u32 handler)
d[1] = SWAPu32(handler1);
d[2] = SWAPu32(handler2);
- // install hle traps
+ // install the hle traps
PSXMu32ref(handler1) = HLEOP(chain_hle_op(handler1));
PSXMu32ref(handler2) = HLEOP(chain_hle_op(handler2));
}
storeRam32(p_pcb, p_tcb);
storeRam32(p_tcb, 0x4000); // first TCB
+
+ // default events
+ storeRam32(A_CD_EVENTS + 0x00, OpenEvent(0xf0000003, 0x0010, EvMdMARK, 0));
+ storeRam32(A_CD_EVENTS + 0x04, OpenEvent(0xf0000003, 0x0020, EvMdMARK, 0));
+ storeRam32(A_CD_EVENTS + 0x08, OpenEvent(0xf0000003, 0x0040, EvMdMARK, 0));
+ storeRam32(A_CD_EVENTS + 0x0c, OpenEvent(0xf0000003, 0x0080, EvMdMARK, 0));
+ storeRam32(A_CD_EVENTS + 0x10, OpenEvent(0xf0000003, 0x8000, EvMdMARK, 0));
+ DeliverEvent(0xf0000003, 0x0010);
}
void psxBiosInit() {
- u32 base, size;
- u32 *ptr, *ram32;
+ u32 *ptr, *ram32, *rom32;
int i;
uLongf len;
biosC0[0x01] = psxBios_InitException;
biosC0[0x02] = psxBios_SysEnqIntRP;
biosC0[0x03] = psxBios_SysDeqIntRP;
- //biosC0[0x04] = psxBios_get_free_EvCB_slot;
+ biosC0[0x04] = psxBios_get_free_EvCB_slot;
//biosC0[0x05] = psxBios_get_free_TCB_slot;
//biosC0[0x06] = psxBios_ExceptionHandler;
//biosC0[0x07] = psxBios_InstallExeptionHandler;
//biosC0[0x1c] = psxBios_PatchAOTable;
//************** THE END ***************************************
/**/
- base = 0x1000;
- size = sizeof(EvCB) * 32;
- EventCB = (void *)&psxR[base]; base += size * 6;
- memset(EventCB, 0, size * 6);
- HwEV = EventCB;
- EvEV = EventCB + 32;
- RcEV = EventCB + 32 * 2;
- UeEV = EventCB + 32 * 3;
- SwEV = EventCB + 32 * 4;
- ThEV = EventCB + 32 * 5;
-
- pad_stopped = 1;
+
pad_buf = NULL;
- pad_buf1 = NULL;
- pad_buf2 = NULL;
- pad_buf1len = pad_buf2len = 0;
heap_addr = NULL;
heap_end = NULL;
heap_size = 0;
- CardState = -1;
- CurThread = 0;
memset(FDesc, 0, sizeof(FDesc));
card_active_chan = 0;
// initial RNG seed
psxMu32ref(0x9010) = SWAPu32(0xac20cc00);
+ rom32 = (u32 *)psxR;
+ rom32[0x100/4] = SWAP32(0x19951204);
+ rom32[0x104/4] = SWAP32(3);
+ strcpy(psxR + 0x108, "PCSX authors");
+ strcpy(psxR + 0x12c, "PCSX HLE");
+
// fonts
len = 0x80000 - 0x66000;
uncompress((Bytef *)(psxR + 0x66000), &len, font_8140, sizeof(font_8140));
// patch: +3d8, +4dc, +594, +62c, +9c8, +1988
// call: +7a0=4b70, +884=4c54, +894=4c64
ptr[0x5b] = SWAP32(0x43d0);
- ram32[0x4b70/4] = SWAP32(0x03e00008); // jr $ra
- ram32[0x4c54/4] = SWAP32(0x03e00008); // jr $ra
+ ram32[0x4b70/4] = SWAP32(0x03e00008); // jr $ra // setPadOutputBuf
+
+ ram32[0x4c54/4] = SWAP32(0x240e0001); // mov $t6, 1
+ ram32[0x4c58/4] = SWAP32(0x03e00008); // jr $ra
+ ram32[0x4c5c/4] = SWAP32(0xac0e0000 + A_PAD_IRQR_ENA); // sw $t6, ...
+
ram32[0x4c64/4] = SWAP32(0x03e00008); // jr $ra
+ ram32[0x4c68/4] = SWAP32(0xac000000 + A_PAD_IRQR_ENA); // sw $0, ...
ptr = (u32 *)&psxM[A_C0_TABLE];
for (i = 0; i < 256/2; i++)
}
static void biosPadHLE() {
- int i, bufcount;
-
if (pad_buf != NULL) {
u32 *buf = (u32*)pad_buf;
*buf |= PAD2_poll(0) << 16;
}
}
- if (!pad_stopped) {
- if (pad_buf1) {
- psxBios_PADpoll(1);
- }
-
- if (pad_buf2) {
- psxBios_PADpoll(2);
- }
- }
}
static void handle_chain_x_x_1(u32 enable, u32 irqbit)
if (psxHu32(0x1074) & psxHu32(0x1070) & 8) { // IRQ3 DMA
psxHwWrite32(0x1f8010f4, (psxHu32(0x10f4) & 0xffffff) | 0x88000000);
//if (--cdrom_irq_counter == 0) // 0xa0009180
- // DeliverEvent(); // 0xf0000003, 0x10
+ // DeliverEvent(0xf0000003, 0x10);
use_cycles(22);
ret = 1;
}
if (code != R3000E_Syscall) {
if (code != 0) {
- // DeliverEvent(); // 0xf0000010, 0x1000
+ DeliverEvent(0xf0000010, 0x1000);
psxBios_SystemErrorUnresolvedException();
}
mips_return_c(0, 17);
break;
}
default:
- // DeliverEvent(); // 0xf0000010, 0x4000
+ DeliverEvent(0xf0000010, 0x4000);
break;
}
use_cycles(30);
{
u32 ret = 0;
if (psxHu32(0x1074) & psxHu32(0x1070) & (1u << irqbit)) {
- // DeliverEvent 0xf2000000 + ev_index, 2
- if (RcEV[ev_index][1].status == EvStACTIVE) {
- softCall(RcEV[ev_index][1].fhandler);
- }
+ DeliverEvent(0xf2000000 + ev_index, 0x0002);
ret = 1;
}
mips_return_c(ret, 22);
size_t i;
for (i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
if (psxHu32(0x1074) & psxHu32(0x1070) & (1u << tab[i].irqbit)) {
- // DeliverEvent 0xf0000000 + ev, 0x1000
+ DeliverEvent(0xf0000000 + tab[i].ev, 0x1000);
use_cycles(7);
}
mips_return_c(0, 11 + 7*11 + 7*11 + 12);
}
+void hleExcPadCard1(void)
+{
+ if (loadRam32(A_PAD_IRQR_ENA)) {
+ u8 *pad_buf1 = loadRam8ptr(A_PAD_INBUF + 0);
+ u8 *pad_buf2 = loadRam8ptr(A_PAD_INBUF + 4);
+ int i, bufcount;
+
+ psxBios_PADpoll(1);
+ psxBios_PADpoll(2);
+ biosPadHLE();
+ use_cycles(100);
+ }
+ if (loadRam32(A_PAD_ACK_VBL))
+ psxHwWrite16(0x1f801070, ~1);
+ if (loadRam32(A_CARD_IRQR_ENA)) {
+ // todo, maybe
+ }
+
+ mips_return_c(0, 18);
+}
+
+void hleExcPadCard2(void)
+{
+ u32 ret = psxHu32(0x1074) & psxHu32(0x1070) & 1;
+ mips_return_c(ret, 15);
+}
+
void psxBiosException() {
u32 tcbPtr = loadRam32(A_TT_PCB);
u32 *chains = loadRam32ptr(A_TT_ExCB);
}
assert(lim < 100);
- // TODO make this a chain entry
- if (psxHu32(0x1070) & 1)
- biosPadHLE();
-
// return from exception (custom or default)
use_cycles(23);
ptr = loadRam32(A_EEXIT_PTR);
u32 base = 0x40000;
bfreezepsxMptr(pad_buf, int);
- bfreezepsxMptr(pad_buf1, char);
- bfreezepsxMptr(pad_buf2, char);
bfreezepsxMptr(heap_addr, u32);
- bfreezel(&pad_buf1len);
- bfreezel(&pad_buf2len);
- bfreezes(regs);
- bfreezel(&CardState);
- bfreezel(&CurThread);
bfreezes(FDesc);
bfreezel(&card_active_chan);
- bfreezel(&pad_stopped);
bfreezel(&heap_size);
}