1 // Based on C-Chip emulation by Jonathan Gevaryahu, David Haywood
2 // Ultra-super double thanks to Caps0ff for dumping the C-Chips
3 
4 #include "burnint.h"
5 #include "taito_ic.h"
6 #include "taito.h"
7 #include "upd7810_intf.h"
8 #include "bitswap.h"
9 #include "m68000_intf.h"
10 
11 //#define DEBUG_CCHIP
12 
13 UINT8 cchip_active = 0;
14 UINT8 *cchip_rom;
15 UINT8 *cchip_eeprom;
16 
17 static UINT8 *cchip_ram; // 0x2000, 8 0x400 chunks. separate banking for 68k and uPD
18 static UINT8 *cchip_updram; // 0x100, internal uPD ram
19 
20 static INT32 bank;
21 static INT32 bank68k;
22 static UINT8 asic_ram[4];
23 static UINT8 porta, portb, portc, portadc;
24 
cchip_interrupt()25 void cchip_interrupt()
26 {
27 	upd7810SetIRQLine(UPD7810_INTF1, CPU_IRQSTATUS_ACK); // core auto un-acks
28 }
29 
cchip_loadports(UINT8 pa,UINT8 pb,UINT8 pc,UINT8 padc)30 void cchip_loadports(UINT8 pa, UINT8 pb, UINT8 pc, UINT8 padc)
31 {
32 	porta = pa; portb = pb; portc = pc; portadc = padc;
33 }
34 
cchip_run(INT32 cyc)35 INT32 cchip_run(INT32 cyc)
36 {
37 	return upd7810Run(cyc);
38 }
39 
cchip_reset()40 void cchip_reset()
41 {
42 	upd7810Reset();
43 	bank = 0;
44 	bank68k = 0;
45 	memset(&asic_ram, 0, 4);
46 	memset(cchip_ram, 0, 0x2000);
47 	memset(cchip_updram, 0, 0x100);
48 	porta = portb = portc = portadc = 0;
49 }
50 
cchip_asic_read(UINT32 offset)51 UINT8 cchip_asic_read(UINT32 offset)
52 {
53 	if (offset < 0x200)
54 		return asic_ram[offset & 3];
55 
56 	return 0x00;
57 }
58 
cchip_asic_write(UINT32 offset,UINT8 data)59 static void cchip_asic_write(UINT32 offset, UINT8 data)
60 {
61 	if (offset == 0x200)
62 	{
63 		bank = data & 7;
64 	}
65 	else
66 		asic_ram[offset & 3] = data;
67 }
68 
cchip_asic_write68k(UINT32 offset,UINT16 data)69 void cchip_asic_write68k(UINT32 offset, UINT16 data)
70 {
71 	if (offset == 0x200)
72 	{
73 		bank68k = data & 7;
74 	}
75 	else
76 		asic_ram[offset & 3] = data & 0xff;
77 }
78 
cchip_68k_write(UINT16 address,UINT8 data)79 void cchip_68k_write(UINT16 address, UINT8 data)
80 {
81 	cchip_ram[(bank68k * 0x400) + (address & 0x3ff)] = data;
82 }
83 
cchip_68k_read(UINT16 address)84 UINT8 cchip_68k_read(UINT16 address)
85 {
86 	return cchip_ram[(bank68k * 0x400) + (address & 0x3ff)];
87 }
88 
upd7810_read_port(UINT8 port)89 static UINT8 upd7810_read_port(UINT8 port)
90 {
91 	switch (port)
92 	{
93 		case UPD7810_PORTA:
94 			return porta;
95 
96 		case UPD7810_PORTB:
97 			return portb;
98 
99 		case UPD7810_PORTC:
100 			return portc;
101 	}
102 
103 	return 0;
104 }
105 
upd7810_write_port(UINT8 port,UINT8 data)106 static void upd7810_write_port(UINT8 port, UINT8 data)   // not impl yet. (usually just coin counters write back)
107 {
108 	switch (port)
109 	{
110 		case UPD7810_PORTA:
111 		return;
112 
113 		case UPD7810_PORTB:
114 		return;
115 
116 		case UPD7810_PORTC:
117 		return;
118 	}
119 }
120 
upd7810_read(UINT16 address)121 static UINT8 upd7810_read(UINT16 address)
122 {
123 	if (address >= 0x1000 && address <= 0x13ff) {
124 		return cchip_ram[(bank * 0x400) + (address & 0x3ff)];
125 	}
126 
127 	if (address >= 0x1400 && address <= 0x17ff) {
128 		return cchip_asic_read(address & 0x3ff);
129 	}
130 
131 	return 0;
132 }
133 
upd7810_write(UINT16 address,UINT8 data)134 static void upd7810_write(UINT16 address, UINT8 data)
135 {
136 	if (address >= 0x1000 && address <= 0x13ff) {
137 		cchip_ram[(bank * 0x400) + (address & 0x3ff)] = data;
138 		return;
139 	}
140 
141 	if (address >= 0x1400 && address <= 0x17ff) {
142 		cchip_asic_write(address & 0x3ff, data);
143 		return;
144 	}
145 }
146 
147 #if 0
148 static void cchip_sync() // probably not needed, saving just incase
149 {
150 	INT32 cyc = ((SekTotalCycles() * 12) / 8) - upd7810TotalCycles();
151 	if (cyc > 0) {
152 		cchip_run(cyc);
153 	}
154 }
155 #endif
156 
157 #ifdef DEBUG_CCHIP
cchip_dumptakedisinhibitorendofframe()158 void cchip_dumptakedisinhibitorendofframe()
159 {
160 	bprintf(0, _T("0x0000: "));
161 	for (INT32 rc = 0; rc < 16; rc++)
162 		bprintf(0, _T("%02X, "), cchip_ram[rc]);
163 
164 	bprintf(0, _T("\n0x0010: "));
165 	for (INT32 rc = 0; rc < 16; rc++)
166 		bprintf(0, _T("%02X, "), cchip_ram[rc+0x10]);
167 
168 	bprintf(0, _T("\n0x0020: "));
169 	for (INT32 rc = 0; rc < 16; rc++)
170 		bprintf(0, _T("%02X, "), cchip_ram[rc+0x20]);
171 	bprintf(0, _T("\n\n"));
172 }
173 #endif
174 
cchip_an0_read()175 static UINT8 cchip_an0_read() {	return BIT(portadc, 0); }
cchip_an1_read()176 static UINT8 cchip_an1_read() {	return BIT(portadc, 1); }
cchip_an2_read()177 static UINT8 cchip_an2_read() {	return BIT(portadc, 2); }
cchip_an3_read()178 static UINT8 cchip_an3_read() {	return BIT(portadc, 3); }
cchip_an4_read()179 static UINT8 cchip_an4_read() {	return BIT(portadc, 4); }
cchip_an5_read()180 static UINT8 cchip_an5_read() {	return BIT(portadc, 5); }
cchip_an6_read()181 static UINT8 cchip_an6_read() {	return BIT(portadc, 6); }
cchip_an7_read()182 static UINT8 cchip_an7_read() {	return BIT(portadc, 7); }
183 
cchip_init()184 void cchip_init()
185 {
186 	cchip_ram = (UINT8 *)BurnMalloc(0x2000);
187 	cchip_updram = (UINT8 *)BurnMalloc(0x100);
188 
189 	upd7810Init(NULL);
190 	upd7810MapMemory(cchip_rom,     0x0000, 0x0fff, MAP_ROM); // c-chip bios
191 	upd7810MapMemory(cchip_eeprom,  0x2000, 0x3fff, MAP_ROM); // pre-game eeprom
192 	upd7810MapMemory(cchip_updram,  0xff00, 0xffff, MAP_RAM); // internal uPD ram
193 
194 	upd7810SetReadPortHandler(upd7810_read_port);
195 	upd7810SetWritePortHandler(upd7810_write_port);
196 	upd7810SetReadHandler(upd7810_read);
197 	upd7810SetWriteHandler(upd7810_write);
198 
199 	upd7810SetAnfunc(0, cchip_an0_read);
200 	upd7810SetAnfunc(1, cchip_an1_read);
201 	upd7810SetAnfunc(2, cchip_an2_read);
202 	upd7810SetAnfunc(3, cchip_an3_read);
203 	upd7810SetAnfunc(4, cchip_an4_read);
204 	upd7810SetAnfunc(5, cchip_an5_read);
205 	upd7810SetAnfunc(6, cchip_an6_read);
206 	upd7810SetAnfunc(7, cchip_an7_read);
207 
208 	cchip_active = 1;
209 
210 	cchip_reset();
211 
212 #ifdef DEBUG_CCHIP
213 	bprintf(0, _T("\n-- c-chippy debug --\ncc eeprom: \n"));
214 	for (INT32 rc = 0; rc < 16; rc++)
215 		bprintf(0, _T("%X, "), cchip_eeprom[rc]);
216 
217 	bprintf(0, _T("\ncc biosrom: \n"));
218 	for (INT32 rc = 0; rc < 16; rc++)
219 		bprintf(0, _T("%X, "), cchip_rom[rc]);
220 	bprintf(0, _T("\n"));
221 #endif
222 }
223 
cchip_exit()224 void cchip_exit()
225 {
226 	upd7810Exit();
227 	BurnFree(cchip_ram);
228 	BurnFree(cchip_updram);
229 	cchip_active = 0;
230 }
231 
cchip_scan(INT32 nAction)232 INT32 cchip_scan(INT32 nAction)
233 {
234 	if (nAction & ACB_VOLATILE)	{
235 		upd7810Scan(nAction);
236 
237 		ScanVar(cchip_updram,   0x100,  "cchip_updram");
238 		ScanVar(cchip_ram,      0x2000, "cchip_bankram");
239 
240 		SCAN_VAR(bank);
241 		SCAN_VAR(bank68k);
242 		SCAN_VAR(asic_ram);
243 
244 		SCAN_VAR(porta);
245 		SCAN_VAR(portb);
246 		SCAN_VAR(portc);
247 		SCAN_VAR(portadc);
248 	}
249 
250 	return 0;
251 }
252 
253