1 #include "burnint.h"
2 #include "pic16c5x_intf.h"
3
4 void pic16c5xDoReset(INT32 type, INT32 *rom, INT32 *ram);
5 extern INT32 pic16c5xScanCpu(INT32 nAction, INT32* pnMin);
6
7 // masks
8 static INT32 rom_address_mask = 0x7ff;
9 static INT32 ram_address_mask = 0x07f;
10
11 INT32 nPic16c5xCpuType = -1;
12 static UINT8 *pic16c5x_rom = NULL;
13 static UINT8 *pic16c5x_ram = NULL;
14
15 static UINT8 (*pPic16c5xReadPort)(UINT16 port) = NULL;
16 static void (*pPic16c5xWritePort)(UINT16 port, UINT8 data) = NULL;
17
18 cpu_core_config pic16c5xConfig =
19 {
20 pic16c5xOpen,
21 pic16c5xClose,
22 pic16c5xCheatRead,
23 pic16c5xCheatWrite,
24 pic16c5xGetActive,
25 pic16c5xTotalCycles,
26 pic16c5xNewFrame,
27 pic16c5xRun,
28 pic16c5xRunEnd,
29 pic16c5xReset,
30 0x7ff,
31 0
32 };
33
pic16c5xFetch(UINT16 address)34 UINT16 pic16c5xFetch(UINT16 address)
35 {
36 #if defined FBA_DEBUG
37 if (!DebugCPU_PIC16C5XInitted) bprintf(PRINT_ERROR, _T("pic16c5x_read_op called without init\n"));
38 #endif
39
40 UINT16 *ROM = (UINT16*)pic16c5x_rom;
41
42 address &= rom_address_mask;
43
44 return ROM[address];
45 }
46
pic16c5xRead(UINT16 address)47 UINT8 pic16c5xRead(UINT16 address)
48 {
49 #if defined FBA_DEBUG
50 if (!DebugCPU_PIC16C5XInitted) bprintf(PRINT_ERROR, _T("pic16c5x_read_byte called without init\n"));
51 #endif
52
53 address &= ram_address_mask;
54
55 if (nPic16c5xCpuType == 0x16C57 || nPic16c5xCpuType == 0x16C58) {
56 if (address >= 0x60 && address <= 0x6f) {
57 // mirror
58 return pic16c5x_ram[address & 0x0f];
59 }
60 }
61 return pic16c5x_ram[address];
62 }
63
pic16c5xWrite(UINT16 address,UINT8 data)64 void pic16c5xWrite(UINT16 address, UINT8 data)
65 {
66 #if defined FBA_DEBUG
67 if (!DebugCPU_PIC16C5XInitted) bprintf(PRINT_ERROR, _T("pic16c5x_write_byte called without init\n"));
68 #endif
69
70 address &= ram_address_mask;
71
72 if (nPic16c5xCpuType == 0x16C57 || nPic16c5xCpuType == 0x16C58) {
73 if (address >= 0x60 && address <= 0x6f) {
74 // mirror
75 pic16c5x_ram[address & 0x0f] = data;
76 return;
77 }
78 }
79
80 pic16c5x_ram[address] = data;
81 }
82
pic16c5xReadPort(UINT16 port)83 UINT8 pic16c5xReadPort(UINT16 port)
84 {
85 #if defined FBA_DEBUG
86 if (!DebugCPU_PIC16C5XInitted) bprintf(PRINT_ERROR, _T("pic16c5x_read_port called without init\n"));
87 #endif
88
89 if (pPic16c5xReadPort) {
90 return pPic16c5xReadPort(port);
91 }
92
93 return 0;
94 }
95
pic16c5xWritePort(UINT16 port,UINT8 data)96 void pic16c5xWritePort(UINT16 port, UINT8 data)
97 {
98 #if defined FBA_DEBUG
99 if (!DebugCPU_PIC16C5XInitted) bprintf(PRINT_ERROR, _T("pic16c5x_write_port called without init\n"));
100 #endif
101
102 if (pPic16c5xWritePort) {
103 pPic16c5xWritePort(port, data);
104 return;
105 }
106 }
107
pic16c5xSetReadPortHandler(UINT8 (* pReadPort)(UINT16 port))108 void pic16c5xSetReadPortHandler(UINT8 (*pReadPort)(UINT16 port))
109 {
110 pPic16c5xReadPort = pReadPort;
111 }
112
pic16c5xSetWritePortHandler(void (* pWritePort)(UINT16 port,UINT8 data))113 void pic16c5xSetWritePortHandler(void (*pWritePort)(UINT16 port, UINT8 data))
114 {
115 pPic16c5xWritePort = pWritePort;
116 }
117
pic16c5xReset()118 void pic16c5xReset()
119 {
120 #if defined FBA_DEBUG
121 if (!DebugCPU_PIC16C5XInitted) bprintf(PRINT_ERROR, _T("pic16c5xReset called without init\n"));
122 #endif
123
124 pic16c5xDoReset(nPic16c5xCpuType, &rom_address_mask, &ram_address_mask);
125 }
126
pic16c5xGetActive()127 INT32 pic16c5xGetActive()
128 {
129 return 0; // only one cpu supported atm
130 }
131
pic16c5xTotalCycles()132 INT32 pic16c5xTotalCycles() // not functional
133 {
134 return 0;
135 }
136
pic16c5xNewFrame()137 void pic16c5xNewFrame() // not functional
138 {
139 //
140 }
141
pic16c5xCheatRead(UINT32 address)142 UINT8 pic16c5xCheatRead(UINT32 address)
143 {
144 return pic16c5xRead(address);
145 }
146
pic16c5xCheatWrite(UINT32 address,UINT8 data)147 void pic16c5xCheatWrite(UINT32 address, UINT8 data)
148 {
149 pic16c5xWrite(address, data);
150 }
151
pic16c5xInit(INT32,INT32 type,UINT8 * mem)152 void pic16c5xInit(INT32 /*nCPU*/, INT32 type, UINT8 *mem)
153 {
154 DebugCPU_PIC16C5XInitted = 1;
155
156 nPic16c5xCpuType = type;
157
158 pic16c5xDoReset(type, &rom_address_mask, &ram_address_mask);
159
160 pic16c5x_rom = mem;
161
162 pic16c5x_ram = (UINT8*)BurnMalloc(ram_address_mask + 1);
163
164 CpuCheatRegister(0/*nCPU*/, &pic16c5xConfig);
165 }
166
pic16c5xExit()167 void pic16c5xExit()
168 {
169 #if defined FBA_DEBUG
170 if (!DebugCPU_PIC16C5XInitted) bprintf(PRINT_ERROR, _T("pic16c5xExit called without init\n"));
171 #endif
172
173 pic16c5x_rom = NULL;
174 nPic16c5xCpuType = -1;
175
176 if (pic16c5x_ram) {
177 BurnFree(pic16c5x_ram);
178 pic16c5x_ram = NULL;
179 }
180
181 pPic16c5xReadPort = NULL;
182 pPic16c5xWritePort = NULL;
183
184 DebugCPU_PIC16C5XInitted = 0;
185 }
186
pic16c5xOpen(INT32)187 void pic16c5xOpen(INT32)
188 {
189 #if defined FBA_DEBUG
190 if (!DebugCPU_PIC16C5XInitted) bprintf(PRINT_ERROR, _T("pic16c5xOpen called without init\n"));
191 #endif
192 }
193
pic16c5xClose()194 void pic16c5xClose()
195 {
196 #if defined FBA_DEBUG
197 if (!DebugCPU_PIC16C5XInitted) bprintf(PRINT_ERROR, _T("pic16c5xClose called without init\n"));
198 #endif
199 }
200
pic16c5xScan(INT32 nAction)201 INT32 pic16c5xScan(INT32 nAction)
202 {
203 #if defined FBA_DEBUG
204 if (!DebugCPU_PIC16C5XInitted) bprintf(PRINT_ERROR, _T("pic16c5xScan called without init\n"));
205 #endif
206
207 struct BurnArea ba;
208
209 pic16c5xScanCpu(nAction, 0);
210
211 if (nAction & ACB_MEMORY_RAM) {
212 ba.Data = pic16c5x_ram;
213 ba.nLen = ram_address_mask + 1;
214 ba.nAddress = 0;
215 ba.szName = "Internal RAM";
216 BurnAcb(&ba);
217 }
218
219 return 0;
220 }
221
222
asciitohex(UINT8 data)223 static UINT8 asciitohex(UINT8 data)
224 {
225 /* Convert ASCII data to HEX */
226
227 if ((data >= 0x30) && (data < 0x3a)) data -= 0x30;
228 data &= 0xdf; /* remove case sensitivity */
229 if ((data >= 0x41) && (data < 0x5b)) data -= 0x37;
230
231 return data;
232 }
233
234 extern void pic16c5x_config(INT32 data);
235
BurnLoadPicROM(UINT8 * src,INT32 offset,INT32 len)236 INT32 BurnLoadPicROM(UINT8 *src, INT32 offset, INT32 len)
237 {
238 UINT8 *PICROM_HEX = (UINT8*)BurnMalloc(len);
239 UINT16 *PICROM = (UINT16*)src;
240 INT32 offs, data;
241 UINT16 src_pos = 0;
242 UINT16 dst_pos = 0;
243 UINT8 data_hi, data_lo;
244
245 if (BurnLoadRom(PICROM_HEX, offset, 1)) return 1;
246
247 // Convert the PIC16C57 ASCII HEX dump to pure HEX
248 do
249 {
250 if ((PICROM_HEX[src_pos + 0] == ':') &&
251 (PICROM_HEX[src_pos + 1] == '1') &&
252 (PICROM_HEX[src_pos + 2] == '0'))
253 {
254 src_pos += 9;
255
256 for (offs = 0; offs < 32; offs += 4)
257 {
258 data_hi = asciitohex((PICROM_HEX[src_pos + offs + 0]));
259 data_lo = asciitohex((PICROM_HEX[src_pos + offs + 1]));
260 if ((data_hi <= 0x0f) && (data_lo <= 0x0f)) {
261 data = (data_hi << 4) | (data_lo << 0);
262 data_hi = asciitohex((PICROM_HEX[src_pos + offs + 2]));
263 data_lo = asciitohex((PICROM_HEX[src_pos + offs + 3]));
264
265 if ((data_hi <= 0x0f) && (data_lo <= 0x0f)) {
266 data |= (data_hi << 12) | (data_lo << 8);
267 PICROM[dst_pos] = data;
268 dst_pos += 1;
269 }
270 }
271 }
272 src_pos += 32;
273 }
274
275 /* Get the PIC16C57 Config register data */
276
277 if ((PICROM_HEX[src_pos + 0] == ':') &&
278 (PICROM_HEX[src_pos + 1] == '0') &&
279 (PICROM_HEX[src_pos + 2] == '2') &&
280 (PICROM_HEX[src_pos + 3] == '1'))
281 {
282 src_pos += 9;
283
284 data_hi = asciitohex((PICROM_HEX[src_pos + 0]));
285 data_lo = asciitohex((PICROM_HEX[src_pos + 1]));
286 data = (data_hi << 4) | (data_lo << 0);
287 data_hi = asciitohex((PICROM_HEX[src_pos + 2]));
288 data_lo = asciitohex((PICROM_HEX[src_pos + 3]));
289 data |= (data_hi << 12) | (data_lo << 8);
290
291 pic16c5x_config(data);
292 src_pos = 0x7fff; /* Force Exit */
293 }
294 src_pos += 1;
295 } while (src_pos < len); /* 0x2d4c is the size of the HEX rom loaded */
296
297 BurnFree (PICROM_HEX);
298
299 return 0;
300 }
301
302