drc: some PCSX-specific const addr io handlers
authornotaz <notasas@gmail.com>
Thu, 17 Feb 2011 16:20:47 +0000 (18:20 +0200)
committernotaz <notasas@gmail.com>
Thu, 17 Feb 2011 21:45:24 +0000 (23:45 +0200)
Makefile
libpcsxcore/new_dynarec/assem_arm.c
libpcsxcore/new_dynarec/emu_if.c
libpcsxcore/new_dynarec/emu_if.h
libpcsxcore/new_dynarec/pcsxmem_inline.c [new file with mode: 0644]

index 63241e5..0a99925 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -39,7 +39,8 @@ OBJS += libpcsxcore/new_dynarec/new_dynarec.o libpcsxcore/new_dynarec/linkage_ar
 OBJS += libpcsxcore/new_dynarec/pcsxmem.o
 endif
 OBJS += libpcsxcore/new_dynarec/emu_if.o
 OBJS += libpcsxcore/new_dynarec/pcsxmem.o
 endif
 OBJS += libpcsxcore/new_dynarec/emu_if.o
-libpcsxcore/new_dynarec/new_dynarec.o: libpcsxcore/new_dynarec/assem_arm.c
+libpcsxcore/new_dynarec/new_dynarec.o: libpcsxcore/new_dynarec/assem_arm.c \
+       libpcsxcore/new_dynarec/pcsxmem_inline.c
 ifdef DRC_DBG
 libpcsxcore/new_dynarec/emu_if.o: CFLAGS += -D_FILE_OFFSET_BITS=64
 CFLAGS += -DDRC_DBG
 ifdef DRC_DBG
 libpcsxcore/new_dynarec/emu_if.o: CFLAGS += -D_FILE_OFFSET_BITS=64
 CFLAGS += -DDRC_DBG
@@ -48,6 +49,7 @@ endif
 # spu
 OBJS += plugins/dfsound/dma.o plugins/dfsound/freeze.o \
        plugins/dfsound/registers.o plugins/dfsound/spu.o
 # spu
 OBJS += plugins/dfsound/dma.o plugins/dfsound/freeze.o \
        plugins/dfsound/registers.o plugins/dfsound/spu.o
+plugins/dfsound/spu.o: plugins/dfsound/xa.c
 ifeq "$(USE_OSS)" "1"
 plugins/dfsound/%.o: CFLAGS += -DUSEOSS
 OBJS += plugins/dfsound/oss.o
 ifeq "$(USE_OSS)" "1"
 plugins/dfsound/%.o: CFLAGS += -DUSEOSS
 OBJS += plugins/dfsound/oss.o
index 8432884..eed584e 100644 (file)
@@ -2602,6 +2602,10 @@ emit_extjump_ds(int addr, int target)
   emit_extjump2(addr, target, (int)dyna_linker_ds);
 }
 
   emit_extjump2(addr, target, (int)dyna_linker_ds);
 }
 
