psxbios: Fixes save issues on Parasite Eve II, Parasite Eve I and others
[pcsx_rearmed.git] / libpcsxcore / psxbios.c
index cd2fb0c..fbc0002 100644 (file)
@@ -322,9 +322,10 @@ static inline void LoadRegs() {
        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); \
        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 */ \
-       if (FDesc[1 + mcd].mode & 0x8000) v0 = 0; \
+       v0 = 0; } \
        else v0 = length; \
        FDesc[1 + mcd].offset += v0; \
 }
@@ -334,10 +335,11 @@ static inline void LoadRegs() {
        SysPrintf("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; \
+       if (FDesc[1 + mcd].mode & 0x8000) { \
        DeliverEvent(0x11, 0x2); /* 0xf0000011, 0x0004 */ \
        DeliverEvent(0x81, 0x2); /* 0xf4000001, 0x0004 */ \
-       FDesc[1 + mcd].offset += length; \
-       if (FDesc[1 + mcd].mode & 0x8000) v0 = 0; \
+       v0 = 0; } \
        else v0 = length; \
 }
 
@@ -1762,9 +1764,15 @@ void psxBios_TestEvent() { // 0b
        ev   = a0 & 0xff;
        spec = (a0 >> 8) & 0xff;
 
-       if (Event[ev][spec].status == EvStALREADY) {
-               Event[ev][spec].status = EvStACTIVE; v0 = 1;
-       } else v0 = 0;
+       if (Event[ev][spec].status == EvStALREADY) 
+       {
+               if (!(Event[ev][spec].mode == EvMdINTR)) Event[ev][spec].status = EvStACTIVE;
+               v0 = 1;
+       } 
+       else 
+       {
+               v0 = 0;
+       }
 
 #ifdef PSXBIOS_LOG
        PSXBIOS_LOG("psxBios_%s %x,%x: %x\n", biosB0n[0x0b], ev, spec, v0);
@@ -2202,7 +2210,18 @@ void psxBios_puts() { // 3e/3f
 char ffile[64], *pfile;
 int nfile;
 
+
+/* To avoid any issues with different behaviour when using the libc's own strlen instead.
+ * We want to mimic the PSX's behaviour in this case for bufile. */
+static size_t strlen_internal(char* p) 
+{
+       size_t size_of_array = 0;
+       while (*p++) size_of_array++;
+       return size_of_array;
+}
+
 #define bufile(mcd) { \
+       size_t size_of_name = strlen_internal(dir->name); \
        while (nfile < 16) { \
                int match=1; \
  \
@@ -2213,8 +2232,8 @@ int nfile;
                if (!ptr[0xa]) continue; \
                ptr+= 0xa; \
                if (pfile[0] == 0) { \
-                       strncpy(dir->name, ptr, sizeof(dir->name)); \
-                       dir->name[sizeof(dir->name) - 1] = '\0'; \
+                       strncpy(dir->name, ptr, sizeof(dir->name) - 1); \
+                       if (size_of_name < sizeof(dir->name)) dir->name[size_of_name] = '\0'; \
                } else for (i=0; i<20; i++) { \
                        if (pfile[i] == ptr[i]) { \
                                                                dir->name[i] = ptr[i]; continue; } \
@@ -3196,6 +3215,9 @@ void psxBiosException() {
                                case 2: // ExitCritical - enable irq's
                                        psxRegs.CP0.n.Status |= 0x404; 
                                        break;
+                               /* Normally this should cover SYS(00h, SYS(04h but they don't do anything relevant so... */
+                               default:
+                                       break;
                        }
                        pc0 = psxRegs.CP0.n.EPC + 4;