+#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); \
+ if (FDesc[1 + mcd].mode & 0x8000) { \
+ DeliverEvent(0x11, 0x2); /* 0xf0000011, 0x0004 */ \
+ DeliverEvent(0x81, 0x2); /* 0xf4000001, 0x0004 */ \
+ 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); \
+ FDesc[1 + mcd].offset += length; \
+ SaveMcd(Config.Mcd##mcd, Mcd##mcd##Data, offset, length); \
+ if (FDesc[1 + mcd].mode & 0x8000) { \
+ DeliverEvent(0x11, 0x2); /* 0xf0000011, 0x0004 */ \
+ DeliverEvent(0x81, 0x2); /* 0xf4000001, 0x0004 */ \
+ 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 != INVALID_PTR) {
+ 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 == INVALID_PTR) {
+ 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;
+}
+