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];
void psxBios_strcmp() { // 0x17
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
-
+ s32 n=0;
+ if (a0 == 0 && a1 == 0)
+ {
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
+ else if (a0 == 0 && a1 != 0)
+ {
+ v0 = -1;
+ pc0 = ra;
+ return;
+ }
+ else if (a0 != 0 && a1 == 0)
+ {
+ v0 = 1;
+ pc0 = ra;
+ return;
+ }
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s: %s (%x), %s (%x)\n", biosA0n[0x17], Ra0, a0, Ra1, a1);
#endif
while (*p1 == *p2++) {
+ n++;
if (*p1++ == '\0') {
+ v1=n-1;
+ a0+=n;
+ a1+=n;
v0 = 0;
pc0 = ra;
return;
}
v0 = (*p1 - *--p2);
+ v1 = n;
+ a0+=n;
+ a1+=n;
pc0 = ra;
}
void psxBios_bzero() { // 0x28
char *p = (char *)Ra0;
+ v0 = a0;
+ /* Same as memset here (See memset below) */
+ if (a1 > 0x7FFFFFFF || a1 == 0)
+ {
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
+ else if (a0 == 0)
+ {
+ pc0 = ra;
+ return;
+ }
while ((s32)a1-- > 0) *p++ = '\0';
+ a1 = 0;
pc0 = ra;
}
void psxBios_memcpy() { // 0x2a
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
- while ((s32)a2-- > 0) *p1++ = *p2++;
-
- v0 = a0; pc0 = ra;
+ s32 n=0;
+ v0 = a0;
+ if (a0 == 0 || a2 > 0x7FFFFFFF)
+ {
+ pc0 = ra;
+ return;
+ }
+ while ((s32)a2-- > 0) {
+ n++;
+ *p1++ = *p2++;
+ }
+ a2 = 0;
+ pc0 = ra;
}
void psxBios_memset() { // 0x2b
char *p = (char *)Ra0;
+ v0 = a0;
+ if (a2 > 0x7FFFFFFF || a2 == 0)
+ {
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
+ if (a0 == 0)
+ {
+ pc0 = ra;
+ return;
+ }
while ((s32)a2-- > 0) *p++ = (char)a1;
-
a2 = 0;
v0 = a0; pc0 = ra;
}
void psxBios_memmove() { // 0x2c
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
-
+ v0 = a0;
+ if (a0 == 0 || a2 > 0x7FFFFFFF)
+ {
+ pc0 = ra;
+ return;
+ }
if (p2 <= p1 && p2 + a2 > p1) {
a2++; // BUG: copy one more byte here
p1 += a2;
} else {
while ((s32)a2-- > 0) *p1++ = *p2++;
}
-
- v0 = a0; pc0 = ra;
+ pc0 = ra;
}
void psxBios_memcmp() { // 0x2d
#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;
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) {
// 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);
}
// 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;
}
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;
//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;
pad_buf1len = pad_buf2len = 0;
heap_addr = NULL;
heap_end = NULL;
+ heap_size = 0;
CardState = -1;
CurThread = 0;
memset(FDesc, 0, sizeof(FDesc));