fix some issues and warnings seen on ctr build
[pcsx_rearmed.git] / libpcsxcore / psxbios.c
CommitLineData
ef79bbde 1/***************************************************************************
8254b5a7 2 * Copyright (C) 2019 Ryan Schultz, PCSX-df Team, PCSX team, gameblabla, *
3 * dmitrysmagin, senquack *
ef79bbde
P
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
19 ***************************************************************************/
20
8254b5a7 21/* Gameblabla 2018-2019 :
22 * Numerous changes to bios calls as well as improvements in order to conform to nocash's findings
23 * for the PSX bios calls. Thanks senquack for helping out with some of the changes
24 * and helping to spot issues and refine my patches.
25 * */
26
ef79bbde
P
27/*
28 * Internal simulated HLE BIOS.
29 */
30
31// TODO: implement all system calls, count the exact CPU cycles of system calls.
32
33#include "psxbios.h"
34#include "psxhw.h"
ddbaf678 35#include "gpu.h"
496d88d4 36#include <zlib.h>
ef79bbde 37
3cf51e08 38#if (defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)
39#pragma GCC diagnostic ignored "-Wpointer-sign"
40#endif
41
452b85f9 42#undef SysPrintf
43#define SysPrintf if (Config.PsxOut) printf
44
ef79bbde
P
45char *biosA0n[256] = {
46// 0x00
47 "open", "lseek", "read", "write",
48 "close", "ioctl", "exit", "sys_a0_07",
49 "getc", "putc", "todigit", "atof",
50 "strtoul", "strtol", "abs", "labs",
51// 0x10
52 "atoi", "atol", "atob", "setjmp",
53 "longjmp", "strcat", "strncat", "strcmp",
54 "strncmp", "strcpy", "strncpy", "strlen",
55 "index", "rindex", "strchr", "strrchr",
56// 0x20
57 "strpbrk", "strspn", "strcspn", "strtok",
58 "strstr", "toupper", "tolower", "bcopy",
59 "bzero", "bcmp", "memcpy", "memset",
60 "memmove", "memcmp", "memchr", "rand",
61// 0x30
62 "srand", "qsort", "strtod", "malloc",
63 "free", "lsearch", "bsearch", "calloc",
64 "realloc", "InitHeap", "_exit", "getchar",
65 "putchar", "gets", "puts", "printf",
66// 0x40
67 "sys_a0_40", "LoadTest", "Load", "Exec",
68 "FlushCache", "InstallInterruptHandler", "GPU_dw", "mem2vram",
69 "SendGPUStatus", "GPU_cw", "GPU_cwb", "SendPackets",
70 "sys_a0_4c", "GetGPUStatus", "GPU_sync", "sys_a0_4f",
71// 0x50
72 "sys_a0_50", "LoadExec", "GetSysSp", "sys_a0_53",
73 "_96_init()", "_bu_init()", "_96_remove()", "sys_a0_57",
74 "sys_a0_58", "sys_a0_59", "sys_a0_5a", "dev_tty_init",
75 "dev_tty_open", "sys_a0_5d", "dev_tty_ioctl","dev_cd_open",
76// 0x60
77 "dev_cd_read", "dev_cd_close", "dev_cd_firstfile", "dev_cd_nextfile",
78 "dev_cd_chdir", "dev_card_open", "dev_card_read", "dev_card_write",
79 "dev_card_close", "dev_card_firstfile", "dev_card_nextfile","dev_card_erase",
80 "dev_card_undelete","dev_card_format", "dev_card_rename", "dev_card_6f",
81// 0x70
82 "_bu_init", "_96_init", "_96_remove", "sys_a0_73",
83 "sys_a0_74", "sys_a0_75", "sys_a0_76", "sys_a0_77",
84 "_96_CdSeekL", "sys_a0_79", "sys_a0_7a", "sys_a0_7b",
85 "_96_CdGetStatus", "sys_a0_7d", "_96_CdRead", "sys_a0_7f",
86// 0x80
87 "sys_a0_80", "sys_a0_81", "sys_a0_82", "sys_a0_83",
88 "sys_a0_84", "_96_CdStop", "sys_a0_86", "sys_a0_87",
89 "sys_a0_88", "sys_a0_89", "sys_a0_8a", "sys_a0_8b",
90 "sys_a0_8c", "sys_a0_8d", "sys_a0_8e", "sys_a0_8f",
91// 0x90
92 "sys_a0_90", "sys_a0_91", "sys_a0_92", "sys_a0_93",
93 "sys_a0_94", "sys_a0_95", "AddCDROMDevice", "AddMemCardDevide",
94 "DisableKernelIORedirection", "EnableKernelIORedirection", "sys_a0_9a", "sys_a0_9b",
95 "SetConf", "GetConf", "sys_a0_9e", "SetMem",
96// 0xa0
97 "_boot", "SystemError", "EnqueueCdIntr", "DequeueCdIntr",
98 "sys_a0_a4", "ReadSector", "get_cd_status", "bufs_cb_0",
99 "bufs_cb_1", "bufs_cb_2", "bufs_cb_3", "_card_info",
100 "_card_load", "_card_auto", "bufs_cd_4", "sys_a0_af",
101// 0xb0
102 "sys_a0_b0", "sys_a0_b1", "do_a_long_jmp", "sys_a0_b3",
103 "?? sub_function",
104};
105
106char *biosB0n[256] = {
107// 0x00
108 "SysMalloc", "sys_b0_01", "sys_b0_02", "sys_b0_03",
109 "sys_b0_04", "sys_b0_05", "sys_b0_06", "DeliverEvent",
110 "OpenEvent", "CloseEvent", "WaitEvent", "TestEvent",
111 "EnableEvent", "DisableEvent", "OpenTh", "CloseTh",
112// 0x10
113 "ChangeTh", "sys_b0_11", "InitPAD", "StartPAD",
114 "StopPAD", "PAD_init", "PAD_dr", "ReturnFromExecption",
115 "ResetEntryInt", "HookEntryInt", "sys_b0_1a", "sys_b0_1b",
116 "sys_b0_1c", "sys_b0_1d", "sys_b0_1e", "sys_b0_1f",
117// 0x20
118 "UnDeliverEvent", "sys_b0_21", "sys_b0_22", "sys_b0_23",
119 "sys_b0_24", "sys_b0_25", "sys_b0_26", "sys_b0_27",
120 "sys_b0_28", "sys_b0_29", "sys_b0_2a", "sys_b0_2b",
121 "sys_b0_2c", "sys_b0_2d", "sys_b0_2e", "sys_b0_2f",
122// 0x30
123 "sys_b0_30", "sys_b0_31", "open", "lseek",
124 "read", "write", "close", "ioctl",
125 "exit", "sys_b0_39", "getc", "putc",
126 "getchar", "putchar", "gets", "puts",
127// 0x40
128 "cd", "format", "firstfile", "nextfile",
129 "rename", "delete", "undelete", "AddDevice",
130 "RemoteDevice", "PrintInstalledDevices", "InitCARD", "StartCARD",
131 "StopCARD", "sys_b0_4d", "_card_write", "_card_read",
132// 0x50
133 "_new_card", "Krom2RawAdd", "sys_b0_52", "sys_b0_53",
134 "_get_errno", "_get_error", "GetC0Table", "GetB0Table",
135 "_card_chan", "sys_b0_59", "sys_b0_5a", "ChangeClearPAD",
136 "_card_status", "_card_wait",
137};
138
139char *biosC0n[256] = {
140// 0x00
141 "InitRCnt", "InitException", "SysEnqIntRP", "SysDeqIntRP",
142 "get_free_EvCB_slot", "get_free_TCB_slot", "ExceptionHandler", "InstallExeptionHandler",
143 "SysInitMemory", "SysInitKMem", "ChangeClearRCnt", "SystemError",
144 "InitDefInt", "sys_c0_0d", "sys_c0_0e", "sys_c0_0f",
145// 0x10
146 "sys_c0_10", "sys_c0_11", "InstallDevices", "FlushStfInOutPut",
147 "sys_c0_14", "_cdevinput", "_cdevscan", "_circgetc",
148 "_circputc", "ioabort", "sys_c0_1a", "KernelRedirect",
149 "PatchAOTable",
150};
151
152//#define r0 (psxRegs.GPR.n.r0)
153#define at (psxRegs.GPR.n.at)
154#define v0 (psxRegs.GPR.n.v0)
155#define v1 (psxRegs.GPR.n.v1)
156#define a0 (psxRegs.GPR.n.a0)
157#define a1 (psxRegs.GPR.n.a1)
158#define a2 (psxRegs.GPR.n.a2)
159#define a3 (psxRegs.GPR.n.a3)
160#define t0 (psxRegs.GPR.n.t0)
161#define t1 (psxRegs.GPR.n.t1)
162#define t2 (psxRegs.GPR.n.t2)
163#define t3 (psxRegs.GPR.n.t3)
164#define t4 (psxRegs.GPR.n.t4)
165#define t5 (psxRegs.GPR.n.t5)
166#define t6 (psxRegs.GPR.n.t6)
167#define t7 (psxRegs.GPR.n.t7)
168#define t8 (psxRegs.GPR.n.t8)
169#define t9 (psxRegs.GPR.n.t9)
170#define s0 (psxRegs.GPR.n.s0)
171#define s1 (psxRegs.GPR.n.s1)
172#define s2 (psxRegs.GPR.n.s2)
173#define s3 (psxRegs.GPR.n.s3)
174#define s4 (psxRegs.GPR.n.s4)
175#define s5 (psxRegs.GPR.n.s5)
176#define s6 (psxRegs.GPR.n.s6)
177#define s7 (psxRegs.GPR.n.s7)
178#define k0 (psxRegs.GPR.n.k0)
179#define k1 (psxRegs.GPR.n.k1)
180#define gp (psxRegs.GPR.n.gp)
181#define sp (psxRegs.GPR.n.sp)
182#define fp (psxRegs.GPR.n.s8)
183#define ra (psxRegs.GPR.n.ra)
184#define pc0 (psxRegs.pc)
185
186#define Ra0 ((char *)PSXM(a0))
187#define Ra1 ((char *)PSXM(a1))
188#define Ra2 ((char *)PSXM(a2))
189#define Ra3 ((char *)PSXM(a3))
190#define Rv0 ((char *)PSXM(v0))
191#define Rsp ((char *)PSXM(sp))
192
193typedef struct {
194 u32 desc;
195 s32 status;
196 s32 mode;
197 u32 fhandler;
198} EvCB[32];
199
200#define EvStUNUSED 0x0000
201#define EvStWAIT 0x1000
202#define EvStACTIVE 0x2000
203#define EvStALREADY 0x4000
204
205#define EvMdINTR 0x1000
206#define EvMdNOINTR 0x2000
207
208/*
209typedef struct {
210 s32 next;
211 s32 func1;
212 s32 func2;
213 s32 pad;
214} SysRPst;
215*/
216
217typedef struct {
218 s32 status;
219 s32 mode;
220 u32 reg[32];
221 u32 func;
222} TCB;
223
224typedef struct {
225 u32 _pc0;
226 u32 gp0;
227 u32 t_addr;
228 u32 t_size;
229 u32 d_addr;
230 u32 d_size;
231 u32 b_addr;
232 u32 b_size;
233 u32 S_addr;
234 u32 s_size;
235 u32 _sp, _fp, _gp, ret, base;
236} EXEC;
237
238struct DIRENTRY {
239 char name[20];
240 s32 attr;
241 s32 size;
242 u32 next;
243 s32 head;
244 char system[4];
245};
246
247typedef struct {
248 char name[32];
249 u32 mode;
250 u32 offset;
251 u32 size;
252 u32 mcfile;
253} FileDesc;
254
255static u32 *jmp_int = NULL;
256static int *pad_buf = NULL;
257static char *pad_buf1 = NULL, *pad_buf2 = NULL;
258static int pad_buf1len, pad_buf2len;
f25c285b 259static int pad_stopped = 0;
ef79bbde
P
260
261static u32 regs[35];
262static EvCB *Event;
263static EvCB *HwEV; // 0xf0
264static EvCB *EvEV; // 0xf1
265static EvCB *RcEV; // 0xf2
266static EvCB *UeEV; // 0xf3
267static EvCB *SwEV; // 0xf4
268static EvCB *ThEV; // 0xff
26b964b5 269static u32 heap_size = 0;
ef79bbde
P
270static u32 *heap_addr = NULL;
271static u32 *heap_end = NULL;
272static u32 SysIntRP[8];
273static int CardState = -1;
274static TCB Thread[8];
275static int CurThread = 0;
276static FileDesc FDesc[32];
e9fda093 277static u32 card_active_chan;
ef79bbde
P
278
279boolean hleSoftCall = FALSE;
280
281static inline void softCall(u32 pc) {
282 pc0 = pc;
283 ra = 0x80001000;
284
285 hleSoftCall = TRUE;
286
287 while (pc0 != 0x80001000) psxCpu->ExecuteBlock();
288
289 hleSoftCall = FALSE;
290}
291
292static inline void softCall2(u32 pc) {
293 u32 sra = ra;
294 pc0 = pc;
295 ra = 0x80001000;
296
297 hleSoftCall = TRUE;
298
299 while (pc0 != 0x80001000) psxCpu->ExecuteBlock();
300 ra = sra;
301
302 hleSoftCall = FALSE;
303}
304
305static inline void DeliverEvent(u32 ev, u32 spec) {
306 if (Event[ev][spec].status != EvStACTIVE) return;
307
308// Event[ev][spec].status = EvStALREADY;
309 if (Event[ev][spec].mode == EvMdINTR) {
310 softCall2(Event[ev][spec].fhandler);
311 } else Event[ev][spec].status = EvStALREADY;
312}
313
f23c2241 314static unsigned interrupt_r26=0x8004E8B0;
315
ef79bbde
P
316static inline void SaveRegs() {
317 memcpy(regs, psxRegs.GPR.r, 32*4);
318 regs[32] = psxRegs.GPR.n.lo;
319 regs[33] = psxRegs.GPR.n.hi;
320 regs[34] = psxRegs.pc;
321}
322
323static inline void LoadRegs() {
324 memcpy(psxRegs.GPR.r, regs, 32*4);
325 psxRegs.GPR.n.lo = regs[32];
326 psxRegs.GPR.n.hi = regs[33];
327}
328
329/* *
330// *
331// *
332// System calls A0 */
333
d99f6068 334
335#define buread(Ra1, mcd, length) { \
336 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); \
337 ptr = Mcd##mcd##Data + 8192 * FDesc[1 + mcd].mcfile + FDesc[1 + mcd].offset; \
338 memcpy(Ra1, ptr, length); \
f1514614 339 if (FDesc[1 + mcd].mode & 0x8000) { \
d99f6068 340 DeliverEvent(0x11, 0x2); /* 0xf0000011, 0x0004 */ \
341 DeliverEvent(0x81, 0x2); /* 0xf4000001, 0x0004 */ \
f1514614 342 v0 = 0; } \
d99f6068 343 else v0 = length; \
344 FDesc[1 + mcd].offset += v0; \
345}
346
347#define buwrite(Ra1, mcd, length) { \
348 u32 offset = + 8192 * FDesc[1 + mcd].mcfile + FDesc[1 + mcd].offset; \
349 SysPrintf("write %d: %x,%x\n", FDesc[1 + mcd].mcfile, FDesc[1 + mcd].offset, a2); \
350 ptr = Mcd##mcd##Data + offset; \
351 memcpy(ptr, Ra1, length); \
f1514614 352 FDesc[1 + mcd].offset += length; \
e49ac7a5 353 SaveMcd(Config.Mcd##mcd, Mcd##mcd##Data, offset, length); \
f1514614 354 if (FDesc[1 + mcd].mode & 0x8000) { \
d99f6068 355 DeliverEvent(0x11, 0x2); /* 0xf0000011, 0x0004 */ \
356 DeliverEvent(0x81, 0x2); /* 0xf4000001, 0x0004 */ \
f1514614 357 v0 = 0; } \
d99f6068 358 else v0 = length; \
359}
360
361
324cec89 362/* Internally redirects to "FileRead(fd,tempbuf,1)".*/
363/* For some strange reason, the returned character is sign-expanded; */
364/* So if a return value of FFFFFFFFh could mean either character FFh, or error. */
365/* TODO FIX ME : Properly implement this behaviour */
366void psxBios_getc(void) // 0x03, 0x35
367{
d99f6068 368 char *ptr;
324cec89 369 void *pa1 = Ra1;
370#ifdef PSXBIOS_LOG
371 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x03]);
372#endif
373 v0 = -1;
374
375 if (pa1) {
376 switch (a0) {
377 case 2: buread(pa1, 1, 1); break;
378 case 3: buread(pa1, 2, 1); break;
379 }
380 }
381
382 pc0 = ra;
383}
384
385/* Copy of psxBios_write, except size is 1. */
386void psxBios_putc(void) // 0x09, 0x3B
387{
d99f6068 388 char *ptr;
324cec89 389 void *pa1 = Ra1;
390#ifdef PSXBIOS_LOG
391 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x09]);
392#endif
393 v0 = -1;
394 if (!pa1) {
395 pc0 = ra;
396 return;
397 }
398
399 if (a0 == 1) { // stdout
400 char *ptr = (char *)pa1;
401
402 v0 = a2;
403 while (a2 > 0) {
404 printf("%c", *ptr++); a2--;
405 }
406 pc0 = ra; return;
407 }
408
409 switch (a0) {
410 case 2: buwrite(pa1, 1, 1); break;
411 case 3: buwrite(pa1, 2, 1); break;
412 }
413
414 pc0 = ra;
415}
ef79bbde 416
ba11675c 417void psxBios_todigit(void) // 0x0a
418{
419 int c = a0;
420#ifdef PSXBIOS_LOG
421 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x0a]);
422#endif
423 c &= 0xFF;
424 if (c >= 0x30 && c < 0x3A) {
425 c -= 0x30;
426 }
427 else if (c > 0x60 && c < 0x7B) {
428 c -= 0x20;
429 }
430 else if (c > 0x40 && c < 0x5B) {
431 c = c - 0x41 + 10;
432 }
433 else if (c >= 0x80) {
434 c = -1;
435 }
436 else
437 {
438 c = 0x0098967F;
439 }
440 v0 = c;
441 pc0 = ra;
442}
443
ef79bbde
P
444void psxBios_abs() { // 0x0e
445 if ((s32)a0 < 0) v0 = -(s32)a0;
446 else v0 = a0;
447 pc0 = ra;
448}
449
450void psxBios_labs() { // 0x0f
451 psxBios_abs();
452}
453
454void psxBios_atoi() { // 0x10
455 s32 n = 0, f = 0;
456 char *p = (char *)Ra0;
457
458 for (;;p++) {
459 switch (*p) {
460 case ' ': case '\t': continue;
461 case '-': f++;
462 case '+': p++;
463 }
464 break;
465 }
466
467 while (*p >= '0' && *p <= '9') {
468 n = n * 10 + *p++ - '0';
469 }
470
471 v0 = (f ? -n : n);
472 pc0 = ra;
473}
474
475void psxBios_atol() { // 0x11
476 psxBios_atoi();
477}
478
479void psxBios_setjmp() { // 0x13
480 u32 *jmp_buf = (u32 *)Ra0;
481 int i;
482
483#ifdef PSXBIOS_LOG
484 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x13]);
485#endif
486
487 jmp_buf[0] = ra;
488 jmp_buf[1] = sp;
489 jmp_buf[2] = fp;
490 for (i = 0; i < 8; i++) // s0-s7
491 jmp_buf[3 + i] = psxRegs.GPR.r[16 + i];
492 jmp_buf[11] = gp;
493
494 v0 = 0; pc0 = ra;
495}
496
497void psxBios_longjmp() { // 0x14
498 u32 *jmp_buf = (u32 *)Ra0;
499 int i;
500
501#ifdef PSXBIOS_LOG
502 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x14]);
503#endif
504
505 ra = jmp_buf[0]; /* ra */
506 sp = jmp_buf[1]; /* sp */
507 fp = jmp_buf[2]; /* fp */
508 for (i = 0; i < 8; i++) // s0-s7
509 psxRegs.GPR.r[16 + i] = jmp_buf[3 + i];
510 gp = jmp_buf[11]; /* gp */
511
512 v0 = a1; pc0 = ra;
513}
514
515void psxBios_strcat() { // 0x15
516 char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
517
518#ifdef PSXBIOS_LOG
519 PSXBIOS_LOG("psxBios_%s: %s, %s\n", biosA0n[0x15], Ra0, Ra1);
520#endif
bee52312 521 if (a0 == 0 || a1 == 0)
522 {
523 v0 = 0;
524 pc0 = ra;
525 return;
526 }
ef79bbde
P
527 while (*p1++);
528 --p1;
529 while ((*p1++ = *p2++) != '\0');
530
531 v0 = a0; pc0 = ra;
532}
533
534void psxBios_strncat() { // 0x16
535 char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
536 s32 n = a2;
537
538#ifdef PSXBIOS_LOG
539 PSXBIOS_LOG("psxBios_%s: %s (%x), %s (%x), %d\n", biosA0n[0x16], Ra0, a0, Ra1, a1, a2);
540#endif
f42e1e90 541 if (a0 == 0 || a1 == 0)
542 {
543 v0 = 0;
544 pc0 = ra;
545 return;
546 }
ef79bbde
P
547 while (*p1++);
548 --p1;
549 while ((*p1++ = *p2++) != '\0') {
550 if (--n < 0) {
551 *--p1 = '\0';
552 break;
553 }
554 }
555
556 v0 = a0; pc0 = ra;
557}
558
559void psxBios_strcmp() { // 0x17
560 char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
c044e3e5 561 s32 n=0;
562 if (a0 == 0 && a1 == 0)
563 {
564 v0 = 0;
565 pc0 = ra;
566 return;
567 }
568 else if (a0 == 0 && a1 != 0)
569 {
570 v0 = -1;
571 pc0 = ra;
572 return;
573 }
574 else if (a0 != 0 && a1 == 0)
575 {
576 v0 = 1;
577 pc0 = ra;
578 return;
579 }
ef79bbde
P
580#ifdef PSXBIOS_LOG
581 PSXBIOS_LOG("psxBios_%s: %s (%x), %s (%x)\n", biosA0n[0x17], Ra0, a0, Ra1, a1);
582#endif
583
584 while (*p1 == *p2++) {
c044e3e5 585 n++;
ef79bbde 586 if (*p1++ == '\0') {
c044e3e5 587 v1=n-1;
588 a0+=n;
589 a1+=n;
ef79bbde
P
590 v0 = 0;
591 pc0 = ra;
592 return;
593 }
594 }
595
596 v0 = (*p1 - *--p2);
c044e3e5 597 v1 = n;
598 a0+=n;
599 a1+=n;
ef79bbde
P
600 pc0 = ra;
601}
602
603void psxBios_strncmp() { // 0x18
604 char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
605 s32 n = a2;
ba4ecb8c 606 if (a0 == 0 && a1 == 0)
607 {
608 v0 = 0;
609 pc0 = ra;
610 return;
611 }
612 else if (a0 == 0 && a1 != 0)
613 {
614 v0 = -1;
615 pc0 = ra;
616 return;
617 }
618 else if (a0 != 0 && a1 == 0)
619 {
620 v0 = 1;
621 pc0 = ra;
622 return;
623 }
ef79bbde
P
624#ifdef PSXBIOS_LOG
625 PSXBIOS_LOG("psxBios_%s: %s (%x), %s (%x), %d\n", biosA0n[0x18], Ra0, a0, Ra1, a1, a2);
626#endif
627
628 while (--n >= 0 && *p1 == *p2++) {
629 if (*p1++ == '\0') {
630 v0 = 0;
631 pc0 = ra;
ba4ecb8c 632 v1 = a2 - ((a2-n) - 1);
633 a0 += (a2-n) - 1;
634 a1 += (a2-n) - 1;
635 a2 = n;
ef79bbde
P
636 return;
637 }
638 }
639
640 v0 = (n < 0 ? 0 : *p1 - *--p2);
641 pc0 = ra;
ba4ecb8c 642 v1 = a2 - ((a2-n) - 1);
643 a0 += (a2-n) - 1;
644 a1 += (a2-n) - 1;
645 a2 = n;
ef79bbde
P
646}
647
648void psxBios_strcpy() { // 0x19
649 char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
c3d791f1 650 if (a0 == 0 || a1 == 0)
651 {
652 v0 = 0;
653 pc0 = ra;
654 return;
655 }
ef79bbde
P
656 while ((*p1++ = *p2++) != '\0');
657
658 v0 = a0; pc0 = ra;
659}
660
661void psxBios_strncpy() { // 0x1a
662 char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
663 s32 n = a2, i;
c3d791f1 664 if (a0 == 0 || a1 == 0)
665 {
666 v0 = 0;
667 pc0 = ra;
668 return;
669 }
ef79bbde
P
670 for (i = 0; i < n; i++) {
671 if ((*p1++ = *p2++) == '\0') {
672 while (++i < n) {
673 *p1++ = '\0';
674 }
675 v0 = a0; pc0 = ra;
676 return;
677 }
678 }
679
680 v0 = a0; pc0 = ra;
681}
682
683void psxBios_strlen() { // 0x1b
684 char *p = (char *)Ra0;
685 v0 = 0;
2c6a5df8 686 if (a0 == 0)
687 {
688 pc0 = ra;
689 return;
690 }
ef79bbde
P
691 while (*p++) v0++;
692 pc0 = ra;
693}
694
695void psxBios_index() { // 0x1c
696 char *p = (char *)Ra0;
fcf7ec6c 697 if (a0 == 0)
698 {
699 v0 = 0;
700 pc0 = ra;
701 return;
702 }
703
ef79bbde
P
704 do {
705 if (*p == a1) {
706 v0 = a0 + (p - (char *)Ra0);
707 pc0 = ra;
708 return;
709 }
710 } while (*p++ != '\0');
711
712 v0 = 0; pc0 = ra;
713}
714
715void psxBios_rindex() { // 0x1d
716 char *p = (char *)Ra0;
717
718 v0 = 0;
fcf7ec6c 719 if (a0 == 0)
720 {
721 pc0 = ra;
722 return;
723 }
ef79bbde
P
724 do {
725 if (*p == a1)
726 v0 = a0 + (p - (char *)Ra0);
727 } while (*p++ != '\0');
728
729 pc0 = ra;
730}
731
732void psxBios_strchr() { // 0x1e
733 psxBios_index();
734}
735
736void psxBios_strrchr() { // 0x1f
737 psxBios_rindex();
738}
739
740void psxBios_strpbrk() { // 0x20
741 char *p1 = (char *)Ra0, *p2 = (char *)Ra1, *scanp, c, sc;
742
743 while ((c = *p1++) != '\0') {
744 for (scanp = p2; (sc = *scanp++) != '\0';) {
745 if (sc == c) {
746 v0 = a0 + (p1 - 1 - (char *)Ra0);
747 pc0 = ra;
748 return;
749 }
750 }
751 }
752
753 // BUG: return a0 instead of NULL if not found
754 v0 = a0; pc0 = ra;
755}
756
757void psxBios_strspn() { // 0x21
758 char *p1, *p2;
759
760 for (p1 = (char *)Ra0; *p1 != '\0'; p1++) {
761 for (p2 = (char *)Ra1; *p2 != '\0' && *p2 != *p1; p2++);
762 if (*p2 == '\0') break;
763 }
764
765 v0 = p1 - (char *)Ra0; pc0 = ra;
766}
767
768void psxBios_strcspn() { // 0x22
769 char *p1, *p2;
770
771 for (p1 = (char *)Ra0; *p1 != '\0'; p1++) {
772 for (p2 = (char *)Ra1; *p2 != '\0' && *p2 != *p1; p2++);
773 if (*p2 != '\0') break;
774 }
775
776 v0 = p1 - (char *)Ra0; pc0 = ra;
777}
778
779void psxBios_strtok() { // 0x23
780 char *pcA0 = (char *)Ra0;
781 char *pcRet = strtok(pcA0, (char *)Ra1);
782 if (pcRet)
783 v0 = a0 + pcRet - pcA0;
784 else
785 v0 = 0;
786 pc0 = ra;
787}
788
789void psxBios_strstr() { // 0x24
790 char *p = (char *)Ra0, *p1, *p2;
791
792 while (*p != '\0') {
793 p1 = p;
794 p2 = (char *)Ra1;
795
796 while (*p1 != '\0' && *p2 != '\0' && *p1 == *p2) {
797 p1++; p2++;
798 }
799
800 if (*p2 == '\0') {
801 v0 = a0 + (p - (char *)Ra0);
802 pc0 = ra;
803 return;
804 }
805
806 p++;
807 }
808
809 v0 = 0; pc0 = ra;
810}
811
812void psxBios_toupper() { // 0x25
813 v0 = (s8)(a0 & 0xff);
814 if (v0 >= 'a' && v0 <= 'z') v0 -= 'a' - 'A';
815 pc0 = ra;
816}
817
818void psxBios_tolower() { // 0x26
819 v0 = (s8)(a0 & 0xff);
820 if (v0 >= 'A' && v0 <= 'Z') v0 += 'a' - 'A';
821 pc0 = ra;
822}
823
824void psxBios_bcopy() { // 0x27
825 char *p1 = (char *)Ra1, *p2 = (char *)Ra0;
0148ffb7 826 v0 = a0;
827 if (a0 == 0 || a2 > 0x7FFFFFFF)
828 {
829 pc0 = ra;
830 return;
831 }
5ec7acdf 832 while ((s32)a2-- > 0) *p1++ = *p2++;
0148ffb7 833 a2 = 0;
ef79bbde
P
834 pc0 = ra;
835}
836
837void psxBios_bzero() { // 0x28
838 char *p = (char *)Ra0;
01724d23 839 v0 = a0;
840 /* Same as memset here (See memset below) */
841 if (a1 > 0x7FFFFFFF || a1 == 0)
842 {
843 v0 = 0;
844 pc0 = ra;
845 return;
846 }
847 else if (a0 == 0)
848 {
849 pc0 = ra;
850 return;
851 }
5ec7acdf 852 while ((s32)a1-- > 0) *p++ = '\0';
01724d23 853 a1 = 0;
ef79bbde
P
854 pc0 = ra;
855}
856
857void psxBios_bcmp() { // 0x29
858 char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
859
860 if (a0 == 0 || a1 == 0) { v0 = 0; pc0 = ra; return; }
861
5ec7acdf 862 while ((s32)a2-- > 0) {
ef79bbde
P
863 if (*p1++ != *p2++) {
864 v0 = *p1 - *p2; // BUG: compare the NEXT byte
865 pc0 = ra;
866 return;
867 }
868 }
869
870 v0 = 0; pc0 = ra;
871}
872
873void psxBios_memcpy() { // 0x2a
874 char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
ef1da3dc 875 v0 = a0;
876 if (a0 == 0 || a2 > 0x7FFFFFFF)
877 {
878 pc0 = ra;
879 return;
880 }
881 while ((s32)a2-- > 0) {
ef1da3dc 882 *p1++ = *p2++;
883 }
884 a2 = 0;
885 pc0 = ra;
ef79bbde
P
886}
887
888void psxBios_memset() { // 0x2b
889 char *p = (char *)Ra0;
3f28b64f 890 v0 = a0;
891 if (a2 > 0x7FFFFFFF || a2 == 0)
892 {
893 v0 = 0;
894 pc0 = ra;
895 return;
896 }
897 if (a0 == 0)
898 {
899 pc0 = ra;
900 return;
901 }
5ec7acdf 902 while ((s32)a2-- > 0) *p++ = (char)a1;
5ec7acdf 903 a2 = 0;
ef79bbde
P
904 v0 = a0; pc0 = ra;
905}
906
907void psxBios_memmove() { // 0x2c
908 char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
112dddf5 909 v0 = a0;
910 if (a0 == 0 || a2 > 0x7FFFFFFF)
911 {
912 pc0 = ra;
913 return;
914 }
ef79bbde
P
915 if (p2 <= p1 && p2 + a2 > p1) {
916 a2++; // BUG: copy one more byte here
917 p1 += a2;
918 p2 += a2;
5ec7acdf 919 while ((s32)a2-- > 0) *--p1 = *--p2;
ef79bbde 920 } else {
5ec7acdf 921 while ((s32)a2-- > 0) *p1++ = *p2++;
ef79bbde 922 }
112dddf5 923 pc0 = ra;
ef79bbde
P
924}
925
926void psxBios_memcmp() { // 0x2d
927 psxBios_bcmp();
928}
929
930void psxBios_memchr() { // 0x2e
931 char *p = (char *)Ra0;
0f598f20 932
933 if (a0 == 0 || a2 > 0x7FFFFFFF)
934 {
935 pc0 = ra;
936 return;
937 }
ef79bbde 938
5ec7acdf 939 while ((s32)a2-- > 0) {
ef79bbde
P
940 if (*p++ != (s8)a1) continue;
941 v0 = a0 + (p - (char *)Ra0 - 1);
942 pc0 = ra;
943 return;
944 }
945
946 v0 = 0; pc0 = ra;
947}
948
949void psxBios_rand() { // 0x2f
950 u32 s = psxMu32(0x9010) * 1103515245 + 12345;
951 v0 = (s >> 16) & 0x7fff;
952 psxMu32ref(0x9010) = SWAPu32(s);
953 pc0 = ra;
954}
955
956void psxBios_srand() { // 0x30
957 psxMu32ref(0x9010) = SWAPu32(a0);
958 pc0 = ra;
959}
960
961static u32 qscmpfunc, qswidth;
962
963static inline int qscmp(char *a, char *b) {
964 u32 sa0 = a0;
965
966 a0 = sa0 + (a - (char *)PSXM(sa0));
967 a1 = sa0 + (b - (char *)PSXM(sa0));
968
969 softCall2(qscmpfunc);
970
971 a0 = sa0;
972 return (s32)v0;
973}
974
975static inline void qexchange(char *i, char *j) {
976 char t;
977 int n = qswidth;
978
979 do {
980 t = *i;
981 *i++ = *j;
982 *j++ = t;
983 } while (--n);
984}
985
986static inline void q3exchange(char *i, char *j, char *k) {
987 char t;
988 int n = qswidth;
989
990 do {
991 t = *i;
992 *i++ = *k;
993 *k++ = *j;
994 *j++ = t;
995 } while (--n);
996}
997
998static void qsort_main(char *a, char *l) {
999 char *i, *j, *lp, *hp;
1000 int c;
1001 unsigned int n;
1002
1003start:
1004 if ((n = l - a) <= qswidth)
1005 return;
1006 n = qswidth * (n / (2 * qswidth));
1007 hp = lp = a + n;
1008 i = a;
1009 j = l - qswidth;
1010 while (TRUE) {
1011 if (i < lp) {
1012 if ((c = qscmp(i, lp)) == 0) {
1013 qexchange(i, lp -= qswidth);
1014 continue;
1015 }
1016 if (c < 0) {
1017 i += qswidth;
1018 continue;
1019 }
1020 }
1021
1022loop:
1023 if (j > hp) {
1024 if ((c = qscmp(hp, j)) == 0) {
1025 qexchange(hp += qswidth, j);
1026 goto loop;
1027 }
1028 if (c > 0) {
1029 if (i == lp) {
1030 q3exchange(i, hp += qswidth, j);
1031 i = lp += qswidth;
1032 goto loop;
1033 }
1034 qexchange(i, j);
1035 j -= qswidth;
1036 i += qswidth;
1037 continue;
1038 }
1039 j -= qswidth;
1040 goto loop;
1041 }
1042
1043 if (i == lp) {
1044 if (lp - a >= l - hp) {
1045 qsort_main(hp + qswidth, l);
1046 l = lp;
1047 } else {
1048 qsort_main(a, lp);
1049 a = hp + qswidth;
1050 }
1051 goto start;
1052 }
1053
1054 q3exchange(j, lp -= qswidth, i);
1055 j = hp -= qswidth;
1056 }
1057}
1058
1059void psxBios_qsort() { // 0x31
1060 qswidth = a2;
1061 qscmpfunc = a3;
1062 qsort_main((char *)Ra0, (char *)Ra0 + a1 * a2);
1063
1064 pc0 = ra;
1065}
1066
1067void psxBios_malloc() { // 0x33
33788798 1068 u32 *chunk, *newchunk = NULL;
808a13bd 1069 unsigned int dsize = 0, csize, cstat;
ef79bbde
P
1070 int colflag;
1071#ifdef PSXBIOS_LOG
1072 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x33]);
1073#endif
26b964b5 1074 if (!a0 || (!heap_size || !heap_addr)) {
1075 v0 = 0;
1076 pc0 = ra;
1077 return;
1078 }
ef79bbde
P
1079
1080 // scan through heap and combine free chunks of space
1081 chunk = heap_addr;
1082 colflag = 0;
1083 while(chunk < heap_end) {
1084 // get size and status of actual chunk
1085 csize = ((u32)*chunk) & 0xfffffffc;
1086 cstat = ((u32)*chunk) & 1;
1087
26b964b5 1088 // most probably broken heap descriptor
1089 // this fixes Burning Road
1090 if (*chunk == 0) {
1091 newchunk = chunk;
1092 dsize = ((uptr)heap_end - (uptr)chunk) - 4;
1093 colflag = 1;
1094 break;
1095 }
1096
ef79bbde
P
1097 // it's a free chunk
1098 if(cstat == 1) {
1099 if(colflag == 0) {
1100 newchunk = chunk;
1101 dsize = csize;
1102 colflag = 1; // let's begin a new collection of free memory
1103 }
1104 else dsize += (csize+4); // add the new size including header
1105 }
1106 // not a free chunk: did we start a collection ?
1107 else {
1108 if(colflag == 1) { // collection is over
1109 colflag = 0;
1110 *newchunk = SWAP32(dsize | 1);
1111 }
1112 }
1113
1114 // next chunk
1115 chunk = (u32*)((uptr)chunk + csize + 4);
1116 }
1117 // if neccessary free memory on end of heap
1118 if (colflag == 1)
1119 *newchunk = SWAP32(dsize | 1);
1120
1121 chunk = heap_addr;
1122 csize = ((u32)*chunk) & 0xfffffffc;
1123 cstat = ((u32)*chunk) & 1;
1124 dsize = (a0 + 3) & 0xfffffffc;
1125
1126 // exit on uninitialized heap
1127 if (chunk == NULL) {
26b964b5 1128 printf("malloc %x,%x: Uninitialized Heap!\n", v0, a0);
ef79bbde
P
1129 v0 = 0;
1130 pc0 = ra;
1131 return;
1132 }
1133
1134 // search an unused chunk that is big enough until the end of the heap
26b964b5 1135 while ((dsize > csize || cstat==0) && chunk < heap_end ) {
ef79bbde 1136 chunk = (u32*)((uptr)chunk + csize + 4);
26b964b5 1137
1138 // catch out of memory
1139 if(chunk >= heap_end) {
1140 printf("malloc %x,%x: Out of memory error!\n",
1141 v0, a0);
1142 v0 = 0; pc0 = ra;
1143 return;
1144 }
1145
ef79bbde
P
1146 csize = ((u32)*chunk) & 0xfffffffc;
1147 cstat = ((u32)*chunk) & 1;
1148 }
1149
ef79bbde
P
1150 // allocate memory
1151 if(dsize == csize) {
1152 // chunk has same size
1153 *chunk &= 0xfffffffc;
26b964b5 1154 } else if (dsize > csize) {
1155 v0 = 0; pc0 = ra;
1156 return;
1157 } else {
ef79bbde
P
1158 // split free chunk
1159 *chunk = SWAP32(dsize);
1160 newchunk = (u32*)((uptr)chunk + dsize + 4);
808a13bd 1161 *newchunk = SWAP32(((csize - dsize - 4) & 0xfffffffc) | 1);
ef79bbde
P
1162 }
1163
1164 // return pointer to allocated memory
26b964b5 1165 v0 = ((uptr)chunk - (uptr)psxM) + 4;
ef79bbde 1166 v0|= 0x80000000;
26b964b5 1167 //printf ("malloc %x,%x\n", v0, a0);
ef79bbde
P
1168 pc0 = ra;
1169}
1170
1171void psxBios_free() { // 0x34
1172
1173#ifdef PSXBIOS_LOG
1174 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x34]);
1175#endif
1176
1177 SysPrintf("free %x: %x bytes\n", a0, *(u32*)(Ra0-4));
1178
ba4ecb8c 1179 if (a0)
1180 *(u32*)(Ra0-4) |= 1; // set chunk to free
ef79bbde
P
1181 pc0 = ra;
1182}
1183
1184void psxBios_calloc() { // 0x37
02949f79 1185 void *pv0;
ef79bbde
P
1186#ifdef PSXBIOS_LOG
1187 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x37]);
1188#endif
1189
1190 a0 = a0 * a1;
1191 psxBios_malloc();
02949f79 1192 pv0 = Rv0;
1193 if (pv0)
1194 memset(pv0, 0, a0);
ef79bbde
P
1195}
1196
1197void psxBios_realloc() { // 0x38
1198 u32 block = a0;
1199 u32 size = a1;
1200#ifdef PSXBIOS_LOG
1201 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x38]);
1202#endif
1203
1204 a0 = block;
391b1d5b 1205 /* If "old_buf" is zero, executes malloc(new_size), and returns r2=new_buf (or 0=failed). */
1206 if (block == 0)
1207 {
1208 psxBios_malloc();
1209 }
1210 /* Else, if "new_size" is zero, executes free(old_buf), and returns r2=garbage. */
1211 else if (size == 0)
1212 {
1213 psxBios_free();
1214 }
1215 /* Else, executes malloc(new_size), bcopy(old_buf,new_buf,new_size), and free(old_buf), and returns r2=new_buf (or 0=failed). */
1216 /* Note that it is not quite implemented this way here. */
1217 else
1218 {
1219 psxBios_free();
1220 a0 = size;
1221 psxBios_malloc();
1222 }
ef79bbde
P
1223}
1224
1225
1226/* InitHeap(void *block , int n) */
1227void psxBios_InitHeap() { // 0x39
1228 unsigned int size;
1229
1230#ifdef PSXBIOS_LOG
1231 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x39]);
1232#endif
1233
1234 if (((a0 & 0x1fffff) + a1)>= 0x200000) size = 0x1ffffc - (a0 & 0x1fffff);
1235 else size = a1;
1236
1237 size &= 0xfffffffc;
1238
1239 heap_addr = (u32 *)Ra0;
a85ffa0e 1240 heap_size = size;
1241 heap_end = (u32 *)((u8 *)heap_addr + heap_size);
1242 /* HACKFIX: Commenting out this line fixes GTA2 crash */
1243 //*heap_addr = SWAP32(size | 1);
ef79bbde 1244
c979c3ee 1245 SysPrintf("InitHeap %x,%x : %x %x\n",a0,a1, (int)((uptr)heap_addr-(uptr)psxM), size);
ef79bbde
P
1246
1247 pc0 = ra;
1248}
1249
1250void psxBios_getchar() { //0x3b
1251 v0 = getchar(); pc0 = ra;
1252}
1253
1254void psxBios_printf() { // 0x3f
1255 char tmp[1024];
1256 char tmp2[1024];
1257 u32 save[4];
1258 char *ptmp = tmp;
1259 int n=1, i=0, j;
02949f79 1260 void *psp;
1261
1262 psp = PSXM(sp);
1263 if (psp) {
1264 memcpy(save, psp, 4 * 4);
1265 psxMu32ref(sp) = SWAP32((u32)a0);
1266 psxMu32ref(sp + 4) = SWAP32((u32)a1);
1267 psxMu32ref(sp + 8) = SWAP32((u32)a2);
1268 psxMu32ref(sp + 12) = SWAP32((u32)a3);
1269 }
ef79bbde
P
1270
1271 while (Ra0[i]) {
1272 switch (Ra0[i]) {
1273 case '%':
1274 j = 0;
1275 tmp2[j++] = '%';
1276_start:
1277 switch (Ra0[++i]) {
1278 case '.':
1279 case 'l':
1280 tmp2[j++] = Ra0[i]; goto _start;
1281 default:
1282 if (Ra0[i] >= '0' && Ra0[i] <= '9') {
1283 tmp2[j++] = Ra0[i];
1284 goto _start;
1285 }
1286 break;
1287 }
1288 tmp2[j++] = Ra0[i];
1289 tmp2[j] = 0;
1290
1291 switch (Ra0[i]) {
1292 case 'f': case 'F':
1293 ptmp += sprintf(ptmp, tmp2, (float)psxMu32(sp + n * 4)); n++; break;
1294 case 'a': case 'A':
1295 case 'e': case 'E':
1296 case 'g': case 'G':
1297 ptmp += sprintf(ptmp, tmp2, (double)psxMu32(sp + n * 4)); n++; break;
1298 case 'p':
888468ff 1299 case 'i': case 'u':
ef79bbde
P
1300 case 'd': case 'D':
1301 case 'o': case 'O':
1302 case 'x': case 'X':
1303 ptmp += sprintf(ptmp, tmp2, (unsigned int)psxMu32(sp + n * 4)); n++; break;
1304 case 'c':
1305 ptmp += sprintf(ptmp, tmp2, (unsigned char)psxMu32(sp + n * 4)); n++; break;
1306 case 's':
1307 ptmp += sprintf(ptmp, tmp2, (char*)PSXM(psxMu32(sp + n * 4))); n++; break;
1308 case '%':
1309 *ptmp++ = Ra0[i]; break;
1310 }
1311 i++;
1312 break;
1313 default:
1314 *ptmp++ = Ra0[i++];
1315 }
1316 }
1317 *ptmp = 0;
1318
02949f79 1319 if (psp)
1320 memcpy(psp, save, 4 * 4);
ef79bbde 1321
808a13bd 1322 SysPrintf("%s", tmp);
ef79bbde
P
1323
1324 pc0 = ra;
1325}
1326
e7e1f572 1327void psxBios_format() { // 0x41
1328 if (strcmp(Ra0, "bu00:") == 0 && Config.Mcd1[0] != '\0')
1329 {
1330 CreateMcd(Config.Mcd1);
1331 LoadMcd(1, Config.Mcd1);
1332 v0 = 1;
1333 }
1334 else if (strcmp(Ra0, "bu10:") == 0 && Config.Mcd2[0] != '\0')
1335 {
1336 CreateMcd(Config.Mcd2);
1337 LoadMcd(2, Config.Mcd2);
1338 v0 = 1;
1339 }
1340 else
1341 {
1342 v0 = 0;
1343 }
1344 pc0 = ra;
1345}
1346
ef79bbde
P
1347/*
1348 * long Load(char *name, struct EXEC *header);
1349 */
1350
1351void psxBios_Load() { // 0x42
1352 EXE_HEADER eheader;
02949f79 1353 void *pa1;
ef79bbde
P
1354
1355#ifdef PSXBIOS_LOG
1356 PSXBIOS_LOG("psxBios_%s: %s, %x\n", biosA0n[0x42], Ra0, a1);
1357#endif
1358
02949f79 1359 pa1 = Ra1;
1360 if (pa1 && LoadCdromFile(Ra0, &eheader) == 0) {
1361 memcpy(pa1, ((char*)&eheader)+16, sizeof(EXEC));
ef79bbde
P
1362 v0 = 1;
1363 } else v0 = 0;
1364
1365 pc0 = ra;
1366}
1367
1368/*
1369 * int Exec(struct EXEC *header , int argc , char **argv);
1370 */
1371
1372void psxBios_Exec() { // 43
1373 EXEC *header = (EXEC*)Ra0;
1374 u32 tmp;
1375
1376#ifdef PSXBIOS_LOG
1377 PSXBIOS_LOG("psxBios_%s: %x, %x, %x\n", biosA0n[0x43], a0, a1, a2);
1378#endif
1379
1380 header->_sp = sp;
1381 header->_fp = fp;
1382 header->_sp = sp;
1383 header->_gp = gp;
1384 header->ret = ra;
1385 header->base = s0;
1386
1387 if (header->S_addr != 0) {
1388 tmp = header->S_addr + header->s_size;
1389 sp = tmp;
1390 fp = sp;
1391 }
1392
1393 gp = header->gp0;
1394
1395 s0 = a0;
1396
1397 a0 = a1;
1398 a1 = a2;
1399
1400 ra = 0x8000;
1401 pc0 = header->_pc0;
1402}
1403
1404void psxBios_FlushCache() { // 44
1405#ifdef PSXBIOS_LOG
1406 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x44]);
1407#endif
943a507a 1408 psxCpu->Notify(R3000ACPU_NOTIFY_CACHE_ISOLATED, NULL);
1409 psxCpu->Notify(R3000ACPU_NOTIFY_CACHE_UNISOLATED, NULL);
ef79bbde
P
1410 pc0 = ra;
1411}
1412
1413void psxBios_GPU_dw() { // 0x46
1414 int size;
3a284665 1415 u32 *ptr;
ef79bbde
P
1416
1417#ifdef PSXBIOS_LOG
1418 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x46]);
1419#endif
1420
1421 GPU_writeData(0xa0000000);
3a284665 1422 GPU_writeData((a1<<0x10)|(a0&0xffff));
1423 GPU_writeData((a3<<0x10)|(a2&0xffff));
1424 size = (a2*a3)/2;
1425 ptr = (u32*)PSXM(Rsp[4]); //that is correct?
1426 while(size--)
1427 {
1428 GPU_writeData(SWAPu32(*ptr++));
1429 }
ef79bbde
P
1430
1431 pc0 = ra;
1432}
1433
1434void psxBios_mem2vram() { // 0x47
1435 int size;
3a284665 1436 gpuSyncPluginSR();
ef79bbde 1437 GPU_writeData(0xa0000000);
3a284665 1438 GPU_writeData((a1<<0x10)|(a0&0xffff));
1439 GPU_writeData((a3<<0x10)|(a2&0xffff));
1440 size = ((((a2 * a3) / 2) >> 4) << 16);
ef79bbde
P
1441 GPU_writeStatus(0x04000002);
1442 psxHwWrite32(0x1f8010f4,0);
1443 psxHwWrite32(0x1f8010f0,psxHwRead32(0x1f8010f0)|0x800);
1444 psxHwWrite32(0x1f8010a0,Rsp[4]);//might have a buggy...
3a284665 1445 psxHwWrite32(0x1f8010a4, size | 0x10);
ef79bbde
P
1446 psxHwWrite32(0x1f8010a8,0x01000201);
1447
1448 pc0 = ra;
1449}
1450
1451void psxBios_SendGPU() { // 0x48
1452 GPU_writeStatus(a0);
ddbaf678 1453 gpuSyncPluginSR();
ef79bbde
P
1454 pc0 = ra;
1455}
1456
1457void psxBios_GPU_cw() { // 0x49
3a284665 1458 gpuSyncPluginSR();
ef79bbde
P
1459 GPU_writeData(a0);
1460 pc0 = ra;
3a284665 1461 v0 = HW_GPU_STATUS;
ef79bbde
P
1462}
1463
1464void psxBios_GPU_cwb() { // 0x4a
3a284665 1465 u32 *ptr = (u32*)Ra0;
ef79bbde 1466 int size = a1;
3a284665 1467 gpuSyncPluginSR();
1468 while(size--)
1469 {
1470 GPU_writeData(SWAPu32(*ptr++));
ef79bbde
P
1471 }
1472
1473 pc0 = ra;
1474}
1475
1476void psxBios_GPU_SendPackets() { //4b:
3a284665 1477 gpuSyncPluginSR();
ef79bbde
P
1478 GPU_writeStatus(0x04000002);
1479 psxHwWrite32(0x1f8010f4,0);
1480 psxHwWrite32(0x1f8010f0,psxHwRead32(0x1f8010f0)|0x800);
1481 psxHwWrite32(0x1f8010a0,a0);
1482 psxHwWrite32(0x1f8010a4,0);
1483 psxHwWrite32(0x1f8010a8,0x010000401);
1484 pc0 = ra;
1485}
1486
1487void psxBios_sys_a0_4c() { // 0x4c GPU relate
1488 psxHwWrite32(0x1f8010a8,0x00000401);
1489 GPU_writeData(0x0400000);
1490 GPU_writeData(0x0200000);
1491 GPU_writeData(0x0100000);
cd1ea245 1492 v0 = 0x1f801814;
ef79bbde
P
1493 pc0 = ra;
1494}
1495
1496void psxBios_GPU_GetGPUStatus() { // 0x4d
1497 v0 = GPU_readStatus();
1498 pc0 = ra;
1499}
1500
1501#undef s_addr
1502
1503void psxBios_LoadExec() { // 51
1504 EXEC *header = (EXEC*)PSXM(0xf000);
1505 u32 s_addr, s_size;
1506
1507#ifdef PSXBIOS_LOG
1508 PSXBIOS_LOG("psxBios_%s: %s: %x,%x\n", biosA0n[0x51], Ra0, a1, a2);
1509#endif
1510 s_addr = a1; s_size = a2;
1511
1512 a1 = 0xf000;
1513 psxBios_Load();
1514
1515 header->S_addr = s_addr;
1516 header->s_size = s_size;
1517
1518 a0 = 0xf000; a1 = 0; a2 = 0;
1519 psxBios_Exec();
1520}
1521
1522void psxBios__bu_init() { // 70
1523#ifdef PSXBIOS_LOG
1524 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x70]);
1525#endif
1526
1527 DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
1528 DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
1529
1530 pc0 = ra;
1531}
1532
1533void psxBios__96_init() { // 71
1534#ifdef PSXBIOS_LOG
1535 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x71]);
1536#endif
1537
1538 pc0 = ra;
1539}
1540
1541void psxBios__96_remove() { // 72
1542#ifdef PSXBIOS_LOG
1543 PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x72]);
1544#endif
1545
1546 pc0 = ra;
1547}
1548
1549void psxBios_SetMem() { // 9f
1550 u32 new = psxHu32(0x1060);
1551
1552#ifdef PSXBIOS_LOG
1553 PSXBIOS_LOG("psxBios_%s: %x, %x\n", biosA0n[0x9f], a0, a1);
1554#endif
1555
1556 switch(a0) {
1557 case 2:
1558 psxHu32ref(0x1060) = SWAP32(new);
1559 psxMu32ref(0x060) = a0;
1560 SysPrintf("Change effective memory : %d MBytes\n",a0);
1561 break;
1562
1563 case 8:
1564 psxHu32ref(0x1060) = SWAP32(new | 0x300);
1565 psxMu32ref(0x060) = a0;
1566 SysPrintf("Change effective memory : %d MBytes\n",a0);
1567
1568 default:
1569 SysPrintf("Effective memory must be 2/8 MBytes\n");
1570 break;
1571 }
1572
1573 pc0 = ra;
1574}
1575
18dd7e9e 1576/* TODO FIXME : Not compliant. -1 indicates failure but using 1 for now. */
1577void psxBios_get_cd_status(void) //a6
1578{
1579 v0 = 1;
1580 pc0 = ra;
1581}
1582
ef79bbde
P
1583void psxBios__card_info() { // ab
1584#ifdef PSXBIOS_LOG
1585 PSXBIOS_LOG("psxBios_%s: %x\n", biosA0n[0xab], a0);
1586#endif
76b81516 1587 u32 ret;
e9fda093 1588 card_active_chan = a0;
1589
76b81516 1590 switch (card_active_chan)
1591 {
1592 case 0x00: case 0x01: case 0x02: case 0x03:
1593 ret = Config.Mcd1[0] ? 0x2 : 0x8;
1594 break;
1595 case 0x10: case 0x11: case 0x12: case 0x13:
1596 ret = Config.Mcd2[0] ? 0x2 : 0x8;
1597 break;
1598 default:
1599#ifdef PSXBIOS_LOG
1600 PSXBIOS_LOG("psxBios_%s: UNKNOWN PORT 0x%x\n", biosA0n[0xab], card_active_chan);
1601#endif
1602 ret = 0x11;
1603 break;
1604 }
1605
c2360853 1606 DeliverEvent(0x11, 0x2); // 0xf4000001, 0x0004
76b81516 1607 DeliverEvent(0x81, ret); // 0xf4000001, 0x0004
ef79bbde
P
1608 v0 = 1; pc0 = ra;
1609}
1610
1611void psxBios__card_load() { // ac
1612#ifdef PSXBIOS_LOG
1613 PSXBIOS_LOG("psxBios_%s: %x\n", biosA0n[0xac], a0);
1614#endif
1615
e9fda093 1616 card_active_chan = a0;
1617
ef79bbde
P
1618// DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
1619 DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
1620
1621 v0 = 1; pc0 = ra;
1622}
1623
1624/* System calls B0 */
1625
1626void psxBios_SetRCnt() { // 02
1627#ifdef PSXBIOS_LOG
1628 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x02]);
1629#endif
1630
1631 a0&= 0x3;
1632 if (a0 != 3) {
1633 u32 mode=0;
1634
1635 psxRcntWtarget(a0, a1);
1636 if (a2&0x1000) mode|= 0x050; // Interrupt Mode
1637 if (a2&0x0100) mode|= 0x008; // Count to 0xffff
1638 if (a2&0x0010) mode|= 0x001; // Timer stop mode
1639 if (a0 == 2) { if (a2&0x0001) mode|= 0x200; } // System Clock mode
1640 else { if (a2&0x0001) mode|= 0x100; } // System Clock mode
1641
1642 psxRcntWmode(a0, mode);
1643 }
1644 pc0 = ra;
1645}
1646
1647void psxBios_GetRCnt() { // 03
1648#ifdef PSXBIOS_LOG
1649 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x03]);
1650#endif
1651
1652 a0&= 0x3;
1653 if (a0 != 3) v0 = psxRcntRcount(a0);
1654 else v0 = 0;
1655 pc0 = ra;
1656}
1657
1658void psxBios_StartRCnt() { // 04
1659#ifdef PSXBIOS_LOG
1660 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x04]);
1661#endif
1662
1663 a0&= 0x3;
1664 if (a0 != 3) psxHu32ref(0x1074)|= SWAP32((u32)((1<<(a0+4))));
1665 else psxHu32ref(0x1074)|= SWAPu32(0x1);
1666 v0 = 1; pc0 = ra;
1667}
1668
1669void psxBios_StopRCnt() { // 05
1670#ifdef PSXBIOS_LOG
1671 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x05]);
1672#endif
1673
1674 a0&= 0x3;
1675 if (a0 != 3) psxHu32ref(0x1074)&= SWAP32((u32)(~(1<<(a0+4))));
1676 else psxHu32ref(0x1074)&= SWAPu32(~0x1);
1677 pc0 = ra;
1678}
1679
1680void psxBios_ResetRCnt() { // 06
1681#ifdef PSXBIOS_LOG
1682 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x06]);
1683#endif
1684
1685 a0&= 0x3;
1686 if (a0 != 3) {
1687 psxRcntWmode(a0, 0);
1688 psxRcntWtarget(a0, 0);
1689 psxRcntWcount(a0, 0);
1690 }
1691 pc0 = ra;
1692}
1693
1694
1695/* gets ev for use with Event */
1696#define GetEv() \
1697 ev = (a0 >> 24) & 0xf; \
1698 if (ev == 0xf) ev = 0x5; \
1699 ev*= 32; \
1700 ev+= a0&0x1f;
1701
1702/* gets spec for use with Event */
1703#define GetSpec() \
1704 spec = 0; \
1705 switch (a1) { \
1706 case 0x0301: spec = 16; break; \
1707 case 0x0302: spec = 17; break; \
1708 default: \
1709 for (i=0; i<16; i++) if (a1 & (1 << i)) { spec = i; break; } \
1710 break; \
1711 }
1712
1713void psxBios_DeliverEvent() { // 07
1714 int ev, spec;
1715 int i;
1716
1717 GetEv();
1718 GetSpec();
1719
1720#ifdef PSXBIOS_LOG
1721 PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x07], ev, spec);
1722#endif
1723
1724 DeliverEvent(ev, spec);
1725
1726 pc0 = ra;
1727}
1728
1729void psxBios_OpenEvent() { // 08
1730 int ev, spec;
1731 int i;
1732
1733 GetEv();
1734 GetSpec();
1735
1736#ifdef PSXBIOS_LOG
1737 PSXBIOS_LOG("psxBios_%s %x,%x (class:%x, spec:%x, mode:%x, func:%x)\n", biosB0n[0x08], ev, spec, a0, a1, a2, a3);
1738#endif
1739
1740 Event[ev][spec].status = EvStWAIT;
1741 Event[ev][spec].mode = a2;
1742 Event[ev][spec].fhandler = a3;
1743
1744 v0 = ev | (spec << 8);
1745 pc0 = ra;
1746}
1747
1748void psxBios_CloseEvent() { // 09
1749 int ev, spec;
1750
1751 ev = a0 & 0xff;
1752 spec = (a0 >> 8) & 0xff;
1753
1754#ifdef PSXBIOS_LOG
1755 PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x09], ev, spec);
1756#endif
1757
1758 Event[ev][spec].status = EvStUNUSED;
1759
1760 v0 = 1; pc0 = ra;
1761}
1762
1763void psxBios_WaitEvent() { // 0a
1764 int ev, spec;
1765
1766 ev = a0 & 0xff;
1767 spec = (a0 >> 8) & 0xff;
ef79bbde
P
1768#ifdef PSXBIOS_LOG
1769 PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0a], ev, spec);
1770#endif
d95c9dcb 1771 if (Event[ev][spec].status == EvStUNUSED)
1772 {
1773 v0 = 0;
1774 pc0 = ra;
1775 return;
1776 }
ef79bbde 1777
d95c9dcb 1778 if (Event[ev][spec].status == EvStALREADY)
1779 {
1780 /* Callback events (mode=EvMdINTR) do never set the ready flag (and thus WaitEvent would hang forever). */
1781 if (!(Event[ev][spec].mode == EvMdINTR)) Event[ev][spec].status = EvStACTIVE;
1782 v0 = 1;
1783 pc0 = ra;
1784 return;
1785 }
ef79bbde 1786
d95c9dcb 1787 v0 = 0;
1788 pc0 = ra;
ef79bbde
P
1789}
1790
1791void psxBios_TestEvent() { // 0b
1792 int ev, spec;
1793
1794 ev = a0 & 0xff;
1795 spec = (a0 >> 8) & 0xff;
1796
b4ae2532 1797 if (Event[ev][spec].status == EvStALREADY)
1798 {
1799 if (!(Event[ev][spec].mode == EvMdINTR)) Event[ev][spec].status = EvStACTIVE;
1800 v0 = 1;
1801 }
1802 else
1803 {
1804 v0 = 0;
1805 }
ef79bbde
P
1806
1807#ifdef PSXBIOS_LOG
1808 PSXBIOS_LOG("psxBios_%s %x,%x: %x\n", biosB0n[0x0b], ev, spec, v0);
1809#endif
1810
1811 pc0 = ra;
1812}
1813
1814void psxBios_EnableEvent() { // 0c
1815 int ev, spec;
1816
1817 ev = a0 & 0xff;
1818 spec = (a0 >> 8) & 0xff;
1819
1820#ifdef PSXBIOS_LOG
1821 PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0c], ev, spec);
1822#endif
1823
1824 Event[ev][spec].status = EvStACTIVE;
1825
1826 v0 = 1; pc0 = ra;
1827}
1828
1829void psxBios_DisableEvent() { // 0d
1830 int ev, spec;
1831
1832 ev = a0 & 0xff;
1833 spec = (a0 >> 8) & 0xff;
1834
1835#ifdef PSXBIOS_LOG
1836 PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0d], ev, spec);
1837#endif
1838
1839 Event[ev][spec].status = EvStWAIT;
1840
1841 v0 = 1; pc0 = ra;
1842}
1843
1844/*
1845 * long OpenTh(long (*func)(), unsigned long sp, unsigned long gp);
1846 */
1847
1848void psxBios_OpenTh() { // 0e
1849 int th;
1850
1851 for (th=1; th<8; th++)
a66d3058 1852 {
ef79bbde
P
1853 if (Thread[th].status == 0) break;
1854
a66d3058 1855 }
1856 if (th == 8) {
1857 // Feb 2019 - Added out-of-bounds fix caught by cppcheck:
1858 // When no free TCB is found, return 0xffffffff according to Nocash doc.
1859#ifdef PSXBIOS_LOG
1860 PSXBIOS_LOG("\t%s() WARNING! No Free TCBs found!\n", __func__);
1861#endif
1862 v0 = 0xffffffff;
1863 pc0 = ra;
1864 return;
1865 }
ef79bbde
P
1866#ifdef PSXBIOS_LOG
1867 PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x0e], th);
1868#endif
1869
1870 Thread[th].status = 1;
1871 Thread[th].func = a0;
1872 Thread[th].reg[29] = a1;
1873 Thread[th].reg[28] = a2;
1874
1875 v0 = th; pc0 = ra;
1876}
1877
1878/*
1879 * int CloseTh(long thread);
1880 */
1881
1882void psxBios_CloseTh() { // 0f
1883 int th = a0 & 0xff;
1884
1885#ifdef PSXBIOS_LOG
1886 PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x0f], th);
1887#endif
9ee77db1 1888 /* The return value is always 1 (even if the handle was already closed). */
1889 v0 = 1;
1890 if (Thread[th].status != 0) {
ef79bbde 1891 Thread[th].status = 0;
ef79bbde
P
1892 }
1893
1894 pc0 = ra;
1895}
1896
1897/*
1898 * int ChangeTh(long thread);
1899 */
1900
1901void psxBios_ChangeTh() { // 10
1902 int th = a0 & 0xff;
1903
1904#ifdef PSXBIOS_LOG
1905// PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x10], th);
1906#endif
9ee77db1 1907 /* The return value is always 1. */
1908 v0 = 1;
ef79bbde 1909 if (Thread[th].status == 0 || CurThread == th) {
ef79bbde
P
1910 pc0 = ra;
1911 } else {
ef79bbde
P
1912 if (Thread[CurThread].status == 2) {
1913 Thread[CurThread].status = 1;
1914 Thread[CurThread].func = ra;
1915 memcpy(Thread[CurThread].reg, psxRegs.GPR.r, 32*4);
1916 }
1917
1918 memcpy(psxRegs.GPR.r, Thread[th].reg, 32*4);
1919 pc0 = Thread[th].func;
1920 Thread[th].status = 2;
1921 CurThread = th;
1922 }
1923}
1924
1925void psxBios_InitPAD() { // 0x12
1926#ifdef PSXBIOS_LOG
1927 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x12]);
1928#endif
1929
1930 pad_buf1 = (char*)Ra0;
1931 pad_buf1len = a1;
1932 pad_buf2 = (char*)Ra2;
1933 pad_buf2len = a3;
1934
1935 v0 = 1; pc0 = ra;
1936}
1937
1938void psxBios_StartPAD() { // 13
1939#ifdef PSXBIOS_LOG
1940 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x13]);
1941#endif
f25c285b 1942 pad_stopped = 0;
ef79bbde
P
1943 psxHwWrite16(0x1f801074, (unsigned short)(psxHwRead16(0x1f801074) | 0x1));
1944 psxRegs.CP0.n.Status |= 0x401;
1945 pc0 = ra;
1946}
1947
1948void psxBios_StopPAD() { // 14
1949#ifdef PSXBIOS_LOG
1950 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x14]);
1951#endif
f25c285b 1952 pad_stopped = 1;
ef79bbde
P
1953 pad_buf1 = NULL;
1954 pad_buf2 = NULL;
1955 pc0 = ra;
1956}
1957
1958void psxBios_PAD_init() { // 15
1959#ifdef PSXBIOS_LOG
1960 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x15]);
1961#endif
a824e83d 1962 if (!(a0 == 0x20000000 || a0 == 0x20000001))
1963 {
1964 v0 = 0;
1965 pc0 = ra;
1966 return;
1967 }
ef79bbde
P
1968 psxHwWrite16(0x1f801074, (u16)(psxHwRead16(0x1f801074) | 0x1));
1969 pad_buf = (int *)Ra1;
1970 *pad_buf = -1;
1971 psxRegs.CP0.n.Status |= 0x401;
a824e83d 1972 v0 = 2;
ef79bbde
P
1973 pc0 = ra;
1974}
1975
1976void psxBios_PAD_dr() { // 16
1977#ifdef PSXBIOS_LOG
1978 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x16]);
1979#endif
1980
1981 v0 = -1; pc0 = ra;
1982}
1983
1984void psxBios_ReturnFromException() { // 17
1985 LoadRegs();
1986
1987 pc0 = psxRegs.CP0.n.EPC;
f23c2241 1988 k0 = interrupt_r26;
ef79bbde
P
1989 if (psxRegs.CP0.n.Cause & 0x80000000) pc0 += 4;
1990
1991 psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) |
1992 ((psxRegs.CP0.n.Status & 0x3c) >> 2);
1993}
1994
1995void psxBios_ResetEntryInt() { // 18
1996#ifdef PSXBIOS_LOG
1997 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x18]);
1998#endif
1999
2000 jmp_int = NULL;
2001 pc0 = ra;
2002}
2003
2004void psxBios_HookEntryInt() { // 19
2005#ifdef PSXBIOS_LOG
2006 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x19]);
2007#endif
2008
2009 jmp_int = (u32*)Ra0;
2010 pc0 = ra;
2011}
2012
2013void psxBios_UnDeliverEvent() { // 0x20
2014 int ev, spec;
2015 int i;
2016
2017 GetEv();
2018 GetSpec();
2019
2020#ifdef PSXBIOS_LOG
2021 PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x20], ev, spec);
2022#endif
2023
2024 if (Event[ev][spec].status == EvStALREADY &&
2025 Event[ev][spec].mode == EvMdNOINTR)
2026 Event[ev][spec].status = EvStACTIVE;
2027
2028 pc0 = ra;
2029}
2030
595a136b 2031char ffile[64], *pfile;
2032int nfile;
857275a9 2033static void buopen(int mcd, char *ptr, char *cfg)
595a136b 2034{
2035 int i;
857275a9 2036 char *fptr = ptr;
595a136b 2037
2038 strcpy(FDesc[1 + mcd].name, Ra0+5);
2039 FDesc[1 + mcd].offset = 0;
2040 FDesc[1 + mcd].mode = a1;
2041
2042 for (i=1; i<16; i++) {
2043 fptr += 128;
2044 if ((*fptr & 0xF0) != 0x50) continue;
2045 if (strcmp(FDesc[1 + mcd].name, fptr+0xa)) continue;
2046 FDesc[1 + mcd].mcfile = i;
2047 SysPrintf("open %s\n", fptr+0xa);
2048 v0 = 1 + mcd;
2049 break;
2050 }
2051 if (a1 & 0x200 && v0 == -1) { /* FCREAT */
2052 fptr = ptr;
2053 for (i=1; i<16; i++) {
2054 int j, xor, nblk = a1 >> 16;
2055 u8 *pptr, *fptr2;
2056
2057 fptr += 128;
2058 if ((*fptr & 0xF0) != 0xa0) continue;
2059
2060 FDesc[1 + mcd].mcfile = i;
2061 fptr[0] = 0x51;
2062 fptr[4] = 0x00;
2063 fptr[5] = 0x20 * nblk;
2064 fptr[6] = 0x00;
2065 fptr[7] = 0x00;
2066 strcpy(fptr+0xa, FDesc[1 + mcd].name);
857275a9 2067 pptr = fptr2 = (u8 *)fptr;
595a136b 2068 for(j=2; j<=nblk; j++) {
2069 int k;
2070 for(i++; i<16; i++) {
2071 fptr2 += 128;
2072
2073 memset(fptr2, 0, 128);
2074 fptr2[0] = j < nblk ? 0x52 : 0x53;
2075 pptr[8] = i - 1;
2076 pptr[9] = 0;
2077 for (k=0, xor=0; k<127; k++) xor^= pptr[k];
2078 pptr[127] = xor;
2079 pptr = fptr2;
2080 break;
2081 }
2082 /* shouldn't this return ENOSPC if i == 16? */
2083 }
2084 pptr[8] = pptr[9] = 0xff;
2085 for (j=0, xor=0; j<127; j++) xor^= pptr[j];
2086 pptr[127] = xor;
2087 SysPrintf("openC %s %d\n", ptr, nblk);
2088 v0 = 1 + mcd;
2089 /* just go ahead and resave them all */
2090 SaveMcd(cfg, ptr, 128, 128 * 15);
2091 break;
2092 }
2093 /* shouldn't this return ENOSPC if i == 16? */
2094 }
ef79bbde
P
2095}
2096
2097/*
2098 * int open(char *name , int mode);
2099 */
2100
2101void psxBios_open() { // 0x32
02949f79 2102 void *pa0 = Ra0;
ef79bbde
P
2103
2104#ifdef PSXBIOS_LOG
2105 PSXBIOS_LOG("psxBios_%s: %s,%x\n", biosB0n[0x32], Ra0, a1);
2106#endif
2107
2108 v0 = -1;
2109
02949f79 2110 if (pa0) {
2111 if (!strncmp(pa0, "bu00", 4)) {
595a136b 2112 buopen(1, Mcd1Data, Config.Mcd1);
02949f79 2113 }
ef79bbde 2114
02949f79 2115 if (!strncmp(pa0, "bu10", 4)) {
595a136b 2116 buopen(2, Mcd2Data, Config.Mcd2);
02949f79 2117 }
ef79bbde
P
2118 }
2119
2120 pc0 = ra;
2121}
2122
2123/*
2124 * int lseek(int fd , int offset , int whence);
2125 */
2126
2127void psxBios_lseek() { // 0x33
2128#ifdef PSXBIOS_LOG
2129 PSXBIOS_LOG("psxBios_%s: %x, %x, %x\n", biosB0n[0x33], a0, a1, a2);
2130#endif
2131
2132 switch (a2) {
2133 case 0: // SEEK_SET
2134 FDesc[a0].offset = a1;
2135 v0 = a1;
2136// DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
2137// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
2138 break;
2139
2140 case 1: // SEEK_CUR
2141 FDesc[a0].offset+= a1;
2142 v0 = FDesc[a0].offset;
2143 break;
2144 }
2145
2146 pc0 = ra;
2147}
2148
595a136b 2149
ef79bbde
P
2150/*
2151 * int read(int fd , void *buf , int nbytes);
2152 */
2153
2154void psxBios_read() { // 0x34
2155 char *ptr;
02949f79 2156 void *pa1 = Ra1;
ef79bbde
P
2157
2158#ifdef PSXBIOS_LOG
2159 PSXBIOS_LOG("psxBios_%s: %x, %x, %x\n", biosB0n[0x34], a0, a1, a2);
2160#endif
2161
2162 v0 = -1;
2163
02949f79 2164 if (pa1) {
2165 switch (a0) {
595a136b 2166 case 2: buread(pa1, 1, a2); break;
2167 case 3: buread(pa1, 2, a2); break;
02949f79 2168 }
ef79bbde
P
2169 }
2170
2171 pc0 = ra;
2172}
2173
ef79bbde
P
2174/*
2175 * int write(int fd , void *buf , int nbytes);
2176 */
2177
2178void psxBios_write() { // 0x35/0x03
2179 char *ptr;
02949f79 2180 void *pa1 = Ra1;
2181
2182#ifdef PSXBIOS_LOG
2183 PSXBIOS_LOG("psxBios_%s: %x,%x,%x\n", biosB0n[0x35], a0, a1, a2);
2184#endif
2185
2186 v0 = -1;
2187 if (!pa1) {
2188 pc0 = ra;
2189 return;
2190 }
ef79bbde
P
2191
2192 if (a0 == 1) { // stdout
02949f79 2193 char *ptr = pa1;
ef79bbde 2194
02949f79 2195 v0 = a2;
ef79bbde
P
2196 while (a2 > 0) {
2197 SysPrintf("%c", *ptr++); a2--;
2198 }
2199 pc0 = ra; return;
2200 }
ef79bbde
P
2201
2202 switch (a0) {
595a136b 2203 case 2: buwrite(pa1, 1, a2); break;
2204 case 3: buwrite(pa1, 2, a2); break;
ef79bbde
P
2205 }
2206
2207 pc0 = ra;
2208}
2209
2210/*
2211 * int close(int fd);
2212 */
2213
2214void psxBios_close() { // 0x36
2215#ifdef PSXBIOS_LOG
2216 PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x36], a0);
2217#endif
2218
2219 v0 = a0;
2220 pc0 = ra;
2221}
2222
2223void psxBios_putchar() { // 3d
2224 SysPrintf("%c", (char)a0);
2225 pc0 = ra;
2226}
2227
2228void psxBios_puts() { // 3e/3f
808a13bd 2229 SysPrintf("%s", Ra0);
ef79bbde
P
2230 pc0 = ra;
2231}
2232
f1514614 2233
2234/* To avoid any issues with different behaviour when using the libc's own strlen instead.
2235 * We want to mimic the PSX's behaviour in this case for bufile. */
2236static size_t strlen_internal(char* p)
2237{
2238 size_t size_of_array = 0;
2239 while (*p++) size_of_array++;
2240 return size_of_array;
2241}
2242
ef79bbde 2243#define bufile(mcd) { \
f1514614 2244 size_t size_of_name = strlen_internal(dir->name); \
ef79bbde
P
2245 while (nfile < 16) { \
2246 int match=1; \
2247 \
595a136b 2248 ptr = Mcd##mcd##Data + 128 * (nfile + 1); \
ef79bbde
P
2249 nfile++; \
2250 if ((*ptr & 0xF0) != 0x50) continue; \
595a136b 2251 /* Bug link files show up as free block. */ \
2252 if (!ptr[0xa]) continue; \
ef79bbde
P
2253 ptr+= 0xa; \
2254 if (pfile[0] == 0) { \
f1514614 2255 strncpy(dir->name, ptr, sizeof(dir->name) - 1); \
2256 if (size_of_name < sizeof(dir->name)) dir->name[size_of_name] = '\0'; \
ef79bbde
P
2257 } else for (i=0; i<20; i++) { \
2258 if (pfile[i] == ptr[i]) { \
595a136b 2259 dir->name[i] = ptr[i]; continue; } \
ef79bbde
P
2260 if (pfile[i] == '?') { \
2261 dir->name[i] = ptr[i]; continue; } \
2262 if (pfile[i] == '*') { \
2263 strcpy(dir->name+i, ptr+i); break; } \
2264 match = 0; break; \
2265 } \
2266 SysPrintf("%d : %s = %s + %s (match=%d)\n", nfile, dir->name, pfile, ptr, match); \
595a136b 2267 if (match == 0) { continue; } \
ef79bbde
P
2268 dir->size = 8192; \
2269 v0 = _dir; \
2270 break; \
2271 } \
2272}
2273
2274/*
2275 * struct DIRENTRY* firstfile(char *name,struct DIRENTRY *dir);
2276 */
2277
2278void psxBios_firstfile() { // 42
2279 struct DIRENTRY *dir = (struct DIRENTRY *)Ra1;
02949f79 2280 void *pa0 = Ra0;
ef79bbde
P
2281 u32 _dir = a1;
2282 char *ptr;
2283 int i;
2284
2285#ifdef PSXBIOS_LOG
2286 PSXBIOS_LOG("psxBios_%s: %s\n", biosB0n[0x42], Ra0);
2287#endif
2288
2289 v0 = 0;
2290
02949f79 2291 if (pa0) {
2292 strcpy(ffile, pa0);
2293 pfile = ffile+5;
8f3b2bd3 2294 nfile = 0;
02949f79 2295 if (!strncmp(pa0, "bu00", 4)) {
857fabea 2296 // firstfile() calls _card_read() internally, so deliver it's event
2297 DeliverEvent(0x11, 0x2);
02949f79 2298 bufile(1);
2299 } else if (!strncmp(pa0, "bu10", 4)) {
857fabea 2300 // firstfile() calls _card_read() internally, so deliver it's event
2301 DeliverEvent(0x11, 0x2);
02949f79 2302 bufile(2);
2303 }
ef79bbde
P
2304 }
2305
2306 pc0 = ra;
2307}
2308
2309/*
2310 * struct DIRENTRY* nextfile(struct DIRENTRY *dir);
2311 */
2312
2313void psxBios_nextfile() { // 43
2314 struct DIRENTRY *dir = (struct DIRENTRY *)Ra0;
2315 u32 _dir = a0;
2316 char *ptr;
2317 int i;
2318
2319#ifdef PSXBIOS_LOG
2320 PSXBIOS_LOG("psxBios_%s: %s\n", biosB0n[0x43], dir->name);
2321#endif
2322
2323 v0 = 0;
2324
2325 if (!strncmp(ffile, "bu00", 4)) {
2326 bufile(1);
2327 }
2328
2329 if (!strncmp(ffile, "bu10", 4)) {
2330 bufile(2);
2331 }
2332
2333 pc0 = ra;
2334}
2335
2336#define burename(mcd) { \
2337 for (i=1; i<16; i++) { \
2338 int namelen, j, xor = 0; \
2339 ptr = Mcd##mcd##Data + 128 * i; \
2340 if ((*ptr & 0xF0) != 0x50) continue; \
2341 if (strcmp(Ra0+5, ptr+0xa)) continue; \
2342 namelen = strlen(Ra1+5); \
2343 memcpy(ptr+0xa, Ra1+5, namelen); \
2344 memset(ptr+0xa+namelen, 0, 0x75-namelen); \
2345 for (j=0; j<127; j++) xor^= ptr[j]; \
2346 ptr[127] = xor; \
2347 SaveMcd(Config.Mcd##mcd, Mcd##mcd##Data, 128 * i + 0xa, 0x76); \
2348 v0 = 1; \
2349 break; \
2350 } \
2351}
2352
2353/*
2354 * int rename(char *old, char *new);
2355 */
2356
2357void psxBios_rename() { // 44
02949f79 2358 void *pa0 = Ra0;
2359 void *pa1 = Ra1;
ef79bbde
P
2360 char *ptr;
2361 int i;
2362
2363#ifdef PSXBIOS_LOG
2364 PSXBIOS_LOG("psxBios_%s: %s,%s\n", biosB0n[0x44], Ra0, Ra1);
2365#endif
2366
2367 v0 = 0;
2368
02949f79 2369 if (pa0 && pa1) {
2370 if (!strncmp(pa0, "bu00", 4) && !strncmp(pa1, "bu00", 4)) {
2371 burename(1);
2372 }
ef79bbde 2373
02949f79 2374 if (!strncmp(pa0, "bu10", 4) && !strncmp(pa1, "bu10", 4)) {
2375 burename(2);
2376 }
ef79bbde
P
2377 }
2378
2379 pc0 = ra;
2380}
2381
2382
2383#define budelete(mcd) { \
2384 for (i=1; i<16; i++) { \
2385 ptr = Mcd##mcd##Data + 128 * i; \
2386 if ((*ptr & 0xF0) != 0x50) continue; \
2387 if (strcmp(Ra0+5, ptr+0xa)) continue; \
2388 *ptr = (*ptr & 0xf) | 0xA0; \
2389 SaveMcd(Config.Mcd##mcd, Mcd##mcd##Data, 128 * i, 1); \
2390 SysPrintf("delete %s\n", ptr+0xa); \
2391 v0 = 1; \
2392 break; \
2393 } \
2394}
2395
2396/*
2397 * int delete(char *name);
2398 */
2399
2400void psxBios_delete() { // 45
02949f79 2401 void *pa0 = Ra0;
ef79bbde
P
2402 char *ptr;
2403 int i;
2404
2405#ifdef PSXBIOS_LOG
2406 PSXBIOS_LOG("psxBios_%s: %s\n", biosB0n[0x45], Ra0);
2407#endif
2408
2409 v0 = 0;
2410
02949f79 2411 if (pa0) {
2412 if (!strncmp(pa0, "bu00", 4)) {
2413 budelete(1);
2414 }
ef79bbde 2415
02949f79 2416 if (!strncmp(pa0, "bu10", 4)) {
2417 budelete(2);
2418 }
ef79bbde
P
2419 }
2420
2421 pc0 = ra;
2422}
2423
2424void psxBios_InitCARD() { // 4a
2425#ifdef PSXBIOS_LOG
2426 PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x4a], a0);
2427#endif
2428
2429 CardState = 0;
2430
2431 pc0 = ra;
2432}
2433
2434void psxBios_StartCARD() { // 4b
2435#ifdef PSXBIOS_LOG
2436 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x4b]);
2437#endif
2438
2439 if (CardState == 0) CardState = 1;
2440
2441 pc0 = ra;
2442}
2443
2444void psxBios_StopCARD() { // 4c
2445#ifdef PSXBIOS_LOG
2446 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x4c]);
2447#endif
2448
2449 if (CardState == 1) CardState = 0;
2450
2451 pc0 = ra;
2452}
2453
2454void psxBios__card_write() { // 0x4e
02949f79 2455 void *pa2 = Ra2;
ef79bbde
P
2456 int port;
2457
2458#ifdef PSXBIOS_LOG
2459 PSXBIOS_LOG("psxBios_%s: %x,%x,%x\n", biosB0n[0x4e], a0, a1, a2);
2460#endif
1059caaf 2461 /*
2462 Function also accepts sector 400h (a bug).
2463 But notaz said we shouldn't allow sector 400h because it can corrupt the emulator.
2464 */
2465 if (!(a1 <= 0x3FF))
bd48ba5e 2466 {
2467 /* Invalid sectors */
2468 v0 = 0; pc0 = ra;
2469 return;
2470 }
e9fda093 2471 card_active_chan = a0;
ef79bbde
P
2472 port = a0 >> 4;
2473
02949f79 2474 if (pa2) {
2475 if (port == 0) {
2476 memcpy(Mcd1Data + a1 * 128, pa2, 128);
2477 SaveMcd(Config.Mcd1, Mcd1Data, a1 * 128, 128);
2478 } else {
2479 memcpy(Mcd2Data + a1 * 128, pa2, 128);
2480 SaveMcd(Config.Mcd2, Mcd2Data, a1 * 128, 128);
2481 }
ef79bbde
P
2482 }
2483
2484 DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
2485// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
2486
2487 v0 = 1; pc0 = ra;
2488}
2489
2490void psxBios__card_read() { // 0x4f
02949f79 2491 void *pa2 = Ra2;
ef79bbde
P
2492 int port;
2493
2494#ifdef PSXBIOS_LOG
2495 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x4f]);
2496#endif
1059caaf 2497 /*
2498 Function also accepts sector 400h (a bug).
2499 But notaz said we shouldn't allow sector 400h because it can corrupt the emulator.
2500 */
2501 if (!(a1 <= 0x3FF))
bd48ba5e 2502 {
2503 /* Invalid sectors */
2504 v0 = 0; pc0 = ra;
2505 return;
2506 }
e9fda093 2507 card_active_chan = a0;
ef79bbde
P
2508 port = a0 >> 4;
2509
02949f79 2510 if (pa2) {
2511 if (port == 0) {
2512 memcpy(pa2, Mcd1Data + a1 * 128, 128);
2513 } else {
2514 memcpy(pa2, Mcd2Data + a1 * 128, 128);
2515 }
ef79bbde
P
2516 }
2517
2518 DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
2519// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
2520
2521 v0 = 1; pc0 = ra;
2522}
2523
2524void psxBios__new_card() { // 0x50
2525#ifdef PSXBIOS_LOG
2526 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x50]);
2527#endif
2528
2529 pc0 = ra;
2530}
2531
002b2f7d 2532/* According to a user, this allows Final Fantasy Tactics to save/load properly */
2533void psxBios__get_error(void) // 55
2534{
2535 v0 = 0;
2536 pc0 = ra;
2537}
2538
ef79bbde
P
2539void psxBios_Krom2RawAdd() { // 0x51
2540 int i = 0;
2541
2542 const u32 table_8140[][2] = {
2543 {0x8140, 0x0000}, {0x8180, 0x0762}, {0x81ad, 0x0cc6}, {0x81b8, 0x0ca8},
2544 {0x81c0, 0x0f00}, {0x81c8, 0x0d98}, {0x81cf, 0x10c2}, {0x81da, 0x0e6a},
2545 {0x81e9, 0x13ce}, {0x81f0, 0x102c}, {0x81f8, 0x1590}, {0x81fc, 0x111c},
2546 {0x81fd, 0x1626}, {0x824f, 0x113a}, {0x8259, 0x20ee}, {0x8260, 0x1266},
2547 {0x827a, 0x24cc}, {0x8281, 0x1572}, {0x829b, 0x28aa}, {0x829f, 0x187e},
2548 {0x82f2, 0x32dc}, {0x8340, 0x2238}, {0x837f, 0x4362}, {0x8380, 0x299a},
2549 {0x8397, 0x4632}, {0x839f, 0x2c4c}, {0x83b7, 0x49f2}, {0x83bf, 0x2f1c},
2550 {0x83d7, 0x4db2}, {0x8440, 0x31ec}, {0x8461, 0x5dde}, {0x8470, 0x35ca},
2551 {0x847f, 0x6162}, {0x8480, 0x378c}, {0x8492, 0x639c}, {0x849f, 0x39a8},
2552 {0xffff, 0}
2553 };
2554
2555 const u32 table_889f[][2] = {
2556 {0x889f, 0x3d68}, {0x8900, 0x40ec}, {0x897f, 0x4fb0}, {0x8a00, 0x56f4},
2557 {0x8a7f, 0x65b8}, {0x8b00, 0x6cfc}, {0x8b7f, 0x7bc0}, {0x8c00, 0x8304},
2558 {0x8c7f, 0x91c8}, {0x8d00, 0x990c}, {0x8d7f, 0xa7d0}, {0x8e00, 0xaf14},
2559 {0x8e7f, 0xbdd8}, {0x8f00, 0xc51c}, {0x8f7f, 0xd3e0}, {0x9000, 0xdb24},
2560 {0x907f, 0xe9e8}, {0x9100, 0xf12c}, {0x917f, 0xfff0}, {0x9200, 0x10734},
2561 {0x927f, 0x115f8}, {0x9300, 0x11d3c}, {0x937f, 0x12c00}, {0x9400, 0x13344},
2562 {0x947f, 0x14208}, {0x9500, 0x1494c}, {0x957f, 0x15810}, {0x9600, 0x15f54},
2563 {0x967f, 0x16e18}, {0x9700, 0x1755c}, {0x977f, 0x18420}, {0x9800, 0x18b64},
2564 {0xffff, 0}
2565 };
2566
2567 if (a0 >= 0x8140 && a0 <= 0x84be) {
2568 while (table_8140[i][0] <= a0) i++;
2569 a0 -= table_8140[i - 1][0];
2570 v0 = 0xbfc66000 + (a0 * 0x1e + table_8140[i - 1][1]);
2571 } else if (a0 >= 0x889f && a0 <= 0x9872) {
2572 while (table_889f[i][0] <= a0) i++;
2573 a0 -= table_889f[i - 1][0];
2574 v0 = 0xbfc66000 + (a0 * 0x1e + table_889f[i - 1][1]);
2575 } else {
2576 v0 = 0xffffffff;
2577 }
2578
2579 pc0 = ra;
2580}
2581
2582void psxBios_GetC0Table() { // 56
2583#ifdef PSXBIOS_LOG
2584 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x56]);
2585#endif
2586
2587 v0 = 0x674; pc0 = ra;
2588}
2589
2590void psxBios_GetB0Table() { // 57
2591#ifdef PSXBIOS_LOG
2592 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x57]);
2593#endif
2594
2595 v0 = 0x874; pc0 = ra;
2596}
2597
e9fda093 2598void psxBios__card_chan() { // 0x58
2599#ifdef PSXBIOS_LOG
2600 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x58]);
2601#endif
2602
2603 v0 = card_active_chan;
2604 pc0 = ra;
2605}
2606
ef79bbde
P
2607void psxBios_ChangeClearPad() { // 5b
2608#ifdef PSXBIOS_LOG
2609 PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x5b], a0);
2610#endif
2611
2612 pc0 = ra;
2613}
2614
21af3ff6 2615void psxBios__card_status() { // 5c
2616#ifdef PSXBIOS_LOG
2617 PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x5c], a0);
2618#endif
2619
cf1af0ed 2620 v0 = card_active_chan;
21af3ff6 2621 pc0 = ra;
2622}
2623
5f652aa9 2624void psxBios__card_wait() { // 5d
2625#ifdef PSXBIOS_LOG
2626 PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x5d], a0);
2627#endif
2628
2629 v0 = 1;
2630 pc0 = ra;
2631}
2632
ef79bbde
P
2633/* System calls C0 */
2634
2635/*
2636 * int SysEnqIntRP(int index , long *queue);
2637 */
2638
2639void psxBios_SysEnqIntRP() { // 02
2640#ifdef PSXBIOS_LOG
2641 PSXBIOS_LOG("psxBios_%s: %x\n", biosC0n[0x02] ,a0);
2642#endif
2643
2644 SysIntRP[a0] = a1;
2645
2646 v0 = 0; pc0 = ra;
2647}
2648
2649/*
2650 * int SysDeqIntRP(int index , long *queue);
2651 */
2652
2653void psxBios_SysDeqIntRP() { // 03
2654#ifdef PSXBIOS_LOG
2655 PSXBIOS_LOG("psxBios_%s: %x\n", biosC0n[0x03], a0);
2656#endif
2657
2658 SysIntRP[a0] = 0;
2659
2660 v0 = 0; pc0 = ra;
2661}
2662
2663void psxBios_ChangeClearRCnt() { // 0a
2664 u32 *ptr;
2665
2666#ifdef PSXBIOS_LOG
2667 PSXBIOS_LOG("psxBios_%s: %x, %x\n", biosC0n[0x0a], a0, a1);
2668#endif
2669
2670 ptr = (u32*)PSXM((a0 << 2) + 0x8600);
2671 v0 = *ptr;
2672 *ptr = a1;
2673
2674// psxRegs.CP0.n.Status|= 0x404;
2675 pc0 = ra;
2676}
2677
2678void psxBios_dummy() {
2679#ifdef PSXBIOS_LOG
2680 PSXBIOS_LOG("unk %x call: %x\n", pc0 & 0x1fffff, t1);
2681#endif
2682 pc0 = ra;
2683}
2684
2685void (*biosA0[256])();
2686void (*biosB0[256])();
2687void (*biosC0[256])();
2688
2689#include "sjisfont.h"
2690
2691void psxBiosInit() {
2692 u32 base, size;
2693 u32 *ptr;
2694 int i;
2695 uLongf len;
2696
2697 for(i = 0; i < 256; i++) {
2698 biosA0[i] = NULL;
2699 biosB0[i] = NULL;
2700 biosC0[i] = NULL;
2701 }
2702 biosA0[0x3e] = psxBios_puts;
2703 biosA0[0x3f] = psxBios_printf;
2704
2705 biosB0[0x3d] = psxBios_putchar;
2706 biosB0[0x3f] = psxBios_puts;
2707
2708 if (!Config.HLE) return;
2709
2710 for(i = 0; i < 256; i++) {
2711 if (biosA0[i] == NULL) biosA0[i] = psxBios_dummy;
2712 if (biosB0[i] == NULL) biosB0[i] = psxBios_dummy;
2713 if (biosC0[i] == NULL) biosC0[i] = psxBios_dummy;
2714 }
2715
2716 biosA0[0x00] = psxBios_open;
2717 biosA0[0x01] = psxBios_lseek;
2718 biosA0[0x02] = psxBios_read;
2719 biosA0[0x03] = psxBios_write;
2720 biosA0[0x04] = psxBios_close;
2721 //biosA0[0x05] = psxBios_ioctl;
2722 //biosA0[0x06] = psxBios_exit;
2723 //biosA0[0x07] = psxBios_sys_a0_07;
324cec89 2724 biosA0[0x08] = psxBios_getc;
2725 biosA0[0x09] = psxBios_putc;
ba11675c 2726 biosA0[0x0a] = psxBios_todigit;
ef79bbde
P
2727 //biosA0[0x0b] = psxBios_atof;
2728 //biosA0[0x0c] = psxBios_strtoul;
2729 //biosA0[0x0d] = psxBios_strtol;
2730 biosA0[0x0e] = psxBios_abs;
2731 biosA0[0x0f] = psxBios_labs;
2732 biosA0[0x10] = psxBios_atoi;
2733 biosA0[0x11] = psxBios_atol;
2734 //biosA0[0x12] = psxBios_atob;
2735 biosA0[0x13] = psxBios_setjmp;
2736 biosA0[0x14] = psxBios_longjmp;
2737 biosA0[0x15] = psxBios_strcat;
2738 biosA0[0x16] = psxBios_strncat;
2739 biosA0[0x17] = psxBios_strcmp;
2740 biosA0[0x18] = psxBios_strncmp;
2741 biosA0[0x19] = psxBios_strcpy;
2742 biosA0[0x1a] = psxBios_strncpy;
2743 biosA0[0x1b] = psxBios_strlen;
2744 biosA0[0x1c] = psxBios_index;
2745 biosA0[0x1d] = psxBios_rindex;
2746 biosA0[0x1e] = psxBios_strchr;
2747 biosA0[0x1f] = psxBios_strrchr;
2748 biosA0[0x20] = psxBios_strpbrk;
2749 biosA0[0x21] = psxBios_strspn;
2750 biosA0[0x22] = psxBios_strcspn;
2751 biosA0[0x23] = psxBios_strtok;
2752 biosA0[0x24] = psxBios_strstr;
2753 biosA0[0x25] = psxBios_toupper;
2754 biosA0[0x26] = psxBios_tolower;
2755 biosA0[0x27] = psxBios_bcopy;
2756 biosA0[0x28] = psxBios_bzero;
2757 biosA0[0x29] = psxBios_bcmp;
2758 biosA0[0x2a] = psxBios_memcpy;
2759 biosA0[0x2b] = psxBios_memset;
2760 biosA0[0x2c] = psxBios_memmove;
2761 biosA0[0x2d] = psxBios_memcmp;
2762 biosA0[0x2e] = psxBios_memchr;
2763 biosA0[0x2f] = psxBios_rand;
2764 biosA0[0x30] = psxBios_srand;
2765 biosA0[0x31] = psxBios_qsort;
2766 //biosA0[0x32] = psxBios_strtod;
2767 biosA0[0x33] = psxBios_malloc;
2768 biosA0[0x34] = psxBios_free;
2769 //biosA0[0x35] = psxBios_lsearch;
2770 //biosA0[0x36] = psxBios_bsearch;
2771 biosA0[0x37] = psxBios_calloc;
2772 biosA0[0x38] = psxBios_realloc;
2773 biosA0[0x39] = psxBios_InitHeap;
2774 //biosA0[0x3a] = psxBios__exit;
2775 biosA0[0x3b] = psxBios_getchar;
2776 biosA0[0x3c] = psxBios_putchar;
2777 //biosA0[0x3d] = psxBios_gets;
2778 //biosA0[0x40] = psxBios_sys_a0_40;
2779 //biosA0[0x41] = psxBios_LoadTest;
2780 biosA0[0x42] = psxBios_Load;
2781 biosA0[0x43] = psxBios_Exec;
2782 biosA0[0x44] = psxBios_FlushCache;
2783 //biosA0[0x45] = psxBios_InstallInterruptHandler;
2784 biosA0[0x46] = psxBios_GPU_dw;
2785 biosA0[0x47] = psxBios_mem2vram;
2786 biosA0[0x48] = psxBios_SendGPU;
2787 biosA0[0x49] = psxBios_GPU_cw;
2788 biosA0[0x4a] = psxBios_GPU_cwb;
2789 biosA0[0x4b] = psxBios_GPU_SendPackets;
2790 biosA0[0x4c] = psxBios_sys_a0_4c;
2791 biosA0[0x4d] = psxBios_GPU_GetGPUStatus;
2792 //biosA0[0x4e] = psxBios_GPU_sync;
2793 //biosA0[0x4f] = psxBios_sys_a0_4f;
2794 //biosA0[0x50] = psxBios_sys_a0_50;
2795 biosA0[0x51] = psxBios_LoadExec;
2796 //biosA0[0x52] = psxBios_GetSysSp;
2797 //biosA0[0x53] = psxBios_sys_a0_53;
2798 //biosA0[0x54] = psxBios__96_init_a54;
2799 //biosA0[0x55] = psxBios__bu_init_a55;
2800 //biosA0[0x56] = psxBios__96_remove_a56;
2801 //biosA0[0x57] = psxBios_sys_a0_57;
2802 //biosA0[0x58] = psxBios_sys_a0_58;
2803 //biosA0[0x59] = psxBios_sys_a0_59;
2804 //biosA0[0x5a] = psxBios_sys_a0_5a;
2805 //biosA0[0x5b] = psxBios_dev_tty_init;
2806 //biosA0[0x5c] = psxBios_dev_tty_open;
2807 //biosA0[0x5d] = psxBios_sys_a0_5d;
2808 //biosA0[0x5e] = psxBios_dev_tty_ioctl;
2809 //biosA0[0x5f] = psxBios_dev_cd_open;
2810 //biosA0[0x60] = psxBios_dev_cd_read;
2811 //biosA0[0x61] = psxBios_dev_cd_close;
2812 //biosA0[0x62] = psxBios_dev_cd_firstfile;
2813 //biosA0[0x63] = psxBios_dev_cd_nextfile;
2814 //biosA0[0x64] = psxBios_dev_cd_chdir;
2815 //biosA0[0x65] = psxBios_dev_card_open;
2816 //biosA0[0x66] = psxBios_dev_card_read;
2817 //biosA0[0x67] = psxBios_dev_card_write;
2818 //biosA0[0x68] = psxBios_dev_card_close;
2819 //biosA0[0x69] = psxBios_dev_card_firstfile;
2820 //biosA0[0x6a] = psxBios_dev_card_nextfile;
2821 //biosA0[0x6b] = psxBios_dev_card_erase;
2822 //biosA0[0x6c] = psxBios_dev_card_undelete;
2823 //biosA0[0x6d] = psxBios_dev_card_format;
2824 //biosA0[0x6e] = psxBios_dev_card_rename;
2825 //biosA0[0x6f] = psxBios_dev_card_6f;
2826 biosA0[0x70] = psxBios__bu_init;
2827 biosA0[0x71] = psxBios__96_init;
2828 biosA0[0x72] = psxBios__96_remove;
2829 //biosA0[0x73] = psxBios_sys_a0_73;
2830 //biosA0[0x74] = psxBios_sys_a0_74;
2831 //biosA0[0x75] = psxBios_sys_a0_75;
2832 //biosA0[0x76] = psxBios_sys_a0_76;
2833 //biosA0[0x77] = psxBios_sys_a0_77;
2834 //biosA0[0x78] = psxBios__96_CdSeekL;
2835 //biosA0[0x79] = psxBios_sys_a0_79;
2836 //biosA0[0x7a] = psxBios_sys_a0_7a;
2837 //biosA0[0x7b] = psxBios_sys_a0_7b;
2838 //biosA0[0x7c] = psxBios__96_CdGetStatus;
2839 //biosA0[0x7d] = psxBios_sys_a0_7d;
2840 //biosA0[0x7e] = psxBios__96_CdRead;
2841 //biosA0[0x7f] = psxBios_sys_a0_7f;
2842 //biosA0[0x80] = psxBios_sys_a0_80;
2843 //biosA0[0x81] = psxBios_sys_a0_81;
2844 //biosA0[0x82] = psxBios_sys_a0_82;
2845 //biosA0[0x83] = psxBios_sys_a0_83;
2846 //biosA0[0x84] = psxBios_sys_a0_84;
2847 //biosA0[0x85] = psxBios__96_CdStop;
2848 //biosA0[0x86] = psxBios_sys_a0_86;
2849 //biosA0[0x87] = psxBios_sys_a0_87;
2850 //biosA0[0x88] = psxBios_sys_a0_88;
2851 //biosA0[0x89] = psxBios_sys_a0_89;
2852 //biosA0[0x8a] = psxBios_sys_a0_8a;
2853 //biosA0[0x8b] = psxBios_sys_a0_8b;
2854 //biosA0[0x8c] = psxBios_sys_a0_8c;
2855 //biosA0[0x8d] = psxBios_sys_a0_8d;
2856 //biosA0[0x8e] = psxBios_sys_a0_8e;
2857 //biosA0[0x8f] = psxBios_sys_a0_8f;
2858 //biosA0[0x90] = psxBios_sys_a0_90;
2859 //biosA0[0x91] = psxBios_sys_a0_91;
2860 //biosA0[0x92] = psxBios_sys_a0_92;
2861 //biosA0[0x93] = psxBios_sys_a0_93;
2862 //biosA0[0x94] = psxBios_sys_a0_94;
2863 //biosA0[0x95] = psxBios_sys_a0_95;
2864 //biosA0[0x96] = psxBios_AddCDROMDevice;
2865 //biosA0[0x97] = psxBios_AddMemCardDevide;
2866 //biosA0[0x98] = psxBios_DisableKernelIORedirection;
2867 //biosA0[0x99] = psxBios_EnableKernelIORedirection;
2868 //biosA0[0x9a] = psxBios_sys_a0_9a;
2869 //biosA0[0x9b] = psxBios_sys_a0_9b;
2870 //biosA0[0x9c] = psxBios_SetConf;
2871 //biosA0[0x9d] = psxBios_GetConf;
2872 //biosA0[0x9e] = psxBios_sys_a0_9e;
2873 biosA0[0x9f] = psxBios_SetMem;
2874 //biosA0[0xa0] = psxBios__boot;
2875 //biosA0[0xa1] = psxBios_SystemError;
2876 //biosA0[0xa2] = psxBios_EnqueueCdIntr;
2877 //biosA0[0xa3] = psxBios_DequeueCdIntr;
2878 //biosA0[0xa4] = psxBios_sys_a0_a4;
2879 //biosA0[0xa5] = psxBios_ReadSector;
18dd7e9e 2880 biosA0[0xa6] = psxBios_get_cd_status;
ef79bbde
P
2881 //biosA0[0xa7] = psxBios_bufs_cb_0;
2882 //biosA0[0xa8] = psxBios_bufs_cb_1;
2883 //biosA0[0xa9] = psxBios_bufs_cb_2;
2884 //biosA0[0xaa] = psxBios_bufs_cb_3;
2885 biosA0[0xab] = psxBios__card_info;
2886 biosA0[0xac] = psxBios__card_load;
2887 //biosA0[0axd] = psxBios__card_auto;
2888 //biosA0[0xae] = psxBios_bufs_cd_4;
2889 //biosA0[0xaf] = psxBios_sys_a0_af;
2890 //biosA0[0xb0] = psxBios_sys_a0_b0;
2891 //biosA0[0xb1] = psxBios_sys_a0_b1;
2892 //biosA0[0xb2] = psxBios_do_a_long_jmp
2893 //biosA0[0xb3] = psxBios_sys_a0_b3;
2894 //biosA0[0xb4] = psxBios_sub_function;
2895//*******************B0 CALLS****************************
2896 //biosB0[0x00] = psxBios_SysMalloc;
2897 //biosB0[0x01] = psxBios_sys_b0_01;
2898 biosB0[0x02] = psxBios_SetRCnt;
2899 biosB0[0x03] = psxBios_GetRCnt;
2900 biosB0[0x04] = psxBios_StartRCnt;
2901 biosB0[0x05] = psxBios_StopRCnt;
2902 biosB0[0x06] = psxBios_ResetRCnt;
2903 biosB0[0x07] = psxBios_DeliverEvent;
2904 biosB0[0x08] = psxBios_OpenEvent;
2905 biosB0[0x09] = psxBios_CloseEvent;
2906 biosB0[0x0a] = psxBios_WaitEvent;
2907 biosB0[0x0b] = psxBios_TestEvent;
2908 biosB0[0x0c] = psxBios_EnableEvent;
2909 biosB0[0x0d] = psxBios_DisableEvent;
2910 biosB0[0x0e] = psxBios_OpenTh;
2911 biosB0[0x0f] = psxBios_CloseTh;
2912 biosB0[0x10] = psxBios_ChangeTh;
2913 //biosB0[0x11] = psxBios_psxBios_b0_11;
2914 biosB0[0x12] = psxBios_InitPAD;
2915 biosB0[0x13] = psxBios_StartPAD;
2916 biosB0[0x14] = psxBios_StopPAD;
2917 biosB0[0x15] = psxBios_PAD_init;
2918 biosB0[0x16] = psxBios_PAD_dr;
2919 biosB0[0x17] = psxBios_ReturnFromException;
2920 biosB0[0x18] = psxBios_ResetEntryInt;
2921 biosB0[0x19] = psxBios_HookEntryInt;
2922 //biosB0[0x1a] = psxBios_sys_b0_1a;
2923 //biosB0[0x1b] = psxBios_sys_b0_1b;
2924 //biosB0[0x1c] = psxBios_sys_b0_1c;
2925 //biosB0[0x1d] = psxBios_sys_b0_1d;
2926 //biosB0[0x1e] = psxBios_sys_b0_1e;
2927 //biosB0[0x1f] = psxBios_sys_b0_1f;
2928 biosB0[0x20] = psxBios_UnDeliverEvent;
2929 //biosB0[0x21] = psxBios_sys_b0_21;
2930 //biosB0[0x22] = psxBios_sys_b0_22;
2931 //biosB0[0x23] = psxBios_sys_b0_23;
2932 //biosB0[0x24] = psxBios_sys_b0_24;
2933 //biosB0[0x25] = psxBios_sys_b0_25;
2934 //biosB0[0x26] = psxBios_sys_b0_26;
2935 //biosB0[0x27] = psxBios_sys_b0_27;
2936 //biosB0[0x28] = psxBios_sys_b0_28;
2937 //biosB0[0x29] = psxBios_sys_b0_29;
2938 //biosB0[0x2a] = psxBios_sys_b0_2a;
2939 //biosB0[0x2b] = psxBios_sys_b0_2b;
2940 //biosB0[0x2c] = psxBios_sys_b0_2c;
2941 //biosB0[0x2d] = psxBios_sys_b0_2d;
2942 //biosB0[0x2e] = psxBios_sys_b0_2e;
2943 //biosB0[0x2f] = psxBios_sys_b0_2f;
2944 //biosB0[0x30] = psxBios_sys_b0_30;
2945 //biosB0[0x31] = psxBios_sys_b0_31;
2946 biosB0[0x32] = psxBios_open;
2947 biosB0[0x33] = psxBios_lseek;
2948 biosB0[0x34] = psxBios_read;
2949 biosB0[0x35] = psxBios_write;
2950 biosB0[0x36] = psxBios_close;
2951 //biosB0[0x37] = psxBios_ioctl;
2952 //biosB0[0x38] = psxBios_exit;
2953 //biosB0[0x39] = psxBios_sys_b0_39;
2954 //biosB0[0x3a] = psxBios_getc;
2955 //biosB0[0x3b] = psxBios_putc;
2956 biosB0[0x3c] = psxBios_getchar;
2957 //biosB0[0x3e] = psxBios_gets;
2958 //biosB0[0x40] = psxBios_cd;
e7e1f572 2959 biosB0[0x41] = psxBios_format;
ef79bbde
P
2960 biosB0[0x42] = psxBios_firstfile;
2961 biosB0[0x43] = psxBios_nextfile;
2962 biosB0[0x44] = psxBios_rename;
2963 biosB0[0x45] = psxBios_delete;
2964 //biosB0[0x46] = psxBios_undelete;
2965 //biosB0[0x47] = psxBios_AddDevice;
2966 //biosB0[0x48] = psxBios_RemoteDevice;
2967 //biosB0[0x49] = psxBios_PrintInstalledDevices;
2968 biosB0[0x4a] = psxBios_InitCARD;
2969 biosB0[0x4b] = psxBios_StartCARD;
2970 biosB0[0x4c] = psxBios_StopCARD;
2971 //biosB0[0x4d] = psxBios_sys_b0_4d;
2972 biosB0[0x4e] = psxBios__card_write;
2973 biosB0[0x4f] = psxBios__card_read;
2974 biosB0[0x50] = psxBios__new_card;
2975 biosB0[0x51] = psxBios_Krom2RawAdd;
2976 //biosB0[0x52] = psxBios_sys_b0_52;
2977 //biosB0[0x53] = psxBios_sys_b0_53;
2978 //biosB0[0x54] = psxBios__get_errno;
002b2f7d 2979 biosB0[0x55] = psxBios__get_error;
ef79bbde
P
2980 biosB0[0x56] = psxBios_GetC0Table;
2981 biosB0[0x57] = psxBios_GetB0Table;
e9fda093 2982 biosB0[0x58] = psxBios__card_chan;
ef79bbde
P
2983 //biosB0[0x59] = psxBios_sys_b0_59;
2984 //biosB0[0x5a] = psxBios_sys_b0_5a;
2985 biosB0[0x5b] = psxBios_ChangeClearPad;
21af3ff6 2986 biosB0[0x5c] = psxBios__card_status;
5f652aa9 2987 biosB0[0x5d] = psxBios__card_wait;
ef79bbde
P
2988//*******************C0 CALLS****************************
2989 //biosC0[0x00] = psxBios_InitRCnt;
2990 //biosC0[0x01] = psxBios_InitException;
2991 biosC0[0x02] = psxBios_SysEnqIntRP;
2992 biosC0[0x03] = psxBios_SysDeqIntRP;
2993 //biosC0[0x04] = psxBios_get_free_EvCB_slot;
2994 //biosC0[0x05] = psxBios_get_free_TCB_slot;
2995 //biosC0[0x06] = psxBios_ExceptionHandler;
2996 //biosC0[0x07] = psxBios_InstallExeptionHandler;
2997 //biosC0[0x08] = psxBios_SysInitMemory;
2998 //biosC0[0x09] = psxBios_SysInitKMem;
2999 biosC0[0x0a] = psxBios_ChangeClearRCnt;
3000 //biosC0[0x0b] = psxBios_SystemError;
3001 //biosC0[0x0c] = psxBios_InitDefInt;
3002 //biosC0[0x0d] = psxBios_sys_c0_0d;
3003 //biosC0[0x0e] = psxBios_sys_c0_0e;
3004 //biosC0[0x0f] = psxBios_sys_c0_0f;
3005 //biosC0[0x10] = psxBios_sys_c0_10;
3006 //biosC0[0x11] = psxBios_sys_c0_11;
3007 //biosC0[0x12] = psxBios_InstallDevices;
3008 //biosC0[0x13] = psxBios_FlushStfInOutPut;
3009 //biosC0[0x14] = psxBios_sys_c0_14;
3010 //biosC0[0x15] = psxBios__cdevinput;
3011 //biosC0[0x16] = psxBios__cdevscan;
3012 //biosC0[0x17] = psxBios__circgetc;
3013 //biosC0[0x18] = psxBios__circputc;
3014 //biosC0[0x19] = psxBios_ioabort;
3015 //biosC0[0x1a] = psxBios_sys_c0_1a
3016 //biosC0[0x1b] = psxBios_KernelRedirect;
3017 //biosC0[0x1c] = psxBios_PatchAOTable;
3018//************** THE END ***************************************
3019/**/
3020 base = 0x1000;
3021 size = sizeof(EvCB) * 32;
3022 Event = (void *)&psxR[base]; base += size * 6;
3023 memset(Event, 0, size * 6);
3024 HwEV = Event;
3025 EvEV = Event + 32;
3026 RcEV = Event + 32 * 2;
3027 UeEV = Event + 32 * 3;
3028 SwEV = Event + 32 * 4;
3029 ThEV = Event + 32 * 5;
3030
3031 ptr = (u32 *)&psxM[0x0874]; // b0 table
3032 ptr[0] = SWAPu32(0x4c54 - 0x884);
3033
3034 ptr = (u32 *)&psxM[0x0674]; // c0 table
3035 ptr[6] = SWAPu32(0xc80);
3036
3037 memset(SysIntRP, 0, sizeof(SysIntRP));
3038 memset(Thread, 0, sizeof(Thread));
3039 Thread[0].status = 2; // main thread
3040
832f0c3c 3041 pad_stopped = 1;
c62b43c9 3042 jmp_int = NULL;
3043 pad_buf = NULL;
3044 pad_buf1 = NULL;
3045 pad_buf2 = NULL;
3046 pad_buf1len = pad_buf2len = 0;
3047 heap_addr = NULL;
3048 heap_end = NULL;
26b964b5 3049 heap_size = 0;
c62b43c9 3050 CardState = -1;
3051 CurThread = 0;
3052 memset(FDesc, 0, sizeof(FDesc));
832f0c3c 3053 card_active_chan = 0;
c62b43c9 3054
ef79bbde
P
3055 psxMu32ref(0x0150) = SWAPu32(0x160);
3056 psxMu32ref(0x0154) = SWAPu32(0x320);
3057 psxMu32ref(0x0160) = SWAPu32(0x248);
3058 strcpy((char *)&psxM[0x248], "bu");
3059/* psxMu32ref(0x0ca8) = SWAPu32(0x1f410004);
3060 psxMu32ref(0x0cf0) = SWAPu32(0x3c020000);
3061 psxMu32ref(0x0cf4) = SWAPu32(0x2442641c);
3062 psxMu32ref(0x09e0) = SWAPu32(0x43d0);
3063 psxMu32ref(0x4d98) = SWAPu32(0x946f000a);
3064*/
3065 // opcode HLE
3066 psxRu32ref(0x0000) = SWAPu32((0x3b << 26) | 4);
bf643fd9 3067 /* Whatever this does, it actually breaks CTR, even without the uninitiliazed memory patch.
3068 Normally games shouldn't read from address 0 yet they do. See explanation below in details. */
3069 //psxMu32ref(0x0000) = SWAPu32((0x3b << 26) | 0);
ef79bbde
P
3070 psxMu32ref(0x00a0) = SWAPu32((0x3b << 26) | 1);
3071 psxMu32ref(0x00b0) = SWAPu32((0x3b << 26) | 2);
3072 psxMu32ref(0x00c0) = SWAPu32((0x3b << 26) | 3);
3073 psxMu32ref(0x4c54) = SWAPu32((0x3b << 26) | 0);
3074 psxMu32ref(0x8000) = SWAPu32((0x3b << 26) | 5);
3075 psxMu32ref(0x07a0) = SWAPu32((0x3b << 26) | 0);
3076 psxMu32ref(0x0884) = SWAPu32((0x3b << 26) | 0);
3077 psxMu32ref(0x0894) = SWAPu32((0x3b << 26) | 0);
3078
3079 // initial stack pointer for BIOS interrupt
3080 psxMu32ref(0x6c80) = SWAPu32(0x000085c8);
3081
3082 // initial RNG seed
3083 psxMu32ref(0x9010) = SWAPu32(0xac20cc00);
3084
3085 // fonts
3086 len = 0x80000 - 0x66000;
3087 uncompress((Bytef *)(psxR + 0x66000), &len, font_8140, sizeof(font_8140));
3088 len = 0x80000 - 0x69d68;
3089 uncompress((Bytef *)(psxR + 0x69d68), &len, font_889f, sizeof(font_889f));
3090
3091 // memory size 2 MB
3092 psxHu32ref(0x1060) = SWAPu32(0x00000b88);
3093
3094 hleSoftCall = FALSE;
bf643fd9 3095
3096 /* Some games like R-Types, CTR, Fade to Black read from adress 0x00000000 due to uninitialized pointers.
3097 See Garbage Area at Address 00000000h in Nocash PSX Specfications for more information.
339cc5b6 3098 Here are some examples of games not working with this fix in place :
3099 R-type won't get past the Irem logo if not implemented.
3100 Crash Team Racing will softlock after the Sony logo.
bf643fd9 3101 */
339cc5b6 3102
3103 psxMu32ref(0x0000) = SWAPu32(0x00000003);
3104 /*
3105 But overwritten by 00000003h after soon.
3106 psxMu32ref(0x0000) = SWAPu32(0x00001A3C);
3107 */
3108 psxMu32ref(0x0004) = SWAPu32(0x800C5A27);
3109 psxMu32ref(0x0008) = SWAPu32(0x08000403);
3110 psxMu32ref(0x000C) = SWAPu32(0x00000000);
ef79bbde
P
3111}
3112
3113void psxBiosShutdown() {
3114}
3115
3116#define psxBios_PADpoll(pad) { \
3117 PAD##pad##_startPoll(pad); \
3118 pad_buf##pad[0] = 0; \
3119 pad_buf##pad[1] = PAD##pad##_poll(0x42); \
3120 if (!(pad_buf##pad[1] & 0x0f)) { \
3121 bufcount = 32; \
3122 } else { \
3123 bufcount = (pad_buf##pad[1] & 0x0f) * 2; \
3124 } \
3125 PAD##pad##_poll(0); \
3126 i = 2; \
3127 while (bufcount--) { \
3128 pad_buf##pad[i++] = PAD##pad##_poll(0); \
3129 } \
3130}
3131
3132void biosInterrupt() {
3133 int i, bufcount;
3134
3135// if (psxHu32(0x1070) & 0x1) { // Vsync
3136 if (pad_buf != NULL) {
3137 u32 *buf = (u32*)pad_buf;
3138
3139 if (!Config.UseNet) {
3140 PAD1_startPoll(1);
3141 if (PAD1_poll(0x42) == 0x23) {
3142 PAD1_poll(0);
3143 *buf = PAD1_poll(0) << 8;
3144 *buf |= PAD1_poll(0);
3145 PAD1_poll(0);
3146 *buf &= ~((PAD1_poll(0) > 0x20) ? 1 << 6 : 0);
3147 *buf &= ~((PAD1_poll(0) > 0x20) ? 1 << 7 : 0);
3148 } else {
3149 PAD1_poll(0);
3150 *buf = PAD1_poll(0) << 8;
3151 *buf|= PAD1_poll(0);
3152 }
3153
3154 PAD2_startPoll(2);
3155 if (PAD2_poll(0x42) == 0x23) {
3156 PAD2_poll(0);
3157 *buf |= PAD2_poll(0) << 24;
3158 *buf |= PAD2_poll(0) << 16;
3159 PAD2_poll(0);
3160 *buf &= ~((PAD2_poll(0) > 0x20) ? 1 << 22 : 0);
3161 *buf &= ~((PAD2_poll(0) > 0x20) ? 1 << 23 : 0);
3162 } else {
3163 PAD2_poll(0);
3164 *buf |= PAD2_poll(0) << 24;
3165 *buf |= PAD2_poll(0) << 16;
3166 }
3167 } else {
3168 u16 data;
3169
3170 PAD1_startPoll(1);
3171 PAD1_poll(0x42);
3172 PAD1_poll(0);
3173 data = PAD1_poll(0) << 8;
3174 data |= PAD1_poll(0);
3175
3176 if (NET_sendPadData(&data, 2) == -1)
3177 netError();
3178
3179 if (NET_recvPadData(&((u16*)buf)[0], 1) == -1)
3180 netError();
3181 if (NET_recvPadData(&((u16*)buf)[1], 2) == -1)
3182 netError();
3183 }
3184 }
3185 if (Config.UseNet && pad_buf1 != NULL && pad_buf2 != NULL) {
3186 psxBios_PADpoll(1);
3187
3188 if (NET_sendPadData(pad_buf1, i) == -1)
3189 netError();
3190
3191 if (NET_recvPadData(pad_buf1, 1) == -1)
3192 netError();
3193 if (NET_recvPadData(pad_buf2, 2) == -1)
3194 netError();
3195 } else {
f25c285b 3196 if (!pad_stopped) {
3197 if (pad_buf1) {
3198 psxBios_PADpoll(1);
3199 }
ef79bbde 3200
f25c285b 3201 if (pad_buf2) {
3202 psxBios_PADpoll(2);
3203 }
ef79bbde
P
3204 }
3205 }
3206
3207 if (psxHu32(0x1070) & 0x1) { // Vsync
3208 if (RcEV[3][1].status == EvStACTIVE) {
3209 softCall(RcEV[3][1].fhandler);
3210// hwWrite32(0x1f801070, ~(1));
3211 }
3212 }
3213
3214 if (psxHu32(0x1070) & 0x70) { // Rcnt 0,1,2
3215 int i;
3216
3217 for (i = 0; i < 3; i++) {
3218 if (psxHu32(0x1070) & (1 << (i + 4))) {
3219 if (RcEV[i][1].status == EvStACTIVE) {
3220 softCall(RcEV[i][1].fhandler);
3221 }
3222 psxHwWrite32(0x1f801070, ~(1 << (i + 4)));
3223 }
3224 }
3225 }
3226}
3227
3228void psxBiosException() {
3229 int i;
3230
3231 switch (psxRegs.CP0.n.Cause & 0x3c) {
3232 case 0x00: // Interrupt
f23c2241 3233 interrupt_r26=psxRegs.CP0.n.EPC;
ef79bbde
P
3234#ifdef PSXCPU_LOG
3235// PSXCPU_LOG("interrupt\n");
3236#endif
3237 SaveRegs();
3238
3239 sp = psxMu32(0x6c80); // create new stack for interrupt handlers
3240
3241 biosInterrupt();
3242
3243 for (i = 0; i < 8; i++) {
3244 if (SysIntRP[i]) {
3245 u32 *queue = (u32 *)PSXM(SysIntRP[i]);
3246
3247 s0 = queue[2];
3248 softCall(queue[1]);
3249 }
3250 }
3251
3252 if (jmp_int != NULL) {
3253 int i;
3254
3255 psxHwWrite32(0x1f801070, 0xffffffff);
3256
3257 ra = jmp_int[0];
3258 sp = jmp_int[1];
3259 fp = jmp_int[2];
3260 for (i = 0; i < 8; i++) // s0-s7
3261 psxRegs.GPR.r[16 + i] = jmp_int[3 + i];
3262 gp = jmp_int[11];
3263
3264 v0 = 1;
3265 pc0 = ra;
3266 return;
3267 }
3268 psxHwWrite16(0x1f801070, 0);
3269 break;
3270
3271 case 0x20: // Syscall
3272#ifdef PSXCPU_LOG
3273 PSXCPU_LOG("syscall exp %x\n", a0);
3274#endif
3275 switch (a0) {
3276 case 1: // EnterCritical - disable irq's
79dad1b3 3277 /* Fixes Medievil 2 not loading up new game, Digimon World not booting up and possibly others */
3278 v0 = (psxRegs.CP0.n.Status & 0x404) == 0x404;
3279 psxRegs.CP0.n.Status &= ~0x404;
ef79bbde
P
3280 break;
3281
3282 case 2: // ExitCritical - enable irq's
3283 psxRegs.CP0.n.Status |= 0x404;
3284 break;
a946d159 3285 /* Normally this should cover SYS(00h, SYS(04h but they don't do anything relevant so... */
3286 default:
3287 break;
ef79bbde
P
3288 }
3289 pc0 = psxRegs.CP0.n.EPC + 4;
3290
3291 psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) |
3292 ((psxRegs.CP0.n.Status & 0x3c) >> 2);
3293 return;
3294
3295 default:
3296#ifdef PSXCPU_LOG
3297 PSXCPU_LOG("unknown bios exception!\n");
3298#endif
3299 break;
3300 }
3301
3302 pc0 = psxRegs.CP0.n.EPC;
3303 if (psxRegs.CP0.n.Cause & 0x80000000) pc0+=4;
3304
3305 psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) |
3306 ((psxRegs.CP0.n.Status & 0x3c) >> 2);
3307}
3308
3309#define bfreeze(ptr, size) { \
3310 if (Mode == 1) memcpy(&psxR[base], ptr, size); \
3311 if (Mode == 0) memcpy(ptr, &psxR[base], size); \
3312 base += size; \
3313}
3314
3315#define bfreezes(ptr) bfreeze(ptr, sizeof(ptr))
3316#define bfreezel(ptr) bfreeze(ptr, sizeof(*ptr))
3317
3318#define bfreezepsxMptr(ptr, type) { \
3319 if (Mode == 1) { \
3320 if (ptr) psxRu32ref(base) = SWAPu32((s8 *)(ptr) - psxM); \
3321 else psxRu32ref(base) = 0; \
3322 } else { \
3323 if (psxRu32(base) != 0) ptr = (type *)(psxM + psxRu32(base)); \
3324 else (ptr) = NULL; \
3325 } \
3326 base += sizeof(u32); \
3327}
3328
3329void psxBiosFreeze(int Mode) {
3330 u32 base = 0x40000;
3331
3332 bfreezepsxMptr(jmp_int, u32);
3333 bfreezepsxMptr(pad_buf, int);
3334 bfreezepsxMptr(pad_buf1, char);
3335 bfreezepsxMptr(pad_buf2, char);
3336 bfreezepsxMptr(heap_addr, u32);
3337 bfreezel(&pad_buf1len);
3338 bfreezel(&pad_buf2len);
3339 bfreezes(regs);
3340 bfreezes(SysIntRP);
3341 bfreezel(&CardState);
3342 bfreezes(Thread);
3343 bfreezel(&CurThread);
3344 bfreezes(FDesc);
e9fda093 3345 bfreezel(&card_active_chan);
a15f3544 3346 bfreezel(&pad_stopped);
17b2d969 3347 bfreezel(&heap_size);
ef79bbde 3348}