drc: some PCSX-specific const addr io handlers
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / pcsxmem_inline.c
1 /*
2  * (C) GraÅžvydas "notaz" Ignotas, 2011
3  *
4  * This work is licensed under the terms of GNU GPL version 2 or later.
5  * See the COPYING file in the top-level directory.
6  */
7
8 static int emit_ldr_type(int type, int offs, int rs, int rt)
9 {
10   switch(type) {
11     case LOADB_STUB:
12       emit_movsbl_indexed(offs,rs,rt);
13       break;
14     case LOADBU_STUB:
15       emit_movzbl_indexed(offs,rs,rt);
16       break;
17     case LOADH_STUB:
18       emit_movswl_indexed(offs,rs,rt);
19       break;
20     case LOADHU_STUB:
21       emit_movzwl_indexed(offs,rs,rt);
22       break;
23     case LOADW_STUB:
24       emit_readword_indexed(offs,rs,rt);
25       break;
26     default:
27       assert(0);
28   }
29 }
30
31 static int emit_str_type(int type, int offs, int rs, int rt)
32 {
33   switch(type) {
34     case STOREB_STUB:
35       emit_writebyte_indexed(rt,offs,rs);
36       break;
37     case STOREH_STUB:
38       emit_writehword_indexed(rt,offs,rs);
39       break;
40     case STOREW_STUB:
41       emit_writeword_indexed(rt,offs,rs);
42       break;
43     default:
44       assert(0);
45   }
46 }
47
48 static void convert_ram_addr(u_int a_rs, u_int a_rt, int rs, int rt)
49 {
50   if(rs<0)
51     emit_movimm(a_rt,rt);
52   else if((a_rs&~0x60000000)==a_rt)
53     emit_andimm(rs,~0x60000000,rt);
54   else if((a_rs&~0x00600000)==a_rt)
55     emit_andimm(rs,~0x00600000,rt);
56   else
57     emit_movimm(a_rt,rt);
58 }
59
60 static int pcsx_direct_read(int type, u_int addr, int rs, int rt)
61 {
62   if((addr & 0x1f800000) == 0) {
63     assem_debug("pcsx_direct_read %08x ram\n",addr);
64     if(rt<0)
65       return 1;
66     u_int a=(addr&~0x60600000)|0x80000000;
67     convert_ram_addr(addr,a,rs,rt);
68     emit_ldr_type(type,0,rt,rt);
69     return 1;
70   }
71   if((addr & 0x1ff80000) == 0x1fc00000) {
72     assem_debug("pcsx_direct_read %08x bios\n",addr);
73     if(rt<0)
74       return 1;
75     emit_movimm((u_int)&psxR[addr&0x7ffff],rt);
76     emit_ldr_type(type,0,rt,rt);
77     return 1;
78   }
79   if((addr & 0xfffff000) == 0x1f800000) {
80     assem_debug("pcsx_direct_read %08x scratchpad\n",addr);
81     if(rt<0)
82       return 1;
83     if(type==LOADW_STUB||type==LOADBU_STUB||(addr&0xf00)==0) {
84       emit_readword((int)&psxH_ptr,rt);
85       emit_ldr_type(type,addr&0xfff,rt,rt);
86     } else {
87       emit_movimm((u_int)&psxH[addr&0xfff],rt);
88       emit_ldr_type(type,0,rt,rt);
89     }
90     return 1;
91   }
92
93   assem_debug("pcsx_direct_read %08x miss\n",addr);
94   return 0;
95 }
96
97 static int pcsx_direct_write(int type, u_int addr, int rs, int rt, signed char *regmap)
98 {
99   if((addr & 0x1f800000) == 0) {
100     assem_debug("pcsx_direct_write %08x ram\n",addr);
101     u_int a=(addr&~0x60600000)|0x80000000;
102     convert_ram_addr(addr,a,rs,HOST_TEMPREG);
103     emit_str_type(type,0,HOST_TEMPREG,rt);
104
105     int ir=get_reg(regmap,INVCP);
106     assert(ir>=0);
107     emit_cmpmem_indexedsr12_reg(ir,rs,1);
108     emit_callne(invalidate_addr_reg[rs]);
109     return 1;
110   }
111   if((addr & 0xfffff000) == 0x1f800000) {
112     assem_debug("pcsx_direct_write %08x scratchpad\n",addr);
113     if(type==STOREW_STUB||type==STOREB_STUB||(addr&0xf00)==0) {
114       emit_readword((int)&psxH_ptr,HOST_TEMPREG);
115       emit_str_type(type,addr&0xfff,HOST_TEMPREG,rt);
116     } else {
117       emit_movimm((u_int)&psxH[addr&0xfff],HOST_TEMPREG);
118       emit_str_type(type,0,HOST_TEMPREG,rt);
119     }
120     return 1;
121   }
122
123   assem_debug("pcsx_direct_write %08x miss\n",addr);
124   return 0;
125 }
126
127 // vim:shiftwidth=2:expandtab