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