X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fpsxbios.c;h=df0550e8d71de0d770fe01a2d3aec3c41960b365;hb=002b2f7d98f8c543cd88cb453c88b09eb5e556ad;hp=399df9a4c61421ce256703446b828e6abb94abd6;hpb=112dddf5f26989d55b257f51bdcb9236bc7c1de0;p=pcsx_rearmed.git diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c index 399df9a4..df0550e8 100644 --- a/libpcsxcore/psxbios.c +++ b/libpcsxcore/psxbios.c @@ -254,6 +254,7 @@ static EvCB *RcEV; // 0xf2 static EvCB *UeEV; // 0xf3 static EvCB *SwEV; // 0xf4 static EvCB *ThEV; // 0xff +static u32 heap_size = 0; static u32 *heap_addr = NULL; static u32 *heap_end = NULL; static u32 SysIntRP[8]; @@ -983,6 +984,11 @@ void psxBios_malloc() { // 0x33 #ifdef PSXBIOS_LOG PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x33]); #endif + if (!a0 || (!heap_size || !heap_addr)) { + v0 = 0; + pc0 = ra; + return; + } // scan through heap and combine free chunks of space chunk = heap_addr; @@ -992,6 +998,15 @@ void psxBios_malloc() { // 0x33 csize = ((u32)*chunk) & 0xfffffffc; cstat = ((u32)*chunk) & 1; + // most probably broken heap descriptor + // this fixes Burning Road + if (*chunk == 0) { + newchunk = chunk; + dsize = ((uptr)heap_end - (uptr)chunk) - 4; + colflag = 1; + break; + } + // it's a free chunk if(cstat == 1) { if(colflag == 0) { @@ -1023,28 +1038,36 @@ void psxBios_malloc() { // 0x33 // exit on uninitialized heap if (chunk == NULL) { - SysPrintf("malloc %x,%x: Uninitialized Heap!\n", v0, a0); + printf("malloc %x,%x: Uninitialized Heap!\n", v0, a0); v0 = 0; pc0 = ra; return; } // search an unused chunk that is big enough until the end of the heap - while ((dsize > csize || cstat == 0) && chunk < heap_end ) { + while ((dsize > csize || cstat==0) && chunk < heap_end ) { chunk = (u32*)((uptr)chunk + csize + 4); + + // catch out of memory + if(chunk >= heap_end) { + printf("malloc %x,%x: Out of memory error!\n", + v0, a0); + v0 = 0; pc0 = ra; + return; + } + csize = ((u32)*chunk) & 0xfffffffc; cstat = ((u32)*chunk) & 1; } - // catch out of memory - if(chunk >= heap_end) { SysPrintf("malloc %x,%x: Out of memory error!\n", v0, a0); v0 = 0; pc0 = ra; return; } - // allocate memory if(dsize == csize) { // chunk has same size *chunk &= 0xfffffffc; - } - else { + } else if (dsize > csize) { + v0 = 0; pc0 = ra; + return; + } else { // split free chunk *chunk = SWAP32(dsize); newchunk = (u32*)((uptr)chunk + dsize + 4); @@ -1052,9 +1075,9 @@ void psxBios_malloc() { // 0x33 } // return pointer to allocated memory - v0 = ((unsigned long)chunk - (unsigned long)psxM) + 4; + v0 = ((uptr)chunk - (uptr)psxM) + 4; v0|= 0x80000000; - SysPrintf ("malloc %x,%x\n", v0, a0); + //printf ("malloc %x,%x\n", v0, a0); pc0 = ra; } @@ -2394,6 +2417,13 @@ void psxBios__new_card() { // 0x50 pc0 = ra; } +/* According to a user, this allows Final Fantasy Tactics to save/load properly */ +void psxBios__get_error(void) // 55 +{ + v0 = 0; + pc0 = ra; +} + void psxBios_Krom2RawAdd() { // 0x51 int i = 0; @@ -2816,7 +2846,7 @@ void psxBiosInit() { //biosB0[0x52] = psxBios_sys_b0_52; //biosB0[0x53] = psxBios_sys_b0_53; //biosB0[0x54] = psxBios__get_errno; - //biosB0[0x55] = psxBios__get_error; + biosB0[0x55] = psxBios__get_error; biosB0[0x56] = psxBios_GetC0Table; biosB0[0x57] = psxBios_GetB0Table; biosB0[0x58] = psxBios__card_chan; @@ -2885,6 +2915,7 @@ void psxBiosInit() { pad_buf1len = pad_buf2len = 0; heap_addr = NULL; heap_end = NULL; + heap_size = 0; CardState = -1; CurThread = 0; memset(FDesc, 0, sizeof(FDesc));