1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - pi_controller.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2014 Bobby Smiles *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22 #include "pi_controller.h"
23
24 #define M64P_CORE_PROTOTYPES 1
25 #include "../api/callbacks.h"
26 #include "../api/m64p_types.h"
27 #include "../main/main.h"
28 #include "../main/device.h"
29 #include "../memory/memory.h"
30 #include "../r4300/cp0.h"
31 #include "../r4300/cp0_private.h"
32 #include "../r4300/r4300_core.h"
33 #include "../ri/rdram_detection_hack.h"
34 #include "../ri/ri_controller.h"
35 #include "../dd/dd_controller.h"
36
37 #include <string.h>
38
39 enum
40 {
41 /* PI_STATUS - read */
42 PI_STATUS_DMA_BUSY = 0x01,
43 PI_STATUS_IO_BUSY = 0x02,
44 PI_STATUS_ERROR = 0x04,
45
46 /* PI_STATUS - write */
47 PI_STATUS_RESET = 0x01,
48 PI_STATUS_CLR_INTR = 0x02
49 };
50
51 /* Copies data from the PI into RDRAM */
dma_pi_read(struct pi_controller * pi)52 static void dma_pi_read(struct pi_controller *pi)
53 {
54 uint32_t length, i;
55 uint32_t dram_address;
56 uint32_t rom_address;
57 const uint8_t* dram;
58 uint8_t* rom;
59
60 /* XXX: end of domain is wrong ? */
61 if (pi->regs[PI_CART_ADDR_REG] >= 0x05000000 && pi->regs[PI_CART_ADDR_REG] < 0x06000000)
62 {
63 //64DD BUFFER WRITES
64 length = (pi->regs[PI_RD_LEN_REG] & 0xFFFFFF) + 1;
65 i = (pi->regs[PI_CART_ADDR_REG] - 0x05000000) & 0x1FFFFFF;
66
67 if (pi->regs[PI_CART_ADDR_REG] == 0x05000400)
68 {
69 //SECTOR BUFFER
70 i -= 0x400;
71 length = (i + length) > 0x100 ? (0x100 - i) : length;
72 rom_address = (pi->regs[PI_CART_ADDR_REG] - 0x05000400) & 0x3fffff;
73 rom = g_dev.dd.sec_buf;
74 }
75 else
76 {
77 pi->regs[PI_STATUS_REG] |= 1;
78 cp0_update_count();
79 add_interrupt_event(PI_INT, 0x1000/* pi->regs[PI_RD_LEN_REG] */);
80 return;
81 }
82
83 length = (pi->regs[PI_DRAM_ADDR_REG] + length) > 0x7FFFFF ?
84 (0x7FFFFF - pi->regs[PI_DRAM_ADDR_REG]) : length;
85
86 dram_address = pi->regs[PI_DRAM_ADDR_REG];
87 dram = (uint8_t*)pi->ri->rdram.dram;
88
89 for (i = 0; i < length; ++i)
90 rom[(rom_address + i) ^ S8] = dram[(dram_address + i) ^ S8];
91 }
92 else if (pi->regs[PI_CART_ADDR_REG] >= 0x08000000
93 && pi->regs[PI_CART_ADDR_REG] < 0x08010000)
94 {
95 if (pi->use_flashram != 1)
96 {
97 dma_write_sram(pi);
98 pi->use_flashram = -1;
99 }
100 else
101 {
102 dma_write_flashram(pi);
103 }
104 }
105 else
106 {
107 DebugMessage(M64MSG_WARNING, "Unknown dma read at 0x%08X in dma_pi_read()", pi->regs[PI_CART_ADDR_REG]);
108 }
109
110 /* Mark DMA as busy */
111 pi->regs[PI_STATUS_REG] |= PI_STATUS_DMA_BUSY;
112
113 /* schedule end of dma interrupt event */
114
115 cp0_update_count();
116 add_interrupt_event(PI_INT, /*pi->regs[PI_WR_LEN_REG]*/0x1000); /* XXX: 0x1000 ??? */
117 }
118
119 /* Copies data from the PI into RDRAM. */
dma_pi_write(struct pi_controller * pi)120 static void dma_pi_write(struct pi_controller *pi)
121 {
122 uint32_t length, i;
123 uint32_t dram_address;
124 uint32_t rom_address;
125 uint8_t* dram;
126 const uint8_t* rom;
127
128 if (pi->regs[PI_CART_ADDR_REG] < 0x10000000 && !(pi->regs[PI_CART_ADDR_REG] >= 0x06000000 && pi->regs[PI_CART_ADDR_REG] < 0x08000000))
129 {
130 /* XXX: end of domain is wrong ? */
131 if (pi->regs[PI_CART_ADDR_REG] >= 0x08000000 && pi->regs[PI_CART_ADDR_REG] < 0x08010000)
132 {
133 if (pi->use_flashram != 1)
134 {
135 dma_read_sram(pi);
136 pi->use_flashram = -1;
137 }
138 else
139 {
140 dma_read_flashram(pi);
141 }
142 }
143 else if (pi->regs[PI_CART_ADDR_REG] >= 0x05000000 && pi->regs[PI_CART_ADDR_REG] < 0x06000000)
144 {
145 /* 64DD REG/BUFFER */
146 length = (pi->regs[PI_WR_LEN_REG] & 0xFFFFFF) + 1;
147 i = (pi->regs[PI_CART_ADDR_REG] - 0x05000000) & 0x1FFFFFF;
148
149 if (pi->regs[PI_CART_ADDR_REG] == 0x05000400)
150 {
151 /* SECTOR BUFFER */
152 i -= 0x400;
153 length = (i + length) > 0x100 ? (0x100 - i) : length;
154 rom_address = (pi->regs[PI_CART_ADDR_REG] - 0x05000400) & 0x3fffff;
155 rom = g_dev.dd.sec_buf;
156 }
157 else if (pi->regs[PI_CART_ADDR_REG] == 0x05000000)
158 {
159 /* C2 BUFFER */
160 rom_address = (pi->regs[PI_CART_ADDR_REG] - 0x05000000) & 0x3fffff;
161 length = (i + length) > 0x400 ? (0x400 - i) : length;
162 rom = g_dev.dd.c2_buf;
163 }
164 else
165 {
166 /* mark both DMA and IO as busy */
167 pi->regs[PI_STATUS_REG] |=
168 PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY;
169
170 /* schedule end of dma interrupt event */
171 cp0_update_count();
172 add_interrupt_event(PI_INT, length / 8);
173
174 return;
175 }
176
177 length = (pi->regs[PI_DRAM_ADDR_REG] + length) > 0x7FFFFF ?
178 (0x7FFFFF - pi->regs[PI_DRAM_ADDR_REG]) : length;
179
180 dram_address = pi->regs[PI_DRAM_ADDR_REG];
181 dram = (uint8_t*)pi->ri->rdram.dram;
182
183 for (i = 0; i < length; ++i)
184 dram[(dram_address + i) ^ S8] = rom[(rom_address + i) ^ S8];
185
186 invalidate_r4300_cached_code(0x80000000 + dram_address, length);
187 invalidate_r4300_cached_code(0xa0000000 + dram_address, length);
188 }
189 else
190 {
191 #if 0
192 DebugMessage(M64MSG_WARNING, "Unknown dma write 0x%" PRIX32 " in dma_pi_write()", pi->regs[PI_CART_ADDR_REG]);
193 #endif
194 }
195
196 /* mark both DMA and IO as busy */
197 pi->regs[PI_STATUS_REG] |=
198 PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY;
199
200 /* schedule end of dma interrupt event */
201 cp0_update_count();
202 #if 0
203 add_interrupt_event(PI_INT, /*pi->regs[PI_WR_LEN_REG]*/0x1000);
204 #else
205 add_interrupt_event(PI_INT, ((pi->regs[PI_WR_LEN_REG] * 63) / 25));
206 #endif
207
208 return;
209 }
210
211 /* XXX: why need special treatment ? */
212 if (pi->regs[PI_CART_ADDR_REG] >= 0x1fc00000) /* for paper mario */
213 {
214 /* mark DMA as busy */
215 pi->regs[PI_STATUS_REG] |= PI_STATUS_DMA_BUSY;
216
217 /* schedule end of dma interrupt event */
218 cp0_update_count();
219 add_interrupt_event(PI_INT, 0x1000); /* XXX: 0x1000 ??? */
220
221 return;
222 }
223
224 if (pi->regs[PI_CART_ADDR_REG] >= 0x06000000 && pi->regs[PI_CART_ADDR_REG] < 0x08000000)
225 {
226 /* 64DD IPL */
227 length = (pi->regs[PI_WR_LEN_REG] & 0xFFFFFE) + 2;
228 i = (pi->regs[PI_CART_ADDR_REG] - 0x06000000) & 0x1FFFFFF;
229 length = (i + length) > pi->dd_rom.rom_size ?
230 (pi->dd_rom.rom_size - i) : length;
231 length = (pi->regs[PI_DRAM_ADDR_REG] + length) > 0x7FFFFF ?
232 (0x7FFFFF - pi->regs[PI_DRAM_ADDR_REG]) : length;
233
234 if (i > pi->dd_rom.rom_size || pi->regs[PI_DRAM_ADDR_REG] > 0x7FFFFF)
235 {
236 pi->regs[PI_STATUS_REG] |= 3;
237 cp0_update_count();
238 add_interrupt_event(PI_INT, length / 8);
239
240 return;
241 }
242
243 dram_address = pi->regs[PI_DRAM_ADDR_REG];
244 rom_address = (pi->regs[PI_CART_ADDR_REG] - 0x06000000) & 0x3fffff;
245 dram = (uint8_t*)pi->ri->rdram.dram;
246 rom = pi->dd_rom.rom;
247 }
248 else
249 {
250 /* CART ROM */
251 length = (pi->regs[PI_WR_LEN_REG] & 0xFFFFFE) + 2;
252 i = (pi->regs[PI_CART_ADDR_REG] - 0x10000000) & 0x3FFFFFF;
253 length = (i + length) > pi->cart_rom.rom_size ?
254 (pi->cart_rom.rom_size - i) : length;
255 length = (pi->regs[PI_DRAM_ADDR_REG] + length) > 0x7FFFFF ?
256 (0x7FFFFF - pi->regs[PI_DRAM_ADDR_REG]) : length;
257
258 if (i > pi->cart_rom.rom_size || pi->regs[PI_DRAM_ADDR_REG] > 0x7FFFFF)
259 {
260 /* mark both DMA and IO as busy */
261 pi->regs[PI_STATUS_REG] |=
262 PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY;
263
264 /* schedule end of dma interrupt event */
265 cp0_update_count();
266 add_interrupt_event(PI_INT, length / 8);
267
268 return;
269 }
270
271 dram_address = pi->regs[PI_DRAM_ADDR_REG];
272 rom_address = (pi->regs[PI_CART_ADDR_REG] - 0x10000000) & 0x3ffffff;
273 dram = (uint8_t*)pi->ri->rdram.dram;
274 rom = pi->cart_rom.rom;
275 }
276
277 for (i = 0; i < length; ++i)
278 dram[(dram_address + i) ^ S8] = rom[(rom_address + i) ^ S8];
279
280 invalidate_r4300_cached_code(0x80000000 + dram_address, length);
281 invalidate_r4300_cached_code(0xa0000000 + dram_address, length);
282
283 /* HACK: monitor PI DMA to trigger RDRAM size detection
284 * hack just before initial cart ROM loading. */
285 if (pi->regs[PI_CART_ADDR_REG] == 0x10001000 || pi->regs[PI_CART_ADDR_REG] == 0x06001000)
286 {
287 force_detected_rdram_size_hack();
288 }
289
290 /* mark both DMA and IO as busy */
291 pi->regs[PI_STATUS_REG] |=
292 PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY;
293
294 /* schedule end of dma interrupt event */
295 cp0_update_count();
296 add_interrupt_event(PI_INT, length / 8);
297 }
298
init_pi(struct pi_controller * pi,uint8_t * rom,size_t rom_size,uint8_t * ddrom,size_t ddrom_size,void * flashram_user_data,void (* flashram_save)(void *),uint8_t * flashram_data,void * sram_user_data,void (* sram_save)(void *),uint8_t * sram_data,struct r4300_core * r4300,struct ri_controller * ri)299 void init_pi(struct pi_controller* pi,
300 uint8_t *rom, size_t rom_size,
301 uint8_t *ddrom, size_t ddrom_size,
302 void* flashram_user_data, void (*flashram_save)(void*), uint8_t* flashram_data,
303 void* sram_user_data, void (*sram_save)(void*), uint8_t* sram_data,
304 struct r4300_core* r4300,
305 struct ri_controller *ri)
306 {
307 init_cart_rom(&pi->cart_rom, rom, rom_size);
308 init_dd_rom(&pi->dd_rom, ddrom, ddrom_size);
309 init_flashram(&pi->flashram, flashram_user_data, flashram_save, flashram_data);
310 init_sram(&pi->sram, sram_user_data, sram_save, sram_data);
311
312 pi->use_flashram = 0;
313
314 pi->r4300 = r4300;
315 pi->ri = ri;
316 }
317
318 /* Initializes the PI. */
poweron_pi(struct pi_controller * pi)319 void poweron_pi(struct pi_controller* pi)
320 {
321 memset(pi->regs, 0, PI_REGS_COUNT*sizeof(uint32_t));
322
323 poweron_cart_rom(&pi->cart_rom);
324 poweron_dd_rom(&pi->dd_rom);
325 poweron_flashram(&pi->flashram);
326
327 }
328
329 /* Reads a word from the PI MMIO register space. */
read_pi_regs(void * opaque,uint32_t address,uint32_t * value)330 int read_pi_regs(void* opaque, uint32_t address, uint32_t* value)
331 {
332 struct pi_controller* pi = (struct pi_controller*)opaque;
333 uint32_t reg = PI_REG(address);
334
335 *value = pi->regs[reg];
336
337 return 0;
338 }
339
340 /* writes a word to the PI MMIO register space. */
write_pi_regs(void * opaque,uint32_t address,uint32_t value,uint32_t mask)341 int write_pi_regs(void* opaque, uint32_t address,
342 uint32_t value, uint32_t mask)
343 {
344 struct pi_controller* pi = (struct pi_controller*)opaque;
345 uint32_t reg = PI_REG(address);
346
347 switch (reg)
348 {
349 case PI_CART_ADDR_REG:
350 {
351 if (value == 0x05000000)
352 {
353 g_dev.dd.regs[ASIC_CMD_STATUS] &= ~0x1C000000;
354 dd_pi_test();
355 }
356 else if (value == 0x05000400)
357 {
358 g_dev.dd.regs[ASIC_CMD_STATUS] &= ~0x4C000000;
359 dd_pi_test();
360 }
361 break;
362 }
363 case PI_RD_LEN_REG:
364 pi->regs[PI_RD_LEN_REG] = MASKED_WRITE(&pi->regs[PI_RD_LEN_REG], value, mask);
365 dma_pi_read(pi);
366 return 0;
367
368 case PI_WR_LEN_REG:
369 pi->regs[PI_WR_LEN_REG] = MASKED_WRITE(&pi->regs[PI_WR_LEN_REG], value, mask);
370 dma_pi_write(pi);
371 return 0;
372
373 case PI_STATUS_REG:
374 if (value & mask & 2)
375 clear_rcp_interrupt(pi->r4300, MI_INTR_PI);
376 return 0;
377
378 case PI_BSD_DOM1_LAT_REG:
379 case PI_BSD_DOM1_PWD_REG:
380 case PI_BSD_DOM1_PGS_REG:
381 case PI_BSD_DOM1_RLS_REG:
382 case PI_BSD_DOM2_LAT_REG:
383 case PI_BSD_DOM2_PWD_REG:
384 case PI_BSD_DOM2_PGS_REG:
385 case PI_BSD_DOM2_RLS_REG:
386 pi->regs[reg] = MASKED_WRITE(&pi->regs[reg], value & 0xff, mask);
387 return 0;
388 }
389
390 pi->regs[reg] = MASKED_WRITE(&pi->regs[reg], value, mask);
391
392 return 0;
393 }
394
pi_end_of_dma_event(struct pi_controller * pi)395 void pi_end_of_dma_event(struct pi_controller* pi)
396 {
397 pi->regs[PI_STATUS_REG] &= ~(PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY);
398 raise_rcp_interrupt(pi->r4300, MI_INTR_PI);
399
400 if ((pi->regs[PI_CART_ADDR_REG] == 0x05000000) || (pi->regs[PI_CART_ADDR_REG] == 0x05000400))
401 {
402 dd_update_bm(&g_dev.dd);
403 }
404 }
405