1 // license:BSD-3-Clause
2 // copyright-holders:Fabio Priuli
3 /***********************************************************************************************************
4
5
6 NES/Famicom cartridge emulation for Nanjing PCBs
7
8 TODO:
9 - Emulate the variants often assigned to mapper 162/164 (and investigate connection with Waixing FS-304)!
10
11 ***********************************************************************************************************/
12
13
14 #include "emu.h"
15 #include "nanjing.h"
16
17 #include "video/ppu2c0x.h"
18
19
20 #ifdef NES_PCB_DEBUG
21 #define VERBOSE 1
22 #else
23 #define VERBOSE 0
24 #endif
25
26 #define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0)
27
28
29 //-------------------------------------------------
30 // constructor
31 //-------------------------------------------------
32
33 DEFINE_DEVICE_TYPE(NES_NANJING, nes_nanjing_device, "nes_nanjing", "NES Cart Nanjing PCB")
34
35
nes_nanjing_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)36 nes_nanjing_device::nes_nanjing_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
37 : nes_nrom_device(mconfig, NES_NANJING, tag, owner, clock)
38 , m_count(0)
39 , m_latch1(0)
40 , m_latch2(0)
41 , m_ppu(*this, ":ppu") // FIXME: this dependency should not exist
42 {
43 }
44
~nes_nanjing_device()45 nes_nanjing_device::~nes_nanjing_device()
46 {
47 }
48
49
50
51
device_start()52 void nes_nanjing_device::device_start()
53 {
54 common_start();
55 save_item(NAME(m_count));
56 save_item(NAME(m_latch1));
57 save_item(NAME(m_latch2));
58 save_item(NAME(m_reg));
59 }
60
pcb_reset()61 void nes_nanjing_device::pcb_reset()
62 {
63 m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
64 prg16_89ab(m_prg_chunks - 2);
65 prg16_cdef(m_prg_chunks - 1);
66 chr8(0, m_chr_source);
67
68 m_count = 0xff;
69 m_latch1 = 0;
70 m_latch2 = 0;
71 m_reg[0] = 0xff;
72 m_reg[1] = 0;
73 }
74
75
76
77
78
79 /*-------------------------------------------------
80 mapper specific handlers
81 -------------------------------------------------*/
82
83 /*-------------------------------------------------
84
85 Bootleg Board by Nanjing
86
87 Games: A lot of pirate originals
88
89 iNES: mapper 163
90
91 In MESS: Unsupported.
92
93 -------------------------------------------------*/
94
hblank_irq(int scanline,int vblank,int blanked)95 void nes_nanjing_device::hblank_irq(int scanline, int vblank, int blanked)
96 {
97 if (BIT(m_reg[0], 7))
98 {
99 if (scanline == 127)
100 {
101 chr4_0(1, CHRRAM);
102 chr4_4(1, CHRRAM);
103 }
104
105 if (scanline == 239)
106 {
107 chr4_0(0, CHRRAM);
108 chr4_4(0, CHRRAM);
109 }
110 }
111
112 }
113
write_l(offs_t offset,uint8_t data)114 void nes_nanjing_device::write_l(offs_t offset, uint8_t data)
115 {
116 LOG_MMC(("nanjing write_l, offset: %04x, data: %02x\n", offset, data));
117
118 offset += 0x100;
119
120 if (offset < 0x1000)
121 return;
122
123 if (offset == 0x1100) // 0x5100
124 {
125 if (data == 6)
126 prg32(3);
127 return;
128 }
129
130 if (offset == 0x1101) // 0x5101
131 {
132 uint8_t temp = m_count;
133 m_count = data;
134
135 if ((temp & ~data) & 1)
136 {
137 m_latch2 ^= 0xff;
138 }
139 }
140
141 switch (offset & 0x300)
142 {
143 case 0x000:
144 case 0x200:
145 m_reg[BIT(offset, 9)] = data;
146 if (!BIT(m_reg[0], 7) && m_ppu->get_current_scanline() <= 127)
147 chr8(0, CHRRAM);
148 break;
149 case 0x300:
150 m_latch1 = data;
151 break;
152 }
153
154 prg32((m_reg[0] & 0x0f) | ((m_reg[1] & 0x0f) << 4));
155 }
156
read_l(offs_t offset)157 uint8_t nes_nanjing_device::read_l(offs_t offset)
158 {
159 uint8_t value = 0;
160 LOG_MMC(("nanjing read_l, offset: %04x\n", offset));
161
162 offset += 0x100;
163
164 if (offset < 0x1000)
165 return 0;
166
167 switch (offset & 0x700)
168 {
169 case 0x100:
170 value = m_latch1;
171 break;
172 case 0x500:
173 value = m_latch2 & m_latch1;
174 break;
175 case 0x000:
176 case 0x200:
177 case 0x300:
178 case 0x400:
179 case 0x600:
180 case 0x700:
181 value = 4;
182 break;
183 }
184 return value;
185 }
186