X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fpsxbios.c;h=924996a31615748b16bce9439f0711a01211e6a7;hp=292d80d6cab80df9b756c0c453d8df4fcad738a6;hb=ba11675ca958088f3c5c1e60a5d437f0c1683514;hpb=5ec7acdfb1bc4c3da372f7f8e1a0a1022becce21 diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c index 292d80d6..924996a3 100644 --- a/libpcsxcore/psxbios.c +++ b/libpcsxcore/psxbios.c @@ -316,6 +316,85 @@ static inline void LoadRegs() { // * // System calls A0 */ +/* 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. */ +/* TODO FIX ME : Properly implement this behaviour */ +void psxBios_getc(void) // 0x03, 0x35 +{ + void *pa1 = Ra1; +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x03]); +#endif + v0 = -1; + + if (pa1) { + switch (a0) { + case 2: buread(pa1, 1, 1); break; + case 3: buread(pa1, 2, 1); break; + } + } + + pc0 = ra; +} + +/* Copy of psxBios_write, except size is 1. */ +void psxBios_putc(void) // 0x09, 0x3B +{ + void *pa1 = Ra1; +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x09]); +#endif + v0 = -1; + if (!pa1) { + pc0 = ra; + return; + } + + if (a0 == 1) { // stdout + char *ptr = (char *)pa1; + + v0 = a2; + while (a2 > 0) { + printf("%c", *ptr++); a2--; + } + pc0 = ra; return; + } + + switch (a0) { + case 2: buwrite(pa1, 1, 1); break; + case 3: buwrite(pa1, 2, 1); break; + } + + pc0 = ra; +} + +void psxBios_todigit(void) // 0x0a +{ + int c = a0; +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x0a]); +#endif + c &= 0xFF; + if (c >= 0x30 && c < 0x3A) { + c -= 0x30; + } + else if (c > 0x60 && c < 0x7B) { + c -= 0x20; + } + else if (c > 0x40 && c < 0x5B) { + c = c - 0x41 + 10; + } + else if (c >= 0x80) { + c = -1; + } + else + { + c = 0x0098967F; + } + v0 = c; + pc0 = ra; +} void psxBios_abs() { // 0x0e if ((s32)a0 < 0) v0 = -(s32)a0; @@ -394,7 +473,12 @@ void psxBios_strcat() { // 0x15 #ifdef PSXBIOS_LOG PSXBIOS_LOG("psxBios_%s: %s, %s\n", biosA0n[0x15], Ra0, Ra1); #endif - + if (a0 == 0 || a1 == 0) + { + v0 = 0; + pc0 = ra; + return; + } while (*p1++); --p1; while ((*p1++ = *p2++) != '\0'); @@ -1186,7 +1270,7 @@ void psxBios_sys_a0_4c() { // 0x4c GPU relate GPU_writeData(0x0400000); GPU_writeData(0x0200000); GPU_writeData(0x0100000); - + v0 = 0x1f801814; pc0 = ra; } @@ -1274,11 +1358,29 @@ void psxBios__card_info() { // ab #ifdef PSXBIOS_LOG PSXBIOS_LOG("psxBios_%s: %x\n", biosA0n[0xab], a0); #endif - + u32 ret; card_active_chan = a0; + switch (card_active_chan) + { + case 0x00: case 0x01: case 0x02: case 0x03: + ret = Config.Mcd1[0] ? 0x2 : 0x8; + break; + case 0x10: case 0x11: case 0x12: case 0x13: + ret = Config.Mcd2[0] ? 0x2 : 0x8; + break; + default: +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("psxBios_%s: UNKNOWN PORT 0x%x\n", biosA0n[0xab], card_active_chan); +#endif + ret = 0x11; + break; + } + +// DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004 // DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004 DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004 + DeliverEvent(0x81, ret); // 0xf4000001, 0x0004 v0 = 1; pc0 = ra; } @@ -1608,10 +1710,17 @@ void psxBios_PAD_init() { // 15 #ifdef PSXBIOS_LOG PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x15]); #endif + if (!(a0 == 0x20000000 || a0 == 0x20000001)) + { + v0 = 0; + pc0 = ra; + return; + } psxHwWrite16(0x1f801074, (u16)(psxHwRead16(0x1f801074) | 0x1)); pad_buf = (int *)Ra1; *pad_buf = -1; psxRegs.CP0.n.Status |= 0x401; + v0 = 2; pc0 = ra; } @@ -1669,43 +1778,70 @@ void psxBios_UnDeliverEvent() { // 0x20 pc0 = ra; } -#define buopen(mcd) { \ - strcpy(FDesc[1 + mcd].name, Ra0+5); \ - FDesc[1 + mcd].offset = 0; \ - FDesc[1 + mcd].mode = a1; \ - \ - for (i=1; i<16; i++) { \ - ptr = Mcd##mcd##Data + 128 * i; \ - if ((*ptr & 0xF0) != 0x50) continue; \ - if (strcmp(FDesc[1 + mcd].name, ptr+0xa)) continue; \ - FDesc[1 + mcd].mcfile = i; \ - SysPrintf("open %s\n", ptr+0xa); \ - v0 = 1 + mcd; \ - break; \ - } \ - if (a1 & 0x200 && v0 == -1) { /* FCREAT */ \ - for (i=1; i<16; i++) { \ - int j, xor = 0; \ - \ - ptr = Mcd##mcd##Data + 128 * i; \ - if ((*ptr & 0xF0) == 0x50) continue; \ - ptr[0] = 0x50 | (u8)(a1 >> 16); \ - ptr[4] = 0x00; \ - ptr[5] = 0x20; \ - ptr[6] = 0x00; \ - ptr[7] = 0x00; \ - ptr[8] = 'B'; \ - ptr[9] = 'I'; \ - strcpy(ptr+0xa, FDesc[1 + mcd].name); \ - for (j=0; j<127; j++) xor^= ptr[j]; \ - ptr[127] = xor; \ - FDesc[1 + mcd].mcfile = i; \ - SysPrintf("openC %s\n", ptr); \ - v0 = 1 + mcd; \ - SaveMcd(Config.Mcd##mcd, Mcd##mcd##Data, 128 * i, 128); \ - break; \ - } \ - } \ +char ffile[64], *pfile; +int nfile; +static void buopen(int mcd, u8 *ptr, u8 *cfg) +{ + int i; + u8 *fptr = ptr; + + strcpy(FDesc[1 + mcd].name, Ra0+5); + FDesc[1 + mcd].offset = 0; + FDesc[1 + mcd].mode = a1; + + for (i=1; i<16; i++) { + fptr += 128; + 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); + v0 = 1 + mcd; + break; + } + if (a1 & 0x200 && v0 == -1) { /* FCREAT */ + fptr = ptr; + for (i=1; i<16; i++) { + int j, xor, nblk = a1 >> 16; + u8 *pptr, *fptr2; + + fptr += 128; + if ((*fptr & 0xF0) != 0xa0) continue; + + FDesc[1 + mcd].mcfile = i; + fptr[0] = 0x51; + fptr[4] = 0x00; + fptr[5] = 0x20 * nblk; + fptr[6] = 0x00; + fptr[7] = 0x00; + strcpy(fptr+0xa, FDesc[1 + mcd].name); + pptr = fptr2 = fptr; + for(j=2; j<=nblk; j++) { + int k; + for(i++; i<16; i++) { + fptr2 += 128; + + memset(fptr2, 0, 128); + fptr2[0] = j < nblk ? 0x52 : 0x53; + pptr[8] = i - 1; + pptr[9] = 0; + for (k=0, xor=0; k<127; k++) xor^= pptr[k]; + pptr[127] = xor; + pptr = fptr2; + break; + } + /* shouldn't this return ENOSPC if i == 16? */ + } + 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); + v0 = 1 + mcd; + /* just go ahead and resave them all */ + SaveMcd(cfg, ptr, 128, 128 * 15); + break; + } + /* shouldn't this return ENOSPC if i == 16? */ + } } /* @@ -1725,11 +1861,11 @@ void psxBios_open() { // 0x32 if (pa0) { if (!strncmp(pa0, "bu00", 4)) { - buopen(1); + buopen(1, Mcd1Data, Config.Mcd1); } if (!strncmp(pa0, "bu10", 4)) { - buopen(2); + buopen(2, Mcd2Data, Config.Mcd2); } } @@ -1762,17 +1898,19 @@ void psxBios_lseek() { // 0x33 pc0 = ra; } -#define buread(Ra1, mcd) { \ +#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); \ ptr = Mcd##mcd##Data + 8192 * FDesc[1 + mcd].mcfile + FDesc[1 + mcd].offset; \ - memcpy(Ra1, ptr, a2); \ - if (FDesc[1 + mcd].mode & 0x8000) v0 = 0; \ - else v0 = a2; \ - FDesc[1 + mcd].offset += v0; \ + memcpy(Ra1, ptr, length); \ DeliverEvent(0x11, 0x2); /* 0xf0000011, 0x0004 */ \ DeliverEvent(0x81, 0x2); /* 0xf4000001, 0x0004 */ \ + if (FDesc[1 + mcd].mode & 0x8000) v0 = 0; \ + else v0 = length; \ + FDesc[1 + mcd].offset += v0; \ } + + /* * int read(int fd , void *buf , int nbytes); */ @@ -1789,25 +1927,24 @@ void psxBios_read() { // 0x34 if (pa1) { switch (a0) { - case 2: buread(pa1, 1); break; - case 3: buread(pa1, 2); break; + case 2: buread(pa1, 1, a2); break; + case 3: buread(pa1, 2, a2); break; } } pc0 = ra; } -#define buwrite(Ra1, mcd) { \ +#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); \ ptr = Mcd##mcd##Data + offset; \ - memcpy(ptr, Ra1, a2); \ - FDesc[1 + mcd].offset += a2; \ - SaveMcd(Config.Mcd##mcd, Mcd##mcd##Data, offset, a2); \ - if (FDesc[1 + mcd].mode & 0x8000) v0 = 0; \ - else v0 = a2; \ + memcpy(ptr, Ra1, length); \ DeliverEvent(0x11, 0x2); /* 0xf0000011, 0x0004 */ \ DeliverEvent(0x81, 0x2); /* 0xf4000001, 0x0004 */ \ + FDesc[1 + mcd].offset += length; \ + if (FDesc[1 + mcd].mode & 0x8000) v0 = 0; \ + else v0 = length; \ } /* @@ -1839,8 +1976,8 @@ void psxBios_write() { // 0x35/0x03 } switch (a0) { - case 2: buwrite(pa1, 1); break; - case 3: buwrite(pa1, 2); break; + case 2: buwrite(pa1, 1, a2); break; + case 3: buwrite(pa1, 2, a2); break; } pc0 = ra; @@ -1876,17 +2013,18 @@ int nfile; while (nfile < 16) { \ int match=1; \ \ - ptr = Mcd##mcd##Data + 128 * nfile; \ + ptr = Mcd##mcd##Data + 128 * (nfile + 1); \ nfile++; \ if ((*ptr & 0xF0) != 0x50) continue; \ + /* Bug link files show up as free block. */ \ + if (!ptr[0xa]) continue; \ ptr+= 0xa; \ if (pfile[0] == 0) { \ 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]; \ - if (ptr[i] == 0) break; else continue; } \ + dir->name[i] = ptr[i]; continue; } \ if (pfile[i] == '?') { \ dir->name[i] = ptr[i]; continue; } \ if (pfile[i] == '*') { \ @@ -1894,7 +2032,7 @@ int nfile; match = 0; break; \ } \ SysPrintf("%d : %s = %s + %s (match=%d)\n", nfile, dir->name, pfile, ptr, match); \ - if (match == 0) continue; \ + if (match == 0) { continue; } \ dir->size = 8192; \ v0 = _dir; \ break; \ @@ -2087,7 +2225,13 @@ void psxBios__card_write() { // 0x4e #ifdef PSXBIOS_LOG PSXBIOS_LOG("psxBios_%s: %x,%x,%x\n", biosB0n[0x4e], a0, a1, a2); #endif - + /* Function also accepts sector 400h (a bug) */ + if (!(a1 <= 0x400)) + { + /* Invalid sectors */ + v0 = 0; pc0 = ra; + return; + } card_active_chan = a0; port = a0 >> 4; @@ -2114,7 +2258,13 @@ void psxBios__card_read() { // 0x4f #ifdef PSXBIOS_LOG PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x4f]); #endif - + /* Function also accepts sector 400h (a bug) */ + if (!(a1 <= 0x400)) + { + /* Invalid sectors */ + v0 = 0; pc0 = ra; + return; + } card_active_chan = a0; port = a0 >> 4; @@ -2307,9 +2457,9 @@ void psxBiosInit() { //biosA0[0x05] = psxBios_ioctl; //biosA0[0x06] = psxBios_exit; //biosA0[0x07] = psxBios_sys_a0_07; - //biosA0[0x08] = psxBios_getc; - //biosA0[0x09] = psxBios_putc; - //biosA0[0x0a] = psxBios_todigit; + biosA0[0x08] = psxBios_getc; + biosA0[0x09] = psxBios_putc; + biosA0[0x0a] = psxBios_todigit; //biosA0[0x0b] = psxBios_atof; //biosA0[0x0c] = psxBios_strtoul; //biosA0[0x0d] = psxBios_strtol; @@ -2836,8 +2986,9 @@ void psxBiosException() { #endif switch (a0) { case 1: // EnterCritical - disable irq's - psxRegs.CP0.n.Status &= ~0x404; -v0=1; // HDHOSHY experimental patch: Spongebob, Coldblood, fearEffect, Medievil2, Martian Gothic + /* Fixes Medievil 2 not loading up new game, Digimon World not booting up and possibly others */ + v0 = (psxRegs.CP0.n.Status & 0x404) == 0x404; + psxRegs.CP0.n.Status &= ~0x404; break; case 2: // ExitCritical - enable irq's