// System calls A0 */
+#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, 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; \
+}
+
+#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, 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; \
+}
+
+
+/* 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
+{
+ char *ptr;
+ 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
+{
+ char *ptr;
+ 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;
else v0 = a0;
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s: %s (%x), %s (%x), %d\n", biosA0n[0x16], Ra0, a0, Ra1, a1, a2);
#endif
-
+ if (a0 == 0 || a1 == 0)
+ {
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
while (*p1++);
--p1;
while ((*p1++ = *p2++) != '\0') {
void psxBios_index() { // 0x1c
char *p = (char *)Ra0;
-
+ if (a0 == 0)
+ {
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
+
do {
if (*p == a1) {
v0 = a0 + (p - (char *)Ra0);
char *p = (char *)Ra0;
v0 = 0;
-
+ if (a0 == 0)
+ {
+ pc0 = ra;
+ return;
+ }
do {
if (*p == a1)
v0 = a0 + (p - (char *)Ra0);
void psxBios_bcopy() { // 0x27
char *p1 = (char *)Ra1, *p2 = (char *)Ra0;
+ v0 = a0;
+ if (a0 == 0 || a2 > 0x7FFFFFFF)
+ {
+ pc0 = ra;
+ return;
+ }
while ((s32)a2-- > 0) *p1++ = *p2++;
-
+ a2 = 0;
pc0 = ra;
}
void psxBios_bzero() { // 0x28
char *p = (char *)Ra0;
while ((s32)a1-- > 0) *p++ = '\0';
-
pc0 = ra;
}
#endif
a0 = block;
- psxBios_free();
- a0 = size;
- psxBios_malloc();
+ /* If "old_buf" is zero, executes malloc(new_size), and returns r2=new_buf (or 0=failed). */
+ if (block == 0)
+ {
+ psxBios_malloc();
+ }
+ /* Else, if "new_size" is zero, executes free(old_buf), and returns r2=garbage. */
+ else if (size == 0)
+ {
+ psxBios_free();
+ }
+ /* Else, executes malloc(new_size), bcopy(old_buf,new_buf,new_size), and free(old_buf), and returns r2=new_buf (or 0=failed). */
+ /* Note that it is not quite implemented this way here. */
+ else
+ {
+ psxBios_free();
+ a0 = size;
+ psxBios_malloc();
+ }
}
ev = a0 & 0xff;
spec = (a0 >> 8) & 0xff;
-
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0a], ev, spec);
#endif
+ if (Event[ev][spec].status == EvStUNUSED)
+ {
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
- Event[ev][spec].status = EvStACTIVE;
+ if (Event[ev][spec].status == EvStALREADY)
+ {
+ /* Callback events (mode=EvMdINTR) do never set the ready flag (and thus WaitEvent would hang forever). */
+ if (!(Event[ev][spec].mode == EvMdINTR)) Event[ev][spec].status = EvStACTIVE;
+ v0 = 1;
+ pc0 = ra;
+ return;
+ }
- v0 = 1; pc0 = ra;
+ v0 = 0;
+ pc0 = ra;
}
void psxBios_TestEvent() { // 0b
int th;
for (th=1; th<8; th++)
+ {
if (Thread[th].status == 0) break;
+ }
+ if (th == 8) {
+ // Feb 2019 - Added out-of-bounds fix caught by cppcheck:
+ // When no free TCB is found, return 0xffffffff according to Nocash doc.
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("\t%s() WARNING! No Free TCBs found!\n", __func__);
+#endif
+ v0 = 0xffffffff;
+ pc0 = ra;
+ return;
+ }
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x0e], th);
#endif
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x14]);
#endif
-
+ if (pad_buf == 0){
pad_buf1 = NULL;
pad_buf2 = NULL;
+ }
pc0 = ra;
}
pc0 = ra;
}
-#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, 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);
pc0 = ra;
}
-#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, 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; \
-}
-
/*
* int write(int fd , void *buf , int nbytes);
*/
pfile = ffile+5;
nfile = 1;
if (!strncmp(pa0, "bu00", 4)) {
+ // firstfile() calls _card_read() internally, so deliver it's event
+ DeliverEvent(0x11, 0x2);
bufile(1);
} else if (!strncmp(pa0, "bu10", 4)) {
+ // firstfile() calls _card_read() internally, so deliver it's event
+ DeliverEvent(0x11, 0x2);
bufile(2);
}
}
- // firstfile() calls _card_read() internally, so deliver it's event
- DeliverEvent(0x11, 0x2);
-
pc0 = ra;
}
//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;