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