1 // license:BSD-3-Clause
2 // copyright-holders:Fabio Priuli
3 /***********************************************************************************************************
4 
5 
6  NES/Famicom cartridge emulation for Jaleco PCBs
7 
8 
9  Here we emulate the following PCBs
10 
11  * Jaleco JF-11 [mapper 140]
12  * Jaleco JF-13 [mapper 86]
13  * Jaleco JF-16 [mapper 78]
14  * Jaleco JF-17 [mapper 72] + its variant with samples
15  * Jaleco JF-19 [mapper 92] + its variant with samples
16  * Jaleco SS88006 [mapper 18] + its variant(s) with samples
17 
18  ***********************************************************************************************************/
19 
20 
21 #include "emu.h"
22 #include "jaleco.h"
23 
24 #include "sound/samples.h"
25 #include "speaker.h"
26 
27 
28 #ifdef NES_PCB_DEBUG
29 #define VERBOSE 1
30 #else
31 #define VERBOSE 0
32 #endif
33 
34 #define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0)
35 
36 
37 //-------------------------------------------------
38 //  constructor
39 //-------------------------------------------------
40 
41 DEFINE_DEVICE_TYPE(NES_JF11,       nes_jf11_device,       "nes_jf11",     "NES Cart Jaleco JF-11 PCB")
42 DEFINE_DEVICE_TYPE(NES_JF13,       nes_jf13_device,       "nes_jf13",     "NES Cart Jaleco JF-13 PCB")
43 DEFINE_DEVICE_TYPE(NES_JF16,       nes_jf16_device,       "nes_jf16",     "NES Cart Jaleco JF-16 PCB")
44 DEFINE_DEVICE_TYPE(NES_JF17,       nes_jf17_device,       "nes_jf17",     "NES Cart Jaleco JF-17 PCB")
45 DEFINE_DEVICE_TYPE(NES_JF17_ADPCM, nes_jf17_adpcm_device, "nes_jf17_pcm", "NES Cart Jaleco JF-17 + ADPCM (Moero!! Pro Tennis) PCB")
46 DEFINE_DEVICE_TYPE(NES_JF19,       nes_jf19_device,       "nes_jf19",     "NES Cart Jaleco JF-19 (Moero!! Pro Soccer) PCB")
47 DEFINE_DEVICE_TYPE(NES_JF19_ADPCM, nes_jf19_adpcm_device, "nes_jf19_pcm", "NES Cart Jaleco JF-19 + ADPCM (Moero!! Pro Yakyuu 88) PCB")
48 DEFINE_DEVICE_TYPE(NES_SS88006,    nes_ss88006_device,    "nes_ss88006",  "NES Cart Jaleco SS88006 PCB")
49 DEFINE_DEVICE_TYPE(NES_JF23,       nes_jf23_device,       "nes_jf23",     "NES Cart Jaleco JF-23 (Shin Moero Pro Yakyuu) PCB")
50 DEFINE_DEVICE_TYPE(NES_JF24,       nes_jf24_device,       "nes_jf24",     "NES Cart Jaleco JF-24 (Terao no Dosukoi Oozumou) PCB")
51 DEFINE_DEVICE_TYPE(NES_JF29,       nes_jf29_device,       "nes_jf29",     "NES Cart Jaleco JF-29 (Moe Pro! '90) PCB")
52 DEFINE_DEVICE_TYPE(NES_JF33,       nes_jf33_device,       "nes_jf33",     "NES Cart Jaleco JF-33 (Moe Pro! Saikyou-hen) PCB")
53 
54 
nes_jf11_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)55 nes_jf11_device::nes_jf11_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
56 	: nes_nrom_device(mconfig, NES_JF11, tag, owner, clock)
57 {
58 }
59 
nes_jf13_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)60 nes_jf13_device::nes_jf13_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
61 	: nes_nrom_device(mconfig, NES_JF13, tag, owner, clock)
62 	, m_samples(*this, "samples")
63 {
64 }
65 
nes_jf16_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)66 nes_jf16_device::nes_jf16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
67 	: nes_nrom_device(mconfig, NES_JF16, tag, owner, clock)
68 {
69 }
70 
nes_jf17_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)71 nes_jf17_device::nes_jf17_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
72 	: nes_nrom_device(mconfig, type, tag, owner, clock), m_latch(0)
73 {
74 }
75 
nes_jf17_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)76 nes_jf17_device::nes_jf17_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
77 	: nes_jf17_device(mconfig, NES_JF17, tag, owner, clock)
78 {
79 }
80 
nes_jf17_adpcm_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)81 nes_jf17_adpcm_device::nes_jf17_adpcm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
82 	: nes_jf17_device(mconfig, NES_JF17_ADPCM, tag, owner, clock)
83 	, m_samples(*this, "samples")
84 {
85 }
86 
nes_jf19_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)87 nes_jf19_device::nes_jf19_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
88 	: nes_nrom_device(mconfig, type, tag, owner, clock)
89 {
90 }
91 
nes_jf19_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)92 nes_jf19_device::nes_jf19_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
93 	: nes_jf19_device(mconfig, NES_JF19, tag, owner, clock)
94 {
95 }
96 
nes_jf19_adpcm_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)97 nes_jf19_adpcm_device::nes_jf19_adpcm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
98 	: nes_jf19_device(mconfig, NES_JF19_ADPCM, tag, owner, clock)
99 	, m_samples(*this, "samples")
100 {
101 }
102 
nes_ss88006_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)103 nes_ss88006_device::nes_ss88006_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
104 	: nes_nrom_device(mconfig, type, tag, owner, clock), m_irq_count(0), m_irq_count_latch(0), m_irq_mode(0), m_irq_enable(0), irq_timer(nullptr), m_latch(0)
105 {
106 }
107 
nes_ss88006_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)108 nes_ss88006_device::nes_ss88006_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
109 	: nes_ss88006_device(mconfig, NES_SS88006, tag, owner, clock)
110 {
111 }
112 
nes_ss88006_adpcm_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)113 nes_ss88006_adpcm_device::nes_ss88006_adpcm_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
114 	: nes_ss88006_device(mconfig, type, tag, owner, clock)
115 {
116 }
117 
nes_jf23_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)118 nes_jf23_device::nes_jf23_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
119 	: nes_ss88006_adpcm_device(mconfig, NES_JF23, tag, owner, clock)
120 	, m_samples(*this, "samples")
121 {
122 }
123 
nes_jf24_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)124 nes_jf24_device::nes_jf24_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
125 	: nes_ss88006_adpcm_device(mconfig, NES_JF24, tag, owner, clock)
126 	, m_samples(*this, "samples")
127 {
128 }
129 
nes_jf29_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)130 nes_jf29_device::nes_jf29_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
131 	: nes_ss88006_adpcm_device(mconfig, NES_JF29, tag, owner, clock)
132 	, m_samples(*this, "samples")
133 {
134 }
135 
nes_jf33_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)136 nes_jf33_device::nes_jf33_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
137 	: nes_ss88006_adpcm_device(mconfig, NES_JF33, tag, owner, clock)
138 	, m_samples(*this, "samples")
139 {
140 }
141 
142 
143 
device_start()144 void nes_jf11_device::device_start()
145 {
146 	common_start();
147 }
148 
pcb_reset()149 void nes_jf11_device::pcb_reset()
150 {
151 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
152 	prg32(0);
153 	chr8(0, m_chr_source);
154 }
155 
device_start()156 void nes_jf13_device::device_start()
157 {
158 	common_start();
159 }
160 
pcb_reset()161 void nes_jf13_device::pcb_reset()
162 {
163 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
164 	prg32(0);
165 	chr8(0, m_chr_source);
166 }
167 
device_start()168 void nes_jf16_device::device_start()
169 {
170 	common_start();
171 }
172 
pcb_reset()173 void nes_jf16_device::pcb_reset()
174 {
175 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
176 	prg16_89ab(0);
177 	prg16_cdef(m_prg_chunks - 1);
178 	chr8(0, m_chr_source);
179 }
180 
device_start()181 void nes_jf17_device::device_start()
182 {
183 	common_start();
184 	save_item(NAME(m_latch));
185 }
186 
pcb_reset()187 void nes_jf17_device::pcb_reset()
188 {
189 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
190 	prg16_89ab(0);
191 	prg16_cdef(m_prg_chunks - 1);
192 	chr8(0, m_chr_source);
193 	m_latch = 0;
194 }
195 
device_start()196 void nes_jf19_device::device_start()
197 {
198 	common_start();
199 }
200 
pcb_reset()201 void nes_jf19_device::pcb_reset()
202 {
203 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
204 	prg32(0);
205 	chr8(0, m_chr_source);
206 }
207 
device_start()208 void nes_ss88006_device::device_start()
209 {
210 	common_start();
211 	irq_timer = timer_alloc(TIMER_IRQ);
212 	irq_timer->adjust(attotime::zero, 0, clocks_to_attotime(1));
213 
214 	save_item(NAME(m_mmc_prg_bank));
215 	save_item(NAME(m_mmc_vrom_bank));
216 	save_item(NAME(m_irq_enable));
217 	save_item(NAME(m_irq_count));
218 	save_item(NAME(m_irq_count_latch));
219 	save_item(NAME(m_irq_mode));
220 	save_item(NAME(m_latch));
221 }
222 
pcb_reset()223 void nes_ss88006_device::pcb_reset()
224 {
225 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
226 	prg16_89ab(0);
227 	prg16_cdef(m_prg_chunks - 1);
228 	chr8(0, m_chr_source);
229 
230 	memset(m_mmc_prg_bank, 0, sizeof(m_mmc_prg_bank));
231 	memset(m_mmc_vrom_bank, 0, sizeof(m_mmc_vrom_bank));
232 	m_irq_enable = 0;
233 	m_irq_mode = 0;
234 	m_irq_count = 0;
235 	m_irq_count_latch = 0;
236 	m_latch = 0;
237 }
238 
239 
240 /*-------------------------------------------------
241  mapper specific handlers
242  -------------------------------------------------*/
243 
244 /*-------------------------------------------------
245 
246  Jaleco JF-11, JF-12 & JF-14 boards emulation
247 
248  Games: Bio Senshi Dan, Mississippi Satsujin Jiken
249 
250  iNES: mapper 140
251 
252  In MESS: Supported.
253 
254  -------------------------------------------------*/
255 
write_m(offs_t offset,uint8_t data)256 void nes_jf11_device::write_m(offs_t offset, uint8_t data)
257 {
258 	LOG_MMC(("jf11 write_m, offset: %04x, data: %02x\n", offset, data));
259 	chr8(data, CHRROM);
260 	prg32(data >> 4);
261 }
262 
263 /*-------------------------------------------------
264 
265  Jaleco JF-13 board emulation
266 
267  Games: Moero Pro Yakyuu
268 
269  Note: we don't emulate the additional sound hardware.
270 
271  iNES: mapper 86
272 
273  In MESS: Supported.
274 
275  -------------------------------------------------*/
276 
write_m(offs_t offset,uint8_t data)277 void nes_jf13_device::write_m(offs_t offset, uint8_t data)
278 {
279 	LOG_MMC(("jf13 write_m, offset: %04x, data: %02x\n", offset, data));
280 
281 	if (offset < 0x1000)
282 	{
283 		prg32((data >> 4) & 0x03);
284 		chr8(((data >> 4) & 0x04) | (data & 0x03), CHRROM);
285 	}
286 	else
287 	{
288 //      printf("sample write: offset: %04x, data: %02x\n", offset, data);
289 		if (data & 0x20)
290 			m_samples->start(data & 0x0f, data & 0x0f);
291 		else
292 			m_samples->stop_all();
293 	}
294 }
295 
296 /*-------------------------------------------------
297 
298  Jaleco JF-16 board emulation
299 
300  iNES: mapper 78 (shared with a diff Irem board)
301 
302  -------------------------------------------------*/
303 
write_h(offs_t offset,uint8_t data)304 void nes_jf16_device::write_h(offs_t offset, uint8_t data)
305 {
306 	LOG_MMC(("jf16 write_h, offset: %04x, data: %02x\n", offset, data));
307 
308 	// this pcb is subject to bus conflict
309 	data = account_bus_conflict(offset, data);
310 
311 	set_nt_mirroring(BIT(data, 3) ? PPU_MIRROR_HIGH : PPU_MIRROR_LOW);
312 	chr8(data >> 4, CHRROM);
313 	prg16_89ab(data);
314 }
315 
316 
317 /*-------------------------------------------------
318 
319  Jaleco JF-17 boards emulation
320 
321  Note: we don't emulate the additional sound hardware
322        for Moero!! Pro Tennis
323 
324  Games: Moero!! Juudou Warriors, Moero!! Pro Tennis, Pinball
325  Quest Jpn
326 
327  iNES: mapper 72
328 
329  In MESS: Supported, see below for the Moero Pro Tennis
330 
331  -------------------------------------------------*/
332 
write_h(offs_t offset,uint8_t data)333 void nes_jf17_device::write_h(offs_t offset, uint8_t data)
334 {
335 	LOG_MMC(("jf17 write_h, offset: %04x, data: %02x\n", offset, data));
336 
337 	// this pcb is subject to bus conflict
338 	data = account_bus_conflict(offset, data);
339 
340 	if (BIT(m_latch, 7) && !BIT(data, 7))
341 		prg16_89ab(m_latch & 0x07);
342 	if (BIT(m_latch, 6) && !BIT(data, 6))
343 		chr8(m_latch & 0x0f, CHRROM);
344 
345 	m_latch = data;
346 }
347 
write_h(offs_t offset,uint8_t data)348 void nes_jf17_adpcm_device::write_h(offs_t offset, uint8_t data)
349 {
350 	LOG_MMC(("jf17 + ADPCM write_h, offset: %04x, data: %02x\n", offset, data));
351 
352 	// this pcb is subject to bus conflict
353 	data = account_bus_conflict(offset, data);
354 
355 	if (BIT(m_latch, 7) && !BIT(data, 7))
356 		prg16_89ab(m_latch & 0x07);
357 	if (BIT(m_latch, 6) && !BIT(data, 6))
358 		chr8(m_latch & 0x0f, CHRROM);
359 	if (BIT(data, 5) && !BIT(data,4))
360 	{
361 //      printf("sample write: offset: %04x, data: %02x\n", offset, data);
362 		m_samples->start(offset & 0x1f, offset & 0x1f);
363 	}
364 
365 	m_latch = data;
366 }
367 
368 /*-------------------------------------------------
369 
370  Jaleco JF-19 boards emulation
371 
372  Note: we don't emulate the additional sound hardware.
373 
374  Games: Moero Pro Soccer, Moero Pro Yakyuu '88
375 
376  iNES: mapper 92
377 
378  In MESS: Supported, see below for the Moero Pro Yakyuu '88
379 
380  -------------------------------------------------*/
381 
write_h(offs_t offset,uint8_t data)382 void nes_jf19_device::write_h(offs_t offset, uint8_t data)
383 {
384 	LOG_MMC(("jf19 write_h, offset: %04x, data: %02x\n", offset, data));
385 
386 	// this pcb is subject to bus conflict
387 	data = account_bus_conflict(offset, data);
388 
389 	if (BIT(data, 7))
390 		prg16_cdef(data & 0x0f);
391 	if (BIT(data, 6))
392 		chr8(data & 0x0f, CHRROM);
393 }
394 
write_h(offs_t offset,uint8_t data)395 void nes_jf19_adpcm_device::write_h(offs_t offset, uint8_t data)
396 {
397 	LOG_MMC(("jf19 + ADPCM write_h, offset: %04x, data: %02x\n", offset, data));
398 
399 	// this pcb is subject to bus conflict
400 	data = account_bus_conflict(offset, data);
401 
402 	if (BIT(data, 7))
403 		prg16_cdef(data & 0x0f);
404 	if (BIT(data, 6))
405 		chr8(data & 0x0f, CHRROM);
406 	if (BIT(data, 5) && !BIT(data,4))
407 	{
408 //      printf("sample write: offset: %04x, data: %02x\n", offset, data);
409 		m_samples->start(offset & 0x1f, offset & 0x1f);
410 	}
411 }
412 
413 /*-------------------------------------------------
414 
415  Jaleco SS88006 board emulation, aka JF-27, JF-29, JF-30, ...,
416  JF-38, JF-40, JF-41
417 
418  Games: Lord of King, Magic John, Moe Pro '90, Ninja Jajamaru,
419  Pizza Pop, Plasma Ball
420 
421  iNES: mapper 18
422 
423  In MESS: Supported, see below for the games with samples
424 
425  -------------------------------------------------*/
426 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)427 void nes_ss88006_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
428 {
429 	if (id == TIMER_IRQ)
430 	{
431 		if (m_irq_enable)
432 		{
433 			if (m_irq_mode & 0x08)  // 4bits counter
434 			{
435 				if (!(m_irq_count & 0x000f))
436 				{
437 					set_irq_line(ASSERT_LINE);
438 					m_irq_count = (m_irq_count & 0xfff0) | 0x000f;
439 				}
440 				else
441 					m_irq_count = (m_irq_count & 0xfff0) | ((m_irq_count & 0x000f) - 1);
442 			}
443 			else if (m_irq_mode & 0x04) // 8bits counter
444 			{
445 				if (!(m_irq_count & 0x00ff))
446 				{
447 					set_irq_line(ASSERT_LINE);
448 					m_irq_count = (m_irq_count & 0xff00) | 0x00ff;
449 				}
450 				else
451 					m_irq_count = (m_irq_count & 0xff00) | ((m_irq_count & 0x00ff) - 1);
452 			}
453 			else if (m_irq_mode & 0x02) // 12bits counter
454 			{
455 				if (!(m_irq_count & 0x0fff))
456 				{
457 					set_irq_line(ASSERT_LINE);
458 					m_irq_count = (m_irq_count & 0xf000) | 0x0fff;
459 				}
460 				else
461 					m_irq_count = (m_irq_count & 0xf000) | ((m_irq_count & 0x0fff) - 1);
462 			}
463 			else    // 16bits counter
464 			{
465 				if (!m_irq_count)
466 				{
467 					set_irq_line(ASSERT_LINE);
468 					m_irq_count = 0xffff;
469 				}
470 				else
471 					m_irq_count = m_irq_count - 1;
472 			}
473 		}
474 	}
475 }
476 
ss88006_write(offs_t offset,uint8_t data)477 void nes_ss88006_device::ss88006_write(offs_t offset, uint8_t data)
478 {
479 	uint8_t bank;
480 	LOG_MMC(("ss88006 write_h, offset: %04x, data: %02x\n", offset, data));
481 
482 	switch (offset & 0x7003)
483 	{
484 		case 0x0000:
485 			m_mmc_prg_bank[0] = (m_mmc_prg_bank[0] & 0xf0) | (data & 0x0f);
486 			prg8_89(m_mmc_prg_bank[0]);
487 			break;
488 		case 0x0001:
489 			m_mmc_prg_bank[0] = (m_mmc_prg_bank[0] & 0x0f) | (data << 4);
490 			prg8_89(m_mmc_prg_bank[0]);
491 			break;
492 		case 0x0002:
493 			m_mmc_prg_bank[1] = (m_mmc_prg_bank[1] & 0xf0) | (data & 0x0f);
494 			prg8_ab(m_mmc_prg_bank[1]);
495 			break;
496 		case 0x0003:
497 			m_mmc_prg_bank[1] = (m_mmc_prg_bank[1] & 0x0f) | (data << 4);
498 			prg8_ab(m_mmc_prg_bank[1]);
499 			break;
500 		case 0x1000:
501 			m_mmc_prg_bank[2] = (m_mmc_prg_bank[2] & 0xf0) | (data & 0x0f);
502 			prg8_cd(m_mmc_prg_bank[2]);
503 			break;
504 		case 0x1001:
505 			m_mmc_prg_bank[2] = (m_mmc_prg_bank[2] & 0x0f) | (data << 4);
506 			prg8_cd(m_mmc_prg_bank[2]);
507 			break;
508 
509 			/* $9002, 3 (1002, 3) uncaught = Jaleco Baseball writes 0 */
510 			/* believe it's related to battery-backed ram enable/disable */
511 
512 		case 0x2000: case 0x2001: case 0x2002: case 0x2003:
513 		case 0x3000: case 0x3001: case 0x3002: case 0x3003:
514 		case 0x4000: case 0x4001: case 0x4002: case 0x4003:
515 		case 0x5000: case 0x5001: case 0x5002: case 0x5003:
516 			bank = ((offset & 0x7000) - 0x2000) / 0x0800 + ((offset & 0x0002) >> 1);
517 			if (offset & 0x0001)
518 				m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & 0x0f) | ((data & 0x0f)<< 4);
519 			else
520 				m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & 0xf0) | (data & 0x0f);
521 
522 			chr1_x(bank, m_mmc_vrom_bank[bank], CHRROM);
523 			break;
524 
525 		case 0x6000:
526 			m_irq_count_latch = (m_irq_count_latch & 0xfff0) | (data & 0x0f);
527 			break;
528 		case 0x6001:
529 			m_irq_count_latch = (m_irq_count_latch & 0xff0f) | ((data & 0x0f) << 4);
530 			break;
531 		case 0x6002:
532 			m_irq_count_latch = (m_irq_count_latch & 0xf0ff) | ((data & 0x0f) << 8);
533 			break;
534 		case 0x6003:
535 			m_irq_count_latch = (m_irq_count_latch & 0x0fff) | ((data & 0x0f) << 12);
536 			break;
537 		case 0x7000:
538 			m_irq_count = m_irq_count_latch;
539 			set_irq_line(CLEAR_LINE);
540 			break;
541 		case 0x7001:
542 			m_irq_enable = data & 0x01;
543 			m_irq_mode = data & 0x0e;
544 			set_irq_line(CLEAR_LINE);
545 			break;
546 
547 		case 0x7002:
548 			switch (data & 0x03)
549 			{
550 				case 0: set_nt_mirroring(PPU_MIRROR_HORZ); break;
551 				case 1: set_nt_mirroring(PPU_MIRROR_VERT); break;
552 				case 2: set_nt_mirroring(PPU_MIRROR_LOW); break;
553 				case 3: set_nt_mirroring(PPU_MIRROR_HIGH); break;
554 			}
555 			break;
556 
557 		default:
558 			logerror("Jaleco SS88006 uncaught write, addr: %04x, value: %02x\n", offset + 0x8000, data);
559 			break;
560 	}
561 }
562 
563 
564 // bits2-bits6 are sample number, bit1 is setup/enable/disable
565 // program first write sample # + bit1 set to 'init' the sample
566 // then it writes sample # + bit1 clear to 'start' the sample
ss88006_adpcm_write(offs_t offset,uint8_t data,samples_device & dev)567 void nes_ss88006_adpcm_device::ss88006_adpcm_write(offs_t offset, uint8_t data, samples_device &dev)
568 {
569 	LOG_MMC(("ss88006 write_h, offset: %04x, data: %02x\n", offset, data));
570 
571 	switch (offset & 0x7003)
572 	{
573 		case 0x7003:
574 			if ((m_latch & 0x7c) == (data & 0x7c))
575 			{
576 //              printf("sample write: data: %02x\n", data);
577 				if ((m_latch & 2) && !(data & 2))
578 					dev.start((data >> 2) & 0x1f, (data >> 2) & 0x1f);
579 			}
580 			m_latch = data;
581 			break;
582 
583 		default:
584 			ss88006_write(offset, data);
585 			break;
586 	}
587 }
588 
589 /**********************************************************
590 
591  Boards with external samples
592  (due to undumpable UPD7755C/UPD7756C)
593 
594  JF-13 (Moero!! Pro Yakyuu) / iNES mapper 86
595  JF-17 (Moero!! Pro Tennis) / iNES mapper 72 + ADPCM
596  JF-19 (Moero!! Pro Yakyuu '88 - Kettei Ban) / iNES mapper 92 + ADPCM
597  JF-23 (Shin Moero Pro Yakyuu) / iNES mapper 18 + ADPCM
598  JF-24 (Terao no Dosukoi Oozumou) / iNES mapper 18 + ADPCM
599  JF-29 (Moe Pro 90) / iNES mapper 18 + ADPCM
600  JF-33 (Moe Pro Saikyou-hen) / iNES mapper 18 + ADPCM
601 
602 
603 ***********************************************************/
604 
605 static const char *const jf13_sample_names[] =
606 {
607 	"*moepro",
608 	"00",   // strike
609 	"01",   // ball
610 	"02",   // time
611 	"03",   // out
612 	"04",   // safe
613 	"05",   // foul
614 	"06",   // (catcher obtains the ball)
615 	"07",   // you're out
616 	"08",   // play ball
617 	"09",   // ball four
618 	"10",   // home run
619 	"11",   // new pitcher
620 	"12",   // ouch (pitcher hits batter)
621 	"13",   // ??
622 	"14",   // (bat hits the ball)
623 	"15",   // (crowd)
624 	nullptr
625 };
626 
627 static const char *const jf17_sample_names[] =
628 {
629 	"*mptennis",
630 	"00",   // NOT EXISTING?
631 	"01",   // NOT EXISTING?
632 	"02",   // "love" (points)
633 	"03",   // 15 (points)
634 	"04",   // 30 (points)
635 	"05",   // 40 (points)
636 	"06",   // advantage
637 	"07",   // (advantage) server
638 	"08",   // (advantage) receiver
639 	"09",   // all (equal points)
640 	"10",   // deuce
641 	"11",   // game
642 	"12",   // (racket hits ball)
643 	"13",   // (crowd?)
644 	"14",   // fault
645 	"15",   // net
646 	"16",   // out
647 	"17",   // ??
648 	"18",   // (ball hits player)
649 	"19",   // NOT EXISTING?
650 	nullptr
651 };
652 
653 static const char *const jf19_sample_names[] =
654 {
655 	"*moepro88",
656 	"00",   // out
657 	"01",   // safe
658 	"02",   // foul
659 	"03",   // fair
660 	"04",   // strike
661 	"05",   // ball
662 	"06",   // time
663 	"07",   // batter out
664 	"08",   // ball four
665 	"09",   // home run
666 	"10",   // play ball
667 	"11",   // new pitcher
668 	"12",   // pinch-hit
669 	"13",   // (hit by pitch)
670 	"14",   // (bat hits the ball)
671 	"15",   // (bunt)
672 	"16",   // NOT EXISTING?
673 	"17",   // (catcher obtains the ball)
674 	"18",   // (pitcher obtains the ball)
675 	"19",   // (crowd)
676 	nullptr
677 };
678 
679 static const char *const jf23_sample_names[] =
680 {
681 	"*smoepro",
682 	"00",   // out
683 	"01",   // safe
684 	"02",   // foul
685 	"03",   // NOT EXISTING?
686 	"04",   // strike
687 	"05",   // ball
688 	"06",   // time
689 	"07",   // batter out
690 	"08",   // ball four
691 	"09",   // home run
692 	"10",   // play ball
693 	"11",   // new pitcher
694 	"12",   // pinch-hit
695 	"13",   // (hit by pitch)
696 	"14",   // (bat hits the ball)
697 	"15",   // (bunt)
698 	"16",   // (catcher obtains the ball)
699 	"17",   // fair
700 	"18",   // (catcher obtains the ball, alt)
701 	"19",   // (crowd)
702 	nullptr
703 };
704 
705 static const char *const jf24_sample_names[] =
706 {
707 	"*terao",
708 	"00",   // (tree beating sound)
709 	"01",   // Hakkyoyoi
710 	"02",   // Nokotta
711 	"03",   // Matta Nashi
712 	"04",   // Nokotta Nokotta
713 	"05",   // Matta Arimasen
714 	nullptr
715 };
716 
717 static const char *const jf29_sample_names[] =
718 {
719 	"*moepro90",
720 	"00",   // out
721 	"01",   // safe
722 	"02",   // foul
723 	"03",   // Not existing?
724 	"04",   // strike
725 	"05",   // ball
726 	"06",   // time
727 	"07",   // batter out
728 	"08",   // ball four
729 	"09",   // home run
730 	"10",   // play ball
731 	"11",   // new pitcher
732 	"12",   // pinch-hit
733 	"13",   // (hit by pitch)
734 	"14",   // (bat hits the ball)
735 	"15",   // (bunt)
736 	"16",   // (catcher obtains the ball, alt)
737 	"17",   // (catcher obtains the ball)
738 	"18",   // (catcher obtains the ball, alt 2)
739 	"19",   // (crowd)
740 	nullptr
741 };
742 
743 static const char *const jf33_sample_names[] =
744 {
745 	"*mpsaikyo",
746 	"00",   // out
747 	"01",   // safe
748 	"02",   // foul
749 	"03",   // ???
750 	"04",   // strike
751 	"05",   // ball
752 	"06",   // time
753 	"07",   // batter out
754 	"08",   // ball four
755 	"09",   // home run
756 	"10",   // play ball
757 	"11",   // new pitcher
758 	"12",   // pinch-hit
759 	"13",   // (hit by pitch)
760 	"14",   // (bat hits the ball)
761 	"15",   // (bunt)
762 	"16",   // (catcher obtains the ball)
763 	"17",   // (catcher obtains the ball, alt)
764 	"18",   // ??
765 	"19",   // (crowd)
766 	nullptr
767 };
768 
769 
770 //-------------------------------------------------
771 //  device_add_mconfig - add device configuration
772 //-------------------------------------------------
773 
device_add_mconfig(machine_config & config)774 void nes_jf13_device::device_add_mconfig(machine_config &config)
775 {
776 	// additional sound hardware
777 	SPEAKER(config, "addon").front_center();
778 
779 	SAMPLES(config, m_samples);
780 	m_samples->set_channels(16);
781 	m_samples->set_samples_names(jf13_sample_names);
782 	m_samples->add_route(ALL_OUTPUTS, "addon", 0.50);
783 }
784 
device_add_mconfig(machine_config & config)785 void nes_jf17_adpcm_device::device_add_mconfig(machine_config &config)
786 {
787 	// additional sound hardware
788 	SPEAKER(config, "addon").front_center();
789 
790 	SAMPLES(config, m_samples);
791 	m_samples->set_channels(20);
792 	m_samples->set_samples_names(jf17_sample_names);
793 	m_samples->add_route(ALL_OUTPUTS, "addon", 0.50);
794 }
795 
device_add_mconfig(machine_config & config)796 void nes_jf19_adpcm_device::device_add_mconfig(machine_config &config)
797 {
798 	// additional sound hardware
799 	SPEAKER(config, "addon").front_center();
800 
801 	SAMPLES(config, m_samples);
802 	m_samples->set_channels(20);
803 	m_samples->set_samples_names(jf19_sample_names);
804 	m_samples->add_route(ALL_OUTPUTS, "addon", 0.50);
805 }
806 
device_add_mconfig(machine_config & config)807 void nes_jf23_device::device_add_mconfig(machine_config &config)
808 {
809 	// additional sound hardware
810 	SPEAKER(config, "addon").front_center();
811 
812 	SAMPLES(config, m_samples);
813 	m_samples->set_channels(20);
814 	m_samples->set_samples_names(jf23_sample_names);
815 	m_samples->add_route(ALL_OUTPUTS, "addon", 0.50);
816 }
817 
device_add_mconfig(machine_config & config)818 void nes_jf24_device::device_add_mconfig(machine_config &config)
819 {
820 	// additional sound hardware
821 	SPEAKER(config, "addon").front_center();
822 
823 	SAMPLES(config, m_samples);
824 	m_samples->set_channels(6);
825 	m_samples->set_samples_names(jf24_sample_names);
826 	m_samples->add_route(ALL_OUTPUTS, "addon", 0.50);
827 }
828 
device_add_mconfig(machine_config & config)829 void nes_jf29_device::device_add_mconfig(machine_config &config)
830 {
831 	// additional sound hardware
832 	SPEAKER(config, "addon").front_center();
833 
834 	SAMPLES(config, m_samples);
835 	m_samples->set_channels(20);
836 	m_samples->set_samples_names(jf29_sample_names);
837 	m_samples->add_route(ALL_OUTPUTS, "addon", 0.50);
838 }
839 
device_add_mconfig(machine_config & config)840 void nes_jf33_device::device_add_mconfig(machine_config &config)
841 {
842 	// additional sound hardware
843 	SPEAKER(config, "addon").front_center();
844 
845 	SAMPLES(config, m_samples);
846 	m_samples->set_channels(20);
847 	m_samples->set_samples_names(jf33_sample_names);
848 	m_samples->add_route(ALL_OUTPUTS, "addon", 0.50);
849 }
850