psxbios: unbreak bcopy
[pcsx_rearmed.git] / libpcsxcore / psxbios.c
index 7e88c9c..17d5044 100644 (file)
@@ -253,12 +253,11 @@ 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;
+// todo: FileDesc layout is wrong
+// todo: get rid of these globals
 static FileDesc FDesc[32];
-static u32 card_active_chan = 0;
+static char ffile[64], *pfile;
+static int nfile;
 
 // fixed RAM offsets, SCPH1001 compatible
 #define A_TT_ExCB       0x0100
@@ -275,17 +274,25 @@ 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_CARD_CHAN1    0x7500
+#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
 #define A_PAD_ACK_VBL   0x8914  // enable vint ack by pad reading code
+#define A_HEAP_BASE     0x9000
+#define A_HEAP_SIZE     0x9004
+#define A_HEAP_END      0x9008
+#define A_HEAP_FLAG     0x900c
 #define A_CD_EVENTS     0xb9b8
 #define A_EXC_GP        0xf450
 
@@ -407,6 +414,7 @@ static void CloseEvent(u32 ev);
        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); \
+       psxCpu->Clear(a1, (length + 3) / 4); \
        if (FDesc[1 + mcd].mode & 0x8000) { \
        DeliverEvent(0xf0000011, 0x0004); \
        DeliverEvent(0xf4000001, 0x0004); \
@@ -897,37 +905,69 @@ void psxBios_tolower() { // 0x26
        pc0 = ra;
 }
 
-void psxBios_bcopy() { // 0x27
-       char *p1 = (char *)Ra1, *p2 = (char *)Ra0;
-       v0 = a0;
-       if (a0 == 0 || a2 > 0x7FFFFFFF)
-       {
-               pc0 = ra;
-               return;
+static void do_memset(u32 dst, u32 v, s32 len)
+{
+       u32 d = dst;
+       s32 l = len;
+       while (l-- > 0) {
+               u8 *db = PSXM(d);
+               if (db != INVALID_PTR)
+                       *db = v;
+               d++;
        }
-       while ((s32)a2-- > 0) *p1++ = *p2++;
-       a2 = 0;
-       pc0 = ra;
+       psxCpu->Clear(dst, (len + 3) / 4);
 }
 
-void psxBios_bzero() { // 0x28
-       char *p = (char *)Ra0;
-       v0 = a0;
-       /* Same as memset here (See memset below) */
-       if (a1 > 0x7FFFFFFF || a1 == 0)
+static void do_memcpy(u32 dst, u32 src, s32 len)
+{
+       u32 d = dst, s = src;
+       s32 l = len;
+       while (l-- > 0) {
+               const u8 *sb = PSXM(s);
+               u8 *db = PSXM(d);
+               if (db != INVALID_PTR && sb != INVALID_PTR)
+                       *db = *sb;
+               d++;
+               s++;
+       }
+       psxCpu->Clear(dst, (len + 3) / 4);
+}
+
+static void psxBios_memcpy();
+
+static void psxBios_bcopy() { // 0x27 - memcpy with args swapped
+       //PSXBIOS_LOG("psxBios_%s %x %x %x\n", biosA0n[0x27], a0, a1, a2);
+       u32 ret = a0, cycles = 0;
+       if (a0 == 0) // ...but it checks src this time
        {
-               v0 = 0;
-               pc0 = ra;
+               mips_return_c(0, 4);
                return;
        }
-       else if (a0 == 0)
+       v1 = a0;
+       if ((s32)a2 > 0) {
+               do_memcpy(a1, a0, a2);
+               cycles = a2 * 6;
+               a0 += a2;
+               a1 += a2;
+               a2 = 0;
+       }
+       mips_return_c(ret, cycles + 5);
+}
+
+static void psxBios_bzero() { // 0x28
+       /* Same as memset here (See memset below) */
+       u32 ret = a0, cycles;
+       if (a0 == 0 || (s32)a1 <= 0)
        {
-               pc0 = ra;
+               mips_return_c(0, 6);
                return;
        }
-       while ((s32)a1-- > 0) *p++ = '\0';
+       do_memset(a0, 0, a1);
+       cycles = a1 * 4;
+       a0 += a1;
        a1 = 0;
-       pc0 = ra;
+       // todo: many more cycles due to uncached bios mem
+       mips_return_c(ret, cycles + 5);
 }
 
 void psxBios_bcmp() { // 0x29
@@ -946,57 +986,70 @@ void psxBios_bcmp() { // 0x29
        v0 = 0; pc0 = ra;
 }
 
-void psxBios_memcpy() { // 0x2a
-       char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
-       v0 = a0;
-       if (a0 == 0 || a2 > 0x7FFFFFFF)
+static void psxBios_memcpy() { // 0x2a
+       u32 ret = a0, cycles = 0;
+       if (a0 == 0)
        {
-               pc0 = ra;
+               mips_return_c(0, 4);
                return;
        }
-       while ((s32)a2-- > 0) {
-               *p1++ = *p2++;
+       if ((s32)a2 > 0) {
+               do_memcpy(a0, a1, a2);
+               cycles = a2 * 6;
+               v1 = a0;
+               a0 += a2;
+               a1 += a2;
+               a2 = 0;
        }
-       a2 = 0;
-       pc0 = ra;
+       mips_return_c(ret, cycles + 5);
 }
 
-void psxBios_memset() { // 0x2b
-       char *p = (char *)Ra0;
-       v0 = a0;
-       if (a2 > 0x7FFFFFFF || a2 == 0)
+static void psxBios_memset() { // 0x2b
+       u32 ret = a0, cycles;
+       if (a0 == 0 || (s32)a2 <= 0)
        {
-               v0 = 0;
-               pc0 = ra;
-               return;
-       }
-       if (a0 == 0)
-       {
-               pc0 = ra;
+               mips_return_c(0, 6);
                return;
        }
-       while ((s32)a2-- > 0) *p++ = (char)a1;
+       do_memset(a0, a1, a2);
+       cycles = a2 * 4;
+       a0 += a2;
        a2 = 0;
-       v0 = a0; pc0 = ra;
+       // todo: many more cycles due to uncached bios mem
+       mips_return_c(ret, cycles + 5);
 }
 
 void psxBios_memmove() { // 0x2c
-       char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
-       v0 = a0;
-       if (a0 == 0 || a2 > 0x7FFFFFFF)
+       u32 ret = a0, cycles = 0;
+       if (a0 == 0)
        {
-               pc0 = ra;
+               mips_return_c(0, 4);
                return;
        }
-       if (p2 <= p1 && p2 + a2 > p1) {
-               a2++; // BUG: copy one more byte here
-               p1 += a2;
-               p2 += a2;
-               while ((s32)a2-- > 0) *--p1 = *--p2;
-       } else {
-               while ((s32)a2-- > 0) *p1++ = *p2++;
+       v1 = a0;
+       if ((s32)a2 > 0 && a0 > a1 && a0 < a1 + a2) {
+               u32 dst = a0, len = a2 + 1;
+               a0 += a2;
+               a1 += a2;
+               while ((s32)a2 >= 0) { // BUG: copies one more byte here
+                       const u8 *sb = PSXM(a1);
+                       u8 *db = PSXM(a0);
+                       if (db != INVALID_PTR && sb != INVALID_PTR)
+                               *db = *sb;
+                       a0--;
+                       a1--;
+                       a2--;
+               }
+               psxCpu->Clear(dst, (len + 3) / 4);
+               cycles = 10 + len * 8;
+       } else if ((s32)a2 > 0) {
+               do_memcpy(a0, a1, a2);
+               cycles = a2 * 6;
+               a0 += a2;
+               a1 += a2;
+               a2 = 0;
        }
-       pc0 = ra;
+       mips_return_c(ret, cycles + 5);
 }
 
 void psxBios_memcmp() { // 0x2d
@@ -1140,14 +1193,16 @@ void psxBios_qsort() { // 0x31
        pc0 = ra;
 }
 
-void psxBios_malloc() { // 0x33
+// this isn't how the real bios works, but maybe good enough
+static void psxBios_malloc() { // 0x33
+       u32 *heap_addr, *heap_end;
        u32 *chunk, *newchunk = NULL;
        unsigned int dsize = 0, csize, cstat;
        int colflag;
-#ifdef PSXBIOS_LOG
-       PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x33]);
-#endif
-       if (!a0 || (!heap_size || !heap_addr)) {
+       PSXBIOS_LOG("psxBios_%s %x\n", biosA0n[0x33], a0);
+       heap_addr = loadRam32ptr(A_HEAP_BASE);
+       heap_end = loadRam32ptr(A_HEAP_END);
+       if (heap_addr >= heap_end) {
                v0 = 0;
                pc0 = ra;
                return;
@@ -1244,27 +1299,24 @@ void psxBios_malloc() { // 0x33
        pc0 = ra;
 }
 
-void psxBios_free() { // 0x34
-
-       PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x34]);
-       PSXBIOS_LOG("free %x: %x bytes\n", a0, *(u32*)(Ra0-4));
-
-       if (a0)
-               *(u32*)(Ra0-4) |= 1;    // set chunk to free
-       pc0 = ra;
+static void psxBios_free() { // 0x34
+       PSXBIOS_LOG("psxBios_%s %x (%x bytes)\n", biosA0n[0x34], a0, loadRam32(a0 - 4));
+       storeRam32(a0 - 4, loadRam32(a0 - 4) | 1); // set chunk to free
+       mips_return_void_c(5);
 }
 
-void psxBios_calloc() { // 0x37
-       void *pv0;
-#ifdef PSXBIOS_LOG
-       PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x37]);
-#endif
+static void psxBios_calloc() { // 0x37
+       u32 ret, size;
+       PSXBIOS_LOG("psxBios_%s %x %x\n", biosA0n[0x37], a0, a1);
 
-       a0 = a0 * a1;
+       a0 = size = a0 * a1;
        psxBios_malloc();
-       pv0 = Rv0;
-       if (pv0)
-               memset(pv0, 0, a0);
+       ret = v0;
+       if (ret) {
+               a0 = ret; a1 = size;
+               psxBios_bzero();
+       }
+       mips_return_c(ret, 21);
 }
 
 void psxBios_realloc() { // 0x38
@@ -1297,27 +1349,16 @@ void psxBios_realloc() { // 0x38
 
 
 /* InitHeap(void *block , int n) */
-void psxBios_InitHeap() { // 0x39
-       unsigned int size;
-
-#ifdef PSXBIOS_LOG
-       PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x39]);
-#endif
-
-       if (((a0 & 0x1fffff) + a1)>= 0x200000) size = 0x1ffffc - (a0 & 0x1fffff);
-       else size = a1;
-
-       size &= 0xfffffffc;
-
-       heap_addr = (u32 *)Ra0;
-       heap_size = size;
-       heap_end = (u32 *)((u8 *)heap_addr + heap_size);
-       /* HACKFIX: Commenting out this line fixes GTA2 crash */
-       //*heap_addr = SWAP32(size | 1);
+static void psxBios_InitHeap() { // 0x39
+       PSXBIOS_LOG("psxBios_%s %x %x\n", biosA0n[0x39], a0, a1);
 
-       PSXBIOS_LOG("InitHeap %x,%x : %x %x\n",a0,a1, (int)((uptr)heap_addr-(uptr)psxM), size);
+       storeRam32(A_HEAP_BASE, a0);
+       storeRam32(A_HEAP_SIZE, a1);
+       storeRam32(A_HEAP_END, a0 + (a1 & ~3) + 4);
+       storeRam32(A_HEAP_FLAG, 0);
+       storeRam32(a0, 0);
 
-       pc0 = ra;
+       mips_return_void_c(14);
 }
 
 void psxBios_getchar() { //0x3b
@@ -1438,8 +1479,9 @@ void psxBios_Load() { // 0x42
        void *pa1;
 
        pa1 = Ra1;
-       if (pa1 && LoadCdromFile(Ra0, &eheader) == 0) {
+       if (pa1 != INVALID_PTR && LoadCdromFile(Ra0, &eheader) == 0) {
                memcpy(pa1, ((char*)&eheader)+16, sizeof(EXEC));
+               psxCpu->Clear(a1, sizeof(EXEC) / 4);
                v0 = 1;
        } else v0 = 0;
        PSXBIOS_LOG("psxBios_%s: %s, %d -> %d\n", biosA0n[0x42], Ra0, a1, v0);
@@ -1683,19 +1725,18 @@ void psxBios_SetMem() { // 9f
 }
 
 /* TODO FIXME : Not compliant. -1 indicates failure but using 1 for now. */
-void psxBios_get_cd_status(void) //a6
+static void psxBios_get_cd_status() // a6
 {
+       PSXBIOS_LOG("psxBios_%s\n", biosA0n[0xa6]);
        v0 = 1;
        pc0 = ra;
 }
 
-void psxBios__card_info() { // ab
-#ifdef PSXBIOS_LOG
+static void psxBios__card_info() { // ab
        PSXBIOS_LOG("psxBios_%s: %x\n", biosA0n[0xab], a0);
-#endif
        u32 ret, port;
-       card_active_chan = a0;
-       port = card_active_chan >> 4;
+       storeRam32(A_CARD_CHAN1, a0);
+       port = a0 >> 4;
 
        switch (port) {
        case 0x0:
@@ -1705,9 +1746,7 @@ void psxBios__card_info() { // ab
                        ret = 0x0100;
                break;
        default:
-#ifdef PSXBIOS_LOG
-               PSXBIOS_LOG("psxBios_%s: UNKNOWN PORT 0x%x\n", biosA0n[0xab], card_active_chan);
-#endif
+               PSXBIOS_LOG("psxBios_%s: UNKNOWN PORT 0x%x\n", biosA0n[0xab], a0);
                ret = 0x0302;
                break;
        }
@@ -1726,7 +1765,7 @@ void psxBios__card_load() { // ac
        PSXBIOS_LOG("psxBios_%s: %x\n", biosA0n[0xac], a0);
 #endif
 
-       card_active_chan = a0;
+       storeRam32(A_CARD_CHAN1, a0);
 
 //     DeliverEvent(0xf0000011, 0x0004);
        DeliverEvent(0xf4000001, 0x0004);
@@ -2078,7 +2117,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;
@@ -2125,30 +2164,53 @@ 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
@@ -2196,9 +2258,6 @@ static void psxBios_UnDeliverEvent() { // 0x20
        mips_return(ret);
 }
 
-char ffile[64], *pfile;
-int nfile;
-
 static void buopen(int mcd, char *ptr, char *cfg)
 {
        int i;
@@ -2658,7 +2717,7 @@ void psxBios__card_write() { // 0x4e
                v0 = 0; pc0 = ra;
                return;
        }
-       card_active_chan = a0;
+       storeRam32(A_CARD_CHAN1, a0);
        port = a0 >> 4;
 
        if (pa2 != INVALID_PTR) {
@@ -2694,7 +2753,7 @@ void psxBios__card_read() { // 0x4f
                v0 = 0; pc0 = ra;
                return;
        }
-       card_active_chan = a0;
+       storeRam32(A_CARD_CHAN1, a0);
        port = a0 >> 4;
 
        if (pa2 != INVALID_PTR) {
@@ -2785,13 +2844,14 @@ void psxBios_GetB0Table() { // 57
        mips_return_c(A_B0_TABLE, 3);
 }
 
-void psxBios__card_chan() { // 0x58
-#ifdef PSXBIOS_LOG
+static void psxBios__card_chan() { // 0x58
+       u32 ret;
        PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x58]);
-#endif
 
-       v0 = card_active_chan;
-       pc0 = ra;
+       // todo: should return active slot chan
+       // (active - which was last processed by irq code)
+       ret = loadRam32(A_CARD_CHAN1);
+       mips_return_c(ret, 8);
 }
 
 static void psxBios_ChangeClearPad() { // 5b
@@ -2803,21 +2863,17 @@ static void psxBios_ChangeClearPad() { // 5b
        mips_return_c(ret, 6);
 }
 
-void psxBios__card_status() { // 5c
-#ifdef PSXBIOS_LOG
-       PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x5c], a0);
-#endif
+static void psxBios__card_status() { // 5c
+       PSXBIOS_LOG("psxBios_%s %x\n", biosB0n[0x5c], a0);
 
-       v0 = card_active_chan;
+       v0 = 1; // ready
        pc0 = ra;
 }
 
-void psxBios__card_wait() { // 5d
-#ifdef PSXBIOS_LOG
-       PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x5d], a0);
-#endif
+static void psxBios__card_wait() { // 5d
+       PSXBIOS_LOG("psxBios_%s %x\n", biosB0n[0x5d], a0);
 
-       v0 = 1;
+       v0 = 1; // ready
        pc0 = ra;
 }
 
@@ -3498,12 +3554,7 @@ void psxBiosInit() {
 //************** THE END ***************************************
 /**/
 
-       pad_buf = NULL;
-       heap_addr = NULL;
-       heap_end = NULL;
-       heap_size = 0;
        memset(FDesc, 0, sizeof(FDesc));
-       card_active_chan = 0;
 
        // initial RNG seed
        psxMu32ref(0x9010) = SWAPu32(0xac20cc00);
@@ -3633,40 +3684,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);
@@ -3852,8 +3869,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);
@@ -3954,9 +3972,5 @@ void psxBiosException() {
 void psxBiosFreeze(int Mode) {
        u32 base = 0x40000;
 
-       bfreezepsxMptr(pad_buf, int);
-       bfreezepsxMptr(heap_addr, u32);
        bfreezes(FDesc);
-       bfreezel(&card_active_chan);
-       bfreezel(&heap_size);
 }