+ ram32 = (u32 *)psxM;
+ ram32[0x0000/4] = SWAPu32(0x00000003); // lui $k0, 0 (overwritten by 3)
+ ram32[0x0004/4] = SWAPu32(0x275a0000 + A_EXCEPTION); // addiu $k0, $k0, 0xc80
+ ram32[0x0008/4] = SWAPu32(0x03400008); // jr $k0
+ ram32[0x000c/4] = SWAPu32(0x00000000); // nop
+
+ ram32[0x0060/4] = SWAPu32(0x00000002); // ram size?
+ ram32[0x0068/4] = SWAPu32(0x000000ff); // unknown
+
+ ram32[0x0080/4] = SWAPu32(0x3c1a0000); // lui $k0, 0 // exception vector
+ ram32[0x0084/4] = SWAPu32(0x275a0000 + A_EXCEPTION); // addiu $k0, $k0, 0xc80
+ ram32[0x0088/4] = SWAPu32(0x03400008); // jr $k0
+ ram32[0x008c/4] = SWAPu32(0x00000000); // nop
+
+ ram32[0x00a0/4] = HLEOP(hleop_a0);
+ ram32[0x00b0/4] = HLEOP(hleop_b0);
+ ram32[0x00c0/4] = HLEOP(hleop_c0);
+
+ // "table of tables". Some games modify it
+ assert(A_TT_ExCB == 0x0100);
+ ram32[0x0100/4] = SWAPu32(0x0000e004); // ExCB - exception chains
+ ram32[0x0104/4] = SWAPu32(0x00000020); // ExCB size
+ ram32[0x0108/4] = SWAPu32(0x0000e1ec); // PCB - process control
+ ram32[0x010c/4] = SWAPu32(0x00000004); // PCB size
+ ram32[0x0110/4] = SWAPu32(0x0000e1f4); // TCB - thread control
+ ram32[0x0114/4] = SWAPu32(0x00000300); // TCB size
+ ram32[0x0120/4] = SWAPu32(0x0000e028); // EvCB - event control
+ ram32[0x0124/4] = SWAPu32(0x000001c0); // EvCB size
+ ram32[0x0140/4] = SWAPu32(0x00008648); // FCB - file control
+ ram32[0x0144/4] = SWAPu32(0x000002c0); // FCB size
+ ram32[0x0150/4] = SWAPu32(0x00006ee0); // DCB - device control
+ ram32[0x0154/4] = SWAPu32(0x00000320); // DCB size
+
+ ram32[0xe000/4] = SWAPu32(0x00000020); // SysMalloc block size
+ ram32[0xe004/4] = SWAPu32(0x000091e0); // chain0
+ ram32[0xe00c/4] = SWAPu32(0x00006d88); // chain1
+ ram32[0xe014/4] = SWAPu32(0x00000000); // chain2
+ ram32[0xe01c/4] = SWAPu32(0x00006d98); // chain3
+
+ ram32[0xe1ec/4] = SWAPu32(0x0000e1f4); // TCB
+ ram32[0xe1f0/4] = SWAPu32(0x00000300); // SysMalloc block size
+ ram32[0xe1f4/4] = SWAPu32(0x00004000); // first TCB
+
+ ram32[0x6ee0/4] = SWAPu32(0x0000eff0); // DCB
+ strcpy((char *)&ram32[0xeff0/4], "bu");
+
+ // default exception handler chains
+ write_chain(&ram32[0x91e0/4], 0x91d0, 0xbfc050a4, 0xbfc04fbc); // chain0.e0
+ write_chain(&ram32[0x91d0/4], 0x6da8, 0xbfc0506c, 0xbfc04dec); // chain0.e1
+ write_chain(&ram32[0x6da8/4], 0, 0, 0x1a00); // chain0.e2
+ write_chain(&ram32[0x6d88/4], 0x6d78, 0x19c8, 0x18bc); // chain1.e0
+ write_chain(&ram32[0x6d78/4], 0x6d68, 0x1990, 0x1858); // chain1.e1
+ write_chain(&ram32[0x6d68/4], 0x6d58, 0x1958, 0x17f4); // chain1.e2
+ write_chain(&ram32[0x6d58/4], 0, 0x1920, 0x1794); // chain1.e3
+ write_chain(&ram32[0x6d98/4], 0, 0, 0x2458); // chain3.e0
+
+ setup_mips_code();
+
+ // fill the api jumptables with fake entries as some games patch them
+ // (or rather the funcs listed there)
+ ptr = (u32 *)&psxM[A_A0_TABLE];
+ for (i = 0; i < 256; i++)
+ ptr[i] = SWAP32(0x1000);
+
+ ptr = (u32 *)&psxM[A_B0_TABLE];
+ for (i = 0; i < 256; i++)
+ ptr[i] = SWAP32(0x2000);
+ // B(5b) is special because games patch (sometimes even jump to)
+ // code at fixed offsets from it, nocash lists offsets:
+ // patch: +3d8, +4dc, +594, +62c, +9c8, +1988
+ // call: +7a0=4b70, +884=4c54, +894=4c64
+ ptr[0x5b] = SWAP32(0x43d0);
+ ram32[0x4b70/4] = SWAP32(0x03e00008); // jr $ra
+ ram32[0x4c54/4] = SWAP32(0x03e00008); // jr $ra
+ ram32[0x4c64/4] = SWAP32(0x03e00008); // jr $ra
+
+ ptr = (u32 *)&psxM[A_C0_TABLE];
+ for (i = 0; i < 256/2; i++)
+ ptr[i] = SWAP32(0x3000);
+ ptr[6] = SWAP32(A_EXCEPTION);
+
+ // more HLE traps
+ ram32[0x1000/4] = HLEOP(hleop_dummy);
+ ram32[0x2000/4] = HLEOP(hleop_dummy);
+ ram32[0x3000/4] = HLEOP(hleop_dummy);
+ ram32[0x4c54/4] = HLEOP(hleop_dummy); // for B12_InitPad?
+ ram32[0x8000/4] = HLEOP(hleop_execret);
+
+ ram32[A_EEXIT_PTR/4] = SWAP32(A_EEXIT_DEF);
+ ram32[A_EXC_SP/4] = SWAP32(A_EXC_STACK);
+ ram32[A_RCNT_VBL_ACK/4 + 0] = SWAP32(1);
+ ram32[A_RCNT_VBL_ACK/4 + 1] = SWAP32(1);
+ ram32[A_RCNT_VBL_ACK/4 + 2] = SWAP32(1);
+ ram32[A_RCNT_VBL_ACK/4 + 3] = SWAP32(1);
+
+ psxRegs.CP0.n.SR &= ~0x400000; // use ram vector