+#ifdef PCSX
+#include "pcsxmem_inline.c"
+#endif
+
 do_readstub(int n)
 {
   assem_debug("do_readstub %x\n",start+stubs[n][3]*4);
 do_readstub(int n)
 {
   assem_debug("do_readstub %x\n",start+stubs[n][3]*4);
@@ -2721,6 +2725,10 @@ inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, i
     ftable=(int)readmemd;
 #endif
   assert(ftable!=0);
     ftable=(int)readmemd;
 #endif
   assert(ftable!=0);
+#ifdef PCSX
+  if(pcsx_direct_read(type,addr,target?rs:-1,rt))
+    return;
+#endif
   if(target==0)
     emit_movimm(addr,rs);
   emit_writeword(rs,(int)&address);
   if(target==0)
     emit_movimm(addr,rs);
   emit_writeword(rs,(int)&address);
@@ -2879,6 +2887,10 @@ inline_writestub(int type, int i, u_int addr, signed char regmap[], int target,
   int rt=get_reg(regmap,target);
   assert(rs>=0);
   assert(rt>=0);
   int rt=get_reg(regmap,target);
   assert(rs>=0);
   assert(rt>=0);
+#ifdef PCSX
+  if(pcsx_direct_write(type,addr,rs,rt,regmap))
+    return;
+#endif
   int ftable=0;
   if(type==STOREB_STUB)
     ftable=(int)writememb;
   int ftable=0;
   if(type==STOREB_STUB)
     ftable=(int)writememb;
index 3bfec4e..b44feb3 100644 (file)
@@ -155,7 +155,6 @@ static int ari64_init()
 {
        extern void (*psxCP2[64])();
        extern void psxNULL();
 {
        extern void (*psxCP2[64])();
        extern void psxNULL();
-       extern void *psxH_ptr;
        size_t i;
 
        new_dynarec_init();
        size_t i;
 
        new_dynarec_init();
index 9e7f710..a561255 100644 (file)
@@ -45,6 +45,8 @@ extern unsigned int word;     /* write */
 extern unsigned short hword;
 extern unsigned char byte;
 
 extern unsigned short hword;
 extern unsigned char byte;
 
+extern void *psxH_ptr;
+
 /* cycles/irqs */
 extern unsigned int next_interupt;
 extern int pending_exception;
 /* cycles/irqs */
 extern unsigned int next_interupt;
 extern int pending_exception;
diff --git a/libpcsxcore/new_dynarec/pcsxmem_inline.c b/libpcsxcore/new_dynarec/pcsxmem_inline.c
new file mode 100644 (file)
index 0000000..90dafa0
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * (C) GraÅžvydas "notaz" Ignotas, 2011
+ *
+ * This work is licensed under the terms of GNU GPL version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+static int emit_ldr_type(int type, int offs, int rs, int rt)
+{
+  switch(type) {
+    case LOADB_STUB:
+      emit_movsbl_indexed(offs,rs,rt);
+      break;
+    case LOADBU_STUB:
+      emit_movzbl_indexed(offs,rs,rt);
+      break;
+    case LOADH_STUB:
+      emit_movswl_indexed(offs,rs,rt);
+      break;
+    case LOADHU_STUB:
+      emit_movzwl_indexed(offs,rs,rt);
+      break;
+    case LOADW_STUB:
+      emit_readword_indexed(offs,rs,rt);
+      break;
+    default:
+      assert(0);
+  }
+}
+
+static int emit_str_type(int type, int offs, int rs, int rt)
+{
+  switch(type) {
+    case STOREB_STUB:
+      emit_writebyte_indexed(rt,offs,rs);
+      break;
+    case STOREH_STUB:
+      emit_writehword_indexed(rt,offs,rs);
+      break;
+    case STOREW_STUB:
+      emit_writeword_indexed(rt,offs,rs);
+      break;
+    default:
+      assert(0);
+  }
+}
+
+static void convert_ram_addr(u_int a_rs, u_int a_rt, int rs, int rt)
+{
+  if(rs<0)
+    emit_movimm(a_rt,rt);
+  else if((a_rs&~0x60000000)==a_rt)
+    emit_andimm(rs,~0x60000000,rt);
+  else if((a_rs&~0x00600000)==a_rt)
+    emit_andimm(rs,~0x00600000,rt);
+  else
+    emit_movimm(a_rt,rt);
+}
+
+static int pcsx_direct_read(int type, u_int addr, int rs, int rt)
+{
+  if((addr & 0x1f800000) == 0) {
+    assem_debug("pcsx_direct_read %08x ram\n",addr);
+    if(rt<0)
+      return 1;
+    u_int a=(addr&~0x60600000)|0x80000000;
+    convert_ram_addr(addr,a,rs,rt);
+    emit_ldr_type(type,0,rt,rt);
+    return 1;
+  }
+  if((addr & 0x1ff80000) == 0x1fc00000) {
+    assem_debug("pcsx_direct_read %08x bios\n",addr);
+    if(rt<0)
+      return 1;
+    emit_movimm((u_int)&psxR[addr&0x7ffff],rt);
+    emit_ldr_type(type,0,rt,rt);
+    return 1;
+  }
+  if((addr & 0xfffff000) == 0x1f800000) {
+    assem_debug("pcsx_direct_read %08x scratchpad\n",addr);
+    if(rt<0)
+      return 1;
+    if(type==LOADW_STUB||type==LOADBU_STUB||(addr&0xf00)==0) {
+      emit_readword((int)&psxH_ptr,rt);
+      emit_ldr_type(type,addr&0xfff,rt,rt);
+    } else {
+      emit_movimm((u_int)&psxH[addr&0xfff],rt);
+      emit_ldr_type(type,0,rt,rt);
+    }
+    return 1;
+  }
+
+  assem_debug("pcsx_direct_read %08x miss\n",addr);
+  return 0;
+}
+
+static int pcsx_direct_write(int type, u_int addr, int rs, int rt, signed char *regmap)
+{
+  if((addr & 0x1f800000) == 0) {
+    assem_debug("pcsx_direct_write %08x ram\n",addr);
+    u_int a=(addr&~0x60600000)|0x80000000;
+    convert_ram_addr(addr,a,rs,HOST_TEMPREG);
+    emit_str_type(type,0,HOST_TEMPREG,rt);
+
+    int ir=get_reg(regmap,INVCP);
+    assert(ir>=0);
+    emit_cmpmem_indexedsr12_reg(ir,rs,1);
+    emit_callne(invalidate_addr_reg[rs]);
+    return 1;
+  }
+  if((addr & 0xfffff000) == 0x1f800000) {
+    assem_debug("pcsx_direct_write %08x scratchpad\n",addr);
+    if(type==STOREW_STUB||type==STOREB_STUB||(addr&0xf00)==0) {
+      emit_readword((int)&psxH_ptr,HOST_TEMPREG);
+      emit_str_type(type,addr&0xfff,HOST_TEMPREG,rt);
+    } else {
+      emit_movimm((u_int)&psxH[addr&0xfff],HOST_TEMPREG);
+      emit_str_type(type,0,HOST_TEMPREG,rt);
+    }
+    return 1;
+  }
+
+  assem_debug("pcsx_direct_write %08x miss\n",addr);
+  return 0;
+}
+
+// vim:shiftwidth=2:expandtab