1 // license:BSD-3-Clause
2 // copyright-holders:Angelo Salese, R. Belmont, Anthony Kruize, Fabio Priuli
3 /***************************************************************************
4
5 snes.c
6
7 Driver file to handle emulation of the Nintendo Super NES.
8
9 Based on original MESS driver by Lee Hammerton (aka Savoury Snax),
10 later contributions by
11 R. Belmont
12 Anthony Kruize
13 Angelo Salese
14 Fabio Priuli
15 byuu (extensive RE of both SNES and add-on chips)
16
17
18 Todo (in no particular order):
19 - Fix sync between 5A22, SPC700 and PPU
20 - Fix remaining sound and video bugs
21 - Fix vertical mosaic effects
22 - Add support for real CX4 and ST018 CPUs
23 - Add support for SA-1 and SuperGB add-ons
24 - Fix superscope support
25 - Add support for other controllers
26
27 ***************************************************************************/
28
29 #include "emu.h"
30 #include "includes/snes.h"
31
32 #include "machine/snescx4.h"
33
34 #include "bus/snes/snes_slot.h"
35 #include "bus/snes/snes_carts.h"
36 #include "bus/snes_ctrl/ctrl.h"
37
38 #include "softlist.h"
39 #include "speaker.h"
40
41
42 class snes_console_state : public snes_state
43 {
44 public:
snes_console_state(const machine_config & mconfig,device_type type,const char * tag)45 snes_console_state(const machine_config &mconfig, device_type type, const char *tag)
46 : snes_state(mconfig, type, tag)
47 , m_ctrl1(*this, "ctrl1")
48 , m_ctrl2(*this, "ctrl2")
49 , m_cartslot(*this, "snsslot")
50 { }
51
52 void snespal(machine_config &config);
53 void snes(machine_config &config);
54
55 private:
56 uint8_t snes20_hi_r(address_space &space, offs_t offset);
57 void snes20_hi_w(address_space &space, offs_t offset, uint8_t data);
58 uint8_t snes20_lo_r(address_space &space, offs_t offset);
59 void snes20_lo_w(address_space &space, offs_t offset, uint8_t data);
60 uint8_t snes21_lo_r(address_space &space, offs_t offset);
61 void snes21_lo_w(address_space &space, offs_t offset, uint8_t data);
62 uint8_t snes21_hi_r(address_space &space, offs_t offset);
63 void snes21_hi_w(address_space &space, offs_t offset, uint8_t data);
64 uint8_t snessfx_hi_r(address_space &space, offs_t offset);
65 uint8_t snessfx_lo_r(address_space &space, offs_t offset);
66 void snessfx_hi_w(address_space &space, offs_t offset, uint8_t data);
67 void snessfx_lo_w(address_space &space, offs_t offset, uint8_t data);
68 uint8_t snessa1_hi_r(address_space &space, offs_t offset);
69 uint8_t snessa1_lo_r(address_space &space, offs_t offset);
70 void snessa1_hi_w(address_space &space, offs_t offset, uint8_t data);
71 void snessa1_lo_w(address_space &space, offs_t offset, uint8_t data);
72 uint8_t snes7110_hi_r(address_space &space, offs_t offset);
73 uint8_t snes7110_lo_r(address_space &space, offs_t offset);
74 void snes7110_hi_w(address_space &space, offs_t offset, uint8_t data);
75 void snes7110_lo_w(address_space &space, offs_t offset, uint8_t data);
76 uint8_t snessdd1_lo_r(address_space &space, offs_t offset);
77 void snessdd1_lo_w(address_space &space, offs_t offset, uint8_t data);
78 uint8_t snessdd1_hi_r(address_space &space, offs_t offset);
79 void snessdd1_hi_w(address_space &space, offs_t offset, uint8_t data);
80 uint8_t snesbsx_hi_r(address_space &space, offs_t offset);
81 void snesbsx_hi_w(address_space &space, offs_t offset, uint8_t data);
82 uint8_t snesbsx_lo_r(address_space &space, offs_t offset);
83 void snesbsx_lo_w(address_space &space, offs_t offset, uint8_t data);
84 uint8_t snessgb_hi_r(address_space &space, offs_t offset);
85 uint8_t snessgb_lo_r(address_space &space, offs_t offset);
86 void snessgb_hi_w(address_space &space, offs_t offset, uint8_t data);
87 void snessgb_lo_w(address_space &space, offs_t offset, uint8_t data);
88 uint8_t pfest94_hi_r(address_space &space, offs_t offset);
89 void pfest94_hi_w(address_space &space, offs_t offset, uint8_t data);
90 uint8_t pfest94_lo_r(address_space &space, offs_t offset);
91 void pfest94_lo_w(address_space &space, offs_t offset, uint8_t data);
92
93 // input related
94 SNESCTRL_ONSCREEN_CB(onscreen_cb);
95 SNESCTRL_GUNLATCH_CB(gun_latch_cb);
96 virtual void io_read() override;
97 virtual uint8_t oldjoy1_read(int latched) override;
98 virtual uint8_t oldjoy2_read(int latched) override;
99 virtual void write_joy_latch(uint8_t data) override;
100 virtual void wrio_write(uint8_t data) override;
101
102 virtual void machine_start() override;
103 virtual void machine_reset() override;
104 int m_type;
105 required_device<snes_control_port_device> m_ctrl1;
106 required_device<snes_control_port_device> m_ctrl2;
107 optional_device<sns_cart_slot_device> m_cartslot;
108
109 void snes_map(address_map &map);
110 void spc_map(address_map &map);
111 };
112
113
114 /*************************************
115 *
116 * Memory handlers
117 *
118 *************************************/
119
120 // Memory access for the various types of carts
121
122 //---------------------------------------------------------------------------------
123 // LoROM & LoROM + BSX slot & LoROM + some add-on chips
124 //---------------------------------------------------------------------------------
125
126 // In general LoROM games have perfect mirror between 0x00-0x7d and 0x80-0xff
127 // But BSX+LoROM games use different read handlers (to access ROM beyond 2MB)
128 // so we use two different set of handlers...
129
130 // Also we have here LoROM + CX4, until the Hitachi CPU is emulated,
131 // and the LoROM + Seta DSP, because their chip_read/chip_write need global offset
132
snes20_hi_r(address_space & space,offs_t offset)133 uint8_t snes_console_state::snes20_hi_r(address_space &space, offs_t offset)
134 {
135 uint16_t address = offset & 0xffff;
136
137 // take care of add-on IO
138 if ((m_cartslot->get_type() == SNES_ST010 || m_cartslot->get_type() == SNES_ST011)
139 && (offset >= 0x600000 && offset < 0x680000 && (offset & 0xffff) < 0x4000))
140 return m_cartslot->chip_read(offset);
141 else if ((m_cartslot->get_type() == SNES_ST010 || m_cartslot->get_type() == SNES_ST011)
142 && (offset >= 0x680000 && offset < 0x700000 && (offset & 0xffff) < 0x8000))
143 return m_cartslot->chip_read(offset);
144 else if (m_cartslot->get_type() == SNES_CX4
145 && (offset < 0x400000 && (offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000)) // hack until we emulate the real CPU
146 return CX4_read((offset & 0xffff) - 0x6000);
147
148 if (offset < 0x400000)
149 {
150 if (address < 0x2000)
151 return m_wram[address];
152 else if (address < 0x6000)
153 return snes_r_io(address);
154 else if (address < 0x8000)
155 return snes_open_bus_r();
156 else
157 return m_cartslot->read_h(offset);
158 }
159 else if (offset < 0x700000)
160 {
161 if (address < 0x8000)
162 return snes_open_bus_r();
163 else
164 return m_cartslot->read_h(offset);
165 }
166 else
167 {
168 if (m_type == SNES_SUFAMITURBO && address >= 0x8000 && offset < 0x740000)
169 return m_cartslot->read_h(offset);
170
171 // here usually there is SRAM mirrored in the whole range, but if ROM is very large then arrives here too (see tokimeki and wizardg4)
172 if (m_cartslot->m_cart->get_rom_size() > 0x200000 && address >= 0x8000)
173 return m_cartslot->read_h(offset);
174 else
175 {
176 if (m_cartslot->m_cart->get_nvram_size() > 0x8000)
177 {
178 // In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc.
179 offset = ((offset - 0x700000) / 0x10000) * 0x8000 + (offset & 0x7fff);
180 return m_cartslot->read_ram(offset);
181 }
182 else if (m_cartslot->m_cart->get_nvram_size() > 0)
183 return m_cartslot->read_ram(offset);
184 else
185 return snes_open_bus_r();
186 }
187 }
188 }
189
snes20_hi_w(address_space & space,offs_t offset,uint8_t data)190 void snes_console_state::snes20_hi_w(address_space &space, offs_t offset, uint8_t data)
191 {
192 uint16_t address = offset & 0xffff;
193
194 // take care of add-on IO
195 if ((m_cartslot->get_type() == SNES_ST010 || m_cartslot->get_type() == SNES_ST011)
196 && (offset >= 0x600000 && offset < 0x680000 && (offset & 0xffff) < 0x4000))
197 { m_cartslot->chip_write(offset, data); return; }
198 else if ((m_cartslot->get_type() == SNES_ST010 || m_cartslot->get_type() == SNES_ST011)
199 && (offset >= 0x680000 && offset < 0x700000 && (offset & 0xffff) < 0x8000))
200 { m_cartslot->chip_write(offset, data); return; }
201 else if (m_cartslot->get_type() == SNES_CX4
202 && (offset < 0x400000 && (offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000)) // hack until we emulate the real CPU
203 { CX4_write(machine(), (offset & 0xffff) - 0x6000, data); return; }
204 else if (m_type == SNES_SUFAMITURBO
205 && address >= 0x8000 && ((offset >= 0x600000 && offset < 0x640000) || (offset >= 0x700000 && offset < 0x740000)))
206 { m_cartslot->write_h(offset, data); return; }
207
208 if (offset < 0x400000)
209 {
210 if (address < 0x2000)
211 m_wram[address] = data;
212 else if (address < 0x6000)
213 snes_w_io(space, address, data);
214 }
215 else if (offset >= 0x700000 && (m_cartslot->m_cart->get_rom_size() <= 0x200000 || address < 0x8000)) // NVRAM access
216 {
217 if (m_cartslot->m_cart->get_nvram_size() > 0x8000)
218 {
219 // In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc.
220 offset = ((offset - 0x700000) / 0x10000) * 0x8000 + (offset & 0x7fff);
221 m_cartslot->write_ram(offset, data);
222 }
223 else if (m_cartslot->m_cart->get_nvram_size() > 0)
224 m_cartslot->write_ram(offset, data);
225 }
226 }
227
snes20_lo_r(address_space & space,offs_t offset)228 uint8_t snes_console_state::snes20_lo_r(address_space &space, offs_t offset)
229 {
230 uint16_t address = offset & 0xffff;
231
232 // take care of add-on IO
233 if ((m_cartslot->get_type() == SNES_ST010 /*|| m_cartslot->get_type() == SNES_ST011*/) // why does this break moritash?
234 && (offset >= 0x600000 && offset < 0x680000 && (offset & 0xffff) < 0x4000))
235 return m_cartslot->chip_read(offset);
236 else if ((m_cartslot->get_type() == SNES_ST010 || m_cartslot->get_type() == SNES_ST011)
237 && (offset >= 0x680000 && offset < 0x700000 && (offset & 0xffff) < 0x8000))
238 return m_cartslot->chip_read(offset);
239 else if (m_cartslot->get_type() == SNES_CX4
240 && (offset < 0x400000 && (offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000)) // hack until we emulate the real CPU
241 return CX4_read((offset & 0xffff) - 0x6000);
242
243 if (offset < 0x400000)
244 {
245 if (address < 0x2000)
246 return m_wram[address];
247 else if (address < 0x6000)
248 return snes_r_io(address);
249 else if (address < 0x8000)
250 return snes_open_bus_r();
251 else
252 return m_cartslot->read_l(offset);
253 }
254 else if (offset < 0x700000)
255 {
256 if (address < 0x8000)
257 return snes_open_bus_r();
258 else
259 return m_cartslot->read_l(offset);
260 }
261 else
262 {
263 if (m_type == SNES_SUFAMITURBO && address >= 0x8000 && offset < 0x740000)
264 return m_cartslot->read_l(offset);
265
266 // here usually there is SRAM mirrored in the whole range, but if ROM is very large then arrives here too (see tokimeki and wizardg4)
267 if (m_cartslot->m_cart->get_rom_size() > 0x200000 && address >= 0x8000)
268 return m_cartslot->read_l(offset);
269 else
270 {
271 if (m_cartslot->m_cart->get_nvram_size() > 0x8000)
272 {
273 // In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc.
274 offset = ((offset - 0x700000) / 0x10000) * 0x8000 + (offset & 0x7fff);
275 return m_cartslot->read_ram(offset);
276 }
277 else if (m_cartslot->m_cart->get_nvram_size() > 0)
278 return m_cartslot->read_ram(offset);
279 else
280 return snes_open_bus_r();
281 }
282 }
283 }
284
snes20_lo_w(address_space & space,offs_t offset,uint8_t data)285 void snes_console_state::snes20_lo_w(address_space &space, offs_t offset, uint8_t data)
286 {
287 if (m_type == SNES_SUFAMITURBO
288 && (offset & 0xffff) >= 0x8000 && ((offset >= 0x600000 && offset < 0x640000) || (offset >= 0x700000 && offset < 0x740000)))
289 { m_cartslot->write_l(offset, data); return; }
290
291 // other add-on writes matches the hi handler
292 snes20_hi_w(space, offset, data);
293 }
294
295
296 //---------------------------------------------------------------------------------
297 // HiROM & HiROM + BSX slot
298 //---------------------------------------------------------------------------------
299
snes21_lo_r(address_space & space,offs_t offset)300 uint8_t snes_console_state::snes21_lo_r(address_space &space, offs_t offset)
301 {
302 uint16_t address = offset & 0xffff;
303
304 if (offset < 0x400000 && address < 0x8000)
305 {
306 if (address < 0x2000)
307 return m_wram[address];
308 else if (address < 0x6000)
309 return snes_r_io(address);
310 else
311 {
312 if (m_type == SNES_BSXHI && m_cartslot->m_cart->get_nvram_size() && offset >= 0x200000)
313 {
314 int mask = (m_cartslot->m_cart->get_nvram_size() - 1) & 0x7fff;
315 return m_cartslot->read_ram((offset - 0x6000) & mask);
316 }
317
318 if (m_cartslot->m_cart->get_nvram_size() && offset >= 0x300000)
319 {
320 /* Donkey Kong Country checks this and detects a copier if 0x800 is not masked out due to sram size */
321 /* OTOH Secret of Mana does not work properly if sram is not mirrored on later banks */
322 int mask = (m_cartslot->m_cart->get_nvram_size() - 1) & 0x7fff; /* Limit SRAM size to what's actually present */
323 return m_cartslot->read_ram((offset - 0x6000) & mask);
324 }
325 else
326 return snes_open_bus_r();
327 }
328 }
329
330 // ROM access
331 return m_cartslot->read_l(offset);
332 }
333
snes21_lo_w(address_space & space,offs_t offset,uint8_t data)334 void snes_console_state::snes21_lo_w(address_space &space, offs_t offset, uint8_t data)
335 {
336 uint16_t address = offset & 0xffff;
337 if (offset < 0x400000 && address < 0x8000)
338 {
339 if (address < 0x2000)
340 m_wram[address] = data;
341 else if (address < 0x6000)
342 snes_w_io(space, address, data);
343 else
344 {
345 if (m_type == SNES_BSXHI && m_cartslot->m_cart->get_nvram_size() && offset >= 0x200000)
346 {
347 int mask = (m_cartslot->m_cart->get_nvram_size() - 1) & 0x7fff;
348 m_cartslot->write_ram((offset - 0x6000) & mask, data);
349 return;
350 }
351 if (m_cartslot->m_cart->get_nvram_size() && offset >= 0x300000)
352 {
353 /* Donkey Kong Country checks this and detects a copier if 0x800 is not masked out due to sram size */
354 /* OTOH Secret of Mana does not work properly if sram is not mirrored on later banks */
355 int mask = (m_cartslot->m_cart->get_nvram_size() - 1) & 0x7fff; /* Limit SRAM size to what's actually present */
356 m_cartslot->write_ram((offset - 0x6000) & mask, data);
357 }
358 }
359 }
360 }
361
snes21_hi_r(address_space & space,offs_t offset)362 uint8_t snes_console_state::snes21_hi_r(address_space &space, offs_t offset)
363 {
364 uint16_t address = offset & 0xffff;
365
366 if (offset < 0x400000 && address < 0x8000)
367 {
368 if (address < 0x2000)
369 return m_wram[address];
370 else if (address < 0x6000)
371 return snes_r_io(address);
372 else
373 {
374 if (m_type == SNES_BSXHI && m_cartslot->m_cart->get_nvram_size() && offset >= 0x200000)
375 {
376 int mask = (m_cartslot->m_cart->get_nvram_size() - 1) & 0x7fff;
377 return m_cartslot->read_ram((offset - 0x6000) & mask);
378 }
379
380 if (m_cartslot->m_cart->get_nvram_size() && offset >= 0x300000)
381 {
382 /* Donkey Kong Country checks this and detects a copier if 0x800 is not masked out due to sram size */
383 /* OTOH Secret of Mana does not work properly if sram is not mirrored on later banks */
384 int mask = (m_cartslot->m_cart->get_nvram_size() - 1) & 0x7fff; /* Limit SRAM size to what's actually present */
385 return m_cartslot->read_ram((offset - 0x6000) & mask);
386 }
387 else
388 return snes_open_bus_r();
389 }
390 }
391
392 // ROM access
393 return m_cartslot->read_h(offset);
394 }
395
snes21_hi_w(address_space & space,offs_t offset,uint8_t data)396 void snes_console_state::snes21_hi_w(address_space &space, offs_t offset, uint8_t data)
397 {
398 uint16_t address = offset & 0xffff;
399 if (offset < 0x400000 && address < 0x8000)
400 {
401 if (address < 0x2000)
402 m_wram[address] = data;
403 else if (address < 0x6000)
404 snes_w_io(space, address, data);
405 else
406 {
407 if (m_type == SNES_BSXHI && m_cartslot->m_cart->get_nvram_size() && offset >= 0x200000)
408 {
409 int mask = (m_cartslot->m_cart->get_nvram_size() - 1) & 0x7fff;
410 m_cartslot->write_ram((offset - 0x6000) & mask, data);
411 return;
412 }
413 if (m_cartslot->m_cart->get_nvram_size() && offset >= 0x300000)
414 {
415 /* Donkey Kong Country checks this and detects a copier if 0x800 is not masked out due to sram size */
416 /* OTOH Secret of Mana does not work properly if sram is not mirrored on later banks */
417 int mask = (m_cartslot->m_cart->get_nvram_size() - 1) & 0x7fff; /* Limit SRAM size to what's actually present */
418 m_cartslot->write_ram((offset - 0x6000) & mask, data);
419 }
420 }
421 }
422 }
423
424 //---------------------------------------------------------------------------------
425 // LoROM + SuperFX / GSU
426 //---------------------------------------------------------------------------------
427
snessfx_hi_r(address_space & space,offs_t offset)428 uint8_t snes_console_state::snessfx_hi_r(address_space &space, offs_t offset)
429 {
430 uint16_t address = offset & 0xffff;
431
432 if (offset < 0x400000)
433 {
434 if (address < 0x2000)
435 return m_wram[address];
436 else if (address < 0x6000)
437 {
438 if (address >= 0x3000 && address < 0x3300)
439 return m_cartslot->chip_read(offset);
440 else
441 return snes_r_io(address);
442 }
443 else if (address < 0x8000)
444 return m_cartslot->read_ram(offset & 0x1fff);
445 else
446 return m_cartslot->read_h(offset);
447 }
448 else if (offset < 0x600000)
449 return m_cartslot->read_h(offset);
450 else
451 return m_cartslot->read_ram(offset);
452 }
453
snessfx_lo_r(address_space & space,offs_t offset)454 uint8_t snes_console_state::snessfx_lo_r(address_space &space, offs_t offset)
455 {
456 uint16_t address = offset & 0xffff;
457
458 if (offset < 0x400000)
459 {
460 if (address < 0x2000)
461 return m_wram[address];
462 else if (address < 0x6000)
463 {
464 if (address >= 0x3000 && address < 0x3300)
465 return m_cartslot->chip_read(offset);
466 else
467 return snes_r_io(address);
468 }
469 else if (address < 0x8000)
470 return m_cartslot->read_ram(offset & 0x1fff);
471 else
472 return m_cartslot->read_l(offset);
473 }
474 else if (offset < 0x600000)
475 return m_cartslot->read_l(offset);
476 else
477 return m_cartslot->read_ram(offset);
478 }
479
snessfx_hi_w(address_space & space,offs_t offset,uint8_t data)480 void snes_console_state::snessfx_hi_w(address_space &space, offs_t offset, uint8_t data)
481 {
482 uint16_t address = offset & 0xffff;
483 if (offset < 0x400000)
484 {
485 if (address < 0x2000)
486 m_wram[address] = data;
487 else if (address < 0x6000)
488 {
489 if (address >= 0x3000 && address < 0x3300)
490 m_cartslot->chip_write(offset, data);
491 else
492 snes_w_io(space, address, data);
493 }
494 else if (address < 0x8000)
495 m_cartslot->write_ram(offset & 0x1fff, data);
496 }
497 else if (offset >= 0x600000)
498 m_cartslot->write_ram(offset, data);
499 }
500
snessfx_lo_w(address_space & space,offs_t offset,uint8_t data)501 void snes_console_state::snessfx_lo_w(address_space &space, offs_t offset, uint8_t data)
502 {
503 snessfx_hi_w(space, offset, data);
504 }
505
506 //---------------------------------------------------------------------------------
507 // LoROM + SA-1
508 //---------------------------------------------------------------------------------
509
snessa1_hi_r(address_space & space,offs_t offset)510 uint8_t snes_console_state::snessa1_hi_r(address_space &space, offs_t offset)
511 {
512 uint16_t address = offset & 0xffff;
513
514 if (offset < 0x400000)
515 {
516 if (address < 0x2000)
517 return m_wram[address];
518 else if (address < 0x6000)
519 {
520 if (address >= 0x2200 && address < 0x2400)
521 return m_cartslot->chip_read(offset); // SA-1 Regs
522 else if (address >= 0x3000 && address < 0x3800)
523 return m_cartslot->chip_read(offset); // Internal SA-1 RAM (2K)
524 else
525 return snes_r_io(address);
526 }
527 else if (address < 0x8000)
528 return m_cartslot->chip_read(offset); // SA-1 BWRAM
529 else
530 return m_cartslot->read_h(offset);
531 }
532 else
533 return m_cartslot->read_h(offset);
534 }
535
snessa1_lo_r(address_space & space,offs_t offset)536 uint8_t snes_console_state::snessa1_lo_r(address_space &space, offs_t offset)
537 {
538 uint16_t address = offset & 0xffff;
539
540 if (offset < 0x400000)
541 {
542 if (address < 0x2000)
543 return m_wram[address];
544 else if (address < 0x6000)
545 {
546 if (address >= 0x2200 && address < 0x2400)
547 return m_cartslot->chip_read(offset); // SA-1 Regs
548 else if (address >= 0x3000 && address < 0x3800)
549 return m_cartslot->chip_read(offset); // Internal SA-1 RAM (2K)
550 else
551 return snes_r_io(address);
552 }
553 else if (address < 0x8000)
554 return m_cartslot->chip_read(offset); // SA-1 BWRAM
555 else
556 return m_cartslot->read_l(offset);
557 }
558 else if (offset < 0x500000)
559 return m_cartslot->chip_read(offset); // SA-1 BWRAM (not mirrored above!)
560 else
561 return snes_r_io(address); // nothing mapped here!
562 }
563
snessa1_hi_w(address_space & space,offs_t offset,uint8_t data)564 void snes_console_state::snessa1_hi_w(address_space &space, offs_t offset, uint8_t data)
565 {
566 uint16_t address = offset & 0xffff;
567 if (offset < 0x400000)
568 {
569 if (address < 0x2000)
570 m_wram[address] = data;
571 else if (address < 0x6000)
572 {
573 if (address >= 0x2200 && address < 0x2400)
574 m_cartslot->chip_write(offset, data); // SA-1 Regs
575 else if (address >= 0x3000 && address < 0x3800)
576 m_cartslot->chip_write(offset, data); // Internal SA-1 RAM (2K)
577 else
578 snes_w_io(space, address, data);
579 }
580 else if (address < 0x8000)
581 m_cartslot->chip_write(offset, data); // SA-1 BWRAM
582 }
583 }
584
snessa1_lo_w(address_space & space,offs_t offset,uint8_t data)585 void snes_console_state::snessa1_lo_w(address_space &space, offs_t offset, uint8_t data)
586 {
587 if (offset >= 0x400000 && offset < 0x500000)
588 m_cartslot->chip_write(offset, data); // SA-1 BWRAM (not mirrored above!)
589 else
590 snessa1_hi_w(space, offset, data);
591 }
592
593 //---------------------------------------------------------------------------------
594 // HiROM + SPC-7110
595 //---------------------------------------------------------------------------------
596
snes7110_hi_r(address_space & space,offs_t offset)597 uint8_t snes_console_state::snes7110_hi_r(address_space &space, offs_t offset)
598 {
599 uint16_t address = offset & 0xffff;
600
601 if (offset < 0x400000)
602 {
603 if (address < 0x2000)
604 return m_wram[address];
605 else if (address < 0x6000)
606 {
607 uint16_t limit = (m_cartslot->get_type() == SNES_SPC7110_RTC) ? 0x4843 : 0x4840;
608 if (address >= 0x4800 && address < limit)
609 return m_cartslot->chip_read(address);
610
611 return snes_r_io(address);
612 }
613 else if (address < 0x8000)
614 {
615 if (offset < 0x10000)
616 return m_cartslot->read_ram(offset);
617 if (offset >= 0x300000 && offset < 0x310000)
618 return m_cartslot->read_ram(offset);
619 }
620 else
621 return m_cartslot->read_h(offset);
622 }
623 return m_cartslot->read_h(offset);
624 }
625
snes7110_lo_r(address_space & space,offs_t offset)626 uint8_t snes_console_state::snes7110_lo_r(address_space &space, offs_t offset)
627 {
628 uint16_t address = offset & 0xffff;
629
630 if (offset < 0x400000)
631 {
632 if (address < 0x2000)
633 return m_wram[address];
634 else if (address < 0x6000)
635 {
636 uint16_t limit = (m_cartslot->get_type() == SNES_SPC7110_RTC) ? 0x4843 : 0x4840;
637 if (address >= 0x4800 && address < limit)
638 return m_cartslot->chip_read(address);
639
640 return snes_r_io(address);
641 }
642 else if (address < 0x8000)
643 {
644 if (offset < 0x10000)
645 return m_cartslot->read_ram(offset);
646 if (offset >= 0x300000 && offset < 0x310000)
647 return m_cartslot->read_ram(offset);
648 }
649 else
650 return m_cartslot->read_l(offset);
651 }
652 if (offset >= 0x500000 && offset < 0x510000)
653 return m_cartslot->chip_read(0x4800);
654
655 return snes_open_bus_r();
656 }
657
snes7110_hi_w(address_space & space,offs_t offset,uint8_t data)658 void snes_console_state::snes7110_hi_w(address_space &space, offs_t offset, uint8_t data)
659 {
660 snes7110_lo_w(space, offset, data);
661 }
662
snes7110_lo_w(address_space & space,offs_t offset,uint8_t data)663 void snes_console_state::snes7110_lo_w (address_space &space, offs_t offset, uint8_t data)
664 {
665 uint16_t address = offset & 0xffff;
666 if (offset < 0x400000)
667 {
668 if (address < 0x2000)
669 m_wram[address] = data;
670 else if (address < 0x6000)
671 {
672 uint16_t limit = (m_cartslot->get_type() == SNES_SPC7110_RTC) ? 0x4843 : 0x4840;
673 if (address >= 0x4800 && address < limit)
674 {
675 m_cartslot->chip_write(address, data);
676 return;
677 }
678 snes_w_io(space, address, data);
679 }
680 else if (address < 0x8000)
681 {
682 if (offset < 0x10000)
683 m_cartslot->write_ram(offset, data);
684 if (offset >= 0x300000 && offset < 0x310000)
685 m_cartslot->write_ram(offset, data);
686 }
687 }
688 }
689
690
691 //---------------------------------------------------------------------------------
692 // LoROM + S-DD1
693 //---------------------------------------------------------------------------------
694
snessdd1_lo_r(address_space & space,offs_t offset)695 uint8_t snes_console_state::snessdd1_lo_r(address_space &space, offs_t offset)
696 {
697 uint16_t address = offset & 0xffff;
698
699 if (offset < 0x400000)
700 {
701 if (address < 0x2000)
702 return m_wram[address];
703 else if (address < 0x6000)
704 {
705 if (address >= 0x4800 && address < 0x4808)
706 return m_cartslot->chip_read(address);
707
708 return snes_r_io(address);
709 }
710 else if (address < 0x8000)
711 return snes_open_bus_r();
712 else
713 return m_cartslot->read_l(offset);
714 }
715 else if (offset >= 0x700000 && address < 0x8000 && m_cartslot->m_cart->get_nvram_size()) // NVRAM access
716 return m_cartslot->read_ram(offset);
717 else // ROM access
718 return m_cartslot->read_l(offset);
719 }
720
snessdd1_hi_r(address_space & space,offs_t offset)721 uint8_t snes_console_state::snessdd1_hi_r(address_space &space, offs_t offset)
722 {
723 if (offset >= 0x400000)
724 return m_cartslot->read_h(offset);
725 else
726 return snessdd1_lo_r(space, offset);
727 }
728
snessdd1_lo_w(address_space & space,offs_t offset,uint8_t data)729 void snes_console_state::snessdd1_lo_w(address_space &space, offs_t offset, uint8_t data)
730 {
731 snessdd1_hi_w(space, offset, data);
732 }
733
snessdd1_hi_w(address_space & space,offs_t offset,uint8_t data)734 void snes_console_state::snessdd1_hi_w(address_space &space, offs_t offset, uint8_t data)
735 {
736 uint16_t address = offset & 0xffff;
737 if (offset < 0x400000)
738 {
739 if (address < 0x2000)
740 m_wram[address] = data;
741 else if (address < 0x6000)
742 {
743 if (address >= 0x4300 && address < 0x4380)
744 {
745 m_cartslot->chip_write(address, data);
746 // here we don't return, but we let the w_io happen...
747 }
748 if (address >= 0x4800 && address < 0x4808)
749 {
750 m_cartslot->chip_write(address, data);
751 return;
752 }
753 snes_w_io(space, address, data);
754 }
755 }
756 if (offset >= 0x700000 && address < 0x8000 && m_cartslot->m_cart->get_nvram_size())
757 return m_cartslot->write_ram(offset, data);
758 }
759
760
761 //---------------------------------------------------------------------------------
762 // LoROM + BS-X (Base unit)
763 //---------------------------------------------------------------------------------
764
snesbsx_hi_r(address_space & space,offs_t offset)765 uint8_t snes_console_state::snesbsx_hi_r(address_space &space, offs_t offset)
766 {
767 uint16_t address = offset & 0xffff;
768
769 if (offset < 0x400000)
770 {
771 if (address < 0x2000)
772 return m_wram[address];
773 else if (address < 0x6000)
774 {
775 if (address >= 0x2188 && address < 0x21a0)
776 return m_cartslot->chip_read(offset);
777 if (address >= 0x5000)
778 return m_cartslot->chip_read(offset);
779 return snes_r_io(address);
780 }
781 else if (address < 0x8000)
782 {
783 if (offset >= 0x200000)
784 return m_cartslot->read_h(offset);
785 else
786 return snes_open_bus_r();
787 }
788 else
789 return m_cartslot->read_h(offset);
790 }
791 return m_cartslot->read_h(offset);
792 }
793
snesbsx_hi_w(address_space & space,offs_t offset,uint8_t data)794 void snes_console_state::snesbsx_hi_w(address_space &space, offs_t offset, uint8_t data)
795 {
796 uint16_t address = offset & 0xffff;
797 if (offset < 0x400000)
798 {
799 if (address < 0x2000)
800 m_wram[address] = data;
801 else if (address < 0x6000)
802 {
803 if (address >= 0x2188 && address < 0x21a0)
804 {
805 m_cartslot->chip_write(offset, data);
806 return;
807 }
808 if (address >= 0x5000)
809 {
810 m_cartslot->chip_write(offset, data);
811 return;
812 }
813 snes_w_io(space, address, data);
814 }
815 else if (address < 0x8000)
816 {
817 if (offset >= 0x200000)
818 return m_cartslot->write_l(offset, data);
819 }
820 else
821 return m_cartslot->write_l(offset, data);
822 }
823 return m_cartslot->write_l(offset, data);
824 }
825
snesbsx_lo_r(address_space & space,offs_t offset)826 uint8_t snes_console_state::snesbsx_lo_r(address_space &space, offs_t offset)
827 {
828 uint16_t address = offset & 0xffff;
829
830 if (offset < 0x400000)
831 {
832 if (address < 0x2000)
833 return m_wram[address];
834 else if (address < 0x6000)
835 {
836 if (address >= 0x2188 && address < 0x21a0)
837 return m_cartslot->chip_read(offset);
838 if (address >= 0x5000)
839 return m_cartslot->chip_read(offset);
840 return snes_r_io(address);
841 }
842 else if (address < 0x8000)
843 {
844 if (offset >= 0x200000)
845 return m_cartslot->read_l(offset);
846 else
847 return snes_open_bus_r();
848 }
849 else
850 return m_cartslot->read_l(offset);
851 }
852 return m_cartslot->read_l(offset);
853 }
854
snesbsx_lo_w(address_space & space,offs_t offset,uint8_t data)855 void snes_console_state::snesbsx_lo_w(address_space &space, offs_t offset, uint8_t data)
856 {
857 snesbsx_hi_w(space, offset, data);
858 }
859
860
861 //---------------------------------------------------------------------------------
862 // LoROM + SuperGB
863 //---------------------------------------------------------------------------------
864
snessgb_hi_r(address_space & space,offs_t offset)865 uint8_t snes_console_state::snessgb_hi_r(address_space &space, offs_t offset)
866 {
867 uint16_t address = offset & 0xffff;
868
869 if (offset < 0x400000)
870 {
871 if (address < 0x2000)
872 return m_wram[address];
873 else if (address < 0x6000)
874 return snes_r_io(address);
875 else if (address < 0x8000)
876 return m_cartslot->chip_read(offset);
877 else
878 return m_cartslot->read_h(offset);
879 }
880 else if (address >= 0x8000)
881 return m_cartslot->read_h(offset);
882
883 return snes_open_bus_r();
884 }
885
snessgb_lo_r(address_space & space,offs_t offset)886 uint8_t snes_console_state::snessgb_lo_r(address_space &space, offs_t offset)
887 {
888 return snessgb_hi_r(space, offset);
889 }
890
snessgb_hi_w(address_space & space,offs_t offset,uint8_t data)891 void snes_console_state::snessgb_hi_w(address_space &space, offs_t offset, uint8_t data)
892 {
893 uint16_t address = offset & 0xffff;
894 if (offset < 0x400000)
895 {
896 if (address < 0x2000)
897 m_wram[address] = data;
898 else if (address < 0x6000)
899 snes_w_io(space, address, data);
900 else if (address < 0x8000)
901 m_cartslot->chip_write(offset, data);
902 }
903 }
904
snessgb_lo_w(address_space & space,offs_t offset,uint8_t data)905 void snes_console_state::snessgb_lo_w(address_space &space, offs_t offset, uint8_t data)
906 {
907 snessgb_hi_w(space, offset, data);
908 }
909
910 //---------------------------------------------------------------------------------
911 // Powerfest '94 event cart
912 //---------------------------------------------------------------------------------
913
pfest94_hi_r(address_space & space,offs_t offset)914 uint8_t snes_console_state::pfest94_hi_r(address_space &space, offs_t offset)
915 {
916 uint16_t address = offset & 0xffff;
917
918 if (offset < 0x400000)
919 {
920 if (address < 0x2000)
921 return m_wram[address];
922 else if (address < 0x6000)
923 return snes_r_io(address);
924 else if (address < 0x8000)
925 {
926 if (offset < 0x100000) // DSP access
927 return m_cartslot->chip_read(offset);
928 else if (offset == 0x106000) // menu access
929 return m_cartslot->chip_read(offset + 0x8000);
930 else if (offset >= 0x300000 && m_cartslot->m_cart->get_nvram_size()) // NVRAM access
931 return m_cartslot->read_ram(offset);
932 else
933 return snes_open_bus_r();
934 }
935 else
936 return m_cartslot->read_h(offset);
937 }
938 return m_cartslot->read_h(offset);
939 }
940
pfest94_hi_w(address_space & space,offs_t offset,uint8_t data)941 void snes_console_state::pfest94_hi_w(address_space &space, offs_t offset, uint8_t data)
942 {
943 uint16_t address = offset & 0xffff;
944 if (offset < 0x400000)
945 {
946 if (address < 0x2000)
947 m_wram[address] = data;
948 else if (address < 0x6000)
949 snes_w_io(space, address, data);
950 else if (address < 0x8000)
951 {
952 if (offset < 0x100000) // DSP access
953 m_cartslot->chip_write(offset, data);
954 else if (offset == 0x206000) // menu access
955 m_cartslot->chip_write(offset + 0x8000, data);
956 else if (offset >= 0x300000 && m_cartslot->m_cart->get_nvram_size()) // NVRAM access
957 m_cartslot->write_ram(offset, data);
958 }
959 }
960 }
961
pfest94_lo_r(address_space & space,offs_t offset)962 uint8_t snes_console_state::pfest94_lo_r(address_space &space, offs_t offset)
963 {
964 uint16_t address = offset & 0xffff;
965
966 if (offset < 0x400000)
967 {
968 if (address < 0x2000)
969 return m_wram[address];
970 else if (address < 0x6000)
971 return snes_r_io(address);
972 else if (address < 0x8000)
973 {
974 if (offset < 0x100000) // DSP access
975 return m_cartslot->chip_read(offset);
976 else if (offset == 0x106000) // menu access
977 return m_cartslot->chip_read(offset + 0x8000);
978 else if (offset >= 0x300000 && m_cartslot->m_cart->get_nvram_size()) // NVRAM access
979 return m_cartslot->read_ram(offset);
980 else
981 return snes_open_bus_r();
982 }
983 else
984 return m_cartslot->read_l(offset);
985 }
986 return 0xff; // or open_bus?
987 }
988
pfest94_lo_w(address_space & space,offs_t offset,uint8_t data)989 void snes_console_state::pfest94_lo_w(address_space &space, offs_t offset, uint8_t data)
990 {
991 pfest94_hi_w(space, offset, data);
992 }
993
994
995 /*************************************
996 *
997 * Address maps
998 *
999 *************************************/
1000
snes_map(address_map & map)1001 void snes_console_state::snes_map(address_map &map)
1002 {
1003 // map(0x000000, 0x7dffff).rw(FUNC(snes_console_state::snes20_lo_r), FUNC(snes_console_state::snes20_lo_w));
1004 map(0x7e0000, 0x7fffff).ram().share("wram"); /* 8KB Low RAM, 24KB High RAM, 96KB Expanded RAM */
1005 // map(0x800000, 0xffffff).rw(FUNC(snes_console_state::snes20_hi_r), FUNC(snes_console_state::snes20_hi_w));
1006 }
1007
spc_map(address_map & map)1008 void snes_console_state::spc_map(address_map &map)
1009 {
1010 map(0x0000, 0xffff).ram().share("aram");
1011 }
1012
1013
1014 /*************************************
1015 *
1016 * Input ports
1017 *
1018 *************************************/
1019
1020 static INPUT_PORTS_START( snes )
1021 // input devices go through slot options
1022 PORT_START("OPTIONS")
1023 PORT_CONFNAME( 0x01, 0x00, "Hi-Res pixels blurring (TV effect)")
DEF_STR(Off)1024 PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
1025 PORT_CONFSETTING( 0x01, DEF_STR( On ) )
1026
1027 #if SNES_LAYER_DEBUG
1028 PORT_START("DEBUG1")
1029 PORT_CONFNAME( 0x03, 0x00, "Select BG1 priority" )
1030 PORT_CONFSETTING( 0x00, "All" )
1031 PORT_CONFSETTING( 0x01, "BG1B (lower) only" )
1032 PORT_CONFSETTING( 0x02, "BG1A (higher) only" )
1033 PORT_CONFNAME( 0x0c, 0x00, "Select BG2 priority" )
1034 PORT_CONFSETTING( 0x00, "All" )
1035 PORT_CONFSETTING( 0x04, "BG2B (lower) only" )
1036 PORT_CONFSETTING( 0x08, "BG2A (higher) only" )
1037 PORT_CONFNAME( 0x30, 0x00, "Select BG3 priority" )
1038 PORT_CONFSETTING( 0x00, "All" )
1039 PORT_CONFSETTING( 0x10, "BG3B (lower) only" )
1040 PORT_CONFSETTING( 0x20, "BG3A (higher) only" )
1041 PORT_CONFNAME( 0xc0, 0x00, "Select BG4 priority" )
1042 PORT_CONFSETTING( 0x00, "All" )
1043 PORT_CONFSETTING( 0x40, "BG4B (lower) only" )
1044 PORT_CONFSETTING( 0x80, "BG4A (higher) only" )
1045
1046 PORT_START("DEBUG2")
1047 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 1") PORT_CODE(KEYCODE_1_PAD) PORT_TOGGLE
1048 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 2") PORT_CODE(KEYCODE_2_PAD) PORT_TOGGLE
1049 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 3") PORT_CODE(KEYCODE_3_PAD) PORT_TOGGLE
1050 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 4") PORT_CODE(KEYCODE_4_PAD) PORT_TOGGLE
1051 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Objects") PORT_CODE(KEYCODE_5_PAD) PORT_TOGGLE
1052 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Main/Sub") PORT_CODE(KEYCODE_6_PAD) PORT_TOGGLE
1053 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Color Math") PORT_CODE(KEYCODE_7_PAD) PORT_TOGGLE
1054 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Windows") PORT_CODE(KEYCODE_8_PAD) PORT_TOGGLE
1055
1056 PORT_START("DEBUG3")
1057 PORT_BIT( 0x4, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mosaic") PORT_CODE(KEYCODE_9_PAD) PORT_TOGGLE
1058 PORT_CONFNAME( 0x70, 0x00, "Select OAM priority" )
1059 PORT_CONFSETTING( 0x00, "All" )
1060 PORT_CONFSETTING( 0x10, "OAM0 only" )
1061 PORT_CONFSETTING( 0x20, "OAM1 only" )
1062 PORT_CONFSETTING( 0x30, "OAM2 only" )
1063 PORT_CONFSETTING( 0x40, "OAM3 only" )
1064 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
1065
1066 PORT_START("DEBUG4")
1067 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 0 draw") PORT_TOGGLE
1068 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 1 draw") PORT_TOGGLE
1069 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 2 draw") PORT_TOGGLE
1070 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 3 draw") PORT_TOGGLE
1071 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 4 draw") PORT_TOGGLE
1072 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 5 draw") PORT_TOGGLE
1073 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 6 draw") PORT_TOGGLE
1074 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 7 draw") PORT_TOGGLE
1075 #endif
1076 INPUT_PORTS_END
1077
1078
1079 /*************************************
1080 *
1081 * Input callbacks
1082 *
1083 *************************************/
1084
1085 void snes_console_state::io_read()
1086 {
1087 // is automatic reading on? if so, read 16bits from oldjoy1/2
1088 if (SNES_CPU_REG(NMITIMEN) & 1)
1089 {
1090 uint16_t joy1 = 0, joy2 = 0, joy3 = 0, joy4 = 0;
1091 m_ctrl1->port_poll();
1092 m_ctrl2->port_poll();
1093
1094 for (int i = 0; i < 16; i++)
1095 {
1096 joy1 |= ((m_ctrl1->read_pin4() & 1) << (15 - i));
1097 joy2 |= ((m_ctrl2->read_pin4() & 1) << (15 - i));
1098 joy3 |= ((m_ctrl1->read_pin5() & 1) << (15 - i));
1099 joy4 |= ((m_ctrl2->read_pin5() & 1) << (15 - i));
1100 }
1101
1102 SNES_CPU_REG(JOY1L) = (joy1 & 0x00ff) >> 0;
1103 SNES_CPU_REG(JOY1H) = (joy1 & 0xff00) >> 8;
1104 SNES_CPU_REG(JOY2L) = (joy2 & 0x00ff) >> 0;
1105 SNES_CPU_REG(JOY2H) = (joy2 & 0xff00) >> 8;
1106 SNES_CPU_REG(JOY3L) = (joy3 & 0x00ff) >> 0;
1107 SNES_CPU_REG(JOY3H) = (joy3 & 0xff00) >> 8;
1108 SNES_CPU_REG(JOY4L) = (joy4 & 0x00ff) >> 0;
1109 SNES_CPU_REG(JOY4H) = (joy4 & 0xff00) >> 8;
1110 }
1111 }
1112
oldjoy1_read(int latched)1113 uint8_t snes_console_state::oldjoy1_read(int latched)
1114 {
1115 uint8_t ret = 0;
1116 ret |= m_ctrl1->read_pin4();
1117 ret |= (m_ctrl1->read_pin5() << 1);
1118 return ret;
1119 }
1120
oldjoy2_read(int latched)1121 uint8_t snes_console_state::oldjoy2_read(int latched)
1122 {
1123 uint8_t ret = 0;
1124 ret |= m_ctrl2->read_pin4();
1125 ret |= (m_ctrl2->read_pin5() << 1);
1126 return ret;
1127 }
1128
write_joy_latch(uint8_t data)1129 void snes_console_state::write_joy_latch(uint8_t data)
1130 {
1131 m_ctrl1->write_strobe(data);
1132 m_ctrl2->write_strobe(data);
1133 }
1134
wrio_write(uint8_t data)1135 void snes_console_state::wrio_write(uint8_t data)
1136 {
1137 if (!(SNES_CPU_REG(WRIO) & 0x80) && (data & 0x80))
1138 {
1139 // external latch
1140 m_ppu->set_latch_hv(m_ppu->current_x(), m_ppu->current_y());
1141 }
1142
1143 m_ctrl1->write_pin6(BIT(data, 6));
1144 m_ctrl2->write_pin6(BIT(data, 7));
1145
1146 }
1147
SNESCTRL_GUNLATCH_CB(snes_console_state::gun_latch_cb)1148 SNESCTRL_GUNLATCH_CB(snes_console_state::gun_latch_cb)
1149 {
1150 // these are the theoretical boundaries
1151 if (x < 0)
1152 x = 0;
1153 if (x > (SNES_SCR_WIDTH - 1))
1154 x = SNES_SCR_WIDTH - 1;
1155
1156 if (y < 0)
1157 y = 0;
1158 if (y > (m_ppu->last_visible_line() - 1))
1159 y = m_ppu->last_visible_line() - 1;
1160
1161 // m_ppu->set_latch_hv(x, y); // it would be more accurate to write twice to WRIO register, first with bit7 = 0 and then with bit7 = 1
1162 m_ppu->set_latch_hv(m_ppu->current_x(), m_ppu->current_y());
1163 }
1164
SNESCTRL_ONSCREEN_CB(snes_console_state::onscreen_cb)1165 SNESCTRL_ONSCREEN_CB(snes_console_state::onscreen_cb)
1166 {
1167 // these are the theoretical boundaries, but we currently are always onscreen due to the
1168 // way IPT_LIGHTGUNs work... investigate more on this!
1169 if (x < 0 || x >= SNES_SCR_WIDTH || y < 0 || y >= m_ppu->last_visible_line())
1170 return false;
1171 else
1172 return true;
1173 }
1174
1175
1176 /*************************************
1177 *
1178 * Machine driver
1179 *
1180 *************************************/
1181
machine_start()1182 void snes_console_state::machine_start()
1183 {
1184 snes_state::machine_start();
1185
1186 if (m_cartslot && m_cartslot->exists())
1187 {
1188 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8m_delegate(*this, FUNC(snes_console_state::snes20_lo_r)), write8m_delegate(*this, FUNC(snes_console_state::snes20_lo_w)));
1189 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8m_delegate(*this, FUNC(snes_console_state::snes20_hi_r)), write8m_delegate(*this, FUNC(snes_console_state::snes20_hi_w)));
1190 m_maincpu->set_5a22_map();
1191
1192 m_type = m_cartslot->get_type();
1193
1194 switch (m_type)
1195 {
1196 // LoROM & LoROM + addons
1197 case SNES_MODE20:
1198 case SNES_BSXLO:
1199 case SNES_SUFAMITURBO:
1200 case SNES_CX4: // this still uses the old simulation instead of emulating the CPU
1201 case SNES_ST010: // this requires two diff kinds of chip access, so we handle it in snes20_lo/hi_r/w
1202 case SNES_ST011: // this requires two diff kinds of chip access, so we handle it in snes20_lo/hi_r/w
1203 case SNES_ST018: // still unemulated
1204 break;
1205 case SNES_Z80GB: // skeleton support
1206 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8m_delegate(*this, FUNC(snes_console_state::snessgb_lo_r)), write8m_delegate(*this, FUNC(snes_console_state::snessgb_lo_w)));
1207 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8m_delegate(*this, FUNC(snes_console_state::snessgb_hi_r)), write8m_delegate(*this, FUNC(snes_console_state::snessgb_hi_w)));
1208 m_maincpu->set_5a22_map();
1209 break;
1210 case SNES_SA1: // skeleton support
1211 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8m_delegate(*this, FUNC(snes_console_state::snessa1_lo_r)), write8m_delegate(*this, FUNC(snes_console_state::snessa1_lo_w)));
1212 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8m_delegate(*this, FUNC(snes_console_state::snessa1_hi_r)), write8m_delegate(*this, FUNC(snes_console_state::snessa1_hi_w)));
1213 m_maincpu->set_5a22_map();
1214 break;
1215 case SNES_DSP:
1216 m_maincpu->space(AS_PROGRAM).install_read_handler(0x208000, 0x20ffff, 0, 0x9f0000, 0, read8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_read)));
1217 m_maincpu->space(AS_PROGRAM).install_write_handler(0x208000, 0x20ffff, 0, 0x9f0000, 0, write8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_write)));
1218 break;
1219 case SNES_DSP_2MB:
1220 m_maincpu->space(AS_PROGRAM).install_read_handler(0x600000, 0x607fff, 0, 0x8f0000, 0, read8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_read)));
1221 m_maincpu->space(AS_PROGRAM).install_write_handler(0x600000, 0x607fff, 0, 0x8f0000, 0, write8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_write)));
1222 break;
1223 case SNES_DSP4:
1224 m_maincpu->space(AS_PROGRAM).install_read_handler(0x308000, 0x30ffff, 0, 0x8f0000, 0, read8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_read)));
1225 m_maincpu->space(AS_PROGRAM).install_write_handler(0x308000, 0x30ffff, 0, 0x8f0000, 0, write8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_write)));
1226 break;
1227 case SNES_OBC1:
1228 m_maincpu->space(AS_PROGRAM).install_read_handler(0x006000, 0x007fff, 0, 0xbf0000, 0, read8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_read)));
1229 m_maincpu->space(AS_PROGRAM).install_write_handler(0x006000, 0x007fff, 0, 0xbf0000, 0, write8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_write)));
1230 break;
1231 case SNES_GSU1:
1232 case SNES_GSU2:
1233 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8m_delegate(*this, FUNC(snes_console_state::snessfx_lo_r)), write8m_delegate(*this, FUNC(snes_console_state::snessfx_lo_w)));
1234 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8m_delegate(*this, FUNC(snes_console_state::snessfx_hi_r)), write8m_delegate(*this, FUNC(snes_console_state::snessfx_hi_w)));
1235 m_maincpu->set_5a22_map();
1236 break;
1237 case SNES_SDD1:
1238 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8m_delegate(*this, FUNC(snes_console_state::snessdd1_lo_r)), write8m_delegate(*this, FUNC(snes_console_state::snessdd1_lo_w)));
1239 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8m_delegate(*this, FUNC(snes_console_state::snessdd1_hi_r)), write8m_delegate(*this, FUNC(snes_console_state::snessdd1_hi_w)));
1240 m_maincpu->set_5a22_map();
1241 break;
1242 case SNES_BSX:
1243 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8m_delegate(*this, FUNC(snes_console_state::snesbsx_lo_r)), write8m_delegate(*this, FUNC(snes_console_state::snesbsx_lo_w)));
1244 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8m_delegate(*this, FUNC(snes_console_state::snesbsx_hi_r)), write8m_delegate(*this, FUNC(snes_console_state::snesbsx_hi_w)));
1245 m_maincpu->set_5a22_map();
1246 break;
1247 // HiROM & HiROM + addons
1248 case SNES_MODE21:
1249 case SNES_BSXHI:
1250 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8m_delegate(*this, FUNC(snes_console_state::snes21_lo_r)), write8m_delegate(*this, FUNC(snes_console_state::snes21_lo_w)));
1251 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8m_delegate(*this, FUNC(snes_console_state::snes21_hi_r)), write8m_delegate(*this, FUNC(snes_console_state::snes21_hi_w)));
1252 m_maincpu->set_5a22_map();
1253 break;
1254 case SNES_DSP_MODE21:
1255 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8m_delegate(*this, FUNC(snes_console_state::snes21_lo_r)), write8m_delegate(*this, FUNC(snes_console_state::snes21_lo_w)));
1256 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8m_delegate(*this, FUNC(snes_console_state::snes21_hi_r)), write8m_delegate(*this, FUNC(snes_console_state::snes21_hi_w)));
1257 m_maincpu->space(AS_PROGRAM).install_read_handler(0x006000, 0x007fff, 0, 0x9f0000, 0, read8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_read)));
1258 m_maincpu->space(AS_PROGRAM).install_write_handler(0x006000, 0x007fff, 0, 0x9f0000, 0, write8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_write)));
1259 m_maincpu->set_5a22_map();
1260 break;
1261 case SNES_SRTC:
1262 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8m_delegate(*this, FUNC(snes_console_state::snes21_lo_r)), write8m_delegate(*this, FUNC(snes_console_state::snes21_lo_w)));
1263 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8m_delegate(*this, FUNC(snes_console_state::snes21_hi_r)), write8m_delegate(*this, FUNC(snes_console_state::snes21_hi_w)));
1264 m_maincpu->space(AS_PROGRAM).install_read_handler(0x002800, 0x002800, 0, 0xbf0000, 0, read8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_read)));
1265 m_maincpu->space(AS_PROGRAM).install_write_handler(0x002801, 0x002801, 0, 0xbf0000, 0, write8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_write)));
1266 m_maincpu->set_5a22_map();
1267 break;
1268 case SNES_SPC7110:
1269 case SNES_SPC7110_RTC:
1270 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8m_delegate(*this, FUNC(snes_console_state::snes7110_lo_r)), write8m_delegate(*this, FUNC(snes_console_state::snes7110_lo_w)));
1271 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8m_delegate(*this, FUNC(snes_console_state::snes7110_hi_r)), write8m_delegate(*this, FUNC(snes_console_state::snes7110_hi_w)));
1272 m_maincpu->set_5a22_map();
1273 break;
1274 case SNES_PFEST94:
1275 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8m_delegate(*this, FUNC(snes_console_state::pfest94_lo_r)), write8m_delegate(*this, FUNC(snes_console_state::pfest94_lo_w)));
1276 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8m_delegate(*this, FUNC(snes_console_state::pfest94_hi_r)), write8m_delegate(*this, FUNC(snes_console_state::pfest94_hi_w)));
1277 m_maincpu->set_5a22_map();
1278 break;
1279 // pirate 'mappers'
1280 case SNES_POKEMON:
1281 m_maincpu->space(AS_PROGRAM).install_read_handler(0x800000, 0x80ffff, 0, 0x780000, 0, read8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_read)));
1282 m_maincpu->space(AS_PROGRAM).install_write_handler(0x800000, 0x80ffff, 0, 0x780000, 0, write8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_write)));
1283 break;
1284 case SNES_TEKKEN2:
1285 m_maincpu->space(AS_PROGRAM).install_read_handler(0x808000, 0x8087ff, 0, 0x3f0000, 0, read8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_read)));
1286 m_maincpu->space(AS_PROGRAM).install_write_handler(0x808000, 0x8087ff, 0, 0x3f0000, 0, write8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_write)));
1287 break;
1288 case SNES_MCPIR1:
1289 case SNES_MCPIR2:
1290 m_maincpu->space(AS_PROGRAM).install_write_handler(0xffff00, 0xffffff, write8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_write)));
1291 break;
1292 case SNES_20COL:
1293 m_maincpu->space(AS_PROGRAM).install_write_handler(0x008000, 0x008fff, write8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_write)));
1294 break;
1295 case SNES_SOULBLAD:
1296 // reads from xxx0-xxx3in range [80-bf] return a fixed sequence of 4bits; reads in range [c0-ff] return open bus
1297 m_maincpu->space(AS_PROGRAM).install_read_handler(0x808000, 0x808003, 0, 0x3f7ff0, 0, read8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_read)));
1298 m_maincpu->space(AS_PROGRAM).install_read_handler(0xc00000, 0xffffff, read8smo_delegate(*this, FUNC(snes_console_state::snes_open_bus_r)));
1299 break;
1300 case SNES_BUGS:
1301 case SNES_BANANA:
1302 // m_maincpu->space(AS_PROGRAM).install_read_handler(0x808000, 0x80ffff, 0, 0x780000, 0, read8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_read)));
1303 // m_maincpu->space(AS_PROGRAM).install_write_handler(0x808000, 0x80ffff, 0, 0x780000, 0, write8sm_delegate(*m_cartslot, FUNC(base_sns_cart_slot_device::chip_write)));
1304 // m_maincpu->set_5a22_map();
1305 break;
1306 }
1307 m_cartslot->save_ram();
1308 }
1309 }
1310
machine_reset()1311 void snes_console_state::machine_reset()
1312 {
1313 snes_state::machine_reset();
1314 }
1315
1316
snes(machine_config & config)1317 void snes_console_state::snes(machine_config &config)
1318 {
1319 /* basic machine hardware */
1320 _5A22(config, m_maincpu, MCLK_NTSC); /* 2.68 MHz, also 3.58 MHz */
1321 m_maincpu->set_addrmap(AS_PROGRAM, &snes_console_state::snes_map);
1322
1323 // runs at 24.576 MHz / 12 = 2.048 MHz
1324 S_SMP(config, m_soundcpu, XTAL(24'576'000) / 12);
1325 m_soundcpu->set_addrmap(AS_DATA, &snes_console_state::spc_map);
1326 m_soundcpu->dsp_io_read_callback().set(m_s_dsp, FUNC(s_dsp_device::dsp_io_r));
1327 m_soundcpu->dsp_io_write_callback().set(m_s_dsp, FUNC(s_dsp_device::dsp_io_w));
1328
1329 //config.set_maximum_quantum(attotime::from_hz(48000));
1330 config.set_perfect_quantum(m_maincpu);
1331
1332 /* video hardware */
1333 SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
1334 m_screen->set_raw(DOTCLK_NTSC * 2, SNES_HTOTAL * 2, 0, SNES_SCR_WIDTH * 2, SNES_VTOTAL_NTSC, 0, SNES_SCR_HEIGHT_NTSC);
1335 m_screen->set_video_attributes(VIDEO_VARIABLE_WIDTH);
1336 m_screen->set_screen_update(FUNC(snes_state::screen_update));
1337
1338 SNES_PPU(config, m_ppu, MCLK_NTSC);
1339 m_ppu->open_bus_callback().set(FUNC(snes_console_state::snes_open_bus_r));
1340 m_ppu->set_screen("screen");
1341
1342 SNES_CONTROL_PORT(config, m_ctrl1, snes_control_port_devices, "joypad");
1343 m_ctrl1->set_onscreen_callback(FUNC(snes_console_state::onscreen_cb));
1344 SNES_CONTROL_PORT(config, m_ctrl2, snes_control_port_devices, "joypad");
1345 m_ctrl2->set_onscreen_callback(FUNC(snes_console_state::onscreen_cb));
1346 m_ctrl2->set_gunlatch_callback(FUNC(snes_console_state::gun_latch_cb));
1347
1348 /* sound hardware */
1349 SPEAKER(config, "lspeaker").front_left();
1350 SPEAKER(config, "rspeaker").front_right();
1351
1352 S_DSP(config, m_s_dsp, XTAL(24'576'000) / 12);
1353 m_s_dsp->set_addrmap(0, &snes_console_state::spc_map);
1354 m_s_dsp->add_route(0, "lspeaker", 1.00);
1355 m_s_dsp->add_route(1, "rspeaker", 1.00);
1356
1357 SNS_CART_SLOT(config, m_cartslot, MCLK_NTSC, snes_cart, nullptr);
1358 m_cartslot->irq_callback().set_inputline(m_maincpu, G65816_LINE_IRQ);
1359 m_cartslot->open_bus_callback().set(FUNC(snes_console_state::snes_open_bus_r));
1360
1361 SOFTWARE_LIST(config, "cart_list").set_original("snes");
1362 SOFTWARE_LIST(config, "bsx_list").set_original("snes_bspack");
1363 SOFTWARE_LIST(config, "st_list").set_original("snes_strom");
1364 }
1365
snespal(machine_config & config)1366 void snes_console_state::snespal(machine_config &config)
1367 {
1368 snes(config);
1369 m_maincpu->set_clock(MCLK_PAL);
1370
1371 m_screen->set_raw(DOTCLK_PAL * 2, SNES_HTOTAL * 2, 0, SNES_SCR_WIDTH * 2, SNES_VTOTAL_PAL, 0, SNES_SCR_HEIGHT_PAL);
1372
1373 m_ppu->set_clock(MCLK_PAL);
1374 m_cartslot->set_clock(MCLK_PAL);
1375 }
1376
1377
1378
1379 /*************************************
1380 *
1381 * ROM definition(s)
1382 *
1383 *************************************/
1384
1385 ROM_START( snes )
1386 ROM_REGION( 0x1000000, "maincpu", ROMREGION_ERASE00 )
1387 ROM_END
1388
1389 #define rom_snespal rom_snes
1390
1391 /*************************************
1392 *
1393 * Game driver(s)
1394 *
1395 *************************************/
1396
1397 /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
1398 CONS( 1989, snes, 0, 0, snes, snes, snes_console_state, empty_init, "Nintendo", "Super Nintendo Entertainment System / Super Famicom (NTSC)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
1399 CONS( 1991, snespal, snes, 0, snespal, snes, snes_console_state, empty_init, "Nintendo", "Super Nintendo Entertainment System (PAL)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
1400