spu: rework synchronization
[pcsx_rearmed.git] / libpcsxcore / psxbios.c
index f2751b8..04c959a 100644 (file)
 
 #include "psxbios.h"
 #include "psxhw.h"
+#include "gpu.h"
+#include <zlib.h>
+
+#undef SysPrintf
+#define SysPrintf if (Config.PsxOut) printf
 
 char *biosA0n[256] = {
 // 0x00
@@ -256,6 +261,7 @@ static int CardState = -1;
 static TCB Thread[8];
 static int CurThread = 0;
 static FileDesc FDesc[32];
+static u32 card_active_chan;
 
 boolean hleSoftCall = FALSE;
 
@@ -800,8 +806,8 @@ void psxBios_qsort() { // 0x31
 }
 
 void psxBios_malloc() { // 0x33
-       unsigned int *chunk, *newchunk;
-       unsigned int dsize, csize, cstat;
+       unsigned int *chunk, *newchunk = NULL;
+       unsigned int dsize = 0, csize, cstat;
        int colflag;
 #ifdef PSXBIOS_LOG
        PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x33]);
@@ -871,7 +877,7 @@ void psxBios_malloc() { // 0x33
                // split free chunk
                *chunk = SWAP32(dsize);
                newchunk = (u32*)((uptr)chunk + dsize + 4);
-               *newchunk = SWAP32((csize - dsize - 4) & 0xfffffffc | 1);
+               *newchunk = SWAP32(((csize - dsize - 4) & 0xfffffffc) | 1);
        }
 
        // return pointer to allocated memory
@@ -894,13 +900,16 @@ void psxBios_free() { // 0x34
 }
 
 void psxBios_calloc() { // 0x37
+       void *pv0;
 #ifdef PSXBIOS_LOG
        PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x37]);
 #endif
 
        a0 = a0 * a1;
        psxBios_malloc();
