X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fpsxbios.c;h=313bc5070756997b6d820c33261a2ec59207698f;hb=ea72f34a365392de7fdcdcb31c53307f2d12f90c;hp=6624207e16f0e014ae8a18b0e0ee252d3ab2bc6d;hpb=dc4fa8bcd7d8fb9ccd6c742a350f69e0683350e0;p=pcsx_rearmed.git diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c index 6624207e..313bc507 100644 --- a/libpcsxcore/psxbios.c +++ b/libpcsxcore/psxbios.c @@ -193,28 +193,21 @@ char *biosC0n[256] = { #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]; + u32 unused[2]; +} EvCB; -#define EvStUNUSED 0x0000 -#define EvStWAIT 0x1000 -#define EvStACTIVE 0x2000 -#define EvStALREADY 0x4000 +#define EvStUNUSED 0x0000 +#define EvStDISABLED 0x1000 +#define EvStACTIVE 0x2000 +#define EvStALREADY 0x4000 -#define EvMdINTR 0x1000 -#define EvMdNOINTR 0x2000 - -/* -typedef struct { - s32 next; - s32 func1; - s32 func2; - s32 pad; -} SysRPst; -*/ +#define EvMdCALL 0x1000 +#define EvMdMARK 0x2000 typedef struct { u32 status; @@ -258,23 +251,9 @@ typedef struct { } 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; @@ -282,6 +261,7 @@ 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 @@ -289,9 +269,21 @@ static u32 card_active_chan = 0; #define A_EXCEPTION 0x0c80 #define A_EXC_SP 0x6cf0 #define A_EEXIT_DEF 0x6cf4 +#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)); @@ -302,17 +294,34 @@ static u32 loadRam32(u32 addr) 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)); @@ -374,14 +383,10 @@ static inline void softCallInException(u32 pc) { 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); /* * // * @@ -394,8 +399,8 @@ static inline void DeliverEvent(u32 ev, u32 spec) { 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; \ @@ -409,8 +414,8 @@ static inline void DeliverEvent(u32 ev, u32 spec) { 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; \ } @@ -1430,15 +1435,12 @@ void psxBios_Load() { // 0x42 EXE_HEADER eheader; void *pa1; -#ifdef PSXBIOS_LOG - PSXBIOS_LOG("psxBios_%s: %s, %x\n", biosA0n[0x42], Ra0, a1); -#endif - pa1 = Ra1; if (pa1 && LoadCdromFile(Ra0, &eheader) == 0) { memcpy(pa1, ((char*)&eheader)+16, sizeof(EXEC)); v0 = 1; } else v0 = 0; + PSXBIOS_LOG("psxBios_%s: %s, %d -> %d\n", biosA0n[0x42], Ra0, a1, v0); pc0 = ra; } @@ -1602,8 +1604,8 @@ void psxBios__bu_init() { // 70 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; } @@ -1616,13 +1618,13 @@ void psxBios__96_init() { // 71 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); } @@ -1634,11 +1636,11 @@ static void psxBios_DequeueCdIntr() { // a3 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, @@ -1693,24 +1695,24 @@ void psxBios__card_info() { // ab 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; } @@ -1721,14 +1723,23 @@ void psxBios__card_load() { // ac card_active_chan = a0; -// DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004 - DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004 +// DeliverEvent(0xf0000011, 0x0004); + DeliverEvent(0xf4000001, 0x0004); v0 = 1; pc0 = ra; } /* System calls B0 */ +static u32 psxBios_SysMalloc_(u32 size); + +static void psxBios_SysMalloc() { // B 00 + u32 ret = psxBios_SysMalloc_(a0); + + PSXBIOS_LOG("psxBios_%s 0x%x -> %x\n", biosB0n[0x00], a0, ret); + mips_return_c(ret, 33); +} + void psxBios_SetRCnt() { // 02 #ifdef PSXBIOS_LOG PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x02]); @@ -1797,154 +1808,176 @@ void psxBios_ResetRCnt() { // 06 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; - -#ifdef PSXBIOS_LOG - PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0c], ev, spec); -#endif - - EventCB[ev][spec].status = EvStACTIVE; +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); - v0 = 1; pc0 = ra; + mips_return_c(1, 15); } -void psxBios_DisableEvent() { // 0d - int ev, spec; - - ev = a0 & 0xff; - spec = (a0 >> 8) & 0xff; - -#ifdef PSXBIOS_LOG - PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0d], ev, spec); -#endif +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); - EventCB[ev][spec].status = EvStWAIT; - - v0 = 1; pc0 = ra; + mips_return_c(1, 15); } /* @@ -2023,36 +2056,55 @@ void psxBios_ChangeTh() { // 10 } 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 @@ -2114,22 +2166,12 @@ void psxBios_HookEntryInt() { // 19 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; @@ -2237,8 +2279,8 @@ void psxBios_lseek() { // 0x33 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 @@ -2417,11 +2459,11 @@ void psxBios_firstfile() { // 42 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); } } @@ -2545,33 +2587,37 @@ void psxBios_delete() { // 45 } 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 @@ -2604,8 +2650,8 @@ 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; } @@ -2638,8 +2684,8 @@ void psxBios__card_read() { // 0x4f } } - DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004 -// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004 + DeliverEvent(0xf0000011, 0x0004); +// DeliverEvent(0xf4000001, 0x0004); v0 = 1; pc0 = ra; } @@ -2727,12 +2773,13 @@ void psxBios__card_chan() { // 0x58 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 @@ -2755,44 +2802,67 @@ void psxBios__card_wait() { // 5d /* System calls C0 */ +static void psxBios_InitRCnt() { // 00 + int i; + PSXBIOS_LOG("psxBios_%s %x\n", biosC0n[0x00], a0); + psxHwWrite16(0x1f801074, psxHu32(0x1074) & ~0x71); + for (i = 0; i < 3; i++) { + psxHwWrite16(0x1f801100 + i*0x10 + 4, 0); + psxHwWrite16(0x1f801100 + i*0x10 + 8, 0); + psxHwWrite16(0x1f801100 + i*0x10 + 0, 0); + } + psxBios_SysEnqIntRP_(a0, 0x6d88); + mips_return_c(0, 9); +} + +static void psxBios_InitException() { // 01 + PSXBIOS_LOG("psxBios_%s %x\n", biosC0n[0x01], a0); + psxBios_SysEnqIntRP_(a0, 0x6da8); + mips_return_c(0, 9); +} + /* * int SysEnqIntRP(int index , long *queue); */ -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; @@ -2801,17 +2871,47 @@ static void psxBios_SysDeqIntRP_() { // 03 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); + storeRam32(A_KMALLOC_SIZE, size); + storeRam32(A_KMALLOC_END, base + (size & ~3) + 4); +} + +// this should be much more complicated, but maybe that'll be enough +static u32 psxBios_SysMalloc_(u32 size) { + u32 ptr = loadRam32(A_KMALLOC_PTR); + + size = (size + 3) & ~3; + storeRam32(A_KMALLOC_PTR, ptr + 4 + size); + storeRam32(ptr, size); + return ptr + 4; +} + +static void psxBios_SysInitMemory() { // 08 + PSXBIOS_LOG("psxBios_%s %x %x\n", biosC0n[0x08], a0, a1); + + psxBios_SysInitMemory_(a0, a1); + mips_return_void_c(12); } -void psxBios_ChangeClearRCnt() { // 0a +static void psxBios_ChangeClearRCnt() { // 0a u32 ret; PSXBIOS_LOG("psxBios_%s: %x, %x\n", biosC0n[0x0a], a0, a1); @@ -2821,6 +2921,13 @@ void psxBios_ChangeClearRCnt() { // 0a mips_return_c(ret, 8); } +static void psxBios_InitDefInt() { // 0c + PSXBIOS_LOG("psxBios_%s %x\n", biosC0n[0x0c], a0); + // should also clear the autoack table + psxBios_SysEnqIntRP_(a0, 0x6d98); + mips_return_c(0, 20 + 6*2); +} + void psxBios_dummy() { u32 pc = (pc0 & 0x1fffff) - 4; char **ntab = pc == 0xa0 ? biosA0n : pc == 0xb0 ? biosB0n @@ -2884,6 +2991,8 @@ static const struct { { 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) @@ -2902,14 +3011,59 @@ static void write_chain(u32 *d, u32 next, u32 handler1, u32 handler2) 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)); } +static void setup_tt(u32 tcb_cnt, u32 evcb_cnt) +{ + u32 *ram32 = (u32 *)psxM; + u32 s_excb = 0x20, s_evcb = 0x1c * evcb_cnt; + u32 s_pcb = 4, s_tcb = 0xc0 * tcb_cnt; + u32 p_excb, p_evcb, p_pcb, p_tcb; + + memset(ram32 + 0xe000/4, 0, s_excb + s_evcb + s_pcb + s_tcb + 5*4); + psxBios_SysInitMemory_(0xa000e000, 0x2000); + p_excb = psxBios_SysMalloc_(s_excb); + p_evcb = psxBios_SysMalloc_(s_evcb); + p_pcb = psxBios_SysMalloc_(s_pcb); + p_tcb = psxBios_SysMalloc_(s_tcb); + + // "table of tables". Some games modify it + assert(A_TT_ExCB == 0x0100); + ram32[0x0100/4] = SWAPu32(p_excb); // ExCB - exception chains + ram32[0x0104/4] = SWAPu32(s_excb); // ExCB size + ram32[0x0108/4] = SWAPu32(p_pcb); // PCB - process control + ram32[0x010c/4] = SWAPu32(s_pcb); // PCB size + ram32[0x0110/4] = SWAPu32(p_tcb); // TCB - thread control + ram32[0x0114/4] = SWAPu32(s_tcb); // TCB size + ram32[0x0120/4] = SWAPu32(p_evcb); // EvCB - event control + ram32[0x0124/4] = SWAPu32(s_evcb); // EvCB size + ram32[0x0140/4] = SWAPu32(0x8648); // FCB - file control + ram32[0x0144/4] = SWAPu32(0x02c0); // FCB size + ram32[0x0150/4] = SWAPu32(0x6ee0); // DCB - device control + ram32[0x0154/4] = SWAPu32(0x0320); // DCB size + + storeRam32(p_excb + 0*4, 0x91e0); // chain0 + storeRam32(p_excb + 2*4, 0x6d88); // chain1 + storeRam32(p_excb + 4*4, 0x0000); // chain2 + storeRam32(p_excb + 6*4, 0x6d98); // chain3 + + 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; @@ -3112,7 +3266,7 @@ void psxBiosInit() { //biosA0[0xb3] = psxBios_sys_a0_b3; //biosA0[0xb4] = psxBios_sub_function; //*******************B0 CALLS**************************** - //biosB0[0x00] = psxBios_SysMalloc; + biosB0[0x00] = psxBios_SysMalloc; //biosB0[0x01] = psxBios_sys_b0_01; biosB0[0x02] = psxBios_SetRCnt; biosB0[0x03] = psxBios_GetRCnt; @@ -3205,19 +3359,19 @@ void psxBiosInit() { biosB0[0x5c] = psxBios__card_status; biosB0[0x5d] = psxBios__card_wait; //*******************C0 CALLS**************************** - //biosC0[0x00] = psxBios_InitRCnt; - //biosC0[0x01] = psxBios_InitException; + biosC0[0x00] = psxBios_InitRCnt; + 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[0x08] = psxBios_SysInitMemory; + biosC0[0x08] = psxBios_SysInitMemory; //biosC0[0x09] = psxBios_SysInitKMem; biosC0[0x0a] = psxBios_ChangeClearRCnt; //biosC0[0x0b] = psxBios_SystemError; - //biosC0[0x0c] = psxBios_InitDefInt; + biosC0[0x0c] = psxBios_InitDefInt; //biosC0[0x0d] = psxBios_sys_c0_0d; //biosC0[0x0e] = psxBios_sys_c0_0e; //biosC0[0x0f] = psxBios_sys_c0_0f; @@ -3236,33 +3390,23 @@ void psxBiosInit() { //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)); @@ -3297,30 +3441,7 @@ void psxBiosInit() { ram32[0x00b0/4] = HLEOP(hleop_b0); ram32[0x00c0/4] = HLEOP(hleop_c0); - // "table of tables". Some games modify it - assert(A_TT_ExCB == 0x0100); - ram32[0x0100/4] = SWAPu32(0x0000e004); // ExCB - exception chains - ram32[0x0104/4] = SWAPu32(0x00000020); // ExCB size - ram32[0x0108/4] = SWAPu32(0x0000e1ec); // PCB - process control - ram32[0x010c/4] = SWAPu32(0x00000004); // PCB size - ram32[0x0110/4] = SWAPu32(0x0000e1f4); // TCB - thread control - ram32[0x0114/4] = SWAPu32(0x00000300); // TCB size - ram32[0x0120/4] = SWAPu32(0x0000e028); // EvCB - event control - ram32[0x0124/4] = SWAPu32(0x000001c0); // EvCB size - ram32[0x0140/4] = SWAPu32(0x00008648); // FCB - file control - ram32[0x0144/4] = SWAPu32(0x000002c0); // FCB size - ram32[0x0150/4] = SWAPu32(0x00006ee0); // DCB - device control - ram32[0x0154/4] = SWAPu32(0x00000320); // DCB size - - ram32[0xe000/4] = SWAPu32(0x00000020); // SysMalloc block size - ram32[0xe004/4] = SWAPu32(0x000091e0); // chain0 - ram32[0xe00c/4] = SWAPu32(0x00006d88); // chain1 - ram32[0xe014/4] = SWAPu32(0x00000000); // chain2 - ram32[0xe01c/4] = SWAPu32(0x00006d98); // chain3 - - ram32[0xe1ec/4] = SWAPu32(0x0000e1f4); // TCB - ram32[0xe1f0/4] = SWAPu32(0x00000300); // SysMalloc block size - ram32[0xe1f4/4] = SWAPu32(0x00004000); // first TCB + setup_tt(4, 16); ram32[0x6ee0/4] = SWAPu32(0x0000eff0); // DCB strcpy((char *)&ram32[0xeff0/4], "bu"); @@ -3351,9 +3472,14 @@ void psxBiosInit() { // 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++) @@ -3373,18 +3499,14 @@ void psxBiosInit() { ram32[A_RCNT_VBL_ACK/4 + 1] = SWAP32(1); ram32[A_RCNT_VBL_ACK/4 + 2] = SWAP32(1); ram32[A_RCNT_VBL_ACK/4 + 3] = SWAP32(1); - - psxRegs.CP0.n.SR &= ~0x400000; // use ram vector } void psxBiosShutdown() { } -void psxBiosCnfLoaded(u32 tcbs, u32 events) { - if (tcbs > 4) - log_unhandled("FIXME: TCB = %x\n", tcbs); - if (events > 16) - log_unhandled("FIXME: EVENT = %x\n", tcbs); +void psxBiosCnfLoaded(u32 tcb_cnt, u32 evcb_cnt) { + if (tcb_cnt != 4 || evcb_cnt != 16) + setup_tt(tcb_cnt, evcb_cnt); } #define psxBios_PADpoll(pad) { \ @@ -3404,8 +3526,6 @@ void psxBiosCnfLoaded(u32 tcbs, u32 events) { } static void biosPadHLE() { - int i, bufcount; - if (pad_buf != NULL) { u32 *buf = (u32*)pad_buf; @@ -3437,15 +3557,6 @@ static void biosPadHLE() { *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) @@ -3475,7 +3586,7 @@ void hleExc0_0_2() // A(91h) - CdromDmaIrqFunc1 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; } @@ -3506,7 +3617,7 @@ void hleExc0_2_2_syscall() // not in any A/B/C table if (code != R3000E_Syscall) { if (code != 0) { - // DeliverEvent(); // 0xf0000010, 0x1000 + DeliverEvent(0xf0000010, 0x1000); psxBios_SystemErrorUnresolvedException(); } mips_return_c(0, 17); @@ -3535,7 +3646,7 @@ void hleExc0_2_2_syscall() // not in any A/B/C table break; } default: - // DeliverEvent(); // 0xf0000010, 0x4000 + DeliverEvent(0xf0000010, 0x4000); break; } use_cycles(30); @@ -3552,10 +3663,7 @@ static void handle_chain_1_x_2(u32 ev_index, u32 irqbit) { 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); @@ -3619,7 +3727,7 @@ void hleExc3_0_2_defint(void) 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); } @@ -3627,6 +3735,33 @@ void hleExc3_0_2_defint(void) 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); @@ -3675,10 +3810,6 @@ void psxBiosException() { } 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); @@ -3716,16 +3847,8 @@ void psxBiosFreeze(int Mode) { 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); }