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