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