drc: hacks for psx bios on PCSX
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / pcsxmem.c
CommitLineData
7e605697 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
18static 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
24static 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
30static 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
36static 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
42static 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
48static 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
54static void read_mem_dummy()
55{
56 readmem_word = 0;
57}
58
59static void write_mem_dummy()
60{
61}
62
63extern void ari_read_ram8();
64extern void ari_read_ram16();
65extern void ari_read_ram32();
66extern void ari_read_ram_mirror8();
67extern void ari_read_ram_mirror16();
68extern void ari_read_ram_mirror32();
69extern void ari_write_ram8();
70extern void ari_write_ram16();
71extern void ari_write_ram32();
72extern void ari_write_ram_mirror8();
73extern void ari_write_ram_mirror16();
74extern void ari_write_ram_mirror32();
a06c1d6e 75extern void ari_read_bios8();
76extern void ari_read_bios16();
77extern void ari_read_bios32();
7e605697 78extern void ari_read_io8();
79extern void ari_read_io16();
80extern void ari_read_io32();
81extern void ari_write_io8();
82extern void ari_write_io16();
83extern void ari_write_io32();
84
85void (*readmem[0x10000])();
86void (*readmemb[0x10000])();
87void (*readmemh[0x10000])();
88void (*writemem[0x10000])();
89void (*writememb[0x10000])();
90void (*writememh[0x10000])();
91
92/* IO handlers */
93static u32 io_read_sio16()
94{
95 return sioRead8() | (sioRead8() << 8);
96}
97
98static u32 io_read_sio32()
99{
100 return sioRead8() | (sioRead8() << 8) | (sioRead8() << 16) | (sioRead8() << 24);
101}
102
103static void io_write_sio16(u32 value)
104{
105 sioWrite8((unsigned char)value);
106 sioWrite8((unsigned char)(value>>8));
107}
108
109static 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) \
118static u32 io_rcnt_read_count##i() { return psxRcntRcount(i); } \
119static u32 io_rcnt_read_mode##i() { return psxRcntRmode(i); } \
120static u32 io_rcnt_read_target##i() { return psxRcntRtarget(i); } \
121static void io_rcnt_write_count##i(u32 val) { psxRcntWcount(i, val & 0xffff); } \
122static void io_rcnt_write_mode##i(u32 val) { psxRcntWmode(i, val); } \
123static void io_rcnt_write_target##i(u32 val) { psxRcntWtarget(i, val & 0xffff); }
124
125make_rcnt_funcs(0)
126make_rcnt_funcs(1)
127make_rcnt_funcs(2)
128
129static 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
136static void io_write_imask16(u32 value)
137{
138 psxHu16ref(0x1074) = value;
139 if (psxHu16ref(0x1070) & value)
d28b54b1 140 new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1);
7e605697 141}
142
143static 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
150static void io_write_imask32(u32 value)
151{
152 psxHu32ref(0x1074) = value;
153 if (psxHu32ref(0x1070) & value)
d28b54b1 154 new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1);
7e605697 155}
156
157static 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) \
164static 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
172make_dma_func(0)
173make_dma_func(1)
174make_dma_func(2)
175make_dma_func(3)
176make_dma_func(4)
177make_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
184static 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};
191static 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};
207static 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)
224static 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};
231static 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};
249static 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
276struct {
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
287void 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;
a06c1d6e 301 writememb[i] = writememh[i] = writemem[i] = write_mem_dummy;
7e605697 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
a06c1d6e 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
7e605697 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
353void 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