drc: map bios and fix dummy reads
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / pcsxmem.c
1 /*
2  * (C) GraÅžvydas "notaz" Ignotas, 2010
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 #include <stdio.h>
9 #include "../psxhw.h"
10 #include "../cdrom.h"
11 #include "../mdec.h"
12 #include "emu_if.h"
13 #include "pcsxmem.h"
14
15 //#define memprintf printf
16 #define memprintf(...)
17
18 static void read_mem8()
19 {
20         memprintf("ari64_read_mem8  %08x @%08x %u\n", address, psxRegs.pc, psxRegs.cycle);
21         readmem_word = psxMemRead8(address) & 0xff;
22 }
23
24 static void read_mem16()
25 {
26         memprintf("ari64_read_mem16 %08x @%08x %u\n", address, psxRegs.pc, psxRegs.cycle);
27         readmem_word = psxMemRead16(address) & 0xffff;
28 }
29
30 static void read_mem32()
31 {
32         memprintf("ari64_read_mem32 %08x @%08x %u\n", address, psxRegs.pc, psxRegs.cycle);
33         readmem_word = psxMemRead32(address);
34 }
35
36 static void write_mem8()
37 {
38         memprintf("ari64_write_mem8  %08x,       %02x @%08x %u\n", address, byte, psxRegs.pc, psxRegs.cycle);
39         psxMemWrite8(address, byte);
40 }
41
42 static void write_mem16()
43 {
44         memprintf("ari64_write_mem16 %08x,     %04x @%08x %u\n", address, hword, psxRegs.pc, psxRegs.cycle);
45         psxMemWrite16(address, hword);
46 }
47
48 static void write_mem32()
49 {
50         memprintf("ari64_write_mem32 %08x, %08x @%08x %u\n", address, word, psxRegs.pc, psxRegs.cycle);
51         psxMemWrite32(address, word);
52 }
53
54 static void read_mem_dummy()
55 {
56         readmem_word = 0;
57 }
58
59 static void write_mem_dummy()
60 {
61 }
62
63 extern void ari_read_ram8();
64 extern void ari_read_ram16();
65 extern void ari_read_ram32();
66 extern void ari_read_ram_mirror8();
67 extern void ari_read_ram_mirror16();
68 extern void ari_read_ram_mirror32();
69 extern void ari_write_ram8();
70 extern void ari_write_ram16();
71 extern void ari_write_ram32();
72 extern void ari_write_ram_mirror8();
73 extern void ari_write_ram_mirror16();
74 extern void ari_write_ram_mirror32();
75 extern void ari_read_bios8();
76 extern void ari_read_bios16();
77 extern void ari_read_bios32();
78 extern void ari_read_io8();
79 extern void ari_read_io16();
80 extern void ari_read_io32();
81 extern void ari_write_io8();
82 extern void ari_write_io16();
83 extern void ari_write_io32();
84
85 void (*readmem[0x10000])();
86 void (*readmemb[0x10000])();
87 void (*readmemh[0x10000])();
88 void (*writemem[0x10000])();
89 void (*writememb[0x10000])();
90 void (*writememh[0x10000])();
91
92 /* IO handlers */
93 static u32 io_read_sio16()
94 {
95         return sioRead8() | (sioRead8() << 8);
96 }
97
98 static u32 io_read_sio32()
99 {
100         return sioRead8() | (sioRead8() << 8) | (sioRead8() << 16) | (sioRead8() << 24);
101 }
102
103 static void io_write_sio16(u32 value)
104 {
105         sioWrite8((unsigned char)value);
106         sioWrite8((unsigned char)(value>>8));
107 }
108
109 static void io_write_sio32(u32 value)
110 {
111         sioWrite8((unsigned char)value);
112         sioWrite8((unsigned char)((value&0xff) >>  8));
113         sioWrite8((unsigned char)((value&0xff) >> 16));
114         sioWrite8((unsigned char)((value&0xff) >> 24));
115 }
116
117 #define make_rcnt_funcs(i) \
118 static u32 io_rcnt_read_count##i()  { return psxRcntRcount(i); } \
119 static u32 io_rcnt_read_mode##i()   { return psxRcntRmode(i); } \
120 static u32 io_rcnt_read_target##i() { return psxRcntRtarget(i); } \
121 static void io_rcnt_write_count##i(u32 val)  { psxRcntWcount(i, val & 0xffff); } \
122 static void io_rcnt_write_mode##i(u32 val)   { psxRcntWmode(i, val); } \
123 static void io_rcnt_write_target##i(u32 val) { psxRcntWtarget(i, val & 0xffff); }
124
125 make_rcnt_funcs(0)
126 make_rcnt_funcs(1)
127 make_rcnt_funcs(2)
128
129 static void io_write_ireg16(u32 value)
130 {
131         if (Config.Sio) psxHu16ref(0x1070) |= 0x80;
132         if (Config.SpuIrq) psxHu16ref(0x1070) |= 0x200;
133         psxHu16ref(0x1070) &= psxHu16(0x1074) & value;
134 }
135
136 static void io_write_imask16(u32 value)
137 {
138         psxHu16ref(0x1074) = value;
139         if (psxHu16ref(0x1070) & value)
140                 new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1);
141 }
142
143 static void io_write_ireg32(u32 value)
144 {
145         if (Config.Sio) psxHu32ref(0x1070) |= 0x80;
146         if (Config.SpuIrq) psxHu32ref(0x1070) |= 0x200;
147         psxHu32ref(0x1070) &= psxHu32(0x1074) & value;
148 }
149
150 static void io_write_imask32(u32 value)
151 {
152         psxHu32ref(0x1074) = value;
153         if (psxHu32ref(0x1070) & value)
154                 new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1);
155 }
156
157 static void io_write_dma_icr32(u32 value)
158 {
159         u32 tmp = ~value & HW_DMA_ICR;
160         HW_DMA_ICR = ((tmp ^ value) & 0xffffff) ^ tmp;
161 }
162
163 #define make_dma_func(n) \
164 static void io_write_chcr##n(u32 value) \
165 { \
166         HW_DMA##n##_CHCR = value; \
167         if (value & 0x01000000 && HW_DMA_PCR & (8 << (n * 4))) { \
168                 psxDma##n(HW_DMA##n##_MADR, HW_DMA##n##_BCR, value); \
169         } \
170 }
171
172 make_dma_func(0)
173 make_dma_func(1)
174 make_dma_func(2)
175 make_dma_func(3)
176 make_dma_func(4)
177 make_dma_func(6)
178
179 /* IO tables for 1000-1880 */
180 #define IOADR8(a)  ((a) & 0xfff)
181 #define IOADR16(a) (((a) & 0xfff) >> 1)
182 #define IOADR32(a) (((a) & 0xfff) >> 2)
183
184 static const void *io_read8 [0x880] = {
185         [IOADR8(0x1040)] = sioRead8,
186         [IOADR8(0x1800)] = cdrRead0,
187         [IOADR8(0x1801)] = cdrRead1,
188         [IOADR8(0x1802)] = cdrRead2,
189         [IOADR8(0x1803)] = cdrRead3,
190 };
191 static const void *io_read16[0x880/2] = {
192         [IOADR16(0x1040)] = io_read_sio16,
193         [IOADR16(0x1044)] = sioReadStat16,
194         [IOADR16(0x1048)] = sioReadMode16,
195         [IOADR16(0x104a)] = sioReadCtrl16,
196         [IOADR16(0x104e)] = sioReadBaud16,
197         [IOADR16(0x1100)] = io_rcnt_read_count0,
198         [IOADR16(0x1104)] = io_rcnt_read_mode0,
199         [IOADR16(0x1108)] = io_rcnt_read_target0,
200         [IOADR16(0x1110)] = io_rcnt_read_count1,
201         [IOADR16(0x1114)] = io_rcnt_read_mode1,
202         [IOADR16(0x1118)] = io_rcnt_read_target1,
203         [IOADR16(0x1120)] = io_rcnt_read_count2,
204         [IOADR16(0x1124)] = io_rcnt_read_mode2,
205         [IOADR16(0x1128)] = io_rcnt_read_target2,
206 };
207 static const void *io_read32[0x880/4] = {
208         [IOADR32(0x1040)] = io_read_sio32,
209         [IOADR32(0x1100)] = io_rcnt_read_count0,
210         [IOADR32(0x1104)] = io_rcnt_read_mode0,
211         [IOADR32(0x1108)] = io_rcnt_read_target0,
212         [IOADR32(0x1110)] = io_rcnt_read_count1,
213         [IOADR32(0x1114)] = io_rcnt_read_mode1,
214         [IOADR32(0x1118)] = io_rcnt_read_target1,
215         [IOADR32(0x1120)] = io_rcnt_read_count2,
216         [IOADR32(0x1124)] = io_rcnt_read_mode2,
217         [IOADR32(0x1128)] = io_rcnt_read_target2,
218 //      [IOADR32(0x1810)] = GPU_readData,
219 //      [IOADR32(0x1814)] = GPU_readStatus,
220         [IOADR32(0x1820)] = mdecRead0,
221         [IOADR32(0x1824)] = mdecRead1,
222 };
223 // write(u32 val)
224 static const void *io_write8 [0x880] = {
225         [IOADR8(0x1040)] = sioWrite8,
226         [IOADR8(0x1800)] = cdrWrite0,
227         [IOADR8(0x1801)] = cdrWrite1,
228         [IOADR8(0x1802)] = cdrWrite2,
229         [IOADR8(0x1803)] = cdrWrite3,
230 };
231 static const void *io_write16[0x880/2] = {
232         [IOADR16(0x1040)] = io_write_sio16,
233         [IOADR16(0x1044)] = sioWriteStat16,
234         [IOADR16(0x1048)] = sioWriteMode16,
235         [IOADR16(0x104a)] = sioWriteCtrl16,
236         [IOADR16(0x104e)] = sioWriteBaud16,
237         [IOADR16(0x1070)] = io_write_ireg16,
238         [IOADR16(0x1074)] = io_write_imask16,
239         [IOADR16(0x1100)] = io_rcnt_write_count0,
240         [IOADR16(0x1104)] = io_rcnt_write_mode0,
241         [IOADR16(0x1108)] = io_rcnt_write_target0,
242         [IOADR16(0x1110)] = io_rcnt_write_count1,
243         [IOADR16(0x1114)] = io_rcnt_write_mode1,
244         [IOADR16(0x1118)] = io_rcnt_write_target1,
245         [IOADR16(0x1120)] = io_rcnt_write_count2,
246         [IOADR16(0x1124)] = io_rcnt_write_mode2,
247         [IOADR16(0x1128)] = io_rcnt_write_target2,
248 };
249 static const void *io_write32[0x880/4] = {
250         [IOADR32(0x1040)] = io_write_sio32,
251         [IOADR32(0x1070)] = io_write_ireg32,
252         [IOADR32(0x1074)] = io_write_imask32,
253         [IOADR32(0x1088)] = io_write_chcr0,
254         [IOADR32(0x1098)] = io_write_chcr1,
255         [IOADR32(0x10a8)] = io_write_chcr2,
256         [IOADR32(0x10b8)] = io_write_chcr3,
257         [IOADR32(0x10c8)] = io_write_chcr4,
258         [IOADR32(0x10e8)] = io_write_chcr6,
259         [IOADR32(0x10f4)] = io_write_dma_icr32,
260         [IOADR32(0x1100)] = io_rcnt_write_count0,
261         [IOADR32(0x1104)] = io_rcnt_write_mode0,
262         [IOADR32(0x1108)] = io_rcnt_write_target0,
263         [IOADR32(0x1110)] = io_rcnt_write_count1,
264         [IOADR32(0x1114)] = io_rcnt_write_mode1,
265         [IOADR32(0x1118)] = io_rcnt_write_target1,
266         [IOADR32(0x1120)] = io_rcnt_write_count2,
267         [IOADR32(0x1124)] = io_rcnt_write_mode2,
268         [IOADR32(0x1128)] = io_rcnt_write_target2,
269 //      [IOADR32(0x1810)] = GPU_writeData,
270 //      [IOADR32(0x1814)] = GPU_writeStatus,
271         [IOADR32(0x1820)] = mdecWrite0,
272         [IOADR32(0x1824)] = mdecWrite1,
273 };
274
275 // this has to be in .bss to link into dynarec_local
276 struct {
277         void *tab_read8;
278         void *tab_read16;
279         void *tab_read32;
280         void *tab_write8;
281         void *tab_write16;
282         void *tab_write32;
283         void *spu_readf;
284         void *spu_writef;
285 } nd_pcsx_io;
286
287 void new_dyna_pcsx_mem_init(void)
288 {
289         int i;
290
291         // default/unmapped handlers
292         for (i = 0; i < 0x10000; i++) {
293                 readmemb[i] = read_mem8;
294                 readmemh[i] = read_mem16;
295                 readmem[i] = read_mem32;
296                 writememb[i] = write_mem8;
297                 writememh[i] = write_mem16;
298                 writemem[i] = write_mem32;
299 #if 1
300                 readmemb[i] = readmemh[i] = readmem[i] = read_mem_dummy;
301                 writememb[i] = writememh[i] = writemem[i] = write_mem_dummy;
302 #endif
303         }
304
305 #if 1
306         // RAM mirrors
307         for (i = 0; i < 0x80; i++) {
308                 readmemb[i] = readmemb[0x8000|i] = readmemb[0xa000|i] = ari_read_ram_mirror8;
309                 readmemh[i] = readmemh[0x8000|i] = readmemh[0xa000|i] = ari_read_ram_mirror16;
310                 readmem[i]  = readmem [0x8000|i] = readmem [0xa000|i] = ari_read_ram_mirror32;
311                 writememb[i] = writememb[0x8000|i] = writememb[0xa000|i] = ari_write_ram_mirror8;
312                 writememh[i] = writememh[0x8000|i] = writememh[0xa000|i] = ari_write_ram_mirror16;
313                 writemem[i]  = writemem [0x8000|i] = writemem [0xa000|i] = ari_write_ram_mirror32;
314         }
315
316         // RAM direct
317         for (i = 0x8000; i < 0x8020; i++) {
318                 readmemb[i] = ari_read_ram8;
319                 readmemh[i] = ari_read_ram16;
320                 readmem[i] = ari_read_ram32;
321                 writememb[i] = ari_write_ram8;
322                 writememh[i] = ari_write_ram16;
323                 writemem[i] = ari_write_ram32;
324         }
325
326         // BIOS and it's mirrors
327         for (i = 0x1fc0; i < 0x1fc8; i++) {
328                 readmemb[i] = readmemb[0x8000|i] = readmemb[0xa000|i] = ari_read_bios8;
329                 readmemh[i] = readmemh[0x8000|i] = readmemh[0xa000|i] = ari_read_bios16;
330                 readmem[i]  = readmem[0x8000|i]  = readmem[0xa000|i]  = ari_read_bios32;
331         }
332
333         // I/O
334         readmemb[0x1f80] = ari_read_io8;
335         readmemh[0x1f80] = ari_read_io16;
336         readmem[0x1f80]  = ari_read_io32;
337         writememb[0x1f80] = ari_write_io8;
338         writememh[0x1f80] = ari_write_io16;
339         writemem[0x1f80]  = ari_write_io32;
340
341         writemem[0xfffe] = write_mem32;
342 #endif
343
344         // fill IO tables
345         nd_pcsx_io.tab_read8 = io_read8;
346         nd_pcsx_io.tab_read16 = io_read16;
347         nd_pcsx_io.tab_read32 = io_read32;
348         nd_pcsx_io.tab_write8 = io_write8;
349         nd_pcsx_io.tab_write16 = io_write16;
350         nd_pcsx_io.tab_write32 = io_write32;
351 }
352
353 void new_dyna_pcsx_mem_reset(void)
354 {
355         // plugins might change so update the pointers
356         nd_pcsx_io.spu_readf = SPU_readRegister;
357         nd_pcsx_io.spu_writef = SPU_writeRegister;
358
359         io_read32[IOADR32(0x1810)] = GPU_readData;
360         io_read32[IOADR32(0x1814)] = GPU_readStatus;
361         io_write32[IOADR32(0x1810)] = GPU_writeData;
362         io_write32[IOADR32(0x1814)] = GPU_writeStatus;
363 }
364