1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - device.c *
3 * Mupen64Plus homepage: https://mupen64plus.org/ *
4 * Copyright (C) 2016 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 "device.h"
23
24#include "memory/memory.h"
25#include "pif/pif.h"
26#include "r4300/r4300_core.h"
27#include "rcp/ai/ai_controller.h"
28#include "rcp/mi/mi_controller.h"
29#include "rcp/pi/pi_controller.h"
30#include "rcp/rdp/rdp_core.h"
31#include "rcp/ri/ri_controller.h"
32#include "rcp/rsp/rsp_core.h"
33#include "rcp/si/si_controller.h"
34#include "rcp/vi/vi_controller.h"
35
36#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
37
38
39static void read_open_bus(void* opaque, uint32_t address, uint32_t* value)
40{
41 *value = (address & 0xffff);
42 *value |= (*value << 16);
43}
44
45static void write_open_bus(void* opaque, uint32_t address, uint32_t value, uint32_t mask)
46{
47}
48
49static void get_pi_dma_handler(struct cart* cart, struct dd_controller* dd, uint32_t address, void** opaque, const struct pi_dma_handler** handler)
50{
51#define RW(o, x) \
52 do { \
53 static const struct pi_dma_handler h = { x ## _dma_read, x ## _dma_write }; \
54 *opaque = (o); \
55 *handler = &h; \
56 } while(0)
57
58 if (address >= MM_CART_ROM) {
59 if (address >= MM_CART_DOM3) {
60 /* 0x1fd00000 - 0x7fffffff : dom3 addr2, cart rom (Paper Mario (U)) ??? */
61 RW(cart, cart_dom3);
62 }
63 else {
64 /* 0x10000000 - 0x1fbfffff : dom1 addr2, cart rom */
65 RW(&cart->cart_rom, cart_rom);
66 }
67 }
68 else if (address >= MM_DOM2_ADDR2) {
69 /* 0x08000000 - 0x0fffffff : dom2 addr2, cart save */
70 RW(cart, cart_dom2);
71 }
72 else if (address >= MM_DOM2_ADDR1) {
73 /* 0x05000000 - 0x05ffffff : dom2 addr1, dd buffers */
74 /* 0x06000000 - 0x07ffffff : dom1 addr1, dd rom */
75 RW(dd, dd_dom);
76 }
77#undef RW
78}
79
80void init_device(struct device* dev,
81 /* memory */
82 void* base,
83 /* r4300 */
84 unsigned int emumode,
85 unsigned int count_per_op,
86 int no_compiled_jump,
87 int randomize_interrupt,
88 /* ai */
89 void* aout, const struct audio_out_backend_interface* iaout,
90 /* si */
91 unsigned int si_dma_duration,
92 /* rdram */
93 size_t dram_size,
94 /* pif */
95 void* jbds[PIF_CHANNELS_COUNT],
96 const struct joybus_device_interface* ijbds[PIF_CHANNELS_COUNT],
97 /* vi */
98 unsigned int vi_clock, unsigned int expected_refresh_rate,
99 /* cart */
100 void* af_rtc_clock, const struct clock_backend_interface* iaf_rtc_clock,
101 size_t rom_size,
102 uint16_t eeprom_type,
103 void* eeprom_storage, const struct storage_backend_interface* ieeprom_storage,
104 uint32_t flashram_type,
105 void* flashram_storage, const struct storage_backend_interface* iflashram_storage,
106 void* sram_storage, const struct storage_backend_interface* isram_storage,
107 /* dd */
108 void* dd_rtc_clock, const struct clock_backend_interface* dd_rtc_iclock,
109 size_t dd_rom_size,
110 void* dd_disk, const struct storage_backend_interface* dd_idisk)
111{
112 struct interrupt_handler interrupt_handlers[] = {
113 { &dev->vi, vi_vertical_interrupt_event }, /* VI */
114 { &dev->r4300, compare_int_handler }, /* COMPARE */
115 { &dev->r4300, check_int_handler }, /* CHECK */
116 { &dev->si, si_end_of_dma_event }, /* SI */
117 { &dev->pi, pi_end_of_dma_event }, /* PI */
118 { &dev->r4300.cp0, special_int_handler }, /* SPECIAL */
119 { &dev->ai, ai_end_of_dma_event }, /* AI */
120 { &dev->sp, rsp_interrupt_event }, /* SP */
121 { &dev->dp, rdp_interrupt_event }, /* DP */
122 { &dev->pif, hw2_int_handler }, /* HW2 */
123 { dev, nmi_int_handler }, /* NMI */
124 { dev, reset_hard_handler } /* reset_hard */
125 };
126
127#define R(x) read_ ## x
128#define W(x) write_ ## x
129#define RW(x) R(x), W(x)
130#define A(x,m) (x), (x) | (m)
131 struct mem_mapping mappings[] = {
132 /* clear mappings */
133 { 0x00000000, 0xffffffff, M64P_MEM_NOTHING, { NULL, RW(open_bus) } },
134 /* memory map */
135 { A(MM_RDRAM_DRAM, dram_size-1), M64P_MEM_RDRAM, { &dev->rdram, RW(rdram_dram) } },
136 { A(MM_RDRAM_REGS, 0xfffff), M64P_MEM_RDRAMREG, { &dev->rdram, RW(rdram_regs) } },
137 { A(MM_RSP_MEM, 0xffff), M64P_MEM_RSPMEM, { &dev->sp, RW(rsp_mem) } },
138 { A(MM_RSP_REGS, 0xffff), M64P_MEM_RSPREG, { &dev->sp, RW(rsp_regs) } },
139 { A(MM_RSP_REGS2, 0xffff), M64P_MEM_RSP, { &dev->sp, RW(rsp_regs2) } },
140 { A(MM_DPC_REGS, 0xffff), M64P_MEM_DP, { &dev->dp, RW(dpc_regs) } },
141 { A(MM_DPS_REGS, 0xffff), M64P_MEM_DPS, { &dev->dp, RW(dps_regs) } },
142 { A(MM_MI_REGS, 0xffff), M64P_MEM_MI, { &dev->mi, RW(mi_regs) } },
143 { A(MM_VI_REGS, 0xffff), M64P_MEM_VI, { &dev->vi, RW(vi_regs) } },
144 { A(MM_AI_REGS, 0xffff), M64P_MEM_AI, { &dev->ai, RW(ai_regs) } },
145 { A(MM_PI_REGS, 0xffff), M64P_MEM_PI, { &dev->pi, RW(pi_regs) } },
146 { A(MM_RI_REGS, 0xffff), M64P_MEM_RI, { &dev->ri, RW(ri_regs) } },
147 { A(MM_SI_REGS, 0xffff), M64P_MEM_SI, { &dev->si, RW(si_regs) } },
148 { A(MM_DOM2_ADDR1, 0xffffff), M64P_MEM_NOTHING, { NULL, RW(open_bus) } },
149 { A(MM_DD_ROM, 0x1ffffff), M64P_MEM_NOTHING, { NULL, RW(open_bus) } },
150 { A(MM_DOM2_ADDR2, 0x1ffff), M64P_MEM_FLASHRAMSTAT, { &dev->cart, RW(cart_dom2) } },
151 { A(MM_CART_ROM, rom_size-1), M64P_MEM_ROM, { &dev->cart.cart_rom, RW(cart_rom) } },
152 { A(MM_PIF_MEM, 0xffff), M64P_MEM_PIF, { &dev->pif, RW(pif_ram) } }
153 };
154
155 /* init and map DD if present */
156 if (dd_rom_size > 0) {
157 mappings[14] = (struct mem_mapping){ A(MM_DOM2_ADDR1, 0xffffff), M64P_MEM_NOTHING, { &dev->dd, RW(dd_regs) } };
158 mappings[15] = (struct mem_mapping){ A(MM_DD_ROM, dd_rom_size-1), M64P_MEM_NOTHING, { &dev->dd, RW(dd_rom) } };
159
160 init_dd(&dev->dd,
161 dd_rtc_clock, dd_rtc_iclock,
162 mem_base_u32(base, MM_DD_ROM), dd_rom_size,
163 dd_disk, dd_idisk,
164 &dev->r4300);
165 }
166
167 struct mem_handler dbg_handler = { &dev->r4300, RW(with_bp_checks) };
168#undef A
169#undef R
170#undef W
171#undef RW
172
173 init_memory(&dev->mem, mappings, ARRAY_SIZE(mappings), base, &dbg_handler);
174
175 init_rdram(&dev->rdram, mem_base_u32(base, MM_RDRAM_DRAM), dram_size, &dev->r4300);
176
177 init_r4300(&dev->r4300, &dev->mem, &dev->mi, &dev->rdram, interrupt_handlers,
178 emumode, count_per_op, no_compiled_jump, randomize_interrupt);
179 init_rdp(&dev->dp, &dev->sp, &dev->mi, &dev->mem, &dev->rdram, &dev->r4300);
180 init_rsp(&dev->sp, mem_base_u32(base, MM_RSP_MEM), &dev->mi, &dev->dp, &dev->ri);
181 init_ai(&dev->ai, &dev->mi, &dev->ri, &dev->vi, aout, iaout);
182 init_mi(&dev->mi, &dev->r4300);
183 init_pi(&dev->pi,
184 get_pi_dma_handler,
185 &dev->cart, &dev->dd,
186 &dev->mi, &dev->ri, &dev->dp);
187 init_ri(&dev->ri, &dev->rdram);
188 init_si(&dev->si, si_dma_duration, &dev->mi, &dev->pif, &dev->ri);
189 init_vi(&dev->vi, vi_clock, expected_refresh_rate, &dev->mi, &dev->dp);
190
191 /* FIXME: should boot on cart, unless only a disk is present, but having no cart is not yet supported by ui/core,
192 * so use another way of selecting boot device:
193 * use CART unless DD is plugged and the plugged CART is not a combo media (cart+disk).
194 */
195 uint8_t media = *((uint8_t*)mem_base_u32(base, MM_CART_ROM) + (0x3b ^ S8));
196 uint32_t rom_base = (dd_rom_size > 0 && media != 'C')
197 ? MM_DD_ROM
198 : MM_CART_ROM;
199
200 init_pif(&dev->pif,
201 (uint8_t*)mem_base_u32(base, MM_PIF_MEM),
202 jbds, ijbds,
203 (uint8_t*)mem_base_u32(base, rom_base) + 0x40,
204 &dev->r4300);
205
206 init_cart(&dev->cart,
207 af_rtc_clock, iaf_rtc_clock,
208 (uint8_t*)mem_base_u32(base, MM_CART_ROM), rom_size,
209 &dev->r4300,
210 eeprom_type, eeprom_storage, ieeprom_storage,
211 flashram_type, flashram_storage, iflashram_storage,
212 (const uint8_t*)dev->rdram.dram,
213 sram_storage, isram_storage);
214}
215
216void poweron_device(struct device* dev)
217{
218 size_t i;
219
220 poweron_rdram(&dev->rdram);
221 poweron_r4300(&dev->r4300);
222 poweron_rdp(&dev->dp);
223 poweron_rsp(&dev->sp);
224 poweron_ai(&dev->ai);
225 poweron_mi(&dev->mi);
226 poweron_pi(&dev->pi);
227 poweron_ri(&dev->ri);
228 poweron_si(&dev->si);
229 poweron_vi(&dev->vi);
230
231 poweron_pif(&dev->pif);
232
233 poweron_cart(&dev->cart);
234
235 /* poweron for controllers */
236 for(i = 0; i < GAME_CONTROLLERS_COUNT; ++i) {
237 struct pif_channel* channel = &dev->pif.channels[i];
238
239 if ((channel->ijbd != NULL) && (channel->ijbd->poweron != NULL)) {
240 channel->ijbd->poweron(channel->jbd);
241 }
242 }
243
244 if (dev->dd.rom != NULL) {
245 poweron_dd(&dev->dd);
246 }
247}
248
249void run_device(struct device* dev)
250{
251 /* device execution is driven by the r4300 */
252 run_r4300(&dev->r4300);
253}
254
255void stop_device(struct device* dev)
256{
257 /* set stop flag so that r4300 execution will be stopped at next interrupt */
258 *r4300_stop(&dev->r4300) = 1;
259}
260
261void hard_reset_device(struct device* dev)
262{
263 /* set reset hard flag so reset_hard will be called at next interrupt */
264 dev->r4300.reset_hard_job = 1;
265}
266
267void soft_reset_device(struct device* dev)
268{
269 /* schedule HW2 interrupt now and an NMI after 1/2 seconds */
270 add_interrupt_event(&dev->r4300.cp0, HW2_INT, 0);
271 add_interrupt_event(&dev->r4300.cp0, NMI_INT, 50000000);
272}
273