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