uint64_t flags_ram = RETRO_MEMDESC_SYSTEM_RAM;
struct retro_memory_map retromap = { 0 };
struct retro_memory_descriptor descs[] = {
- { flags_ram, psxM, 0, 0x00000000, 0x5fe00000, 0, 0x200000 },
- { flags_ram, psxH, 0, 0x1f800000, 0x7ffffc00, 0, 0x000400 },
+ { flags_ram, psxRegs.ptrs.psxM, 0, 0x00000000, 0x5fe00000, 0, 0x200000 },
+ { flags_ram, psxRegs.ptrs.psxH, 0, 0x1f800000, 0x7ffffc00, 0, 0x000400 },
// not ram but let the frontend patch it if it wants; should be last
- { flags_ram, psxR, 0, 0x1fc00000, 0x5ff80000, 0, 0x080000 },
+ { flags_ram, psxRegs.ptrs.psxR, 0, 0x1fc00000, 0x5ff80000, 0, 0x080000 },
};
retromap.descriptors = descs;
if (id == RETRO_MEMORY_SAVE_RAM)
return Mcd1Data;
else if (id == RETRO_MEMORY_SYSTEM_RAM)
- return psxM;
+ return psxRegs.ptrs.psxM;
else
return NULL;
}
+#ifndef PCSX_COMPILER_FEATURES_H_
+#define PCSX_COMPILER_FEATURES_H_
#ifdef __GNUC__
# define likely(x) __builtin_expect((x),1)
# define noinline __attribute__((noinline,noclone))
# endif
# define attr_unused __attribute__((unused))
+# define nosanitize(x) __attribute__((no_sanitize(x)))
#else
# define likely(x) (x)
# define unlikely(x) (x)
# define preload (x)
# define noinline
# define attr_unused
+# define nosanitize(x)
#endif
// doesn't work on Android, mingw...
#define sub_overflow(a, b, r) ({r = (u32)a - (u32)b; (a ^ b) & (a ^ r) & (1u<<31);})
#endif
+#endif // PCSX_COMPILER_FEATURES_H_
break;
case CHEAT_SCRATCHPAD16: // 1F
- psxHs16ref(addr) = SWAPu16(val);
+ psxHu16ref(addr) = SWAPu16(val);
break;
case CHEAT_INC16:
void CheatSearchBackupMemory() {
if (prevM != NULL) {
- memcpy(prevM, psxM, 0x200000);
+ memcpy(prevM, psxRegs.ptrs.psxM, 0x200000);
}
}
}
err = 0;
- psxM = (s8 *)base;
+ psxRegs.ptrs.psxM = (u8 *)base;
err_close_memfd:
close(memfd);
int lightrec_init_mmap(void)
{
unsigned int i;
- s8 *base, *target;
+ u8 *base, *target;
void *map;
int err = lightrec_mmap_ram(true);
if (err) {
}
}
- base = psxM;
+ base = psxRegs.ptrs.psxM;
target = base + 0x1f000000;
map = mmap(target, 0x10000,
if (map != target)
SysMessage("lightrec: mapped parallel port at %p, wanted %p", map, target);
- psxP = (s8 *)map;
+ psxRegs.ptrs.psxP = (u8 *)map;
target = base + 0x1fc00000;
map = mmap_huge(target, 0x200000,
if (map != target)
SysMessage("lightrec: mapped bios at %p, wanted %p", map, target);
- psxR = (s8 *)map;
+ psxRegs.ptrs.psxR = (u8 *)map;
target = base + 0x1f800000;
map = mmap(target, 0x10000,
if (map != target)
SysMessage("lightrec: mapped scratchpad at %p, wanted %p", map, target);
- psxH = (s8 *)map;
+ psxRegs.ptrs.psxH = (u8 *)map;
target = base + 0x800000;
map = mmap_huge(target, CODE_BUFFER_SIZE,
return 0;
err_unmap_scratch:
- munmap(psxH, 0x10000);
+ munmap(psxRegs.ptrs.psxH, 0x10000);
err_unmap_bios:
- munmap(psxR, 0x200000);
+ munmap(psxRegs.ptrs.psxR, 0x200000);
err_unmap_parallel:
- munmap(psxP, 0x10000);
+ munmap(psxRegs.ptrs.psxP, 0x10000);
err_unmap:
for (i = 0; i < 4; i++)
- munmap((void *)((uintptr_t)psxM + i * 0x200000), 0x200000);
+ munmap((void *)((uintptr_t)psxRegs.ptrs.psxM + i * 0x200000), 0x200000);
return err;
}
unsigned int i;
munmap(code_buffer, CODE_BUFFER_SIZE);
- munmap(psxH, 0x10000);
- munmap(psxR, 0x200000);
- munmap(psxP, 0x10000);
+ munmap(psxRegs.ptrs.psxH, 0x10000);
+ munmap(psxRegs.ptrs.psxR, 0x200000);
+ munmap(psxRegs.ptrs.psxP, 0x10000);
for (i = 0; i < 4; i++)
- munmap((void *)((uintptr_t)psxM + i * 0x200000), 0x200000);
+ munmap((void *)((uintptr_t)psxRegs.ptrs.psxM + i * 0x200000), 0x200000);
}
static void lightrec_enable_ram(struct lightrec_state *state, bool enable)
{
if (enable)
- memcpy(psxM, cache_buf, sizeof(cache_buf));
+ memcpy(psxRegs.ptrs.psxM, cache_buf, sizeof(cache_buf));
else
- memcpy(cache_buf, psxM, sizeof(cache_buf));
+ memcpy(cache_buf, psxRegs.ptrs.psxM, sizeof(cache_buf));
ram_disabled = !enable;
}
static int lightrec_plugin_init(void)
{
- lightrec_map[PSX_MAP_KERNEL_USER_RAM].address = psxM;
- lightrec_map[PSX_MAP_BIOS].address = psxR;
- lightrec_map[PSX_MAP_SCRATCH_PAD].address = psxH;
- lightrec_map[PSX_MAP_HW_REGISTERS].address = psxH + 0x1000;
- lightrec_map[PSX_MAP_PARALLEL_PORT].address = psxP;
+ lightrec_map[PSX_MAP_KERNEL_USER_RAM].address = psxRegs.ptrs.psxM;
+ lightrec_map[PSX_MAP_BIOS].address = psxRegs.ptrs.psxR;
+ lightrec_map[PSX_MAP_SCRATCH_PAD].address = psxRegs.ptrs.psxH;
+ lightrec_map[PSX_MAP_HW_REGISTERS].address = psxRegs.ptrs.psxH + 0x1000;
+ lightrec_map[PSX_MAP_PARALLEL_PORT].address = psxRegs.ptrs.psxP;
if (!LIGHTREC_CUSTOM_MAP) {
#if P_HAVE_MMAP
}
if (LIGHTREC_CUSTOM_MAP) {
- lightrec_map[PSX_MAP_MIRROR1].address = psxM + 0x200000;
- lightrec_map[PSX_MAP_MIRROR2].address = psxM + 0x400000;
- lightrec_map[PSX_MAP_MIRROR3].address = psxM + 0x600000;
+ lightrec_map[PSX_MAP_MIRROR1].address = psxRegs.ptrs.psxM + 0x200000;
+ lightrec_map[PSX_MAP_MIRROR2].address = psxRegs.ptrs.psxM + 0x400000;
+ lightrec_map[PSX_MAP_MIRROR3].address = psxRegs.ptrs.psxM + 0x600000;
}
lightrec_map[PSX_MAP_CODE_BUFFER].address = code_buffer;
&lightrec_ops);
// fprintf(stderr, "M=0x%lx, P=0x%lx, R=0x%lx, H=0x%lx\n",
- // (uintptr_t) psxM,
- // (uintptr_t) psxP,
- // (uintptr_t) psxR,
- // (uintptr_t) psxH);
+ // (uintptr_t) psxRegs.ptrs.psxM,
+ // (uintptr_t) psxRegs.ptrs.psxP,
+ // (uintptr_t) psxRegs.ptrs.psxR,
+ // (uintptr_t) psxRegs.ptrs.psxH);
#ifndef _WIN32
signal(SIGPIPE, exit);
if (lightrec_very_debug)
printf(" RAM 0x%08x SCRATCH 0x%08x HW 0x%08x",
- hash_calculate_ram(psxM, 0x200000),
- hash_calculate_le(psxH, 0x400),
- hash_calculate_le(psxH + 0x1000, 0x2000));
+ hash_calculate_ram(psxRegs.ptrs.psxM, 0x200000),
+ hash_calculate_le(psxRegs.ptrs.psxH, 0x400),
+ hash_calculate_le(psxRegs.ptrs.psxH + 0x1000, 0x2000));
printf(" CP0 0x%08x CP2D 0x%08x CP2C 0x%08x INT 0x%04x INTCYCLE 0x%08x GPU 0x%08x",
hash_calculate(regs->cp0, sizeof(regs->cp0)),
memset(&mdec, 0, sizeof(mdec));
memset(iq_y, 0, sizeof(iq_y));
memset(iq_uv, 0, sizeof(iq_uv));
- mdec.rl = (u16 *)&psxM[0x100000];
+ mdec.rl = (u16 *)&psxRegs.ptrs.psxM[0x100000];
}
// command register
}
int mdecFreeze(void *f, int Mode) {
- u8 *base = (u8 *)psxM;
+ u8 *base = (u8 *)psxRegs.ptrs.psxM;
u32 v;
gzfreeze(&mdec.reg0, sizeof(mdec.reg0));
#define EX_SCREENPIC_SIZE (128 * 96 * 3)
int SaveState(const char *file) {
- struct misc_save_data *misc = (void *)(psxH + 0xf000);
+ struct misc_save_data *misc = (void *)(psxRegs.ptrs.psxH + 0xf000);
struct origin_info oi = { 0, };
GPUFreeze_t *gpufP = NULL;
SPUFreezeHdr_t spufH;
if (Config.HLE)
psxBiosFreeze(1);
- SaveFuncs.write(f, psxM, 0x00200000);
- SaveFuncs.write(f, psxR, 0x00080000);
- SaveFuncs.write(f, psxH, 0x00010000);
+ SaveFuncs.write(f, psxRegs.ptrs.psxM, 0x00200000);
+ SaveFuncs.write(f, psxRegs.ptrs.psxR, 0x00080000);
+ SaveFuncs.write(f, psxRegs.ptrs.psxH, 0x00010000);
// only partial save of psxRegisters to maintain savestate compat
SaveFuncs.write(f, &psxRegs, offsetof(psxRegisters, gteBusyCycle));
}
int LoadState(const char *file) {
- struct misc_save_data *misc = (void *)(psxH + 0xf000);
+ struct misc_save_data *misc = (void *)(psxRegs.ptrs.psxH + 0xf000);
u32 biosBranchCheckOld = psxRegs.biosBranchCheck;
void *f;
GPUFreeze_t *gpufP = NULL;
// ex-ScreenPic space
SaveFuncs.seek(f, EX_SCREENPIC_SIZE, SEEK_CUR);
- SaveFuncs.read(f, psxM, 0x00200000);
- SaveFuncs.read(f, psxR, 0x00080000);
- SaveFuncs.read(f, psxH, 0x00010000);
+ SaveFuncs.read(f, psxRegs.ptrs.psxM, 0x00200000);
+ SaveFuncs.read(f, psxRegs.ptrs.psxR, 0x00080000);
+ SaveFuncs.read(f, psxRegs.ptrs.psxH, 0x00010000);
SaveFuncs.read(f, &psxRegs, offsetof(psxRegisters, gteBusyCycle));
psxRegs.gteBusyCycle = psxRegs.cycle;
psxRegs.branching = 0;
#ifdef DRC_DBG
memcpy(gte_handlers_nf, gte_handlers, sizeof(gte_handlers_nf));
#endif
- psxH_ptr = psxH;
+ psxH_ptr = psxRegs.ptrs.psxH;
zeromem_ptr = zero_mem;
scratch_buf_ptr = scratch_buf; // for gte_neon.S
#define LO_muldivBusyCycle (LO_gteBusyCycle + 4)
#define LO_psxRegs_subCycle (LO_muldivBusyCycle + 4)
#define LO_psxRegs_biuReg (LO_psxRegs_subCycle + 4*2)
-#define LO_stop (LO_psxRegs_biuReg + 4)
-#define LO_psxRegs_end (LO_stop + 4*9)
+#define LO_stop (LO_psxRegs_biuReg + 4)
+#define LO_psxRegs_ptrs (LO_stop + 4*7)
+#define LO_psxRegs_end (LO_psxRegs_ptrs + PTRSZ*10)
#define LO_rcnts (LO_psxRegs_end)
#define LO_rcnts_end (LO_rcnts + 7*4*4)
#define LO_inv_code_start (LO_rcnts_end)
type=0;
}
else if(type==MTYPE_1F80) { // scratchpad
- if (psxH == (void *)0x1f800000) {
+ if (psxRegs.ptrs.psxH == (void *)0x1f800000) {
host_tempreg_acquire();
emit_xorimm(addr,0x1f800000,HOST_TEMPREG);
emit_cmpimm(HOST_TEMPREG,0x1000);
#endif
arch_init();
new_dynarec_test();
- ram_offset = (uintptr_t)psxM - 0x80000000;
+ ram_offset = (uintptr_t)psxRegs.ptrs.psxM - 0x80000000;
if (ram_offset != 0)
SysPrintf("RAM is not directly mapped\n");
SysPrintf("Mapped (RAM/scrp/ROM/LUTs/TC):\n");
- SysPrintf("%p/%p/%p/%p/%p\n", psxM, psxH, psxR, mem_rtab, out);
+ SysPrintf("%p/%p/%p/%p/%p\n", psxRegs.ptrs.psxM, psxRegs.ptrs.psxH,
+ psxRegs.ptrs.psxR, mem_rtab, out);
}
void new_dynarec_cleanup(void)
{
// used for BIOS calls mostly?
*limit = (addr & 0xa0600000) + 0x00200000;
- return (u_int *)(psxM + (addr & 0x1fffff));
+ return (u_int *)(psxRegs.ptrs.psxM + (addr & 0x1fffff));
}
else if (
(0x9fc00000u <= addr && addr < 0x9fc80000u) ||
// cycle_multiplier_active = 200;
*limit = (addr & 0xfff00000) | 0x80000;
- return (u_int *)((u_char *)psxR + (addr&0x7ffff));
+ return (u_int *)((u_char *)psxRegs.ptrs.psxR + (addr&0x7ffff));
}
return NULL;
}
if (!is_ram_addr(addr))
return;
- str = (char *)psxM + (addr & 0x1fffff);
+ str = (char *)psxRegs.ptrs.psxM + (addr & 0x1fffff);
if (!str || strncmp(str, "VSync: timeout", 14))
return;
// jal clearPad, jal clearRCnt; j return; nop
static void map_rcnt_rcount2(u32 mode)
{
if ((mode & 7) == 1 || (mode & 7) == 7) { // sync mode
- map_item(&mem_iortab[IOMEM32(0x1120)], &psxH[0x1000], 0);
- map_item(&mem_iortab[IOMEM16(0x1120)], &psxH[0x1000], 0);
+ map_item(&mem_iortab[IOMEM32(0x1120)], &psxRegs.ptrs.psxH[0x1000], 0);
+ map_item(&mem_iortab[IOMEM16(0x1120)], &psxRegs.ptrs.psxH[0x1000], 0);
}
else if (mode & 0x200) { // clk/8
map_item(&mem_iortab[IOMEM32(0x1120)], rcnt2_read_count_m1, 1);
}
else {
for (i = 0; i < (0x800000 >> 12); i++) {
- map_l1_mem(mem_writetab, i, 0x80000000, 0x200000, psxM);
- map_l1_mem(mem_writetab, i, 0x00000000, 0x200000, psxM);
- map_l1_mem(mem_writetab, i, 0xa0000000, 0x200000, psxM);
+ void *ram = psxRegs.ptrs.psxM;
+ map_l1_mem(mem_writetab, i, 0x80000000, 0x200000, ram);
+ map_l1_mem(mem_writetab, i, 0x00000000, 0x200000, ram);
+ map_l1_mem(mem_writetab, i, 0xa0000000, 0x200000, ram);
}
}
}
map_item(&mem_writetab[i], mem_unmwtab, 1);
}
- // RAM and it's mirrors
+ // RAM and its mirrors
for (i = 0; i < (0x800000 >> 12); i++) {
- map_l1_mem(mem_readtab, i, 0x80000000, 0x200000, psxM);
- map_l1_mem(mem_readtab, i, 0x00000000, 0x200000, psxM);
- map_l1_mem(mem_readtab, i, 0xa0000000, 0x200000, psxM);
+ void *ram = psxRegs.ptrs.psxM;
+ map_l1_mem(mem_readtab, i, 0x80000000, 0x200000, ram);
+ map_l1_mem(mem_readtab, i, 0x00000000, 0x200000, ram);
+ map_l1_mem(mem_readtab, i, 0xa0000000, 0x200000, ram);
}
new_dyna_pcsx_mem_isolate(0);
- // BIOS and it's mirrors
+ // BIOS and its mirrors
for (i = 0; i < (0x80000 >> 12); i++) {
- map_l1_mem(mem_readtab, i, 0x1fc00000, 0x80000, psxR);
- map_l1_mem(mem_readtab, i, 0xbfc00000, 0x80000, psxR);
+ map_l1_mem(mem_readtab, i, 0x1fc00000, 0x80000, psxRegs.ptrs.psxR);
+ map_l1_mem(mem_readtab, i, 0xbfc00000, 0x80000, psxRegs.ptrs.psxR);
}
// scratchpad
- map_l1_mem(mem_readtab, 0, 0x1f800000, 0x1000, psxH);
- map_l1_mem(mem_readtab, 0, 0x9f800000, 0x1000, psxH);
- map_l1_mem(mem_writetab, 0, 0x1f800000, 0x1000, psxH);
- map_l1_mem(mem_writetab, 0, 0x9f800000, 0x1000, psxH);
+ map_l1_mem(mem_readtab, 0, 0x1f800000, 0x1000, psxRegs.ptrs.psxH);
+ map_l1_mem(mem_readtab, 0, 0x9f800000, 0x1000, psxRegs.ptrs.psxH);
+ map_l1_mem(mem_writetab, 0, 0x1f800000, 0x1000, psxRegs.ptrs.psxH);
+ map_l1_mem(mem_writetab, 0, 0x9f800000, 0x1000, psxRegs.ptrs.psxH);
// I/O
map_item(&mem_readtab[0x1f801000u >> 12], mem_iortab, 1);
// fill IO tables
for (i = 0; i < 0x1000/4; i++) {
- map_item(&mem_iortab[i], &psxH[0x1000], 0);
- map_item(&mem_iowtab[i], &psxH[0x1000], 0);
+ map_item(&mem_iortab[i], &psxRegs.ptrs.psxH[0x1000], 0);
+ map_item(&mem_iowtab[i], &psxRegs.ptrs.psxH[0x1000], 0);
}
for (; i < 0x1000/4 + 0x1000/2; i++) {
- map_item(&mem_iortab[i], &psxH[0x1000], 0);
- map_item(&mem_iowtab[i], &psxH[0x1000], 0);
+ map_item(&mem_iortab[i], &psxRegs.ptrs.psxH[0x1000], 0);
+ map_item(&mem_iowtab[i], &psxRegs.ptrs.psxH[0x1000], 0);
}
for (; i < 0x1000/4 + 0x1000/2 + 0x1000; i++) {
- map_item(&mem_iortab[i], &psxH[0x1000], 0);
- map_item(&mem_iowtab[i], &psxH[0x1000], 0);
+ map_item(&mem_iortab[i], &psxRegs.ptrs.psxH[0x1000], 0);
+ map_item(&mem_iowtab[i], &psxRegs.ptrs.psxH[0x1000], 0);
}
map_item(&mem_iortab[IOMEM32(0x1040)], io_read_sio32, 1);
static u8 loadRam8(u32 addr)
{
assert(!(addr & 0x5f800000));
- return psxM[addr & 0x1fffff];
+ return psxRegs.ptrs.psxM[addr & 0x1fffff];
}
static u32 loadRam32(u32 addr)
{
assert(!(addr & 0x5f800000));
- return SWAP32(*((u32 *)psxM + ((addr & 0x1fffff) >> 2)));
+ return SWAP32(*((u32 *)psxRegs.ptrs.psxM + ((addr & 0x1fffff) >> 2)));
}
static void *castRam8ptr(u32 addr)
{
assert(!(addr & 0x5f800000));
- return psxM + (addr & 0x1fffff);
+ return psxRegs.ptrs.psxM + (addr & 0x1fffff);
}
static void *castRam32ptr(u32 addr)
{
assert(!(addr & 0x5f800003));
- return psxM + (addr & 0x1ffffc);
+ return psxRegs.ptrs.psxM + (addr & 0x1ffffc);
}
static void *loadRam8ptr(u32 addr)
static void storeRam8(u32 addr, u8 d)
{
assert(!(addr & 0x5f800000));
- *((u8 *)psxM + (addr & 0x1fffff)) = d;
+ *((u8 *)psxRegs.ptrs.psxM + (addr & 0x1fffff)) = d;
}
static void storeRam32(u32 addr, u32 d)
{
assert(!(addr & 0x5f800000));
- *((u32 *)psxM + ((addr & 0x1fffff) >> 2)) = SWAP32(d);
+ *((u32 *)psxRegs.ptrs.psxM + ((addr & 0x1fffff) >> 2)) = SWAP32(d);
}
static void mips_return(u32 val)
SaveMcd(Config.Mcd2, Mcd2Data, offset, size);
}
else {
- size_t ram_offset = (s8 *)buf - psxM;
+ size_t ram_offset = (u8 *)buf - psxRegs.ptrs.psxM;
memcpy(buf, mcdptr + offset, size);
if (ram_offset < 0x200000)
psxCpu->Clear(ram_offset, (size + 3) / 4);
static void psxBios_EnqueueCdIntr_(void)
{
- u32 *ram32 = (u32 *)psxM;
+ u32 *ram32 = (u32 *)psxRegs.ptrs.psxM;
// traps should already be installed by write_chain()
ram32[0x91d0/4] = 0;
SysPrintf("psxBios_%s %x\n", biosA0n[0xb4], a0);
switch (a0) {
case 0:
- case 1: ret = SWAP32(((u32 *)psxR)[0x100/4 + a0]); break;
+ case 1: ret = SWAP32(((u32 *)psxRegs.ptrs.psxR)[0x100/4 + a0]); break;
case 2: ret = 0xbfc0012c; break;
case 5: ret = loadRam32(0x60) << 10; break;
}
}
void psxBios_InitPAD() { // 0x12
- u32 i, *ram32 = (u32 *)psxM;
+ u32 i, *ram32 = (u32 *)psxRegs.ptrs.psxM;
PSXBIOS_LOG("psxBios_%s %x %x %x %x\n", biosB0n[0x12], a0, a1, a2, a3);
// printf("%s", "PS-X Control PAD Driver Ver 3.0");
}
void psxBios_InitCARD() { // 4a
- u8 *ram8 = (u8 *)psxM;
- u32 *ram32 = (u32 *)psxM;
+ u8 *ram8 = (u8 *)psxRegs.ptrs.psxM;
+ u32 *ram32 = (u32 *)psxRegs.ptrs.psxM;
PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x4a], a0);
write_chain(ram32 + A_PADCRD_CHN_E/4, 0, 0x49bc, 0x4a4c);
//card_error = 0;
static void setup_mips_code()
{
u32 *ptr;
- ptr = (u32 *)&psxM[A_SYSCALL];
+ ptr = (u32 *)&psxRegs.ptrs.psxM[A_SYSCALL];
ptr[0x00/4] = SWAPu32(0x0000000c); // syscall 0
ptr[0x04/4] = SWAPu32(0x03e00008); // jr $ra
ptr[0x08/4] = SWAPu32(0x00000000); // nop
- ptr = (u32 *)&psxM[A_EXCEPTION];
+ ptr = (u32 *)&psxRegs.ptrs.psxM[A_EXCEPTION];
memset(ptr, 0, 0xc0); // nops (to be patched by games sometimes)
ptr[0x10/4] = SWAPu32(0x8c1a0108); // lw $k0, (0x108) // PCB
ptr[0x14/4] = SWAPu32(0x00000000); // nop
static void setup_tt(u32 tcb_cnt, u32 evcb_cnt, u32 stack)
{
- u32 *ram32 = (u32 *)psxM;
+ u32 *ram32 = (u32 *)psxRegs.ptrs.psxM;
u32 s_excb = 0x20, s_evcb, s_pcb = 4, s_tcb;
u32 p_excb, p_evcb, p_pcb, p_tcb;
u32 i;
void psxBiosSetupBootState(void)
{
boolean hle = Config.HLE;
- u32 *hw = (u32 *)psxH;
+ u32 *hw = (u32 *)psxRegs.ptrs.psxH;
int i;
// see also SetBootRegs()
psxRegs.biosBranchCheck = ~0;
- memset(psxM, 0, 0x10000);
+ memset(psxRegs.ptrs.psxM, 0, 0x10000);
for(i = 0; i < 256; i++) {
biosA0[i] = NULL;
biosB0[i] = NULL;
if (!Config.HLE) {
char verstr[0x24+1];
- rom32 = (u32 *)psxR;
- memcpy(verstr, psxR + 0x12c, 0x24);
+ rom32 = (u32 *)psxRegs.ptrs.psxR;
+ memcpy(verstr, psxRegs.ptrs.psxR + 0x12c, 0x24);
verstr[0x24] = 0;
SysPrintf("BIOS: %08x, '%s', '%c'\n", SWAP32(rom32[0x100/4]),
- verstr, psxR[0x7ff52]);
+ verstr, psxRegs.ptrs.psxR[0x7ff52]);
return;
}
// somewhat pretend to be a SCPH1001 BIOS
// some games look for these and take an exception if they're missing
- rom32 = (u32 *)psxR;
+ rom32 = (u32 *)psxRegs.ptrs.psxR;
rom32[0x100/4] = SWAP32(0x19951204);
rom32[0x104/4] = SWAP32(3);
- romc = (char *)psxR;
+ romc = (char *)psxRegs.ptrs.psxR;
strcpy(romc + 0x108, "PCSX authors");
strcpy(romc + 0x12c, "CEX-3000 PCSX HLE"); // see psxBios_GetSystemInfo
strcpy(romc + 0x7ff32, "System ROM Version 2.2 12/04/95 A");
// fonts
len = 0x80000 - 0x66000;
- uncompress((Bytef *)(psxR + 0x66000), &len, font_8140, sizeof(font_8140));
+ uncompress((Bytef *)(romc + 0x66000), &len, font_8140, sizeof(font_8140));
len = 0x80000 - 0x69d68;
- uncompress((Bytef *)(psxR + 0x69d68), &len, font_889f, sizeof(font_889f));
+ uncompress((Bytef *)(romc + 0x69d68), &len, font_889f, sizeof(font_889f));
// trap attempts to call bios directly
rom32[0x00000/4] = HLEOP(hleop_dummy);
Crash Team Racing will softlock after the Sony logo.
*/
- ram32 = (u32 *)psxM;
+ ram32 = (u32 *)psxRegs.ptrs.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
// (or rather the funcs listed there)
// also trap the destination as some "Cheats Edition" thing overrides the
// dispatcher with a wrapper and then jumps to the table entries directly
- ptr = (u32 *)&psxM[A_A0_TABLE];
+ ptr = (u32 *)&psxRegs.ptrs.psxM[A_A0_TABLE];
for (i = 0; i < 256; i++) {
ptr[i] = SWAP32(A_A0_TRAPS + i*4);
ram32[A_A0_TRAPS/4 + i] = HLEOP(hleop_a0t);
}
- ptr = (u32 *)&psxM[A_B0_TABLE];
+ ptr = (u32 *)&psxRegs.ptrs.psxM[A_B0_TABLE];
for (i = 0; i < 256; i++) {
ptr[i] = SWAP32(A_B0_TRAPS + i*4);
ram32[A_B0_TRAPS/4 + i] = HLEOP(hleop_b0t);
ram32[0x4c64/4] = SWAP32(0x03e00008); // jr $ra
ram32[0x4c68/4] = SWAP32(0xac000000 + A_PAD_IRQR_ENA); // sw $0, ...
- ptr = (u32 *)&psxM[A_C0_TABLE];
+ ptr = (u32 *)&psxRegs.ptrs.psxM[A_C0_TABLE];
for (i = 0; i < 256/2; i++) {
ptr[i] = SWAP32(A_C0_TRAPS + i*4);
ram32[A_C0_TRAPS/4 + i] = HLEOP(hleop_c0t);
u32 start = t_addr & 0x1ffffc;
u32 end = (start + t_size) & 0x1ffffc;
u32 buf[sizeof(pattern) / sizeof(u32)];
- const u32 *r32 = (u32 *)(psxM + start);
+ const u32 *r32 = (u32 *)(psxRegs.ptrs.psxM + start);
u32 i, j;
if (end <= start)
}
#define bfreeze(ptr, size) { \
- if (Mode == 1) memcpy(&psxR[base], ptr, size); \
- if (Mode == 0) memcpy(ptr, &psxR[base], size); \
+ if (Mode == 1) memcpy(&psxRegs.ptrs.psxR[base], ptr, size); \
+ if (Mode == 0) memcpy(ptr, &psxRegs.ptrs.psxR[base], size); \
base += size; \
}
do_walking = Config.hacks.gpu_slow_list_walking;
madr_next_p = do_walking ? &madr_next : NULL;
- cycles_sum = GPU_dmaChain((u32 *)psxM, madr & 0x1fffff,
+ cycles_sum = GPU_dmaChain((u32 *)psxRegs.ptrs.psxM, madr & 0x1fffff,
madr_next_p, &cycles_last_cmd);
HW_DMA2_MADR = SWAPu32(madr_next);
do {
cycles_sum += cycles_last_cmd;
- cycles_sum += GPU_dmaChain((u32 *)psxM, madr_next & 0x1fffff,
- &madr_next, &cycles_last_cmd);
+ cycles_sum += GPU_dmaChain((u32 *)psxRegs.ptrs.psxM,
+ madr_next & 0x1fffff, &madr_next, &cycles_last_cmd);
}
while (cycles_sum <= 0 && !(madr_next & 0x800000));
HW_DMA2_MADR = SWAPu32(madr_next);
// already 32-bit size
words = bcr;
- while (bcr-- && mem > (u32 *)psxM) {
+ while (bcr-- && mem > (u32 *)psxRegs.ptrs.psxM) {
*mem-- = SWAP32((madr - 4) & 0xffffff);
madr -= 4;
}
if (!(madr & 0x800000)) {
madr &= 0x1ffffc;
*max_words = (0x200000 - madr) / 4;
- return psxM + madr;
+ return psxRegs.ptrs.psxM + madr;
}
return INVALID_PTR;
}
#include "../include/compiler_features.h"
void psxHwReset() {
- memset(psxH, 0, 0x10000);
+ memset(psxRegs.ptrs.psxH, 0, 0x10000);
mdecInit(); // initialize mdec decoder
cdrReset();
case 0x1124: psxRcntWmode(2, value); return;
case 0x1128: psxRcntWtarget(2, value & 0xffff); return;
+ case 0x1060:
+ if ((value >> 9) != 5)
+ log_unhandled("unhandled RAM_SIZE %08x @%08x\n", value, psxRegs.pc);
+ break;
+
case 0x1044:
case 0x1048:
case 0x104c:
#define DO_EXCEPTION_RESERVEDI
#define HANDLE_LOAD_DELAY
-#ifdef __i386__
-#define INT_ATTR __attribute__((regparm(2)))
-#else
-#define INT_ATTR
-#endif
#ifndef INVALID_PTR
#define INVALID_PTR NULL
#endif
// get an opcode without triggering exceptions or affecting cache
u32 intFakeFetch(u32 pc)
{
- u32 *code = (u32 *)psxm(pc & ~0x3, 0);
- if (unlikely(code == INVALID_PTR))
+ const u32 *code;
+ if (!psxm_lut((u8 **)&code, &psxRegs, pc & ~0x3, 0, psxRegs.ptrs.memRLUT))
return 0; // nop
return SWAP32(*code);
}
-static u32 INT_ATTR fetchNoCache(psxRegisters *regs, u8 **memRLUT, u32 pc)
+static u32 INT_ATTR fetchNoCache(psxRegisters *regs, const uintptr_t *memRLUT, u32 pc)
{
- u32 *code = (u32 *)psxm_lut(pc & ~0x3, 0, memRLUT);
- if (unlikely(code == INVALID_PTR)) {
+ const u32 *code;
+ if (!psxm_lut((u8 **)&code, regs, pc & ~0x3, 0, memRLUT)) {
SysPrintf("game crash @%08x, ra=%08x\n", pc, regs->GPR.n.ra);
intException(regs, pc, R3000E_IBE << 2);
return 0; // execute as nop
u32 data[4];
} ICache[256];
-static u32 INT_ATTR fetchICache(psxRegisters *regs, u8 **memRLUT, u32 pc)
+static u32 INT_ATTR fetchICache(psxRegisters *regs, const uintptr_t *memRLUT, u32 pc)
{
// cached?
if (pc < 0xa0000000)
if (((entry->tag ^ pc) & 0xfffffff0) != 0 || pc < entry->tag)
{
- const u32 *code = (u32 *)psxm_lut(pc & ~0xf, 0, memRLUT);
- if (unlikely(code == INVALID_PTR)) {
+ const u32 *code;
+ if (!psxm_lut((u8 **)&code, regs, pc & ~0x0f, 0, memRLUT)) {
SysPrintf("game crash @%08x, ra=%08x\n", pc, regs->GPR.n.ra);
intException(regs, pc, R3000E_IBE << 2);
return 0; // execute as nop
return fetchNoCache(regs, memRLUT, pc);
}
-static u32 (INT_ATTR *fetch)(psxRegisters *regs_, u8 **memRLUT, u32 pc) = fetchNoCache;
-
// Make the timing events trigger faster as we are currently assuming everything
// takes one cycle, which is not the case on real hardware.
// FIXME: count cache misses, memory latencies, stalls to get rid of this
* has no normal delay slot, instruction at tar1 was fetched instead)
*/
for (lim = 0; lim < 8; lim++) {
- regs->code = code = fetch(regs, psxMemRLUT, tar1);
+ code = regs->ptrs.intFetch(regs, regs->ptrs.memRLUT, tar1);
+ regs->code = code;
addCycle(regs);
if (likely(!isBranch(code))) {
dloadStep(regs);
// fetch the delay slot
pc = regs->pc;
regs->pc = pc + 4;
- regs->code = code = fetch(regs, psxMemRLUT, pc);
+ regs->code = code = regs->ptrs.intFetch(regs, regs->ptrs.memRLUT, pc);
addCycle(regs);
intExceptionInsn(regs_, R3000E_Syscall << 2);
}
-static inline void execI_(u8 **memRLUT, psxRegisters *regs_);
+static inline void execI_(
+ u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc),
+ const uintptr_t *memRLUT, psxRegisters *regs);
-static inline void psxTestSWInts(psxRegisters *regs_, int step) {
- if ((regs_->CP0.n.Cause & regs_->CP0.n.SR & 0x0300) &&
- (regs_->CP0.n.SR & 0x1)) {
+static inline void psxTestSWInts(psxRegisters *regs, int step) {
+ if ((regs->CP0.n.Cause & regs->CP0.n.SR & 0x0300) &&
+ (regs->CP0.n.SR & 0x1)) {
if (step)
- execI_(psxMemRLUT, regs_);
- regs_->CP0.n.Cause &= ~0x7c;
- intException(regs_, regs_->pc, regs_->CP0.n.Cause);
+ execI_(regs->ptrs.intFetch, regs->ptrs.memRLUT, regs);
+ regs->CP0.n.Cause &= ~0x7c;
+ intException(regs, regs->pc, regs->CP0.n.Cause);
}
}
#define _oB_ (regs_->GPR.r[_Rs_] + _Imm_)
-OP(psxLB) { doLoad(regs_, _Rt_, (s8)psxMemRead8(_oB_)); }
-OP(psxLBU) { doLoad(regs_, _Rt_, psxMemRead8(_oB_)); }
-OP(psxLH) { doLoad(regs_, _Rt_, (s16)psxMemRead16(_oB_ & ~1)); }
-OP(psxLHU) { doLoad(regs_, _Rt_, psxMemRead16(_oB_ & ~1)); }
-OP(psxLW) { doLoad(regs_, _Rt_, psxMemRead32(_oB_ & ~3)); }
+OP(psxLB) { doLoad(regs_, _Rt_, (s8)psxMemRead8(regs_, _oB_)); }
+OP(psxLBU) { doLoad(regs_, _Rt_, psxMemRead8(regs_, _oB_)); }
+OP(psxLH) { doLoad(regs_, _Rt_, (s16)psxMemRead16(regs_, _oB_ & ~1)); }
+OP(psxLHU) { doLoad(regs_, _Rt_, psxMemRead16(regs_, _oB_ & ~1)); }
+OP(psxLW) { doLoad(regs_, _Rt_, psxMemRead32(regs_, _oB_ & ~3)); }
-OP(psxLBe) { if (checkLD(regs_, _oB_, 0)) doLoad(regs_, _Rt_, (s8)psxMemRead8(_oB_)); }
-OP(psxLBUe) { if (checkLD(regs_, _oB_, 0)) doLoad(regs_, _Rt_, psxMemRead8(_oB_)); }
-OP(psxLHe) { if (checkLD(regs_, _oB_, 1)) doLoad(regs_, _Rt_, (s16)psxMemRead16(_oB_)); }
-OP(psxLHUe) { if (checkLD(regs_, _oB_, 1)) doLoad(regs_, _Rt_, psxMemRead16(_oB_)); }
-OP(psxLWe) { if (checkLD(regs_, _oB_, 3)) doLoad(regs_, _Rt_, psxMemRead32(_oB_)); }
+OP(psxLBe) { if (checkLD(regs_, _oB_, 0)) doLoad(regs_, _Rt_, (s8)psxMemRead8(regs_, _oB_)); }
+OP(psxLBUe) { if (checkLD(regs_, _oB_, 0)) doLoad(regs_, _Rt_, psxMemRead8(regs_, _oB_)); }
+OP(psxLHe) { if (checkLD(regs_, _oB_, 1)) doLoad(regs_, _Rt_, (s16)psxMemRead16(regs_, _oB_)); }
+OP(psxLHUe) { if (checkLD(regs_, _oB_, 1)) doLoad(regs_, _Rt_, psxMemRead16(regs_, _oB_)); }
+OP(psxLWe) { if (checkLD(regs_, _oB_, 3)) doLoad(regs_, _Rt_, psxMemRead32(regs_, _oB_)); }
static void doLWL(psxRegisters *regs, u32 rt, u32 addr) {
static const u32 LWL_MASK[4] = { 0xffffff, 0xffff, 0xff, 0 };
if (regs->dloadReg[sel] == rt)
oldval = regs->dloadVal[sel];
#endif
- mem = psxMemRead32(addr & ~3);
+ mem = psxMemRead32(regs, addr & ~3);
val = (oldval & LWL_MASK[shift]) | (mem << LWL_SHIFT[shift]);
doLoad(regs, rt, val);
if (regs->dloadReg[sel] == rt)
oldval = regs->dloadVal[sel];
#endif
- mem = psxMemRead32(addr & ~3);
+ mem = psxMemRead32(regs, addr & ~3);
val = (oldval & LWR_MASK[shift]) | (mem >> LWR_SHIFT[shift]);
doLoad(regs, rt, val);
OP(psxLWLe) { if (checkLD(regs_, _oB_ & ~3, 0)) doLWL(regs_, _Rt_, _oB_); }
OP(psxLWRe) { if (checkLD(regs_, _oB_ , 0)) doLWR(regs_, _Rt_, _oB_); }
-OP(psxSB) { psxMemWrite8 (_oB_, _rRt_); }
-OP(psxSH) { psxMemWrite16(_oB_, _rRt_); }
-OP(psxSW) { psxMemWrite32(_oB_, _rRt_); }
+OP(psxSB) { psxMemWrite8 (regs_, _oB_, _rRt_); }
+OP(psxSH) { psxMemWrite16(regs_, _oB_, _rRt_); }
+OP(psxSW) { psxMemWrite32(regs_, _oB_, _rRt_); }
-OP(psxSBe) { if (checkST(regs_, _oB_, 0)) psxMemWrite8 (_oB_, _rRt_); }
-OP(psxSHe) { if (checkST(regs_, _oB_, 1)) psxMemWrite16(_oB_, _rRt_); }
-OP(psxSWe) { if (checkST(regs_, _oB_, 3)) psxMemWrite32(_oB_, _rRt_); }
+OP(psxSBe) { if (checkST(regs_, _oB_, 0)) psxMemWrite8 (regs_, _oB_, _rRt_); }
+OP(psxSHe) { if (checkST(regs_, _oB_, 1)) psxMemWrite16(regs_, _oB_, _rRt_); }
+OP(psxSWe) { if (checkST(regs_, _oB_, 3)) psxMemWrite32(regs_, _oB_, _rRt_); }
static void doSWL(psxRegisters *regs, u32 rt, u32 addr) {
u32 val = regs->GPR.r[rt];
switch (addr & 3) {
- case 0: psxMemWrite8( addr , val >> 24); break;
- case 1: psxMemWrite16(addr & ~3, val >> 16); break;
+ case 0: psxMemWrite8( regs, addr , val >> 24); break;
+ case 1: psxMemWrite16(regs, addr & ~3, val >> 16); break;
case 2: // revisit: should be a single 24bit write
- psxMemWrite16(addr & ~3, (val >> 8) & 0xffff);
- psxMemWrite8( addr , val >> 24); break;
- case 3: psxMemWrite32(addr & ~3, val); break;
+ psxMemWrite16(regs, addr & ~3, (val >> 8) & 0xffff);
+ psxMemWrite8( regs, addr , val >> 24); break;
+ case 3: psxMemWrite32(regs, addr & ~3, val); break;
}
/*
Mem = 1234. Reg = abcd
static void doSWR(psxRegisters *regs, u32 rt, u32 addr) {
u32 val = regs->GPR.r[rt];
switch (addr & 3) {
- case 0: psxMemWrite32(addr , val); break;
+ case 0: psxMemWrite32(regs, addr , val); break;
case 1: // revisit: should be a single 24bit write
- psxMemWrite8 (addr , val & 0xff);
- psxMemWrite16(addr + 1, (val >> 8) & 0xffff); break;
- case 2: psxMemWrite16(addr , val & 0xffff); break;
- case 3: psxMemWrite8 (addr , val & 0xff); break;
+ psxMemWrite8 (regs, addr , val & 0xff);
+ psxMemWrite16(regs, addr + 1, (val >> 8) & 0xffff); break;
+ case 2: psxMemWrite16(regs, addr , val & 0xffff); break;
+ case 3: psxMemWrite8 (regs, addr , val & 0xff); break;
}
/*
}
OP(gteLWC2) {
- MTC2(®s_->CP2, psxMemRead32(_oB_), _Rt_);
+ MTC2(®s_->CP2, psxMemRead32(regs_, _oB_), _Rt_);
}
OP(gteLWC2_stall) {
OP(gteLWC2e_stall) {
gteCheckStall(0);
if (checkLD(regs_, _oB_, 3))
- MTC2(®s_->CP2, psxMemRead32(_oB_), _Rt_);
+ MTC2(®s_->CP2, psxMemRead32(regs_, _oB_), _Rt_);
}
OP(gteSWC2) {
- psxMemWrite32(_oB_, MFC2(®s_->CP2, _Rt_));
+ psxMemWrite32(regs_, _oB_, MFC2(®s_->CP2, _Rt_));
}
OP(gteSWC2_stall) {
psxRegs.subCycle = 0;
}
-static inline void execI_(u8 **memRLUT, psxRegisters *regs) {
+static inline void execI_(
+ u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc),
+ const uintptr_t *memRLUT, psxRegisters *regs)
+{
u32 pc = regs->pc;
addCycle(regs);
psxBSC[regs->code >> 26](regs, regs->code);
}
-static inline void execIbp(u8 **memRLUT, psxRegisters *regs) {
+static inline void execIbp(
+ u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc),
+ const uintptr_t *memRLUT, psxRegisters *regs)
+{
u32 pc = regs->pc;
addCycle(regs);
}
static void intExecute(psxRegisters *regs) {
- u8 **memRLUT = psxMemRLUT;
+ u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc) =
+ regs->ptrs.intFetch;
+ const uintptr_t *memRLUT = regs->ptrs.memRLUT;
while (!regs->stop)
- execI_(memRLUT, regs);
+ execI_(fetch, memRLUT, regs);
}
static void intExecuteBp(psxRegisters *regs) {
- u8 **memRLUT = psxMemRLUT;
+ u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc) =
+ regs->ptrs.intFetch;
+ const uintptr_t *memRLUT = regs->ptrs.memRLUT;
while (!regs->stop)
- execIbp(memRLUT, regs);
+ execIbp(fetch, memRLUT, regs);
}
static void intExecuteBlock(psxRegisters *regs, enum blockExecCaller caller) {
- u8 **memRLUT = psxMemRLUT;
+ u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc) =
+ regs->ptrs.intFetch;
+ const uintptr_t *memRLUT = regs->ptrs.memRLUT;
regs->branchSeen = 0;
while (!regs->branchSeen)
- execI_(memRLUT, regs);
+ execI_(fetch, memRLUT, regs);
}
static void intExecuteBlockBp(psxRegisters *regs, enum blockExecCaller caller) {
- u8 **memRLUT = psxMemRLUT;
+ u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc) =
+ regs->ptrs.intFetch;
+ const uintptr_t *memRLUT = regs->ptrs.memRLUT;
regs->branchSeen = 0;
while (!regs->branchSeen)
- execIbp(memRLUT, regs);
+ execIbp(fetch, memRLUT, regs);
}
static void intClear(u32 Addr, u32 Size) {
setupCop(psxRegs.CP0.n.SR);
// fallthrough
case R3000ACPU_NOTIFY_CACHE_ISOLATED: // Armored Core?
- if (fetch == fetchICache)
+ if (psxRegs.ptrs.intFetch == fetchICache)
memset(&ICache, 0xff, sizeof(ICache));
break;
case R3000ACPU_NOTIFY_CACHE_UNISOLATED:
// the dynarec may occasionally call the interpreter, in such a case the
// cache won't work (cache only works right if all fetches go through it)
if (!Config.icache_emulation || psxCpu != &psxInt) {
- fetch = fetchNoCache;
+ psxRegs.ptrs.intFetch = fetchNoCache;
memset(&ICache, 0xff, sizeof(ICache));
}
else
- fetch = fetchICache;
+ psxRegs.ptrs.intFetch = fetchICache;
cycle_mult = Config.cycle_multiplier_override && Config.cycle_multiplier == CYCLE_MULT_DEFAULT
? Config.cycle_multiplier_override : Config.cycle_multiplier;
// single step (may do several ops in case of a branch or load delay)
// called by asm/dynarec
void execI(psxRegisters *regs) {
+ u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc) =
+ regs->ptrs.intFetch;
+ const uintptr_t *memRLUT = regs->ptrs.memRLUT;
+
do {
- execIbp(psxMemRLUT, regs);
+ execIbp(fetch, memRLUT, regs);
} while (regs->dloadReg[0] || regs->dloadReg[1]);
}
// TODO: Implement caches & cycle penalty.
#include <stdio.h>
+#include <assert.h>
#include "psxmem.h"
#include "psxmem_map.h"
#include "r3000a.h"
#include "lightrec/mem.h"
#include "memmap.h"
+#include "compiler_features.h"
#ifdef USE_LIBRETRO_VFS
#include <streams/file_stream_transforms.h>
psxUnmapHook(ptr, size, tag);
}
-s8 *psxM = NULL; // Kernel & User Memory (2 Meg)
-s8 *psxP = NULL; // Parallel Port (64K)
-s8 *psxR = NULL; // BIOS ROM (512K)
-s8 *psxH = NULL; // Scratch Pad (1K) & Hardware Registers (8K)
-
-u8 **psxMemWLUT = NULL;
-u8 **psxMemRLUT = NULL;
-
/* Playstation Memory Map (from Playstation doc by Joshua Walker)
0x0000_0000-0x0000_ffff Kernel (64K)
0x0001_0000-0x001f_ffff User Memory (1.9 Meg)
static int psxMemInitMap(void)
{
- psxM = psxMap(0x80000000, 0x00210000, 1, MAP_TAG_RAM);
- if (psxM == MAP_FAILED)
- psxM = psxMap(0x77000000, 0x00210000, 0, MAP_TAG_RAM);
- if (psxM == MAP_FAILED) {
+ u8 *ptr;
+
+ ptr = psxMap(0x80000000, 0x00210000, 1, MAP_TAG_RAM);
+ if (ptr == MAP_FAILED)
+ ptr = psxMap(0x77000000, 0x00210000, 0, MAP_TAG_RAM);
+ if (ptr == MAP_FAILED) {
SysMessage("mapping main RAM failed");
- psxM = NULL;
return -1;
}
- psxP = &psxM[0x200000];
+ psxRegs.ptrs.psxM = ptr;
+ psxRegs.ptrs.psxP = ptr + 0x200000;
- psxH = psxMap(0x1f800000, 0x10000, 0, MAP_TAG_OTHER);
- if (psxH == MAP_FAILED) {
+ ptr = psxMap(0x1f800000, 0x10000, 0, MAP_TAG_OTHER);
+ if (ptr == MAP_FAILED) {
SysMessage("Error allocating psxH");
- psxH = NULL;
return -1;
}
+ psxRegs.ptrs.psxH = ptr;
- psxR = psxMap(0x1fc00000, 0x80000, 0, MAP_TAG_OTHER);
- if (psxR == MAP_FAILED) {
+ ptr = psxMap(0x1fc00000, 0x80000, 0, MAP_TAG_OTHER);
+ if (ptr == MAP_FAILED) {
SysMessage("Error allocating psxR");
- psxR = NULL;
return -1;
}
+ psxRegs.ptrs.psxR = ptr;
return 0;
}
static void psxMemFreeMap(void)
{
- if (psxM) psxUnmap(psxM, 0x00210000, MAP_TAG_RAM);
- if (psxH) psxUnmap(psxH, 0x10000, MAP_TAG_OTHER);
- if (psxR) psxUnmap(psxR, 0x80000, MAP_TAG_OTHER);
- psxM = psxH = psxR = NULL;
- psxP = NULL;
+ if (psxRegs.ptrs.psxM) psxUnmap(psxRegs.ptrs.psxM, 0x00210000, MAP_TAG_RAM);
+ if (psxRegs.ptrs.psxH) psxUnmap(psxRegs.ptrs.psxH, 0x10000, MAP_TAG_OTHER);
+ if (psxRegs.ptrs.psxR) psxUnmap(psxRegs.ptrs.psxR, 0x80000, MAP_TAG_OTHER);
+ psxRegs.ptrs.psxM = psxRegs.ptrs.psxH = psxRegs.ptrs.psxR = NULL;
+ psxRegs.ptrs.psxP = NULL;
+}
+
+static void lutMap(uintptr_t *lut, u8 *mem, u32 size, u32 start, u32 end)
+{
+ u32 i;
+ assert((size & ((1u << PSXM_SHIFT) - 1)) == 0);
+ assert((start & ((1u << PSXM_SHIFT) - 1)) == 0);
+ assert((end & ((1u << PSXM_SHIFT) - 1)) == 0);
+
+ for (i = start; i < end; i += (1u << PSXM_SHIFT))
+ lut[i >> PSXM_SHIFT] = (uintptr_t)mem - (i & ~(size - 1));
+}
+
+// shouldn't this affect reads, more mirrors?
+static void mapRam(int isMapped)
+{
+ //uintptr_t *rLUT = psxRegs.ptrs.memRLUT;
+ uintptr_t *wLUT = psxRegs.ptrs.memWLUT;
+
+ if (isMapped) {
+ u8 *ram = psxRegs.ptrs.psxM;
+ u32 i;
+ for (i = 0; i < 0x800000; i += 0x200000) {
+ lutMap(wLUT, ram, 0x200000, 0x00000000u + i, 0x00200000u + i);
+ lutMap(wLUT, ram, 0x200000, 0x80000000u + i, 0x80200000u + i);
+ lutMap(wLUT, ram, 0x200000, 0xa0000000u + i, 0xa0200000u + i);
+ }
+ }
+ else {
+ size_t len = (0x200000 >> PSXM_SHIFT) * sizeof(wLUT[0]);
+ //memset(rLUT + (0x00000000 >> PSXM_SHIFT), INVALID_PTR_VAL, len);
+ //memset(rLUT + (0x80000000 >> PSXM_SHIFT), INVALID_PTR_VAL, len);
+ //memset(rLUT + (0xa0000000 >> PSXM_SHIFT), INVALID_PTR_VAL, len);
+ memset(wLUT + (0x00000000 >> PSXM_SHIFT), INVALID_PTR_VAL, len);
+ memset(wLUT + (0x80000000 >> PSXM_SHIFT), INVALID_PTR_VAL, len);
+ //memset(wLUT + (0xa0000000 >> PSXM_SHIFT), INVALID_PTR_VAL, len);
+ }
}
int psxMemInit(void)
{
+ size_t table_size = 1ul << (32 - PSXM_SHIFT);
+ uintptr_t *memRLUT;
+ uintptr_t *memWLUT;
unsigned int i;
int ret;
if (DISABLE_MEM_LUTS)
return 0;
- psxMemRLUT = (u8 **)malloc(0x10000 * sizeof(void *));
- psxMemWLUT = (u8 **)malloc(0x10000 * sizeof(void *));
-
- if (psxMemRLUT == NULL || psxMemWLUT == NULL) {
+ memRLUT = malloc(table_size * sizeof(memRLUT[0]) * 2);
+ if (memRLUT == NULL) {
SysMessage("Error allocating psxMem LUTs");
psxMemShutdown();
return -1;
}
- memset(psxMemRLUT, (int)(uintptr_t)INVALID_PTR, 0x10000 * sizeof(void *));
- memset(psxMemWLUT, (int)(uintptr_t)INVALID_PTR, 0x10000 * sizeof(void *));
-
-// MemR
- for (i = 0; i < 0x80; i++) psxMemRLUT[i + 0x0000] = (u8 *)&psxM[(i & 0x1f) << 16];
-
- memcpy(psxMemRLUT + 0x8000, psxMemRLUT, 0x80 * sizeof(void *));
- memcpy(psxMemRLUT + 0xa000, psxMemRLUT, 0x80 * sizeof(void *));
-
- psxMemRLUT[0x1f00] = (u8 *)psxP;
- psxMemRLUT[0x1f80] = (u8 *)psxH;
-
- for (i = 0; i < 0x08; i++) psxMemRLUT[i + 0x1fc0] = (u8 *)&psxR[i << 16];
-
- memcpy(psxMemRLUT + 0x9fc0, psxMemRLUT + 0x1fc0, 0x08 * sizeof(void *));
- memcpy(psxMemRLUT + 0xbfc0, psxMemRLUT + 0x1fc0, 0x08 * sizeof(void *));
-
-// MemW
- for (i = 0; i < 0x80; i++) psxMemWLUT[i + 0x0000] = (u8 *)&psxM[(i & 0x1f) << 16];
+ assert((s8)INVALID_PTR_VAL == INVALID_PTR_VAL);
+ memset(memRLUT, INVALID_PTR_VAL, table_size * sizeof(memRLUT[0]) * 2);
+ memWLUT = memRLUT + table_size;
+ psxRegs.ptrs.memRLUT = memRLUT;
+ psxRegs.ptrs.memWLUT = memWLUT;
+
+ // ram
+ for (i = 0; i < 0x800000; i += 0x200000) {
+ u8 *ram = psxRegs.ptrs.psxM;
+ lutMap(memRLUT, ram, 0x200000, 0x00000000u + i, 0x00200000u + i);
+ lutMap(memRLUT, ram, 0x200000, 0x80000000u + i, 0x80200000u + i);
+ lutMap(memRLUT, ram, 0x200000, 0xa0000000u + i, 0xa0200000u + i);
+ }
+ mapRam(1);
- memcpy(psxMemWLUT + 0x8000, psxMemWLUT, 0x80 * sizeof(void *));
- memcpy(psxMemWLUT + 0xa000, psxMemWLUT, 0x80 * sizeof(void *));
+ // bios
+ lutMap(memRLUT, psxRegs.ptrs.psxR, 0x80000, 0x1fc00000u, 0x1fc80000u);
+ lutMap(memRLUT, psxRegs.ptrs.psxR, 0x80000, 0x9fc00000u, 0x9fc80000u);
+ lutMap(memRLUT, psxRegs.ptrs.psxR, 0x80000, 0xbfc00000u, 0xbfc80000u);
// Don't allow writes to PIO Expansion region (psxP) to take effect.
// NOTE: Not sure if this is needed to fix any games but seems wise,
// seeing as some games do read from PIO as part of copy-protection
// check. (See fix in psxMemReset() regarding psxP region reads).
- psxMemWLUT[0x1f00] = INVALID_PTR;
- psxMemWLUT[0x1f80] = (u8 *)psxH;
+ //memWLUT[0x1f000000 >> PSXM_SHIFT] = INVALID_PTR_VAL;
return 0;
}
FILE *f = NULL;
char bios[1024];
- memset(psxM, 0, 0x00200000);
- memset(psxP, 0xff, 0x00010000);
+ memset(psxRegs.ptrs.psxM, 0, 0x00200000);
+ memset(psxRegs.ptrs.psxP, 0xff, 0x00010000);
+
+ if (!DISABLE_MEM_LUTS)
+ mapRam(1);
Config.HLE = TRUE;
if (f == NULL) {
SysMessage(_("Could not open BIOS:\"%s\". Enabling HLE Bios!\n"), bios);
} else {
- if (fread(psxR, 1, 0x80000, f) == 0x80000) {
+ if (fread(psxRegs.ptrs.psxR, 1, 0x80000, f) == 0x80000) {
Config.HLE = FALSE;
} else {
SysMessage(_("The selected BIOS:\"%s\" is of wrong size. Enabling HLE Bios!\n"), bios);
}
}
if (Config.HLE)
- memset(psxR, 0, 0x80000);
+ memset(psxRegs.ptrs.psxR, 0, 0x80000);
}
void psxMemShutdown() {
else
psxMemFreeMap();
- free(psxMemRLUT); psxMemRLUT = NULL;
- free(psxMemWLUT); psxMemWLUT = NULL;
+ free(psxRegs.ptrs.memRLUT);
+ psxRegs.ptrs.memRLUT = NULL;
+ psxRegs.ptrs.memWLUT = NULL;
}
int cache_isolated;
void psxMemOnIsolate(int enable)
{
if (!DISABLE_MEM_LUTS) {
- if (enable) {
- memset(psxMemWLUT + 0x0000, (int)(uintptr_t)INVALID_PTR, 0x80 * sizeof(void *));
- memset(psxMemWLUT + 0x8000, (int)(uintptr_t)INVALID_PTR, 0x80 * sizeof(void *));
- //memset(psxMemWLUT + 0xa000, (int)(uintptr_t)INVALID_PTR, 0x80 * sizeof(void *));
- } else {
- int i;
- for (i = 0; i < 0x80; i++)
- psxMemWLUT[i + 0x0000] = (void *)&psxM[(i & 0x1f) << 16];
- memcpy(psxMemWLUT + 0x8000, psxMemWLUT, 0x80 * sizeof(void *));
- memcpy(psxMemWLUT + 0xa000, psxMemWLUT, 0x80 * sizeof(void *));
- }
+ mapRam(!enable);
}
cache_isolated = enable;
: R3000ACPU_NOTIFY_CACHE_UNISOLATED, NULL);
}
-u8 psxMemRead8(u32 mem) {
- char *p;
+u8 psxMemRead8(psxRegisters *regs, u32 mem) {
+ u8 *p;
u32 t;
+ if (likely(psxm_(&p, regs, mem, 0)))
+ return *p;
+
t = mem >> 16;
if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) {
if ((mem & 0xffff) < 0x400)
- return psxHu8(mem);
+ return regs->ptrs.psxH[mem & 0x3ff];
else
return psxHwRead8(mem);
- } else {
- p = psxm(mem, 0);
- if (p != INVALID_PTR) {
- if (Config.Debug)
- DebugCheckBP((mem & 0xffffff) | 0x80000000, R1);
- return *(u8 *)p;
- } else {
-#ifdef PSXMEM_LOG
- PSXMEM_LOG("err lb %8.8lx\n", mem);
-#endif
- return 0xFF;
- }
}
+ return 0xFF;
}
-u16 psxMemRead16(u32 mem) {
- char *p;
+u16 psxMemRead16(psxRegisters *regs, u32 mem) {
+ u8 *p;
u32 t;
+ if (likely(psxm_(&p, regs, mem, 0)))
+ return SWAPu16(*(u16 *)p);
+
t = mem >> 16;
if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) {
if ((mem & 0xffff) < 0x400)
- return psxHu16(mem);
+ return SWAPu16(*(u16 *)(regs->ptrs.psxH + (mem & 0x3fe)));
else
return psxHwRead16(mem);
- } else {
- p = psxm(mem, 0);
- if (p != INVALID_PTR) {
- if (Config.Debug)
- DebugCheckBP((mem & 0xffffff) | 0x80000000, R2);
- return SWAPu16(*(u16 *)p);
- } else {
-#ifdef PSXMEM_LOG
- PSXMEM_LOG("err lh %8.8lx\n", mem);
-#endif
- return 0xFFFF;
- }
}
+ return 0xFFFF;
}
-u32 psxMemRead32(u32 mem) {
- char *p;
+u32 psxMemRead32(psxRegisters *regs, u32 mem) {
+ u8 *p;
u32 t;
+ if (likely(psxm_(&p, regs, mem, 0)))
+ return SWAPu32(*(u32 *)p);
+
t = mem >> 16;
if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) {
if ((mem & 0xffff) < 0x400)
- return psxHu32(mem);
+ return SWAPu32(*(u32 *)(regs->ptrs.psxH + (mem & 0x3fc)));
else
return psxHwRead32(mem);
- } else {
- p = psxm(mem, 0);
- if (p != INVALID_PTR) {
- if (Config.Debug)
- DebugCheckBP((mem & 0xffffff) | 0x80000000, R4);
- return SWAPu32(*(u32 *)p);
- } else {
- if (mem == 0xfffe0130)
- return psxRegs.biuReg;
-#ifdef PSXMEM_LOG
- PSXMEM_LOG("err lw %8.8lx\n", mem);
-#endif
- return 0xFFFFFFFF;
- }
}
+ if (mem == 0xfffe0130)
+ return regs->biuReg;
+ return 0xFFFFFFFF;
}
-void psxMemWrite8(u32 mem, u32 value) {
- char *p;
+void psxMemWrite8(psxRegisters *regs, u32 mem, u32 value) {
+ u8 *p;
u32 t;
+ if (likely(psxm_(&p, regs, mem, 1))) {
+ *p = value;
+#ifndef DRC_DISABLE
+ psxCpu->Clear(mem & ~3, 1);
+#endif
+ return;
+ }
+
t = mem >> 16;
if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) {
if ((mem & 0xffff) < 0x400)
- psxHu8(mem) = value;
+ regs->ptrs.psxH[mem & 0x3ff] = value;
else
psxHwWrite8(mem, value);
- } else {
- p = psxm(mem, 1);
- if (p != INVALID_PTR) {
- if (Config.Debug)
- DebugCheckBP((mem & 0xffffff) | 0x80000000, W1);
- *(u8 *)p = value;
-#ifndef DRC_DISABLE
- psxCpu->Clear((mem & (~3)), 1);
-#endif
- } else {
-#ifdef PSXMEM_LOG
- PSXMEM_LOG("err sb %8.8lx\n", mem);
-#endif
- }
+ return;
}
+ log_unhandled("unhandled w8 %08x %08x @%08x\n", mem, value, regs->pc);
}
-void psxMemWrite16(u32 mem, u32 value) {
- char *p;
+void psxMemWrite16(psxRegisters *regs, u32 mem, u32 value) {
+ u8 *p;
u32 t;
+ if (likely(psxm_(&p, regs, mem, 1))) {
+ *(u16 *)p = SWAPu16(value);
+#ifndef DRC_DISABLE
+ psxCpu->Clear(mem & ~3, 1);
+#endif
+ return;
+ }
+
t = mem >> 16;
if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) {
if ((mem & 0xffff) < 0x400)
- psxHu16ref(mem) = SWAPu16(value);
+ *(u16 *)(regs->ptrs.psxH + (mem & 0x3fe)) = SWAPu16(value);
else
psxHwWrite16(mem, value);
- } else {
- p = psxm(mem, 1);
- if (p != INVALID_PTR) {
- if (Config.Debug)
- DebugCheckBP((mem & 0xffffff) | 0x80000000, W2);
- *(u16 *)p = SWAPu16(value);
-#ifndef DRC_DISABLE
- psxCpu->Clear((mem & (~3)), 1);
-#endif
- } else {
-#ifdef PSXMEM_LOG
- PSXMEM_LOG("err sh %8.8lx\n", mem);
-#endif
- }
+ return;
}
+ log_unhandled("unhandled w16 %08x %08x @%08x\n", mem, value, regs->pc);
}
-void psxMemWrite32(u32 mem, u32 value) {
- char *p;
+void psxMemWrite32(psxRegisters *regs, u32 mem, u32 value) {
+ u8 *p;
u32 t;
-// if ((mem&0x1fffff) == 0x71E18 || value == 0x48088800) SysPrintf("t2fix!!\n");
- t = mem >> 16;
- if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) {
- if ((mem & 0xffff) < 0x400)
- psxHu32ref(mem) = SWAPu32(value);
- else
- psxHwWrite32(mem, value);
- } else {
- p = psxm(mem, 1);
- if (p != INVALID_PTR) {
- if (Config.Debug)
- DebugCheckBP((mem & 0xffffff) | 0x80000000, W4);
- *(u32 *)p = SWAPu32(value);
+ if (likely(psxm_(&p, regs, mem, 1))) {
+ *(u32 *)p = SWAPu32(value);
#ifndef DRC_DISABLE
- psxCpu->Clear(mem, 1);
+ psxCpu->Clear(mem & ~3, 1);
#endif
- } else {
- if (mem == 0xfffe0130) {
- psxRegs.biuReg = value;
- return;
- }
-#ifdef PSXMEM_LOG
- PSXMEM_LOG("err sw %8.8lx\n", mem);
-#endif
- }
+ return;
}
-}
-
-void *psxMemPointer(u32 mem) {
- char *p;
- u32 t;
t = mem >> 16;
if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) {
if ((mem & 0xffff) < 0x400)
- return (void *)&psxH[mem];
+ *(u32 *)(regs->ptrs.psxH + (mem & 0x3fc)) = SWAPu32(value);
else
- return NULL;
- } else {
- p = psxm(mem, 1);
- if (p != INVALID_PTR) {
- return (void *)p;
- }
- return NULL;
+ psxHwWrite32(mem, value);
+ return;
+ }
+ if (mem == 0xfffe0130) {
+ regs->biuReg = value;
+ return;
}
+ if (!(regs->CP0.n.SR & ((1u << 16))))
+ log_unhandled("unhandled w32 %08x %08x @%08x\n", mem, value, regs->pc);
}
#endif
#include "psxcommon.h"
+#include "r3000a.h"
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#endif
+// this is needed because:
+// - lighrec sometimes maps ram at address 0
+// - memRLUT[] may contain 0 as a valid entry
+#define INVALID_PTR_VAL -1l
#ifdef LIGHTREC
-#define INVALID_PTR ((void *)-1)
+#define INVALID_PTR ((void *)INVALID_PTR_VAL)
#else
#define INVALID_PTR NULL
#endif
-extern s8 *psxM;
-#define psxMs8(mem) psxM[(mem) & 0x1fffff]
-#define psxMs16(mem) (SWAP16(*(s16 *)&psxM[(mem) & 0x1fffff]))
-#define psxMs32(mem) (SWAP32(*(s32 *)&psxM[(mem) & 0x1fffff]))
-#define psxMu8(mem) (*(u8 *)&psxM[(mem) & 0x1fffff])
-#define psxMu16(mem) (SWAP16(*(u16 *)&psxM[(mem) & 0x1fffff]))
-#define psxMu32(mem) (SWAP32(*(u32 *)&psxM[(mem) & 0x1fffff]))
-
-#define psxMs8ref(mem) psxM[(mem) & 0x1fffff]
-#define psxMs16ref(mem) (*(s16 *)&psxM[(mem) & 0x1fffff])
-#define psxMs32ref(mem) (*(s32 *)&psxM[(mem) & 0x1fffff])
-#define psxMu8ref(mem) (*(u8 *)&psxM[(mem) & 0x1fffff])
-#define psxMu16ref(mem) (*(u16 *)&psxM[(mem) & 0x1fffff])
-#define psxMu32ref(mem) (*(u32 *)&psxM[(mem) & 0x1fffff])
-
-extern s8 *psxP;
-#define psxPs8(mem) psxP[(mem) & 0xffff]
-#define psxPs16(mem) (SWAP16(*(s16 *)&psxP[(mem) & 0xffff]))
-#define psxPs32(mem) (SWAP32(*(s32 *)&psxP[(mem) & 0xffff]))
-#define psxPu8(mem) (*(u8 *)&psxP[(mem) & 0xffff])
-#define psxPu16(mem) (SWAP16(*(u16 *)&psxP[(mem) & 0xffff]))
-#define psxPu32(mem) (SWAP32(*(u32 *)&psxP[(mem) & 0xffff]))
-
-#define psxPs8ref(mem) psxP[(mem) & 0xffff]
-#define psxPs16ref(mem) (*(s16 *)&psxP[(mem) & 0xffff])
-#define psxPs32ref(mem) (*(s32 *)&psxP[(mem) & 0xffff])
-#define psxPu8ref(mem) (*(u8 *)&psxP[(mem) & 0xffff])
-#define psxPu16ref(mem) (*(u16 *)&psxP[(mem) & 0xffff])
-#define psxPu32ref(mem) (*(u32 *)&psxP[(mem) & 0xffff])
-
-extern s8 *psxR;
-#define psxRs8(mem) psxR[(mem) & 0x7ffff]
-#define psxRs16(mem) (SWAP16(*(s16 *)&psxR[(mem) & 0x7ffff]))
-#define psxRs32(mem) (SWAP32(*(s32 *)&psxR[(mem) & 0x7ffff]))
-#define psxRu8(mem) (*(u8* )&psxR[(mem) & 0x7ffff])
-#define psxRu16(mem) (SWAP16(*(u16 *)&psxR[(mem) & 0x7ffff]))
-#define psxRu32(mem) (SWAP32(*(u32 *)&psxR[(mem) & 0x7ffff]))
-
-#define psxRs8ref(mem) psxR[(mem) & 0x7ffff]
-#define psxRs16ref(mem) (*(s16*)&psxR[(mem) & 0x7ffff])
-#define psxRs32ref(mem) (*(s32*)&psxR[(mem) & 0x7ffff])
-#define psxRu8ref(mem) (*(u8 *)&psxR[(mem) & 0x7ffff])
-#define psxRu16ref(mem) (*(u16*)&psxR[(mem) & 0x7ffff])
-#define psxRu32ref(mem) (*(u32*)&psxR[(mem) & 0x7ffff])
-
-extern s8 *psxH;
-#define psxHs8(mem) psxH[(mem) & 0xffff]
-#define psxHs16(mem) (SWAP16(*(s16 *)&psxH[(mem) & 0xffff]))
-#define psxHs32(mem) (SWAP32(*(s32 *)&psxH[(mem) & 0xffff]))
-#define psxHu8(mem) (*(u8 *)&psxH[(mem) & 0xffff])
-#define psxHu16(mem) (SWAP16(*(u16 *)&psxH[(mem) & 0xffff]))
-#define psxHu32(mem) (SWAP32(*(u32 *)&psxH[(mem) & 0xffff]))
-
-#define psxHs8ref(mem) psxH[(mem) & 0xffff]
-#define psxHs16ref(mem) (*(s16 *)&psxH[(mem) & 0xffff])
-#define psxHs32ref(mem) (*(s32 *)&psxH[(mem) & 0xffff])
-#define psxHu8ref(mem) (*(u8 *)&psxH[(mem) & 0xffff])
-#define psxHu16ref(mem) (*(u16 *)&psxH[(mem) & 0xffff])
-#define psxHu32ref(mem) (*(u32 *)&psxH[(mem) & 0xffff])
-
-extern u8 **psxMemWLUT;
-extern u8 **psxMemRLUT;
+#define PSXM_SHIFT 19
+
+#define psxMu8(mem) (*(u8 *)&psxRegs.ptrs.psxM[(mem) & 0x1fffff])
+#define psxMu16(mem) (SWAP16(*(u16 *)&psxRegs.ptrs.psxM[(mem) & 0x1fffff]))
+#define psxMu32(mem) (SWAP32(*(u32 *)&psxRegs.ptrs.psxM[(mem) & 0x1fffff]))
+
+#define psxMu8ref(mem) (*(u8 *)&psxRegs.ptrs.psxM[(mem) & 0x1fffff])
+#define psxMu16ref(mem) (*(u16 *)&psxRegs.ptrs.psxM[(mem) & 0x1fffff])
+#define psxMu32ref(mem) (*(u32 *)&psxRegs.ptrs.psxM[(mem) & 0x1fffff])
+
+#define psxHu8(mem) (*(u8 *)&psxRegs.ptrs.psxH[(mem) & 0xffff])
+#define psxHu16(mem) (SWAP16(*(u16 *)&psxRegs.ptrs.psxH[(mem) & 0xffff]))
+#define psxHu32(mem) (SWAP32(*(u32 *)&psxRegs.ptrs.psxH[(mem) & 0xffff]))
+
+#define psxHu8ref(mem) (*(u8 *)&psxRegs.ptrs.psxH[(mem) & 0xffff])
+#define psxHu16ref(mem) (*(u16 *)&psxRegs.ptrs.psxH[(mem) & 0xffff])
+#define psxHu32ref(mem) (*(u32 *)&psxRegs.ptrs.psxH[(mem) & 0xffff])
+
extern int cache_isolated;
#ifndef DISABLE_MEM_LUTS
#define DISABLE_MEM_LUTS 0
#endif
-static inline void * psxm_lut(u32 mem, int write, u8 **lut)
+// it may seem returning the pointer would be convenient here,
+// but that causes double compare (after lut and after ptr arithmetic),
+// and this is a hot path for the interpreter and non-dynarec-allowing systems, like apple
+static inline int psxm_lut(u8 **ret, const psxRegisters *regs, u32 mem, int write,
+ const uintptr_t *lut)
{
if (!DISABLE_MEM_LUTS) {
- void *ptr = lut[mem >> 16];
-
- return ptr == INVALID_PTR ? INVALID_PTR
- : (void *)((uintptr_t)ptr + (u16)mem);
+ uintptr_t ptr = lut[mem >> PSXM_SHIFT];
+ if (ptr != INVALID_PTR_VAL) {
+ *ret = (u8 *)(ptr + mem);
+ return 1;
+ }
+ return 0;
}
if (mem >= 0xa0000000)
else
mem &= ~0x80000000;
- if (mem < 0x800000) {
- if (cache_isolated)
- return INVALID_PTR;
+ if (mem < 0x800000u) {
+ if (write && cache_isolated)
+ return 0;
- return &psxM[mem & 0x1fffff];
+ *ret = regs->ptrs.psxM + (mem & 0x1fffff);
+ return 1;
}
- if (mem > 0x1f800000 && mem <= 0x1f810000)
- return &psxH[mem - 0x1f800000];
-
- if (!write) {
- if (mem > 0x1fc00000 && mem <= 0x1fc80000)
- return &psxR[mem - 0x1fc00000];
-
- if (mem > 0x1f000000 && mem <= 0x1f010000)
- return &psxP[mem - 0x1f000000];
+ if (!write && mem - 0x1fc00000u < 0x80000u) {
+ *ret = regs->ptrs.psxR + (mem - 0x1fc00000u);
+ return 1;
}
- return INVALID_PTR;
+ return 0;
+}
+
+static inline int psxm_(u8 **ret, const psxRegisters *regs, u32 mem, int write)
+{
+ return psxm_lut(ret, regs, mem, write,
+ write ? regs->ptrs.memWLUT : regs->ptrs.memRLUT);
}
static inline void * psxm(u32 mem, int write)
{
- return psxm_lut(mem, write, write ? psxMemWLUT : psxMemRLUT);
+ u8 *ret;
+ if (psxm_(&ret, &psxRegs, mem, write))
+ return ret;
+ return INVALID_PTR;
}
#define PSXM(mem) psxm(mem, 0)
-#define PSXMs8(mem) (*(s8 *)PSXM(mem))
-#define PSXMs16(mem) (SWAP16(*(s16 *)PSXM(mem)))
-#define PSXMs32(mem) (SWAP32(*(s32 *)PSXM(mem)))
#define PSXMu8(mem) (*(u8 *)PSXM(mem))
#define PSXMu16(mem) (SWAP16(*(u16 *)PSXM(mem)))
#define PSXMu32(mem) (SWAP32(*(u32 *)PSXM(mem)))
#define PSXMu32ref(mem) (*(u32 *)PSXM(mem))
+struct psxRegisters;
+
int psxMemInit();
void psxMemReset();
void psxMemOnIsolate(int enable);
void psxMemShutdown();
-u8 psxMemRead8 (u32 mem);
-u16 psxMemRead16(u32 mem);
-u32 psxMemRead32(u32 mem);
-void psxMemWrite8 (u32 mem, u32 value);
-void psxMemWrite16(u32 mem, u32 value);
-void psxMemWrite32(u32 mem, u32 value);
-void *psxMemPointer(u32 mem);
+u8 psxMemRead8 (struct psxRegisters *regs, u32 mem);
+u16 psxMemRead16(struct psxRegisters *regs, u32 mem);
+u32 psxMemRead32(struct psxRegisters *regs, u32 mem);
+void psxMemWrite8 (struct psxRegisters *regs, u32 mem, u32 value);
+void psxMemWrite16(struct psxRegisters *regs, u32 mem, u32 value);
+void psxMemWrite32(struct psxRegisters *regs, u32 mem, u32 value);
#ifdef __cplusplus
}
#include "psxbios.h"
#include "psxevents.h"
#include "../include/compiler_features.h"
+#include <stddef.h>
#include <assert.h>
#ifndef ARRAY_SIZE
psxMemReset();
- memset(&psxRegs, 0, sizeof(psxRegs));
+ memset(&psxRegs, 0, offsetof(psxRegisters, ptrs));
psxRegs.pc = 0xbfc00000; // Start in bootstrap
#include "psxcommon.h"
+#ifdef __i386__
+#define INT_ATTR __attribute__((regparm(2)))
+#else
+#define INT_ATTR
+#endif
+
enum R3000Aexception {
R3000E_Int = 0, // Interrupt
R3000E_AdEL = 4, // Address error (on load/I-fetch)
u32 biosBranchCheck;
u32 cpuInRecursion;
u32 gpuIdleAfter;
- u32 unused3[2];
// warning: changing anything in psxRegisters requires update of all
// asm in libpcsxcore/new_dynarec/ and may break savestates
+ // ptrs must be last
+ struct {
+ u8 *psxM; // Kernel & User Memory (2 Meg)
+ u8 *psxP; // Parallel/Expansion Port (64K) (not used)
+ u8 *psxR; // BIOS ROM (512K)
+ u8 *psxH; // Scratch Pad (1K) & Hardware Registers (8K)
+ uintptr_t *memRLUT;
+ uintptr_t *memWLUT;
+ u32 (INT_ATTR *intFetch)(struct psxRegisters *regs_,
+ const uintptr_t *memRLUT, u32 pc);
+ void *unused3[3];
+ } ptrs;
} psxRegisters;
extern psxRegisters psxRegs;