1 // license:BSD-3-Clause
2 // copyright-holders:Fabio Priuli
3 /***********************************************************************************************************
4 
5 
6  NES/Famicom cartridge emulation for Bootleg PCBs
7 
8 
9  Here we emulate the PCBs used in FDS2NES conversions which are common in the Taiwanese & HK markets
10  Notice that many of these have unusual PRG sizes (32KB+8KB, 32KB+24KB) partially mapped in the WRAM
11  area, or WRAM overlapping the usual PRG area, so that we often skip the usual bankswitching mechanisms
12  in favor of direct handling of the PRG accesses
13 
14  TODO:
15  - review all PCBs and fix the starting banks (which are often the main problem of not working games)
16  - investigate pcbs listed in FCEUmm but with apparently no dumps available (LE05 and LH53)
17 
18  ***********************************************************************************************************/
19 
20 
21 #include "emu.h"
22 #include "bootleg.h"
23 
24 #include "video/ppu2c0x.h"      // this has to be included so that IRQ functions can access ppu2c0x_device::BOTTOM_VISIBLE_SCANLINE
25 #include "screen.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_AX5705,         nes_ax5705_device,    "nes_ax5705",    "NES Cart AX5705 PCB")
42 DEFINE_DEVICE_TYPE(NES_SC127,          nes_sc127_device,     "nes_sc127",     "NES Cart SC-127 PCB")
43 DEFINE_DEVICE_TYPE(NES_MARIOBABY,      nes_mbaby_device,     "nes_mbaby",     "NES Cart Mario Baby Bootleg PCB")
44 DEFINE_DEVICE_TYPE(NES_ASN,            nes_asn_device,       "nes_asn",       "NES Cart Ai Senshi Nicol Bootleg PCB")
45 DEFINE_DEVICE_TYPE(NES_SMB3PIRATE,     nes_smb3p_device,     "nes_smb3p",     "NES Cart Super Mario Bros. 3 Pirate PCB")
46 DEFINE_DEVICE_TYPE(NES_BTL_DNINJA,     nes_btl_dn_device,    "nes_btl_dn",    "NES Cart DragonNinja Pirate PCB")
47 DEFINE_DEVICE_TYPE(NES_WHIRLWIND_2706, nes_whirl2706_device, "nes_whirl2706", "NES Cart Whilwind 2706 PCB")
48 DEFINE_DEVICE_TYPE(NES_SMB2J,          nes_smb2j_device,     "nes_smb2j",     "NES Cart Super Mario Bros. 2 Jpn PCB")
49 DEFINE_DEVICE_TYPE(NES_SMB2JA,         nes_smb2ja_device,    "nes_smb2ja",    "NES Cart Super Mario Bros. 2 Jpn (Alt) PCB")
50 DEFINE_DEVICE_TYPE(NES_SMB2JB,         nes_smb2jb_device,    "nes_smb2jb",    "NES Cart Super Mario Bros. 2 Jpn (Alt 2) PCB")
51 DEFINE_DEVICE_TYPE(NES_09034A,         nes_09034a_device,    "nes_09034a",    "NES Cart 09-034A PCB")
52 DEFINE_DEVICE_TYPE(NES_TOBIDASE,       nes_tobidase_device,  "nes_tobidase",  "NES Cart Tobidase Daisakusen Pirate PCB")
53 DEFINE_DEVICE_TYPE(NES_LH32,           nes_lh32_device,      "nes_lh32",      "NES Cart LH-32 Pirate PCB")
54 DEFINE_DEVICE_TYPE(NES_LH10,           nes_lh10_device,      "nes_lh10",      "NES Cart LH-10 Pirate PCB")
55 DEFINE_DEVICE_TYPE(NES_LH53,           nes_lh53_device,      "nes_lh53",      "NES Cart LH-53 Pirate PCB")
56 DEFINE_DEVICE_TYPE(NES_2708,           nes_2708_device,      "nes_2708",      "NES Cart BTL-2708 Pirate PCB")
57 DEFINE_DEVICE_TYPE(NES_AC08,           nes_ac08_device,      "nes_ac08",      "NES Cart AC08 Pirate PCB")
58 DEFINE_DEVICE_TYPE(NES_UNL_BB,         nes_unl_bb_device,    "nes_unl_bb",    "NES Cart FDS+CHR Pirate PCB")
59 DEFINE_DEVICE_TYPE(NES_MMALEE,         nes_mmalee_device,    "nes_mmalee",    "NES Cart Super Mario Bros. Malee 2 Pirate PCB")
60 DEFINE_DEVICE_TYPE(NES_SHUIGUAN,       nes_shuiguan_device,  "nes_shuiguan",  "NES Cart Shui Guan Pipe Pirate PCB")
61 DEFINE_DEVICE_TYPE(NES_RT01,           nes_rt01_device,      "nes_rt01",      "NES Cart RT-01 PCB")
62 
63 
nes_ax5705_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)64 nes_ax5705_device::nes_ax5705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
65 	: nes_nrom_device(mconfig, NES_AX5705, tag, owner, clock)
66 {
67 }
68 
nes_sc127_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)69 nes_sc127_device::nes_sc127_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
70 	: nes_nrom_device(mconfig, NES_SC127, tag, owner, clock), m_irq_count(0), m_irq_enable(0)
71 {
72 }
73 
nes_mbaby_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)74 nes_mbaby_device::nes_mbaby_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
75 	: nes_nrom_device(mconfig, NES_MARIOBABY, tag, owner, clock), m_latch(0), m_irq_enable(0), irq_timer(nullptr)
76 {
77 }
78 
nes_asn_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)79 nes_asn_device::nes_asn_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
80 	: nes_nrom_device(mconfig, NES_ASN, tag, owner, clock), m_latch(0)
81 {
82 }
83 
nes_smb3p_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)84 nes_smb3p_device::nes_smb3p_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
85 	: nes_nrom_device(mconfig, NES_SMB3PIRATE, tag, owner, clock), m_irq_count(0), m_irq_enable(0), irq_timer(nullptr)
86 {
87 }
88 
nes_btl_dn_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)89 nes_btl_dn_device::nes_btl_dn_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
90 	: nes_nrom_device(mconfig, NES_BTL_DNINJA, tag, owner, clock), m_irq_count(0)
91 {
92 }
93 
nes_whirl2706_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)94 nes_whirl2706_device::nes_whirl2706_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
95 	: nes_nrom_device(mconfig, NES_WHIRLWIND_2706, tag, owner, clock), m_latch(0)
96 {
97 }
98 
nes_smb2j_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)99 nes_smb2j_device::nes_smb2j_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
100 	: nes_nrom_device(mconfig, NES_SMB2J, tag, owner, clock), m_irq_count(0), m_irq_enable(0), irq_timer(nullptr)
101 {
102 }
103 
nes_smb2ja_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)104 nes_smb2ja_device::nes_smb2ja_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
105 	: nes_nrom_device(mconfig, NES_SMB2JA, tag, owner, clock), m_irq_count(0), m_irq_enable(0), irq_timer(nullptr)
106 {
107 }
108 
nes_smb2jb_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)109 nes_smb2jb_device::nes_smb2jb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
110 	: nes_nrom_device(mconfig, NES_SMB2JB, tag, owner, clock), m_irq_count(0), m_irq_enable(0), irq_timer(nullptr)
111 {
112 }
113 
nes_09034a_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)114 nes_09034a_device::nes_09034a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
115 	: nes_nrom_device(mconfig, NES_09034A, tag, owner, clock), m_reg(0)
116 {
117 }
118 
nes_tobidase_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)119 nes_tobidase_device::nes_tobidase_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
120 	: nes_nrom_device(mconfig, NES_TOBIDASE, tag, owner, clock), m_latch(0)
121 {
122 }
123 
nes_lh32_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)124 nes_lh32_device::nes_lh32_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
125 	: nes_nrom_device(mconfig, NES_LH32, tag, owner, clock), m_latch(0)
126 {
127 }
128 
nes_lh10_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)129 nes_lh10_device::nes_lh10_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
130 	: nes_nrom_device(mconfig, NES_LH10, tag, owner, clock), m_latch(0)
131 {
132 }
133 
nes_lh53_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)134 nes_lh53_device::nes_lh53_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
135 	: nes_nrom_device(mconfig, NES_LH53, tag, owner, clock), m_irq_count(0), m_irq_enable(0), m_reg(0), irq_timer(nullptr)
136 {
137 }
138 
nes_2708_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)139 nes_2708_device::nes_2708_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
140 	: nes_nrom_device(mconfig, NES_2708, tag, owner, clock)
141 {
142 }
143 
nes_ac08_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)144 nes_ac08_device::nes_ac08_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
145 	: nes_nrom_device(mconfig, NES_AC08, tag, owner, clock), m_latch(0)
146 {
147 }
148 
nes_unl_bb_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)149 nes_unl_bb_device::nes_unl_bb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
150 	: nes_nrom_device(mconfig, NES_UNL_BB, tag, owner, clock)
151 {
152 }
153 
nes_mmalee_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)154 nes_mmalee_device::nes_mmalee_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
155 	: nes_nrom_device(mconfig, NES_MMALEE, tag, owner, clock)
156 {
157 }
158 
nes_shuiguan_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)159 nes_shuiguan_device::nes_shuiguan_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
160 	: nes_nrom_device(mconfig, NES_SHUIGUAN, tag, owner, clock), m_irq_count(0), m_irq_enable(0), irq_timer(nullptr)
161 {
162 }
163 
nes_rt01_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)164 nes_rt01_device::nes_rt01_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
165 	: nes_nrom_device(mconfig, NES_RT01, tag, owner, clock)
166 {
167 }
168 
169 
170 
171 
device_start()172 void nes_ax5705_device::device_start()
173 {
174 	common_start();
175 	save_item(NAME(m_mmc_prg_bank));
176 	save_item(NAME(m_mmc_vrom_bank));
177 }
178 
pcb_reset()179 void nes_ax5705_device::pcb_reset()
180 {
181 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
182 	chr8(0, m_chr_source);
183 
184 	m_mmc_prg_bank[0] = 0;
185 	m_mmc_prg_bank[1] = 1;
186 	prg8_89(m_mmc_prg_bank[0]);
187 	prg8_ab(m_mmc_prg_bank[1]);
188 	prg8_cd(0xfe);
189 	prg8_ef(0xff);
190 
191 	memset(m_mmc_vrom_bank, 0, sizeof(m_mmc_vrom_bank));
192 }
193 
device_start()194 void nes_sc127_device::device_start()
195 {
196 	common_start();
197 	save_item(NAME(m_irq_enable));
198 	save_item(NAME(m_irq_count));
199 }
200 
pcb_reset()201 void nes_sc127_device::pcb_reset()
202 {
203 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
204 	prg32(0xff);
205 	chr8(0, m_chr_source);
206 
207 	m_irq_enable = 0;
208 	m_irq_count = 0;
209 }
210 
device_start()211 void nes_mbaby_device::device_start()
212 {
213 	common_start();
214 	irq_timer = timer_alloc(TIMER_IRQ);
215 	irq_timer->reset();
216 	timer_freq = clocks_to_attotime(24576);
217 
218 	save_item(NAME(m_irq_enable));
219 	save_item(NAME(m_latch));
220 }
221 
pcb_reset()222 void nes_mbaby_device::pcb_reset()
223 {
224 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
225 	prg32((m_prg_chunks - 1) >> 1);
226 	chr8(0, m_chr_source);
227 
228 	m_irq_enable = 0;
229 	m_latch = 0;
230 }
231 
device_start()232 void nes_asn_device::device_start()
233 {
234 	common_start();
235 	save_item(NAME(m_latch));
236 }
237 
pcb_reset()238 void nes_asn_device::pcb_reset()
239 {
240 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
241 	prg32((m_prg_chunks - 1) >> 1);
242 	chr8(0, m_chr_source);
243 
244 	m_latch = 0;
245 }
246 
device_start()247 void nes_smb3p_device::device_start()
248 {
249 	common_start();
250 	irq_timer = timer_alloc(TIMER_IRQ);
251 	irq_timer->adjust(attotime::zero, 0, clocks_to_attotime(1));
252 
253 	save_item(NAME(m_irq_enable));
254 	save_item(NAME(m_irq_count));
255 }
256 
pcb_reset()257 void nes_smb3p_device::pcb_reset()
258 {
259 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
260 	prg8_89((m_prg_chunks << 1) - 1);
261 	prg8_ab(0);
262 	prg8_cd(0);
263 	prg8_ef((m_prg_chunks << 1) - 1);
264 	chr8(0, m_chr_source);
265 
266 	m_irq_enable = 0;
267 	m_irq_count = 0;
268 }
269 
device_start()270 void nes_btl_dn_device::device_start()
271 {
272 	common_start();
273 	save_item(NAME(m_irq_count));
274 }
275 
pcb_reset()276 void nes_btl_dn_device::pcb_reset()
277 {
278 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
279 	prg16_89ab(0);
280 	prg16_cdef(m_prg_chunks - 1);
281 	chr8(0, m_chr_source);
282 
283 	m_irq_count = 0;
284 }
285 
device_start()286 void nes_whirl2706_device::device_start()
287 {
288 	common_start();
289 	save_item(NAME(m_latch));
290 }
291 
pcb_reset()292 void nes_whirl2706_device::pcb_reset()
293 {
294 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
295 	prg32(0xff);
296 	chr8(0, m_chr_source);
297 
298 	m_latch = 0;
299 }
300 
device_start()301 void nes_smb2j_device::device_start()
302 {
303 	common_start();
304 	irq_timer = timer_alloc(TIMER_IRQ);
305 	irq_timer->adjust(attotime::zero, 0, clocks_to_attotime(1));
306 
307 	save_item(NAME(m_irq_enable));
308 	save_item(NAME(m_irq_count));
309 }
310 
pcb_reset()311 void nes_smb2j_device::pcb_reset()
312 {
313 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
314 	chr8(0, m_chr_source);
315 	prg8_89(1);
316 	prg8_ab(0);
317 	prg8_cd(0);
318 	prg8_ef(9);
319 
320 	m_irq_enable = 0;
321 	m_irq_count = 0;
322 }
323 
device_start()324 void nes_smb2ja_device::device_start()
325 {
326 	common_start();
327 	irq_timer = timer_alloc(TIMER_IRQ);
328 	irq_timer->adjust(attotime::zero, 0, clocks_to_attotime(1));
329 
330 	save_item(NAME(m_irq_enable));
331 	save_item(NAME(m_irq_count));
332 }
333 
pcb_reset()334 void nes_smb2ja_device::pcb_reset()
335 {
336 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
337 	prg8_89(0xfc);
338 	prg8_ab(0xfd);
339 	prg8_cd(0xfe);
340 	prg8_ef(0xff);
341 	chr8(0, m_chr_source);
342 
343 	m_irq_enable = 0;
344 	m_irq_count = 0;
345 }
346 
device_start()347 void nes_smb2jb_device::device_start()
348 {
349 	common_start();
350 	irq_timer = timer_alloc(TIMER_IRQ);
351 	irq_timer->adjust(attotime::zero, 0, clocks_to_attotime(1));
352 
353 	save_item(NAME(m_irq_enable));
354 	save_item(NAME(m_irq_count));
355 }
356 
pcb_reset()357 void nes_smb2jb_device::pcb_reset()
358 {
359 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
360 	prg8_89(0x08);
361 	prg8_ab(0x09);
362 	prg8_cd(0);
363 	prg8_ef(0x0b);
364 	chr8(0, m_chr_source);
365 
366 	m_irq_enable = 0;
367 	m_irq_count = 0;
368 }
369 
device_start()370 void nes_09034a_device::device_start()
371 {
372 	common_start();
373 	save_item(NAME(m_reg));
374 }
375 
pcb_reset()376 void nes_09034a_device::pcb_reset()
377 {
378 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
379 	prg32(0);
380 	chr8(0, m_chr_source);
381 	m_reg = 0;
382 }
383 
device_start()384 void nes_tobidase_device::device_start()
385 {
386 	common_start();
387 	save_item(NAME(m_latch));
388 }
389 
pcb_reset()390 void nes_tobidase_device::pcb_reset()
391 {
392 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
393 	prg32(2);
394 	chr8(0, m_chr_source);
395 
396 	m_latch = 0;
397 }
398 
device_start()399 void nes_lh32_device::device_start()
400 {
401 	common_start();
402 	save_item(NAME(m_latch));
403 }
404 
pcb_reset()405 void nes_lh32_device::pcb_reset()
406 {
407 	chr8(0, CHRRAM);
408 
409 	prg32((m_prg_chunks - 1) >> 1);
410 	// 0xc000-0xdfff reads/writes WRAM
411 	m_latch = 0xf;
412 }
413 
device_start()414 void nes_lh10_device::device_start()
415 {
416 	common_start();
417 	save_item(NAME(m_latch));
418 	save_item(NAME(m_reg));
419 }
420 
pcb_reset()421 void nes_lh10_device::pcb_reset()
422 {
423 	chr8(0, CHRRAM);
424 
425 	prg8_89(0);
426 	prg8_ab(0);
427 	// 0xc000-0xdfff reads/writes WRAM
428 	prg8_ef(0xff);
429 	memset(m_reg, 0, sizeof(m_reg));
430 	m_latch = 0;
431 }
432 
device_start()433 void nes_lh53_device::device_start()
434 {
435 	common_start();
436 	irq_timer = timer_alloc(TIMER_IRQ);
437 	irq_timer->adjust(attotime::zero, 0, clocks_to_attotime(1));
438 
439 	save_item(NAME(m_irq_enable));
440 	save_item(NAME(m_irq_count));
441 	save_item(NAME(m_reg));
442 }
443 
pcb_reset()444 void nes_lh53_device::pcb_reset()
445 {
446 	chr8(0, CHRRAM);
447 
448 	prg8_89(0xc);
449 	prg8_ab(0xd);   // last 2K are overlayed by WRAM
450 	prg8_cd(0xe);   // first 6K are overlayed by WRAM
451 	prg8_ef(0xf);
452 	m_reg = 0;
453 	m_irq_count = 0;
454 	m_irq_enable = 0;
455 }
456 
device_start()457 void nes_2708_device::device_start()
458 {
459 	common_start();
460 	save_item(NAME(m_reg));
461 }
462 
pcb_reset()463 void nes_2708_device::pcb_reset()
464 {
465 	chr8(0, CHRRAM);
466 
467 	prg32(7);
468 	// the upper PRG banks never change, but there are 8K of WRAM overlayed to the ROM area based on reg1
469 	m_reg[0] = 0;
470 	m_reg[1] = 0;
471 }
472 
device_start()473 void nes_ac08_device::device_start()
474 {
475 	common_start();
476 	save_item(NAME(m_latch));
477 }
478 
pcb_reset()479 void nes_ac08_device::pcb_reset()
480 {
481 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
482 	chr8(0, m_chr_source);
483 	prg32(0xff);
484 	m_latch = 0xff;
485 }
486 
device_start()487 void nes_unl_bb_device::device_start()
488 {
489 	common_start();
490 	save_item(NAME(m_reg));
491 }
492 
pcb_reset()493 void nes_unl_bb_device::pcb_reset()
494 {
495 	chr8(0, CHRROM);
496 	prg32(0xff);
497 	// the upper PRG banks never change, but there are 8K of WRAM overlayed to the ROM area based on reg1
498 	m_reg[0] = 0xff;
499 	m_reg[1] = 0;
500 }
501 
device_start()502 void nes_mmalee_device::device_start()
503 {
504 	common_start();
505 }
506 
pcb_reset()507 void nes_mmalee_device::pcb_reset()
508 {
509 	chr8(0, CHRROM);
510 	prg32(0);
511 }
512 
device_start()513 void nes_shuiguan_device::device_start()
514 {
515 	common_start();
516 	irq_timer = timer_alloc(TIMER_IRQ);
517 	// always running and checking for IRQ every 114 cycles? or resetting every frame?
518 	irq_timer->adjust(attotime::zero, 0, clocks_to_attotime(114));
519 
520 	save_item(NAME(m_irq_enable));
521 	save_item(NAME(m_irq_count));
522 	save_item(NAME(m_mmc_vrom_bank));
523 }
524 
pcb_reset()525 void nes_shuiguan_device::pcb_reset()
526 {
527 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
528 	prg32((m_prg_chunks << 1) - 1);
529 	chr8(0, m_chr_source);
530 
531 	m_irq_enable = 0;
532 	m_irq_count = 0;
533 	memset(m_mmc_vrom_bank, 0, sizeof(m_mmc_vrom_bank));
534 }
535 
536 
device_start()537 void nes_rt01_device::device_start()
538 {
539 	common_start();
540 }
541 
pcb_reset()542 void nes_rt01_device::pcb_reset()
543 {
544 	chr2_0(0, CHRROM);
545 	chr2_2(0, CHRROM);
546 	chr2_4(0, CHRROM);
547 	chr2_6(0, CHRROM);
548 	prg16_89ab(0);
549 	prg16_cdef(0);
550 }
551 
552 
553 /*-------------------------------------------------
554  mapper specific handlers
555  -------------------------------------------------*/
556 
557 /*-------------------------------------------------
558 
559  Board UNL-AX5705
560 
561  Games: Super Mario Bros. Pocker Mali (Crayon Shin-chan pirate hack)
562 
563  In MESS: Supported
564 
565  -------------------------------------------------*/
566 
set_prg()567 void nes_ax5705_device::set_prg()
568 {
569 	prg8_89(m_mmc_prg_bank[0]);
570 	prg8_ab(m_mmc_prg_bank[1]);
571 }
572 
write_h(offs_t offset,uint8_t data)573 void nes_ax5705_device::write_h(offs_t offset, uint8_t data)
574 {
575 	uint8_t bank;
576 	LOG_MMC(("ax5705 write_h, offset: %04x, data: %02x\n", offset, data));
577 
578 	switch (offset & 0x700f)
579 	{
580 		case 0x0000:
581 			m_mmc_prg_bank[0] = (data & 0x05) | ((data & 0x08) >> 2) | ((data & 0x02) << 2);
582 			set_prg();
583 			break;
584 		case 0x0008:
585 			set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
586 			break;
587 		case 0x2000:
588 			m_mmc_prg_bank[1] = (data & 0x05) | ((data & 0x08) >> 2) | ((data & 0x02) << 2);
589 			set_prg();
590 			break;
591 			/* CHR banks 0, 1, 4, 5 */
592 		case 0x2008:
593 		case 0x200a:
594 		case 0x4008:
595 		case 0x400a:
596 			bank = ((offset & 0x4000) ? 4 : 0) + ((offset & 0x0002) ? 1 : 0);
597 			m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & 0xf0) | (data & 0x0f);
598 			chr1_x(bank, m_mmc_vrom_bank[bank], CHRROM);
599 			break;
600 		case 0x2009:
601 		case 0x200b:
602 		case 0x4009:
603 		case 0x400b:
604 			bank = ((offset & 0x4000) ? 4 : 0) + ((offset & 0x0002) ? 1 : 0);
605 			m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & 0x0f) | ((data & 0x04) << 3) | ((data & 0x02) << 5) | ((data & 0x09) << 4);
606 			chr1_x(bank, m_mmc_vrom_bank[bank], CHRROM);
607 			break;
608 			/* CHR banks 2, 3, 6, 7 */
609 		case 0x4000:
610 		case 0x4002:
611 		case 0x6000:
612 		case 0x6002:
613 			bank = 2 + ((offset & 0x2000) ? 4 : 0) + ((offset & 0x0002) ? 1 : 0);
614 			m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & 0xf0) | (data & 0x0f);
615 			chr1_x(bank, m_mmc_vrom_bank[bank], CHRROM);
616 			break;
617 		case 0x4001:
618 		case 0x4003:
619 		case 0x6001:
620 		case 0x6003:
621 			bank = 2 + ((offset & 0x2000) ? 4 : 0) + ((offset & 0x0002) ? 1 : 0);
622 			m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & 0x0f) | ((data & 0x04) << 3) | ((data & 0x02) << 5) | ((data & 0x09) << 4);
623 			chr1_x(bank, m_mmc_vrom_bank[bank], CHRROM);
624 			break;
625 	}
626 }
627 
628 /*-------------------------------------------------
629 
630  SC-127 Board
631 
632  Games: Wario World II (Kirby Hack)
633 
634  iNES: mapper 35
635 
636  In MESS: Supported
637 
638  -------------------------------------------------*/
639 
hblank_irq(int scanline,int vblank,int blanked)640 void nes_sc127_device::hblank_irq(int scanline, int vblank, int blanked)
641 {
642 	if (scanline < ppu2c0x_device::BOTTOM_VISIBLE_SCANLINE && m_irq_enable)
643 	{
644 		m_irq_count--;
645 
646 		if (!blanked && (m_irq_count == 0))
647 		{
648 			LOG_MMC(("irq fired, scanline: %d\n", scanline));
649 			hold_irq_line();
650 			m_irq_enable = 0;
651 		}
652 	}
653 }
654 
write_h(offs_t offset,uint8_t data)655 void nes_sc127_device::write_h(offs_t offset, uint8_t data)
656 {
657 	LOG_MMC(("sc127 write_h, offset: %04x, data: %02x\n", offset, data));
658 
659 	switch (offset)
660 	{
661 		case 0x0000:
662 			prg8_89(data);
663 			break;
664 		case 0x0001:
665 			prg8_ab(data);
666 			break;
667 		case 0x0002:
668 //          m_mmc_prg_bank[offset & 0x02] = data;
669 			prg8_cd(data);
670 			break;
671 		case 0x1000:
672 		case 0x1001:
673 		case 0x1002:
674 		case 0x1003:
675 		case 0x1004:
676 		case 0x1005:
677 		case 0x1006:
678 		case 0x1007:
679 //          m_mmc_vrom_bank[offset & 0x07] = data;
680 			chr1_x(offset & 0x07, data, CHRROM);
681 			break;
682 		case 0x4002:
683 			m_irq_enable = 0;
684 			break;
685 		case 0x4003:
686 			m_irq_enable = 1;
687 			break;
688 		case 0x4005:
689 			m_irq_count = data;
690 			break;
691 		case 0x5001:
692 			set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
693 			break;
694 	}
695 }
696 
697 /*-------------------------------------------------
698 
699  BTL-MARIOBABY
700 
701  Games: Mario Baby, Ai Senshi Nicol
702 
703  iNES: mapper 42
704 
705  In MESS: Supported.
706 
707  -------------------------------------------------*/
708 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)709 void nes_mbaby_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
710 {
711 	if (id == TIMER_IRQ)
712 	{
713 		hold_irq_line();
714 		irq_timer->adjust(attotime::never);
715 	}
716 }
717 
write_h(offs_t offset,uint8_t data)718 void nes_mbaby_device::write_h(offs_t offset, uint8_t data)
719 {
720 	LOG_MMC(("Mario Baby write_h, offset: %04x, data: %02x\n", offset, data));
721 
722 	if (offset >= 0x7000)
723 	{
724 		switch (offset & 0x03)
725 		{
726 			case 0x00:
727 				m_latch = data;
728 				break;
729 			case 0x01:
730 				set_nt_mirroring(BIT(data, 3) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
731 				break;
732 			case 0x02:
733 				/* Check if IRQ is being enabled */
734 				if (!m_irq_enable && (data & 0x02))
735 				{
736 					m_irq_enable = 1;
737 					irq_timer->adjust(timer_freq);
738 				}
739 				if (!(data & 0x02))
740 				{
741 					m_irq_enable = 0;
742 					irq_timer->adjust(attotime::never);
743 				}
744 				break;
745 		}
746 	}
747 }
748 
read_m(offs_t offset)749 uint8_t nes_mbaby_device::read_m(offs_t offset)
750 {
751 	LOG_MMC(("Mario Baby read_m, offset: %04x\n", offset));
752 	return m_prg[(m_latch * 0x2000) + (offset & 0x1fff)];
753 }
754 
755 /*-------------------------------------------------
756 
757  BTL-AISENSHINICOL
758 
759  Games: Ai Senshi Nicol
760 
761  iNES: mapper 42 with no IRQ and no NT, but CHR switch
762 
763  In MESS: Partially Supported.
764 
765  -------------------------------------------------*/
766 
write_h(offs_t offset,uint8_t data)767 void nes_asn_device::write_h(offs_t offset, uint8_t data)
768 {
769 	LOG_MMC(("Ai Senshi Nicol write_h, offset: %04x, data: %02x\n", offset, data));
770 
771 	if (offset == 0x0000)
772 		chr8(data, CHRROM);
773 
774 	if (offset == 0x7000)
775 		m_latch = data;
776 }
777 
read_m(offs_t offset)778 uint8_t nes_asn_device::read_m(offs_t offset)
779 {
780 	LOG_MMC(("Ai Senshi Nicol read_m, offset: %04x\n", offset));
781 	return m_prg[((m_latch * 0x2000) + (offset & 0x1fff)) & (m_prg_size - 1)];
782 }
783 
784 
785 /*-------------------------------------------------
786 
787  BTL-SMB3
788 
789  Games: Super Mario Bros. 3 Pirate
790 
791  iNES: mapper 106
792 
793  In MESS: Supported.
794 
795  -------------------------------------------------*/
796 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)797 void nes_smb3p_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
798 {
799 	if (id == TIMER_IRQ)
800 	{
801 		if (m_irq_enable)
802 		{
803 			if (m_irq_count == 0xffff)
804 			{
805 				hold_irq_line();
806 				m_irq_enable = 0;
807 			}
808 			else
809 				m_irq_count++;
810 		}
811 	}
812 }
813 
write_h(offs_t offset,uint8_t data)814 void nes_smb3p_device::write_h(offs_t offset, uint8_t data)
815 {
816 	LOG_MMC(("btl_smb3_w, offset: %04x, data: %02x\n", offset, data));
817 	switch (offset & 0x0f)
818 	{
819 		case 0x00:
820 		case 0x02:
821 			chr1_x(offset & 0x07, data & 0xfe, CHRROM);
822 			break;
823 		case 0x01:
824 		case 0x03:
825 			chr1_x(offset & 0x07, data | 0x01, CHRROM);
826 			break;
827 		case 0x04: case 0x05:
828 		case 0x06: case 0x07:
829 			chr1_x(offset & 0x07, data, CHRROM);
830 			break;
831 		case 0x08:
832 			prg8_89(data | 0x10);
833 			break;
834 		case 0x09:
835 			prg8_ab(data);
836 			break;
837 		case 0x0a:
838 			prg8_cd(data);
839 			break;
840 		case 0x0b:
841 			prg8_ef(data | 0x10);
842 			break;
843 		case 0x0c:
844 			set_nt_mirroring(BIT(data, 0) ?  PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
845 			break;
846 		case 0x0d:
847 			m_irq_count = 0;
848 			m_irq_enable = 0;
849 			break;
850 		case 0x0e:
851 			m_irq_count = (m_irq_count & 0xff00) | data;
852 			break;
853 		case 0x0f:
854 			m_irq_count = (m_irq_count & 0x00ff) | (data << 8);
855 			m_irq_enable = 1;
856 			break;
857 	}
858 }
859 
860 /*-------------------------------------------------
861 
862  BTL-DRAGONNINJA
863 
864  Games: Dragon Ninja (Bootleg), Super Mario Bros. 8
865 
866  iNES: mapper 222
867 
868  In MESS: Unsupported.
869 
870  -------------------------------------------------*/
871 
872 /* Scanline based IRQ ? */
hblank_irq(int scanline,int vblank,int blanked)873 void nes_btl_dn_device::hblank_irq(int scanline, int vblank, int blanked )
874 {
875 	if (!m_irq_count || ++m_irq_count < 240)
876 		return;
877 
878 	m_irq_count = 0;
879 	hold_irq_line();
880 }
881 
write_h(offs_t offset,uint8_t data)882 void nes_btl_dn_device::write_h(offs_t offset, uint8_t data)
883 {
884 	uint8_t bank;
885 	LOG_MMC(("btl_dn write_h, offset: %04x, data: %02x\n", offset, data));
886 
887 	switch (offset & 0x7003)
888 	{
889 		case 0x0000:
890 			prg8_89(data);
891 			break;
892 		case 0x1000:
893 			set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
894 			break;
895 		case 0x2000:
896 			prg8_ab(data);
897 			break;
898 		case 0x3000:
899 		case 0x3002:
900 		case 0x4000:
901 		case 0x4002:
902 		case 0x5000:
903 		case 0x5002:
904 		case 0x6000:
905 		case 0x6002:
906 			bank = ((offset & 0x7000) - 0x3000) / 0x0800 + ((offset & 0x0002) >> 1);
907 			chr1_x(bank, data, CHRROM);
908 			break;
909 		case 0x7000:
910 			m_irq_count = data;
911 			break;
912 	}
913 }
914 
915 /*-------------------------------------------------
916 
917  BOOTLEG FC VERSIONS OF FDS GAMES
918 
919  -------------------------------------------------*/
920 
921 /*-------------------------------------------------
922 
923  WHIRLWIND-2706
924 
925  Games: Meikyuu Jiin Dababa (FDS conversion) and a few
926  others
927 
928  This PCB maps PRG in 0x6000-0x7fff
929 
930  iNES: mapper 108
931 
932  In MESS: Supported.
933 
934  -------------------------------------------------*/
935 
write_h(offs_t offset,uint8_t data)936 void nes_whirl2706_device::write_h(offs_t offset, uint8_t data)
937 {
938 	LOG_MMC(("whirl2706 write_h, offset: %04x, data: %02x\n", offset, data));
939 	m_latch = data;
940 }
941 
read_m(offs_t offset)942 uint8_t nes_whirl2706_device::read_m(offs_t offset)
943 {
944 	LOG_MMC(("whirl2706 read_m, offset: %04x\n", offset));
945 	return m_prg[(m_latch * 0x2000 + (offset & 0x1fff)) & (m_prg_size - 1)];
946 }
947 
948 /*-------------------------------------------------
949 
950  Bootleg Board SMB2J
951 
952  Games: Super Mario Bros. 2 Pirate (LF36)
953 
954  iNES: mapper 43
955 
956  In MESS: Supported.
957 
958  -------------------------------------------------*/
959 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)960 void nes_smb2j_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
961 {
962 	if (id == TIMER_IRQ)
963 	{
964 		if (m_irq_enable)
965 		{
966 			if (m_irq_count == 0xfff)
967 			{
968 				hold_irq_line();
969 				m_irq_enable = 0;
970 				m_irq_count = 0;
971 			}
972 			else
973 				m_irq_count++;
974 		}
975 	}
976 }
977 
write_l(offs_t offset,uint8_t data)978 void nes_smb2j_device::write_l(offs_t offset, uint8_t data)
979 {
980 	LOG_MMC(("smb2j write_l, offset: %04x, data: %02x\n", offset, data));
981 	offset += 0x100;
982 
983 	if (offset == 0x122)    // $4122
984 		m_irq_enable = data & 3;    // maybe also m_irq_count = 0?!?
985 }
986 
write_h(offs_t offset,uint8_t data)987 void nes_smb2j_device::write_h(offs_t offset, uint8_t data)
988 {
989 	LOG_MMC(("smb2j write_h, offset: %04x, data: %02x\n", offset, data));
990 
991 	if (offset == 0x122)    // $8122 too?
992 		m_irq_enable = data & 3;
993 }
994 
write_ex(offs_t offset,uint8_t data)995 void nes_smb2j_device::write_ex(offs_t offset, uint8_t data)
996 {
997 	LOG_MMC(("smb2j write_ex, offset: %04x, data: %02x\n", offset, data));
998 
999 	if (offset == 2)
1000 	{
1001 		int temp;
1002 
1003 		// According to hardware tests
1004 		if (data & 1)
1005 			temp = 3;
1006 		else
1007 			temp = 4 + ((data & 7) >> 1);
1008 
1009 		prg8_cd(temp);
1010 	}
1011 }
1012 
read_l(offs_t offset)1013 uint8_t nes_smb2j_device::read_l(offs_t offset)
1014 {
1015 	LOG_MMC(("smb2j read_l, offset: %04x\n", offset));
1016 	offset += 0x100;
1017 
1018 	if (offset >= 0x1000)
1019 		return m_prg[0x10000 + (offset & 0x0fff)];
1020 
1021 	return get_open_bus();   // open bus
1022 }
1023 
read_m(offs_t offset)1024 uint8_t nes_smb2j_device::read_m(offs_t offset)
1025 {
1026 	LOG_MMC(("smb2j read_m, offset: %04x\n", offset));
1027 	return m_prg[0x4000 + offset];
1028 }
1029 
1030 /*-------------------------------------------------
1031 
1032  BTL-SMB2A
1033 
1034  Games: Super Mario Bros. 2 Pirate (Jpn version of SMB2)
1035 
1036  iNES: mapper 40
1037 
1038  In MESS: Supported.
1039 
1040  -------------------------------------------------*/
1041 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)1042 void nes_smb2ja_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
1043 {
1044 	if (id == TIMER_IRQ)
1045 	{
1046 		if (m_irq_enable)
1047 		{
1048 			if (m_irq_count == 0xfff)
1049 			{
1050 				hold_irq_line();
1051 				m_irq_enable = 0;
1052 				m_irq_count = 0;
1053 			}
1054 			else
1055 				m_irq_count++;
1056 		}
1057 	}
1058 }
1059 
write_h(offs_t offset,uint8_t data)1060 void nes_smb2ja_device::write_h(offs_t offset, uint8_t data)
1061 {
1062 	LOG_MMC(("smb2ja write_h, offset: %04x, data: %02x\n", offset, data));
1063 
1064 	switch (offset & 0x6000)
1065 	{
1066 		case 0x0000:
1067 			m_irq_enable = 0;
1068 			m_irq_count = 0;
1069 			break;
1070 		case 0x2000:
1071 			m_irq_enable = 1;
1072 			break;
1073 		case 0x6000:
1074 			prg8_cd(data);
1075 			break;
1076 	}
1077 }
1078 
read_m(offs_t offset)1079 uint8_t nes_smb2ja_device::read_m(offs_t offset)
1080 {
1081 	LOG_MMC(("smb2ja read_m, offset: %04x\n", offset));
1082 	return m_prg[(0xfe * 0x2000 + (offset & 0x1fff)) & (m_prg_size - 1)];
1083 }
1084 
1085 /*-------------------------------------------------
1086 
1087  BTL-SMB2B
1088 
1089  Games: Super Mario Bros. 2 Pirate (Jpn version of SMB2)
1090 
1091  This was marked as Alt. Levels. is it true?
1092 
1093  iNES: mapper 50
1094 
1095  In MESS: Partially Supported.
1096 
1097  -------------------------------------------------*/
1098 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)1099 void nes_smb2jb_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
1100 {
1101 	if (id == TIMER_IRQ)
1102 	{
1103 		if (m_irq_enable)
1104 		{
1105 			if (m_irq_count == 0xfff)
1106 			{
1107 				hold_irq_line();
1108 				m_irq_enable = 0;
1109 				m_irq_count = 0;
1110 			}
1111 			else
1112 				m_irq_count++;
1113 		}
1114 	}
1115 }
1116 
write_l(offs_t offset,uint8_t data)1117 void nes_smb2jb_device::write_l(offs_t offset, uint8_t data)
1118 {
1119 	uint8_t prg;
1120 	LOG_MMC(("smb2jb write_l, offset: %04x, data: %02x\n", offset, data));
1121 	offset += 0x100;
1122 
1123 	switch (offset & 0x1e0)
1124 	{
1125 		case 0x020:
1126 		case 0x0a0:
1127 			prg = (data & 0x08) | ((data & 0x06) >> 1) | ((data & 0x01) << 2);
1128 			prg8_cd(prg);
1129 			break;
1130 		case 0x120:
1131 		case 0x1a0:
1132 			m_irq_enable = data & 0x01;
1133 			break;
1134 	}
1135 }
1136 
read_m(offs_t offset)1137 uint8_t nes_smb2jb_device::read_m(offs_t offset)
1138 {
1139 	LOG_MMC(("smb2jb read_m, offset: %04x\n", offset));
1140 	return m_prg[((0x0f * 0x2000) + (offset & 0x1fff)) & (m_prg_size - 1)];
1141 }
1142 
1143 /* This goes to 0x4020-0x403f & 0x40a0-0x40bf */
write_ex(offs_t offset,uint8_t data)1144 void nes_smb2jb_device::write_ex(offs_t offset, uint8_t data)
1145 {
1146 	uint8_t prg;
1147 	LOG_MMC(("smb2jb write_ex, offset: %04x, data: %02x\n", offset, data));
1148 
1149 	if ((offset < 0x20) || (offset >= 0x80 && offset < 0xa0))
1150 	{
1151 		prg = (data & 0x08) | ((data & 0x06) >> 1) | ((data & 0x01) << 2);
1152 		prg8_cd(prg);
1153 	}
1154 }
1155 
1156 /*-------------------------------------------------
1157 
1158  (UNL-)09-034A
1159 
1160  Games: Zanac FDS conversion with two PRG chips and
1161  no CHRROM and Volleyball FDS conversion with two PRG
1162  chips and CHRROM.
1163  Originally dumps were marked as UNL-SMB2J pcb
1164 
1165  iNES:
1166 
1167  In MESS: Partially Supported. Need to emulate IRQ
1168  (needed by smb2 conversion?)
1169 
1170  -------------------------------------------------*/
1171 
write_ex(offs_t offset,uint8_t data)1172 void nes_09034a_device::write_ex(offs_t offset, uint8_t data)
1173 {
1174 	LOG_MMC(("09-034a write_ex, offset: %04x, data: %02x\n", offset, data));
1175 
1176 	if (offset == 7)    // $4027
1177 		m_reg = data & 1;
1178 }
1179 
read_m(offs_t offset)1180 uint8_t nes_09034a_device::read_m(offs_t offset)
1181 {
1182 	LOG_MMC(("09-034a read_m, offset: %04x\n", offset));
1183 	// in 0x6000-0x7fff is mapped the 2nd PRG chip which starts after 32K (hence the +4)
1184 	return m_prg[((m_reg + 4) * 0x2000) + offset];
1185 }
1186 
1187 /*-------------------------------------------------
1188 
1189  Bootleg Board used for FDS conversion
1190 
1191  Games: Tobidase Daisakusen (FDS conversion)
1192 
1193  This PCB maps PRG in 0x6000-0x7fff
1194 
1195  iNES: mapper 120
1196 
1197  In MESS: Partially Supported.
1198 
1199  -------------------------------------------------*/
1200 
write_l(offs_t offset,uint8_t data)1201 void nes_tobidase_device::write_l(offs_t offset, uint8_t data)
1202 {
1203 	LOG_MMC(("tobidase write_h, offset: %04x, data: %02x\n", offset, data));
1204 	offset += 0x4100;
1205 
1206 	if ((offset & 0x63c0) == 0x41c0)
1207 		m_latch = data & 0x0f;
1208 }
1209 
read_m(offs_t offset)1210 uint8_t nes_tobidase_device::read_m(offs_t offset)
1211 {
1212 	LOG_MMC(("tobidase read_m, offset: %04x\n", offset));
1213 	if (m_latch >= 0x0c)
1214 		m_latch -= 4;
1215 	return m_prg[(m_latch * 0x2000) + (offset & 0x1fff)];
1216 }
1217 
1218 /*-------------------------------------------------
1219 
1220  UNL-LH32
1221 
1222  Games: Monty no Doki Doki Daidassou (FDS conversion)
1223 
1224  This PCB maps WRAM in 0xc000-0xdfff and PRG in 0x6000-0x7fff
1225 
1226  iNES:
1227 
1228  In MESS: Supported.
1229 
1230 -------------------------------------------------*/
1231 
read_m(offs_t offset)1232 uint8_t nes_lh32_device::read_m(offs_t offset)
1233 {
1234 	LOG_MMC(("lh32 read_m, offset: %04x\n", offset));
1235 	return m_prg[(m_latch * 0x2000) + (offset & 0x1fff)];
1236 }
1237 
read_h(offs_t offset)1238 uint8_t nes_lh32_device::read_h(offs_t offset)
1239 {
1240 //  LOG_MMC(("lh32 read_h, offset: %04x\n", offset));
1241 
1242 	if (offset >= 0x4000 && offset < 0x6000)
1243 		return m_prgram[offset & 0x1fff];
1244 
1245 	return hi_access_rom(offset);
1246 }
1247 
write_m(offs_t offset,uint8_t data)1248 void nes_lh32_device::write_m(offs_t offset, uint8_t data)
1249 {
1250 	LOG_MMC(("lh32 write_m, offset: %04x, data: %02x\n", offset, data));
1251 
1252 	if (offset == 0)    // 0x6000 only?
1253 	{
1254 //      printf("write %x\n", data);
1255 		m_latch = data & 0xf;
1256 	}
1257 }
1258 
write_h(offs_t offset,uint8_t data)1259 void nes_lh32_device::write_h(offs_t offset, uint8_t data)
1260 {
1261 	LOG_MMC(("lh32 write_h, offset: %04x, data: %02x\n", offset, data));
1262 
1263 	if (offset >= 0x4000 && offset < 0x6000)
1264 		m_prgram[offset & 0x1fff] = data;
1265 }
1266 
1267 /*-------------------------------------------------
1268 
1269  UNL-LH10
1270 
1271  Games: Fuuun Shaolin Kyo (FDS conversion)
1272 
1273  This PCB maps WRAM in 0xc000-0xdfff and PRG in 0x6000-0x7fff
1274  This is very similar to KS7037 (see kaiser.cpp)
1275 
1276  iNES:
1277 
1278  In MESS: Supported.
1279 
1280  -------------------------------------------------*/
1281 
update_prg()1282 void nes_lh10_device::update_prg()
1283 {
1284 	prg8_89(m_reg[6]);
1285 	prg8_ab(m_reg[7]);
1286 }
1287 
read_m(offs_t offset)1288 uint8_t nes_lh10_device::read_m(offs_t offset)
1289 {
1290 	LOG_MMC(("lh10 read_m, offset: %04x\n", offset));
1291 	return m_prg[(0x0e * 0x2000) + (offset & 0x1fff)];
1292 }
1293 
read_h(offs_t offset)1294 uint8_t nes_lh10_device::read_h(offs_t offset)
1295 {
1296 //  LOG_MMC(("lh10 read_h, offset: %04x\n", offset));
1297 
1298 	if (offset >= 0x4000 && offset < 0x6000)
1299 		return m_prgram[offset & 0x1fff];
1300 
1301 	return hi_access_rom(offset);
1302 }
1303 
write_h(offs_t offset,uint8_t data)1304 void nes_lh10_device::write_h(offs_t offset, uint8_t data)
1305 {
1306 	LOG_MMC(("lh10 write_h, offset: %04x, data: %02x\n", offset, data));
1307 
1308 	if (offset >= 0x4000 && offset < 0x6000)
1309 		m_prgram[offset & 0x1fff] = data;
1310 
1311 	else
1312 	{
1313 		switch (offset & 0x6001)
1314 		{
1315 			case 0x0000:
1316 				m_latch = data & 7;
1317 				break;
1318 			case 0x0001:
1319 				m_reg[m_latch] = data;
1320 				update_prg();
1321 				break;
1322 		}
1323 	}
1324 }
1325 
1326 /*-------------------------------------------------
1327 
1328  UNL-LH53
1329 
1330  Games: Nazo no Murasamejou (FDS conversion)
1331 
1332  This PCB maps WRAM (w/battery) in 0xb800-0xd7ff and
1333  PRG in 0x6000-0x7fff
1334 
1335  iNES:
1336 
1337  In MESS: Preliminar Support only.
1338 
1339  -------------------------------------------------*/
1340 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)1341 void nes_lh53_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
1342 {
1343 	if (id == TIMER_IRQ)
1344 	{
1345 		if (m_irq_enable)
1346 		{
1347 			m_irq_count++;
1348 			if (m_irq_count > 7560)//value from FCEUMM...
1349 			{
1350 				m_irq_count = 0;
1351 				set_irq_line(ASSERT_LINE);
1352 			}
1353 		}
1354 	}
1355 }
1356 
read_m(offs_t offset)1357 uint8_t nes_lh53_device::read_m(offs_t offset)
1358 {
1359 	LOG_MMC(("lh53 read_m, offset: %04x\n", offset));
1360 	return m_prg[(m_reg * 0x2000) + (offset & 0x1fff)];
1361 }
1362 
read_h(offs_t offset)1363 uint8_t nes_lh53_device::read_h(offs_t offset)
1364 {
1365 //  LOG_MMC(("lh53 read_h, offset: %04x\n", offset));
1366 
1367 	if (offset >= 0x3800 && offset < 0x5800)
1368 		return m_battery[offset & 0x1fff];
1369 
1370 	return hi_access_rom(offset);
1371 }
1372 
write_h(offs_t offset,uint8_t data)1373 void nes_lh53_device::write_h(offs_t offset, uint8_t data)
1374 {
1375 	LOG_MMC(("lh53 write_h, offset: %04x, data: %02x\n", offset, data));
1376 
1377 	if (offset >= 0x3800 && offset < 0x5800)
1378 		m_battery[offset & 0x1fff] = data;
1379 
1380 	else
1381 	{
1382 		switch (offset & 0x7000)
1383 		{
1384 			case 0x6000:
1385 				m_irq_enable = BIT(data, 1);
1386 				m_irq_count = 0;
1387 				if (!m_irq_enable)
1388 					set_irq_line(CLEAR_LINE);
1389 				break;
1390 			case 0x7000:
1391 				m_reg = data & 0x0f;
1392 				break;
1393 		}
1394 	}
1395 }
1396 
1397 /*-------------------------------------------------
1398 
1399  BTL-2708
1400 
1401  Games: Doki Doki Panic (FDS conversion)
1402 
1403  iNES: mapper 103?
1404 
1405  This board has a very unique setup, with 8KB of WRAM
1406  in 0x6000-0x7fff and other 8KB of WRAM in 0xb800-0xd7ff
1407  which can be switched in 2KB chunks (we attempt to
1408  emulate this by intercepting reads in that area before
1409  they get to the PRG banks...)
1410 
1411  In MESS: Supported.
1412 
1413  -------------------------------------------------*/
1414 
read_m(offs_t offset)1415 uint8_t nes_2708_device::read_m(offs_t offset)
1416 {
1417 	LOG_MMC(("btl-2708 read_m, offset: %04x\n", offset));
1418 	if (!m_reg[1])
1419 		return m_prgram[offset];    // lower 8K of WRAM
1420 	else
1421 		return m_prg[(m_reg[0] * 0x2000) + (offset & 0x1fff)];
1422 }
1423 
write_m(offs_t offset,uint8_t data)1424 void nes_2708_device::write_m(offs_t offset, uint8_t data)
1425 {
1426 	LOG_MMC(("btl-2708 write_m, offset: %04x, data: %02x\n", offset, data));
1427 //  if (!m_reg[1])
1428 		m_prgram[offset] = data;    // lower 8K of WRAM
1429 }
1430 
read_h(offs_t offset)1431 uint8_t nes_2708_device::read_h(offs_t offset)
1432 {
1433 //  LOG_MMC(("btl-2708 read_h, offset: %04x\n", offset));
1434 
1435 	if (offset >= 0x3800 && offset < 0x5800 && !m_reg[1])
1436 		return m_prgram[0x2000 + ((offset - 0x3800) & 0x1fff)]; // higher 8K of WRAM
1437 
1438 	return hi_access_rom(offset);
1439 }
1440 
write_h(offs_t offset,uint8_t data)1441 void nes_2708_device::write_h(offs_t offset, uint8_t data)
1442 {
1443 	LOG_MMC(("btl-2708 write_h, offset: %04x, data: %02x\n", offset, data));
1444 
1445 	if (offset >= 0x3800 && offset < 0x5800/* && !m_reg[1]*/)
1446 		m_prgram[0x2000 + ((offset - 0x3800) & 0x1fff)] = data; // higher 8K of WRAM
1447 
1448 	switch (offset & 0x7000)
1449 	{
1450 		case 0x0000:
1451 			m_reg[0] = data & 0x0f; // PRG bank in 0x6000-0x7fff
1452 			break;
1453 		case 0x6000:
1454 			set_nt_mirroring(BIT(data, 3) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
1455 			break;
1456 		case 0x7000:
1457 			m_reg[1] = BIT(data, 4);    // bit4 enables the two WRAM banks
1458 			break;
1459 	}
1460 }
1461 
1462 /*-------------------------------------------------
1463 
1464  UNL-AC08
1465 
1466  Games: Green Beret (FDS conversions)
1467 
1468  iNES:
1469 
1470  This board has two PRG chips. The first (128K) is
1471  connected to 0x6000-0x7fff and switches among the
1472  16x8K banks; the second (32K) is fixed in 0x8000-0xffff
1473 
1474  In MESS: Supported.
1475 
1476  -------------------------------------------------*/
1477 
write_ex(offs_t offset,uint8_t data)1478 void nes_ac08_device::write_ex(offs_t offset, uint8_t data)
1479 {
1480 	LOG_MMC(("AC-08 write_ex, offset: %04x, data: %02x\n", offset, data));
1481 	if (offset == 5)    // $4025
1482 		set_nt_mirroring(!BIT(data, 3) ? PPU_MIRROR_VERT : PPU_MIRROR_HORZ);
1483 }
1484 
read_m(offs_t offset)1485 uint8_t nes_ac08_device::read_m(offs_t offset)
1486 {
1487 	LOG_MMC(("AC-08 read_m, offset: %04x\n", offset));
1488 	return m_prg[(m_latch * 0x2000) + (offset & 0x1fff)];
1489 }
1490 
write_h(offs_t offset,uint8_t data)1491 void nes_ac08_device::write_h(offs_t offset, uint8_t data)
1492 {
1493 	LOG_MMC(("AC-08 write_h, offset: %04x, data: %02x\n", offset, data));
1494 
1495 	if (offset == 1)
1496 		m_latch = (data >> 1) & 0x0f;
1497 	else
1498 		m_latch = data & 0x0f;  // apparently there also is a Castlevania FDS conversion using same board with different banking lines
1499 }
1500 
1501 /*-------------------------------------------------
1502 
1503  UNL-BB
1504 
1505  Games: Bubble Bobble and other FDS conversions with CHRROM!
1506 
1507  iNES:
1508 
1509 
1510  In MESS: Supported.
1511 
1512  -------------------------------------------------*/
1513 
read_m(offs_t offset)1514 uint8_t nes_unl_bb_device::read_m(offs_t offset)
1515 {
1516 	LOG_MMC(("unl-bb read_m, offset: %04x\n", offset));
1517 	return m_prg[(((m_reg[0] & 3 & m_prg_mask) * 0x2000) + (offset & 0x1fff))];
1518 }
1519 
write_h(offs_t offset,uint8_t data)1520 void nes_unl_bb_device::write_h(offs_t offset, uint8_t data)
1521 {
1522 	LOG_MMC(("unl-bb write_h, offset: %04x, data: %02x\n", offset, data));
1523 
1524 	if (!(offset & 0x1000))
1525 	{
1526 		m_reg[0] = data;
1527 		m_reg[1] = data;
1528 	}
1529 	else
1530 		m_reg[1] = data & 1;    // Pro Wrestling uses this
1531 
1532 	chr8(m_reg[1] & 3, m_chr_source);
1533 }
1534 
1535 /*-------------------------------------------------
1536 
1537  BTL-MARIO1-MALEE2 (aka Genius Merio Bros)
1538 
1539  Games: Super Mario Bros Malee 2
1540 
1541  iNES:
1542 
1543  This PCB has two PRG chips (32K+2K) + one CHR chip (8K)
1544  + 2KB of WRAM
1545  The second PRG chip (2K) is connected at 0x6000-0x6800
1546  while WRAM is at 0x7000-0x7800
1547 
1548  In MESS: Supported.
1549 
1550  -------------------------------------------------*/
1551 
read_m(offs_t offset)1552 uint8_t nes_mmalee_device::read_m(offs_t offset)
1553 {
1554 	LOG_MMC(("mmalee read_m, offset: %04x\n", offset));
1555 
1556 	if (offset < 0x0800)
1557 		return m_prg[0x8000 + offset];
1558 	else if (!m_prgram.empty() && offset >= 0x1000 && offset < 0x1800)   // WRAM only in these 2K
1559 		return m_prgram[offset & 0x7ff];
1560 
1561 	return ((offset + 0x6000) & 0xff00) >> 8;
1562 }
1563 
write_m(offs_t offset,uint8_t data)1564 void nes_mmalee_device::write_m(offs_t offset, uint8_t data)
1565 {
1566 	LOG_MMC(("mmalee write_m, offset: %04x, data: %02x\n", offset, data));
1567 
1568 	if (!m_prgram.empty() && offset >= 0x1000 && offset < 0x1800)    // WRAM only in these 2K
1569 		m_prgram[offset & 0x7ff] = data;
1570 }
1571 
1572 /*-------------------------------------------------
1573 
1574  BTL-SHUIGUANPIPE
1575 
1576  Games: Shui Guan Pipe (Gimmick Pirate)
1577 
1578  iNES:
1579 
1580  In MESS: Supported, but there are glitches (PPU or IRQ?)
1581 
1582  -------------------------------------------------*/
1583 
1584 // timer always running and checking IRQ every 114 CPU cycles?
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)1585 void nes_shuiguan_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
1586 {
1587 	if (id == TIMER_IRQ)
1588 	{
1589 		m_irq_count++;
1590 		m_irq_count &= 0xff;
1591 
1592 		if (m_irq_enable && !m_irq_count)
1593 			hold_irq_line();
1594 	}
1595 }
1596 
write_h(offs_t offset,uint8_t data)1597 void nes_shuiguan_device::write_h(offs_t offset, uint8_t data)
1598 {
1599 	int bank;
1600 	LOG_MMC(("shuiguan write_h, offset: %04x, data: %02x\n", offset, data));
1601 
1602 	switch (offset & 0x7000)
1603 	{
1604 		case 0x0000:
1605 			if (offset & 0x800 && !(offset & 0x0c)) // 0x8800-0x8803 + N*0x10
1606 				prg8_89(data);
1607 			break;
1608 		case 0x1000:
1609 			if (offset & 0x800 && !(offset & 0x0c)) // 0x9800-0x9803 + N*0x10
1610 			{
1611 				switch (data & 0x03)
1612 				{
1613 					case 0: set_nt_mirroring(PPU_MIRROR_VERT); break;
1614 					case 1: set_nt_mirroring(PPU_MIRROR_HORZ); break;
1615 					case 2: set_nt_mirroring(PPU_MIRROR_LOW); break;
1616 					case 3: set_nt_mirroring(PPU_MIRROR_HIGH); break;
1617 				}
1618 			}
1619 			break;
1620 		case 0x2000:
1621 			if (!(offset & 0x800) && !(offset & 0x0c))  // 0xa000-0xa003 + N*0x10
1622 				prg8_cd(data);
1623 			if (offset & 0x800 && !(offset & 0x0c)) // 0xa800-0xa803 + N*0x10
1624 				prg8_ab(data);
1625 			break;
1626 		case 0x3000:
1627 		case 0x4000:
1628 		case 0x5000:
1629 		case 0x6000:
1630 			bank = (((offset + 0x1000) >> 11) | (offset >> 3)) & 0x07;
1631 			if (offset & 4)
1632 				m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & 0x0f) | ((data & 0x0f) << 4);
1633 			else
1634 				m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & 0xf0) | ((data & 0x0f) << 0);
1635 			chr1_x(bank, m_mmc_vrom_bank[bank], m_chr_source);
1636 			break;
1637 		case 0x7000:
1638 			switch (offset & 0x0c)
1639 			{
1640 				case 0x00: m_irq_count = (m_irq_count & 0xf0) | ((data & 0x0f) << 0); break;
1641 				case 0x04: m_irq_count = (m_irq_count & 0x0f) | ((data & 0x0f) << 4); break;
1642 				case 0x08: m_irq_enable= data; break;
1643 				case 0x0c: break;
1644 			}
1645 			break;
1646 	}
1647 }
1648 
read_m(offs_t offset)1649 uint8_t nes_shuiguan_device::read_m(offs_t offset)
1650 {
1651 	// always first bank??
1652 	LOG_MMC(("shuiguan read_m, offset: %04x\n", offset));
1653 	return m_prg[offset & 0x1fff];
1654 }
1655 
1656 
1657 /*-------------------------------------------------
1658 
1659  RT-01
1660 
1661  Games: Russian test cart
1662 
1663  The PRG EPROM has copy protected areas with
1664  "weak bits", which is tested at some points (info
1665  from Cah4e3).
1666 
1667  iNES:
1668 
1669  In MESS:
1670 
1671  -------------------------------------------------*/
1672 
read_h(offs_t offset)1673 uint8_t nes_rt01_device::read_h(offs_t offset)
1674 {
1675 //  LOG_MMC(("rt01 read_h, offset: %04x\n", offset));
1676 
1677 	if ((offset >= 0x4e80) && (offset < 0x4f00))
1678 		return 0xf2 | (machine().rand() & 0x0d);
1679 	if ((offset >= 0x7e80) && (offset < 0x7f00))
1680 		return 0xf2 | (machine().rand() & 0x0d);
1681 
1682 	return hi_access_rom(offset);
1683 }
1684