-       memset(Rv0, 0, a0);
+       pv0 = Rv0;
+       if (pv0)
+               memset(pv0, 0, a0);
 }
 
 void psxBios_realloc() { // 0x38
@@ -934,7 +943,7 @@ void psxBios_InitHeap() { // 0x39
        heap_end = (u32 *)((u8 *)heap_addr + size);
        *heap_addr = SWAP32(size | 1);
 
-       SysPrintf("InitHeap %x,%x : %x %x\n",a0,a1, (uptr)heap_addr-(uptr)psxM, size);
+       SysPrintf("InitHeap %x,%x : %x %x\n",a0,a1, (int)((uptr)heap_addr-(uptr)psxM), size);
 
        pc0 = ra;
 }
@@ -949,12 +958,16 @@ void psxBios_printf() { // 0x3f
        u32 save[4];
        char *ptmp = tmp;
        int n=1, i=0, j;
-
-       memcpy(save, (char*)PSXM(sp), 4 * 4);
-       psxMu32ref(sp) = SWAP32((u32)a0);
-       psxMu32ref(sp + 4) = SWAP32((u32)a1);
-       psxMu32ref(sp + 8) = SWAP32((u32)a2);
-       psxMu32ref(sp + 12) = SWAP32((u32)a3);
+       void *psp;
+
+       psp = PSXM(sp);
+       if (psp) {
+               memcpy(save, psp, 4 * 4);
+               psxMu32ref(sp) = SWAP32((u32)a0);
+               psxMu32ref(sp + 4) = SWAP32((u32)a1);
+               psxMu32ref(sp + 8) = SWAP32((u32)a2);
+               psxMu32ref(sp + 12) = SWAP32((u32)a3);
+       }
 
        while (Ra0[i]) {
                switch (Ra0[i]) {
@@ -984,7 +997,7 @@ _start:
                                        case 'g': case 'G':
                                                ptmp += sprintf(ptmp, tmp2, (double)psxMu32(sp + n * 4)); n++; break;
                                        case 'p':
-                                       case 'i':
+                                       case 'i': case 'u':
                                        case 'd': case 'D':
                                        case 'o': case 'O':
                                        case 'x': case 'X':
@@ -1004,9 +1017,10 @@ _start:
        }
        *ptmp = 0;
 
-       memcpy((char*)PSXM(sp), save, 4 * 4);
+       if (psp)
+               memcpy(psp, save, 4 * 4);
 
-       SysPrintf(tmp);
+       SysPrintf("%s", tmp);
 
        pc0 = ra;
 }
@@ -1017,13 +1031,15 @@ _start:
 
 void psxBios_Load() { // 0x42
        EXE_HEADER eheader;
+       void *pa1;
 
 #ifdef PSXBIOS_LOG
        PSXBIOS_LOG("psxBios_%s: %s, %x\n", biosA0n[0x42], Ra0, a1);
 #endif
 
-       if (LoadCdromFile(Ra0, &eheader) == 0) {
-               memcpy(Ra1, ((char*)&eheader)+16, sizeof(EXEC));
+       pa1 = Ra1;
+       if (pa1 && LoadCdromFile(Ra0, &eheader) == 0) {
+               memcpy(pa1, ((char*)&eheader)+16, sizeof(EXEC));
                v0 = 1;
        } else v0 = 0;
 
@@ -1114,6 +1130,7 @@ void psxBios_mem2vram() { // 0x47
 
 void psxBios_SendGPU() { // 0x48
        GPU_writeStatus(a0);
+       gpuSyncPluginSR();
        pc0 = ra;
 }
 
@@ -1237,6 +1254,8 @@ void psxBios__card_info() { // ab
        PSXBIOS_LOG("psxBios_%s: %x\n", biosA0n[0xab], a0);
 #endif
 
+       card_active_chan = a0;
+
 //     DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
        DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
 
@@ -1248,6 +1267,8 @@ void psxBios__card_load() { // ac
        PSXBIOS_LOG("psxBios_%s: %x\n", biosA0n[0xac], a0);
 #endif
 
+       card_active_chan = a0;
+
 //     DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
        DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
 
@@ -1673,6 +1694,7 @@ void psxBios_UnDeliverEvent() { // 0x20
 void psxBios_open() { // 0x32
        int i;
        char *ptr;
+       void *pa0 = Ra0;
 
 #ifdef PSXBIOS_LOG
        PSXBIOS_LOG("psxBios_%s: %s,%x\n", biosB0n[0x32], Ra0, a1);
@@ -1680,12 +1702,14 @@ void psxBios_open() { // 0x32
 
        v0 = -1;
 
-       if (!strncmp(Ra0, "bu00", 4)) {
-               buopen(1);
-       }
+       if (pa0) {
+               if (!strncmp(pa0, "bu00", 4)) {
+                       buopen(1);
+               }
 
-       if (!strncmp(Ra0, "bu10", 4)) {
-               buopen(2);
+               if (!strncmp(pa0, "bu10", 4)) {
+                       buopen(2);
+               }
        }
 
        pc0 = ra;
@@ -1717,7 +1741,7 @@ void psxBios_lseek() { // 0x33
        pc0 = ra;
 }
 
-#define buread(mcd) { \
+#define buread(Ra1, mcd) { \
        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, a2); \
@@ -1734,6 +1758,7 @@ void psxBios_lseek() { // 0x33
 
 void psxBios_read() { // 0x34
        char *ptr;
+       void *pa1 = Ra1;
 
 #ifdef PSXBIOS_LOG
        PSXBIOS_LOG("psxBios_%s: %x, %x, %x\n", biosB0n[0x34], a0, a1, a2);
@@ -1741,15 +1766,17 @@ void psxBios_read() { // 0x34
 
        v0 = -1;
 
-       switch (a0) {
-               case 2: buread(1); break;
-               case 3: buread(2); break;
+       if (pa1) {
+               switch (a0) {
+                       case 2: buread(pa1, 1); break;
+                       case 3: buread(pa1, 2); break;
+               }
        }
                
        pc0 = ra;
 }
 
-#define buwrite(mcd) { \
+#define buwrite(Ra1, mcd) { \
        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); \
        ptr = Mcd##mcd##Data + offset; \
@@ -1768,24 +1795,31 @@ void psxBios_read() { // 0x34
 
 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
+
+       v0 = -1;
+       if (!pa1) {
+               pc0 = ra;
+               return;
+       }
 
        if (a0 == 1) { // stdout
-               char *ptr = Ra1;
+               char *ptr = pa1;
 
+               v0 = a2;
                while (a2 > 0) {
                        SysPrintf("%c", *ptr++); a2--;
                }
                pc0 = ra; return;
        }
-#ifdef PSXBIOS_LOG
-       PSXBIOS_LOG("psxBios_%s: %x,%x,%x\n", biosB0n[0x35], a0, a1, a2);
-#endif
-
-       v0 = -1;
 
        switch (a0) {
-               case 2: buwrite(1); break;
-               case 3: buwrite(2); break;
+               case 2: buwrite(pa1, 1); break;
+               case 3: buwrite(pa1, 2); break;
        }
 
        pc0 = ra;
@@ -1810,7 +1844,7 @@ void psxBios_putchar() { // 3d
 }
 
 void psxBios_puts() { // 3e/3f
-       SysPrintf(Ra0);
+       SysPrintf("%s", Ra0);
        pc0 = ra;
 }
 
@@ -1826,7 +1860,8 @@ int nfile;
                if ((*ptr & 0xF0) != 0x50) continue; \
                ptr+= 0xa; \
                if (pfile[0] == 0) { \
-                       strcpy(dir->name, ptr); \
+                       strncpy(dir->name, ptr, sizeof(dir->name)); \
+                       dir->name[sizeof(dir->name) - 1] = '\0'; \
                } else for (i=0; i<20; i++) { \
                        if (pfile[i] == ptr[i]) { \
                                dir->name[i] = ptr[i]; \
@@ -1851,6 +1886,7 @@ int nfile;
  
 void psxBios_firstfile() { // 42
        struct DIRENTRY *dir = (struct DIRENTRY *)Ra1;
+       void *pa0 = Ra0;
        u32 _dir = a1;
        char *ptr;
        int i;
@@ -1861,18 +1897,19 @@ void psxBios_firstfile() { // 42
 
        v0 = 0;
 
-       strcpy(ffile, Ra0);
-       pfile = ffile+5;
-       nfile = 1;
-       if (!strncmp(Ra0, "bu00", 4)) {
-               bufile(1);
-               v0 = _dir;
+       if (pa0) {
+               strcpy(ffile, pa0);
+               pfile = ffile+5;
+               nfile = 1;
+               if (!strncmp(pa0, "bu00", 4)) {
+                       bufile(1);
+               } else if (!strncmp(pa0, "bu10", 4)) {
+                       bufile(2);
+               }
        }
 
-       if (!strncmp(Ra0, "bu10", 4)) {
-               bufile(2);
-               v0 = _dir;
-       }
+       // firstfile() calls _card_read() internally, so deliver it's event
+       DeliverEvent(0x11, 0x2);
 
        pc0 = ra;
 }
@@ -1926,6 +1963,8 @@ void psxBios_nextfile() { // 43
  */
 
 void psxBios_rename() { // 44
+       void *pa0 = Ra0;
+       void *pa1 = Ra1;
        char *ptr;
        int i;
 
@@ -1935,12 +1974,14 @@ void psxBios_rename() { // 44
 
        v0 = 0;
 
-       if (!strncmp(Ra0, "bu00", 4) && !strncmp(Ra1, "bu00", 4)) {
-               burename(1);
-       }
+       if (pa0 && pa1) {
+               if (!strncmp(pa0, "bu00", 4) && !strncmp(pa1, "bu00", 4)) {
+                       burename(1);
+               }
 
-       if (!strncmp(Ra0, "bu10", 4) && !strncmp(Ra1, "bu10", 4)) {
-               burename(2);
+               if (!strncmp(pa0, "bu10", 4) && !strncmp(pa1, "bu10", 4)) {
+                       burename(2);
+               }
        }
 
        pc0 = ra;
@@ -1965,6 +2006,7 @@ void psxBios_rename() { // 44
  */
 
 void psxBios_delete() { // 45
+       void *pa0 = Ra0;
        char *ptr;
        int i;
 
@@ -1974,12 +2016,14 @@ void psxBios_delete() { // 45
 
        v0 = 0;
 
-       if (!strncmp(Ra0, "bu00", 4)) {
-               budelete(1);
-       }
+       if (pa0) {
+               if (!strncmp(pa0, "bu00", 4)) {
+                       budelete(1);
+               }
 
-       if (!strncmp(Ra0, "bu10", 4)) {
-               budelete(2);
+               if (!strncmp(pa0, "bu10", 4)) {
+                       budelete(2);
+               }
        }
 
        pc0 = ra;
@@ -2016,20 +2060,24 @@ void psxBios_StopCARD() { // 4c
 }
 
 void psxBios__card_write() { // 0x4e
+       void *pa2 = Ra2;
        int port;
 
 #ifdef PSXBIOS_LOG
        PSXBIOS_LOG("psxBios_%s: %x,%x,%x\n", biosB0n[0x4e], a0, a1, a2);
 #endif
 
+       card_active_chan = a0;
        port = a0 >> 4;
 
-       if (port == 0) {
-               memcpy(Mcd1Data + a1 * 128, Ra2, 128);
-               SaveMcd(Config.Mcd1, Mcd1Data, a1 * 128, 128);
-       } else {
-               memcpy(Mcd2Data + a1 * 128, Ra2, 128);
-               SaveMcd(Config.Mcd2, Mcd2Data, a1 * 128, 128);
+       if (pa2) {
+               if (port == 0) {
+                       memcpy(Mcd1Data + a1 * 128, pa2, 128);
+                       SaveMcd(Config.Mcd1, Mcd1Data, a1 * 128, 128);
+               } else {
+                       memcpy(Mcd2Data + a1 * 128, pa2, 128);
+                       SaveMcd(Config.Mcd2, Mcd2Data, a1 * 128, 128);
+               }
        }
 
        DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
@@ -2039,18 +2087,22 @@ void psxBios__card_write() { // 0x4e
 }
 
 void psxBios__card_read() { // 0x4f
+       void *pa2 = Ra2;
        int port;
 
 #ifdef PSXBIOS_LOG
        PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x4f]);
 #endif
 
+       card_active_chan = a0;
        port = a0 >> 4;
 
-       if (port == 0) {
-               memcpy(Ra2, Mcd1Data + a1 * 128, 128);
-       } else {
-               memcpy(Ra2, Mcd2Data + a1 * 128, 128);
+       if (pa2) {
+               if (port == 0) {
+                       memcpy(pa2, Mcd1Data + a1 * 128, 128);
+               } else {
+                       memcpy(pa2, Mcd2Data + a1 * 128, 128);
+               }
        }
 
        DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
@@ -2126,6 +2178,15 @@ void psxBios_GetB0Table() { // 57
        v0 = 0x874; pc0 = ra;
 }
 
+void psxBios__card_chan() { // 0x58
+#ifdef PSXBIOS_LOG
+       PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x58]);
+#endif
+
+       v0 = card_active_chan;
+       pc0 = ra;
+}
+
 void psxBios_ChangeClearPad() { // 5b
 #ifdef PSXBIOS_LOG
        PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x5b], a0);
@@ -2483,7 +2544,7 @@ void psxBiosInit() {
        //biosB0[0x55] = psxBios__get_error;
        biosB0[0x56] = psxBios_GetC0Table;
        biosB0[0x57] = psxBios_GetB0Table;
-       //biosB0[0x58] = psxBios__card_chan;
+       biosB0[0x58] = psxBios__card_chan;
        //biosB0[0x59] = psxBios_sys_b0_59;
        //biosB0[0x5a] = psxBios_sys_b0_5a;
        biosB0[0x5b] = psxBios_ChangeClearPad;
@@ -2542,6 +2603,17 @@ void psxBiosInit() {
        memset(Thread, 0, sizeof(Thread));
        Thread[0].status = 2; // main thread
 
+       jmp_int = NULL;
+       pad_buf = NULL;
+       pad_buf1 = NULL;
+       pad_buf2 = NULL;
+       pad_buf1len = pad_buf2len = 0;
+       heap_addr = NULL;
+       heap_end = NULL;
+       CardState = -1;
+       CurThread = 0;
+       memset(FDesc, 0, sizeof(FDesc));
+
        psxMu32ref(0x0150) = SWAPu32(0x160);
        psxMu32ref(0x0154) = SWAPu32(0x320);
        psxMu32ref(0x0160) = SWAPu32(0x248);
@@ -2807,4 +2879,5 @@ void psxBiosFreeze(int Mode) {
        bfreezes(Thread);
        bfreezel(&CurThread);
        bfreezes(FDesc);
+       bfreezel(&card_active_chan);
 }