psxbios: more pad stuff
[pcsx_rearmed.git] / libpcsxcore / psxbios.c
index c7cbf09..be3bc84 100644 (file)
 #include "gpu.h"
 #include "sio.h"
 #include "psxhle.h"
+#include "psxinterpreter.h"
 #include <zlib.h>
 
 #if (defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)
 #pragma GCC diagnostic ignored "-Wpointer-sign"
 #endif
 
-#undef SysPrintf
-#define SysPrintf if (Config.PsxOut) printf
+#ifndef PSXBIOS_LOG
+//#define PSXBIOS_LOG printf
+#define PSXBIOS_LOG(...)
+#endif
 
 char *biosA0n[256] = {
 // 0x00
@@ -66,9 +69,9 @@ char *biosA0n[256] = {
        "realloc",      "InitHeap",     "_exit",        "getchar",
        "putchar",      "gets",         "puts",         "printf",
 // 0x40
-       "sys_a0_40",            "LoadTest",                                     "Load",         "Exec",
+       "SystemErrorUnresolvedException", "LoadTest",           "Load",         "Exec",
        "FlushCache",           "InstallInterruptHandler",      "GPU_dw",       "mem2vram",
-       "SendGPUStatus",        "GPU_cw",                                       "GPU_cwb",      "SendPackets",
+       "SendGPUStatus",        "GPU_cw",                       "GPU_cwb",      "SendPackets",
        "sys_a0_4c",            "GetGPUStatus",                         "GPU_sync",     "sys_a0_4f",
 // 0x50
        "sys_a0_50",            "LoadExec",                             "GetSysSp",             "sys_a0_53",
@@ -102,7 +105,7 @@ char *biosA0n[256] = {
        "_card_load",           "_card_auto",   "bufs_cd_4",            "sys_a0_af",
 // 0xb0
        "sys_a0_b0",            "sys_a0_b1",    "do_a_long_jmp",        "sys_a0_b3",
-       "?? sub_function",
+       "GetSystemInfo",
 };
 
 char *biosB0n[256] = {
@@ -224,10 +227,10 @@ typedef struct {
        u32 gp0;
        u32 t_addr;
        u32 t_size;
-       u32 d_addr;
+       u32 d_addr; // 10
        u32 d_size;
        u32 b_addr;
-       u32 b_size;
+       u32 b_size; // 1c
        u32 S_addr;
        u32 s_size;
        u32 _sp, _fp, _gp, ret, base;
@@ -250,7 +253,6 @@ typedef struct {
        u32  mcfile;
 } FileDesc;
 
-static int *pad_buf = NULL;
 static u32 heap_size = 0;
 static u32 *heap_addr = NULL;
 static u32 *heap_end = NULL;
@@ -272,13 +274,16 @@ static u32 card_active_chan = 0;
 #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_PADCRD_CHN_E  0x74a8  // pad/card irq chain entry, see hleExcPadCard1()
 #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_PAD_DR_DST    0x74c4
+#define A_PAD_DR_BUF1   0x7570
+#define A_PAD_DR_BUF2   0x7598
 #define A_EEXIT_PTR     0x75d0
 #define A_EXC_STACK     0x85d8  // exception stack top
 #define A_RCNT_VBL_ACK  0x8600
@@ -360,25 +365,31 @@ static int returned_from_exception(void)
 static inline void softCall(u32 pc) {
        u32 sra = ra;
        u32 ssr = psxRegs.CP0.n.SR;
+       u32 lim = 0;
        pc0 = pc;
        ra = 0x80001000;
        psxRegs.CP0.n.SR &= ~0x404; // disable interrupts
 
-       while (pc0 != 0x80001000)
+       while (pc0 != 0x80001000 && ++lim < 1000000)
                psxCpu->ExecuteBlock(EXEC_CALLER_HLE);
 
+       if (lim == 1000000)
+               PSXBIOS_LOG("softCall @%x hit lim\n", pc);
        ra = sra;
-       psxRegs.CP0.n.SR = ssr;
+       psxRegs.CP0.n.SR |= ssr & 0x404;
 }
 
 static inline void softCallInException(u32 pc) {
        u32 sra = ra;
+       u32 lim = 0;
        pc0 = pc;
        ra = 0x80001000;
 
-       while (!returned_from_exception() && pc0 != 0x80001000)
+       while (!returned_from_exception() && pc0 != 0x80001000 && ++lim < 1000000)
                psxCpu->ExecuteBlock(EXEC_CALLER_HLE);
 
+       if (lim == 1000000)
+               PSXBIOS_LOG("softCallInException @%x hit lim\n", pc);
        if (pc0 == 0x80001000)
                ra = sra;
 }
@@ -395,7 +406,7 @@ static void CloseEvent(u32 ev);
 
 
 #define buread(Ra1, mcd, length) { \
-       SysPrintf("read %d: %x,%x (%s)\n", FDesc[1 + mcd].mcfile, FDesc[1 + mcd].offset, a2, Mcd##mcd##Data + 128 * FDesc[1 + mcd].mcfile + 0xa); \
+       PSXBIOS_LOG("read %d: %x,%x (%s)\n", FDesc[1 + mcd].mcfile, FDesc[1 + mcd].offset, a2, Mcd##mcd##Data + 128 * FDesc[1 + mcd].mcfile + 0xa); \
        ptr = Mcd##mcd##Data + 8192 * FDesc[1 + mcd].mcfile + FDesc[1 + mcd].offset; \
        memcpy(Ra1, ptr, length); \
        if (FDesc[1 + mcd].mode & 0x8000) { \
@@ -408,7 +419,7 @@ static void CloseEvent(u32 ev);
 
 #define buwrite(Ra1, mcd, length) { \
        u32 offset =  + 8192 * FDesc[1 + mcd].mcfile + FDesc[1 + mcd].offset; \
-       SysPrintf("write %d: %x,%x\n", FDesc[1 + mcd].mcfile, FDesc[1 + mcd].offset, a2); \
+       PSXBIOS_LOG("write %d: %x,%x\n", FDesc[1 + mcd].mcfile, FDesc[1 + mcd].offset, a2); \
        ptr = Mcd##mcd##Data + offset; \
        memcpy(ptr, Ra1, length); \
        FDesc[1 + mcd].offset += length; \
@@ -420,11 +431,6 @@ static void CloseEvent(u32 ev);
        else v0 = length; \
 }
 
-#ifndef PSXBIOS_LOG
-//#define PSXBIOS_LOG printf
-#define PSXBIOS_LOG(...)
-#endif
-
 /* Internally redirects to "FileRead(fd,tempbuf,1)".*/
 /* For some strange reason, the returned character is sign-expanded; */
 /* So if a return value of FFFFFFFFh could mean either character FFh, or error. */
@@ -1242,11 +1248,8 @@ void psxBios_malloc() { // 0x33
 
 void psxBios_free() { // 0x34
 
-#ifdef PSXBIOS_LOG
        PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x34]);
-#endif
-
-       SysPrintf("free %x: %x bytes\n", a0, *(u32*)(Ra0-4));
+       PSXBIOS_LOG("free %x: %x bytes\n", a0, *(u32*)(Ra0-4));
 
        if (a0)
                *(u32*)(Ra0-4) |= 1;    // set chunk to free
@@ -1314,7 +1317,7 @@ void psxBios_InitHeap() { // 0x39
        /* HACKFIX: Commenting out this line fixes GTA2 crash */
        //*heap_addr = SWAP32(size | 1);
 
-       SysPrintf("InitHeap %x,%x : %x %x\n",a0,a1, (int)((uptr)heap_addr-(uptr)psxM), size);
+       PSXBIOS_LOG("InitHeap %x,%x : %x %x\n",a0,a1, (int)((uptr)heap_addr-(uptr)psxM), size);
 
        pc0 = ra;
 }
@@ -1391,7 +1394,8 @@ _start:
        if (psp != INVALID_PTR)
                memcpy(psp, save, 4 * 4);
 
-       SysPrintf("%s", tmp);
+       if (Config.PsxOut)
+               SysPrintf("%s", tmp);
 }
 
 void psxBios_printf() { // 0x3f
@@ -1421,7 +1425,7 @@ void psxBios_format() { // 0x41
 
 static void psxBios_SystemErrorUnresolvedException() {
        if (loadRam32(0xfffc) != 0x12345678) { // prevent log flood
-               SysPrintf("psxBios_%s\n", biosA0n[0x40]);
+               SysPrintf("psxBios_%s called from %08x\n", biosA0n[0x40], ra);
                storeRam32(0xfffc, 0x12345678);
        }
        mips_return_void_c(1000);
@@ -1450,27 +1454,30 @@ void psxBios_Load() { // 0x42
  */
 
 void psxBios_Exec() { // 43
-       EXEC *header = (EXEC*)Ra0;
-       u32 tmp;
+       EXEC *header = (EXEC *)castRam32ptr(a0);
+       u32 ptr;
+       s32 len;
 
-#ifdef PSXBIOS_LOG
        PSXBIOS_LOG("psxBios_%s: %x, %x, %x\n", biosA0n[0x43], a0, a1, a2);
-#endif
 
-       header->_sp = sp;
-       header->_fp = fp;
-       header->_sp = sp;
-       header->_gp = gp;
-       header->ret = ra;
-       header->base = s0;
+       header->_sp = SWAP32(sp);
+       header->_fp = SWAP32(fp);
+       header->_sp = SWAP32(sp);
+       header->_gp = SWAP32(gp);
+       header->ret = SWAP32(ra);
+       header->base = SWAP32(s0);
 
-       if (header->S_addr != 0) {
-               tmp = header->S_addr + header->s_size;
-               sp = tmp;
-               fp = sp;
-       }
+       ptr = SWAP32(header->b_addr);
+       len = SWAP32(header->b_size);
+       if (len != 0) do {
+               storeRam32(ptr, 0);
+               len -= 4; ptr += 4;
+       } while (len > 0);
 
-       gp = header->gp0;
+       if (header->S_addr != 0)
+               sp = fp = SWAP32(header->S_addr) + SWAP32(header->s_size);
+
+       gp = SWAP32(header->gp0);
 
        s0 = a0;
 
@@ -1478,7 +1485,7 @@ void psxBios_Exec() { // 43
        a1 = a2;
 
        ra = 0x8000;
-       pc0 = header->_pc0;
+       pc0 = SWAP32(header->_pc0);
 }
 
 void psxBios_FlushCache() { // 44
@@ -1661,16 +1668,16 @@ void psxBios_SetMem() { // 9f
                case 2:
                        psxHu32ref(0x1060) = SWAP32(new);
                        psxMu32ref(0x060) = a0;
-                       SysPrintf("Change effective memory : %d MBytes\n",a0);
+                       PSXBIOS_LOG("Change effective memory : %d MBytes\n",a0);
                        break;
 
                case 8:
                        psxHu32ref(0x1060) = SWAP32(new | 0x300);
                        psxMu32ref(0x060) = a0;
-                       SysPrintf("Change effective memory : %d MBytes\n",a0);
+                       PSXBIOS_LOG("Change effective memory : %d MBytes\n",a0);
 
                default:
-                       SysPrintf("Effective memory must be 2/8 MBytes\n");
+                       PSXBIOS_LOG("Effective memory must be 2/8 MBytes\n");
                break;
        }
 
@@ -1729,6 +1736,19 @@ void psxBios__card_load() { // ac
        v0 = 1; pc0 = ra;
 }
 
+static void psxBios_GetSystemInfo() { // b4
+       u32 ret = 0;
+       //PSXBIOS_LOG("psxBios_%s %x\n", biosA0n[0xb4], a0);
+       SysPrintf("psxBios_%s %x\n", biosA0n[0xb4], a0);
+       switch (a0) {
+       case 0:
+       case 1: ret = SWAP32(((u32 *)psxR)[0x100/4 + a0]); break;
+       case 2: ret = 0xbfc0012c; break;
+       case 5: ret = loadRam32(0x60) << 10; break;
+       }
+       mips_return_c(ret, 20);
+}
+
 /* System calls B0 */
 
 static u32 psxBios_SysMalloc_(u32 size);
@@ -2044,9 +2064,9 @@ void psxBios_ChangeTh() { // 10
        u32 tcbBase = loadRam32(A_TT_TCB);
        u32 th = a0 & 0xffff;
 
-#ifdef PSXBIOS_LOG
-//     PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x10], th);
-#endif
+       // this is quite spammy
+       //PSXBIOS_LOG("psxBios_%s %x\n", biosB0n[0x10], th);
+
        // without doing any argument checks, just issue a syscall
        // (like the real bios does)
        a0 = 3;
@@ -2060,7 +2080,7 @@ void psxBios_InitPAD() { // 0x12
        PSXBIOS_LOG("psxBios_%s %x %x %x %x\n", biosB0n[0x12], a0, a1, a2, a3);
 
        // printf("%s", "PS-X Control PAD Driver  Ver 3.0");
-       // PAD_dr_enable = 0;
+       ram32[A_PAD_DR_DST/4] = 0;
        ram32[A_PAD_OUTBUF/4 + 0] = 0;
        ram32[A_PAD_OUTBUF/4 + 1] = 0;
        ram32[A_PAD_OUT_LEN/4 + 0] = 0;
@@ -2107,47 +2127,74 @@ void psxBios_StopPAD() { // 14
        mips_return_void_c(200);
 }
 
-void psxBios_PAD_init() { // 15
-#ifdef PSXBIOS_LOG
+static void psxBios_PAD_init() { // 15
+       u32 ret = 0;
        PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x15]);
-#endif
-       if (!(a0 == 0x20000000 || a0 == 0x20000001))
+       if (a0 == 0x20000000 || a0 == 0x20000001)
        {
-               v0 = 0;
-               pc0 = ra;
-               return;
+               u32 dst = a1;
+               a0 = A_PAD_DR_BUF1; a1 = 0x22;
+               a2 = A_PAD_DR_BUF2; a3 = 0x22;
+               psxBios_InitPAD();
+               psxBios_StartPAD();
+               storeRam32(A_PAD_DR_DST, dst);
+               ret = 2;
+       }
+       mips_return_c(ret, 100);
+}
+
+static u32 psxBios_PAD_dr_() {
+       u8 *dst = loadRam32ptr(A_PAD_DR_DST);
+       u8 *buf1 = castRam8ptr(A_PAD_DR_BUF1);
+       u8 *buf2 = castRam8ptr(A_PAD_DR_BUF2);
+       dst[0] = dst[1] = dst[2] = dst[3] = ~0;
+       if (buf1[0] == 0 && (buf1[1] == 0x23 || buf1[1] == 0x41))
+       {
+               dst[0] = buf1[3], dst[1] = buf1[2];
+               if (buf1[1] == 0x23) {
+                       dst[0] |= 0xc7, dst[1] |= 7;
+                       if (buf1[5] >= 0x10) dst[0] &= ~(1u << 6);
+                       if (buf1[6] >= 0x10) dst[0] &= ~(1u << 7);
+               }
        }
-       psxHwWrite16(0x1f801074, (u16)(psxHwRead16(0x1f801074) | 0x1));
-       pad_buf = (int *)Ra1;
-       *pad_buf = -1;
-       psxRegs.CP0.n.SR |= 0x401;
-       v0 = 2;
-       pc0 = ra;
+       if (buf2[0] == 0 && (buf2[1] == 0x23 || buf2[1] == 0x41))
+       {
+               dst[2] = buf2[3], dst[3] = buf2[2];
+               if (buf2[1] == 0x23) {
+                       dst[2] |= 0xc7, dst[3] |= 7;
+                       if (buf2[5] >= 0x10) dst[2] &= ~(1u << 6);
+                       if (buf2[6] >= 0x10) dst[2] &= ~(1u << 7);
+               }
+       }
+       use_cycles(55);
+       return SWAP32(*(u32 *)dst);
 }
 
-void psxBios_PAD_dr() { // 16
-#ifdef PSXBIOS_LOG
+static void psxBios_PAD_dr() { // 16
        PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x16]);
-#endif
-
-       v0 = -1; pc0 = ra;
+       u32 ret = psxBios_PAD_dr_();
+       mips_return(ret);
 }
 
 static void psxBios_ReturnFromException() { // 17
        u32 tcbPtr = loadRam32(A_TT_PCB);
        const TCB *tcb = loadRam32ptr(tcbPtr);
+       u32 sr;
        int i;
 
        for (i = 1; i < 32; i++)
                psxRegs.GPR.r[i] = SWAP32(tcb->reg[i]);
        psxRegs.GPR.n.lo = SWAP32(tcb->lo);
        psxRegs.GPR.n.hi = SWAP32(tcb->hi);
-       psxRegs.CP0.n.SR = SWAP32(tcb->sr);
+       sr = SWAP32(tcb->sr);
 
        //printf("%s %08x->%08x %u\n", __func__, pc0, tcb->epc, psxRegs.cycle);
        pc0 = k0 = SWAP32(tcb->epc);
 
-       psxRegs.CP0.n.SR = (psxRegs.CP0.n.SR & ~0x0f) | ((psxRegs.CP0.n.SR & 0x3c) >> 2);
+       // the interpreter wants to know about sr changes, so do a MTC0
+       sr = (sr & ~0x0f) | ((sr & 0x3c) >> 2);
+       MTC0(&psxRegs, 12, sr);
+
        use_cycles(53);
        psxBranchTest();
 }
@@ -2191,7 +2238,7 @@ static void buopen(int mcd, char *ptr, char *cfg)
                if ((*fptr & 0xF0) != 0x50) continue;
                if (strcmp(FDesc[1 + mcd].name, fptr+0xa)) continue;
                FDesc[1 + mcd].mcfile = i;
-               SysPrintf("open %s\n", fptr+0xa);
+               PSXBIOS_LOG("open %s\n", fptr+0xa);
                v0 = 1 + mcd;
                break;
        }
@@ -2230,7 +2277,7 @@ static void buopen(int mcd, char *ptr, char *cfg)
                        pptr[8] = pptr[9] = 0xff;
                        for (j=0, xor=0; j<127; j++) xor^= pptr[j];
                        pptr[127] = xor;
-                       SysPrintf("openC %s %d\n", ptr, nblk);
+                       PSXBIOS_LOG("openC %s %d\n", ptr, nblk);
                        v0 = 1 + mcd;
                        /* just go ahead and resave them all */
                        SaveMcd(cfg, ptr, 128, 128 * 15);
@@ -2325,9 +2372,8 @@ void psxBios_write() { // 0x35/0x03
        char *ptr;
        void *pa1 = Ra1;
 
-#ifdef PSXBIOS_LOG
-       PSXBIOS_LOG("psxBios_%s: %x,%x,%x\n", biosB0n[0x35], a0, a1, a2);
-#endif
+       if (a0 != 1) // stdout
+               PSXBIOS_LOG("psxBios_%s: %x,%x,%x\n", biosB0n[0x35], a0, a1, a2);
 
        v0 = -1;
        if (pa1 == INVALID_PTR) {
@@ -2339,7 +2385,7 @@ void psxBios_write() { // 0x35/0x03
                char *ptr = pa1;
 
                v0 = a2;
-               while (a2 > 0) {
+               if (Config.PsxOut) while (a2 > 0) {
                        SysPrintf("%c", *ptr++); a2--;
                }
                pc0 = ra; return;
@@ -2386,12 +2432,12 @@ void psxBios_close() { // 0x36
 }
 
 void psxBios_putchar() { // 3d
-       SysPrintf("%c", (char)a0);
+       if (Config.PsxOut) SysPrintf("%c", (char)a0);
        pc0 = ra;
 }
 
 void psxBios_puts() { // 3e/3f
-       SysPrintf("%s", Ra0);
+       if (Config.PsxOut) SysPrintf("%s", Ra0);
        pc0 = ra;
 }
 
@@ -2428,7 +2474,7 @@ static size_t strlen_internal(char* p)
                                strcpy(dir->name+i, ptr+i); break; } \
                        match = 0; break; \
                } \
-               SysPrintf("%d : %s = %s + %s (match=%d)\n", nfile, dir->name, pfile, ptr, match); \
+               PSXBIOS_LOG("%d : %s = %s + %s (match=%d)\n", nfile, dir->name, pfile, ptr, match); \
                if (match == 0) { continue; } \
                dir->size = 8192; \
                v0 = _dir; \
@@ -2552,7 +2598,7 @@ void psxBios_rename() { // 44
                if (strcmp(Ra0+5, ptr+0xa)) continue; \
                *ptr = (*ptr & 0xf) | 0xA0; \
                SaveMcd(Config.Mcd##mcd, Mcd##mcd##Data, 128 * i, 1); \
-               SysPrintf("delete %s\n", ptr+0xa); \
+               PSXBIOS_LOG("delete %s\n", ptr+0xa); \
                v0 = 1; \
                break; \
        } \
@@ -3230,6 +3276,8 @@ void psxBiosInit() {
        biosA0[0x3b] = psxBios_getchar;
        biosA0[0x3c] = psxBios_putchar;
        //biosA0[0x3d] = psxBios_gets;
+       biosA0[0x3e] = psxBios_puts;
+       biosA0[0x3f] = psxBios_printf;
        biosA0[0x40] = psxBios_SystemErrorUnresolvedException;
        //biosA0[0x41] = psxBios_LoadTest;
        biosA0[0x42] = psxBios_Load;
@@ -3346,7 +3394,7 @@ void psxBiosInit() {
        //biosA0[0xb1] = psxBios_sys_a0_b1;
        //biosA0[0xb2] = psxBios_do_a_long_jmp
        //biosA0[0xb3] = psxBios_sys_a0_b3;
-       //biosA0[0xb4] = psxBios_sub_function;
+       biosA0[0xb4] = psxBios_GetSystemInfo;
 //*******************B0 CALLS****************************
        biosB0[0x00] = psxBios_SysMalloc;
        //biosB0[0x01] = psxBios_sys_b0_01;
@@ -3409,7 +3457,9 @@ void psxBiosInit() {
        //biosB0[0x3a] = psxBios_getc;
        //biosB0[0x3b] = psxBios_putc;
        biosB0[0x3c] = psxBios_getchar;
+       biosB0[0x3d] = psxBios_putchar;
        //biosB0[0x3e] = psxBios_gets;
+       biosB0[0x3f] = psxBios_puts;
        //biosB0[0x40] = psxBios_cd;
        biosB0[0x41] = psxBios_format;
        biosB0[0x42] = psxBios_firstfile;
@@ -3473,7 +3523,6 @@ void psxBiosInit() {
 //************** THE END ***************************************
 /**/
 
-       pad_buf = NULL;
        heap_addr = NULL;
        heap_end = NULL;
        heap_size = 0;
@@ -3483,11 +3532,15 @@ void psxBiosInit() {
        // initial RNG seed
        psxMu32ref(0x9010) = SWAPu32(0xac20cc00);
 
+       // somewhat pretend to be a SCPH1001 BIOS
+       // some games look for these and take an exception if they're missing
        rom32 = (u32 *)psxR;
        rom32[0x100/4] = SWAP32(0x19951204);
        rom32[0x104/4] = SWAP32(3);
        strcpy(psxR + 0x108, "PCSX authors");
-       strcpy(psxR + 0x12c, "PCSX HLE");
+       strcpy(psxR + 0x12c, "CEX-3000 PCSX HLE"); // see psxBios_GetSystemInfo
+       strcpy(psxR + 0x7ff32, "System ROM Version 2.2 12/04/95 A");
+       strcpy(psxR + 0x7ff54, "GPL-2.0-or-later");
 
        // fonts
        len = 0x80000 - 0x66000;
@@ -3604,40 +3657,6 @@ void psxBiosCnfLoaded(u32 tcb_cnt, u32 evcb_cnt) {
        } \
 }
 
-static void biosPadHLE() {
-       if (pad_buf != NULL) {
-               u32 *buf = (u32*)pad_buf;
-
-               PAD1_startPoll(1);
-               if (PAD1_poll(0x42) == 0x23) {
-                       PAD1_poll(0);
-                       *buf = PAD1_poll(0) << 8;
-                       *buf |= PAD1_poll(0);
-                       PAD1_poll(0);
-                       *buf &= ~((PAD1_poll(0) > 0x20) ? 1 << 6 : 0);
-                       *buf &= ~((PAD1_poll(0) > 0x20) ? 1 << 7 : 0);
-               } else {
-                       PAD1_poll(0);
-                       *buf = PAD1_poll(0) << 8;
-                       *buf|= PAD1_poll(0);
-               }
-
-               PAD2_startPoll(2);
-               if (PAD2_poll(0x42) == 0x23) {
-                       PAD2_poll(0);
-                       *buf |= PAD2_poll(0) << 24;
-                       *buf |= PAD2_poll(0) << 16;
-                       PAD2_poll(0);
-                       *buf &= ~((PAD2_poll(0) > 0x20) ? 1 << 22 : 0);
-                       *buf &= ~((PAD2_poll(0) > 0x20) ? 1 << 23 : 0);
-               } else {
-                       PAD2_poll(0);
-                       *buf |= PAD2_poll(0) << 24;
-                       *buf |= PAD2_poll(0) << 16;
-               }
-       }
-}
-
 static void handle_chain_x_x_1(u32 enable, u32 irqbit)
 {
        use_cycles(10);
@@ -3697,7 +3716,7 @@ void hleExc0_2_2_syscall() // not in any A/B/C table
        if (code != R3000E_Syscall) {
                if (code != 0) {
                        DeliverEvent(0xf0000010, 0x1000);
-                       psxBios_SystemErrorUnresolvedException();
+                       //psxBios_SystemErrorUnresolvedException();
                }
                mips_return_c(0, 17);
                return;
@@ -3823,8 +3842,9 @@ void hleExcPadCard1(void)
 
                psxBios_PADpoll(1);
                psxBios_PADpoll(2);
-               biosPadHLE();
                use_cycles(100);
+               if (loadRam32(A_PAD_DR_DST))
+                       psxBios_PAD_dr_();
        }
        if (loadRam32(A_PAD_ACK_VBL))
                psxHwWrite16(0x1f801070, ~1);
@@ -3925,7 +3945,6 @@ void psxBiosException() {
 void psxBiosFreeze(int Mode) {
        u32 base = 0x40000;
 
-       bfreezepsxMptr(pad_buf, int);
        bfreezepsxMptr(heap_addr, u32);
        bfreezes(FDesc);
        bfreezel(&card_active_chan);