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