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