1 #include "burnint.h"
2 #include "h6280/h6280.h"
3 #include "h6280_intf.h"
4 #include <stddef.h>
5 
6 #define MAX_H6280	2	//
7 
8 #define MEMORY_SPACE	0x200000
9 #define PAGE_SIZE	0x800
10 #define PAGE_MASK	0x7ff
11 #define PAGE_SHIFT	11
12 #define PAGE_COUNT	MEMORY_SPACE / PAGE_SIZE
13 
14 #define READ		0
15 #define WRITE		1
16 #define FETCH		2
17 
18 struct h6280_handler
19 {
20 	UINT8 (*h6280Read)(UINT32 address);
21 	void (*h6280Write)(UINT32 address, UINT8 data);
22 	void (*h6280WriteIO)(UINT8 port, UINT8 data);
23 	UINT8 *mem[3][PAGE_COUNT];
24 
25 	h6280_Regs *h6280;
26 };
27 
28 static struct h6280_handler sHandler[MAX_H6280];
29 static struct h6280_handler *sPointer;
30 
31 INT32 nh6280CpuCount = 0;
32 INT32 nh6280CpuActive = -1;
33 
34 void h6280_set_irq_line(INT32 irqline, INT32 state);
35 
core_set_irq(INT32 cpu,INT32 line,INT32 state)36 static void core_set_irq(INT32 cpu, INT32 line, INT32 state)
37 {
38 	INT32 active = nh6280CpuActive;
39 
40 	if (cpu != active)
41 	{
42 		h6280Close();
43 		h6280Open(cpu);
44 	}
45 
46 	h6280SetIRQLine(line, state);
47 
48 	if (cpu != active)
49 	{
50 		h6280Close();
51 		h6280Open(active);
52 	}
53 }
54 
55 cpu_core_config H6280Config =
56 {
57 	"h6280",
58 	h6280Open,
59 	h6280Close,
60 	h6280Read,
61 	h6280_write_rom,
62 	h6280GetActive,
63 	h6280TotalCycles,
64 	h6280NewFrame,
65 	h6280Idle,
66 	core_set_irq,
67 	h6280Run,
68 	h6280RunEnd,
69 	h6280Reset,
70 	0x200000,
71 	0
72 };
73 
h6280MapMemory(UINT8 * src,UINT32 start,UINT32 finish,INT32 type)74 void h6280MapMemory(UINT8 *src, UINT32 start, UINT32 finish, INT32 type)
75 {
76 #if defined FBNEO_DEBUG
77 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280MapMemory called without init\n"));
78 	if (nh6280CpuActive == -1) bprintf(PRINT_ERROR, _T("h6280MapMemory called with no CPU open\n"));
79 #endif
80 
81 	UINT32 len = (finish-start) >> PAGE_SHIFT;
82 
83 	for (UINT32 i = 0; i < len+1; i++)
84 	{
85 		UINT32 offset = i + (start >> PAGE_SHIFT);
86 		if (type & (1 <<  READ)) sPointer->mem[ READ][offset] = src + (i << PAGE_SHIFT);
87 		if (type & (1 << WRITE)) sPointer->mem[WRITE][offset] = src + (i << PAGE_SHIFT);
88 		if (type & (1 << FETCH)) sPointer->mem[FETCH][offset] = src + (i << PAGE_SHIFT);
89 	}
90 }
91 
h6280DummyIrqCallback(INT32)92 INT32 h6280DummyIrqCallback(INT32)
93 {
94 	return 0;
95 }
96 
h6280SetIrqCallbackHandler(INT32 (* callback)(INT32))97 void h6280SetIrqCallbackHandler(INT32 (*callback)(INT32))
98 {
99 #if defined FBNEO_DEBUG
100 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280SetIrqCallbackHandler called without init\n"));
101 	if (nh6280CpuActive == -1) bprintf(PRINT_ERROR, _T("h6280SetIrqCallbackHandler called with no CPU open\n"));
102 #endif
103 
104 	h6280_irqcallback(callback);
105 }
106 
h6280SetWriteHandler(void (* write)(UINT32,UINT8))107 void h6280SetWriteHandler(void (*write)(UINT32, UINT8))
108 {
109 #if defined FBNEO_DEBUG
110 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280SetWriteHandler called without init\n"));
111 	if (nh6280CpuActive == -1) bprintf(PRINT_ERROR, _T("h6280SetWriteHandler called with no CPU open\n"));
112 #endif
113 
114 	sPointer->h6280Write = write;
115 }
116 
h6280SetWritePortHandler(void (* write)(UINT8,UINT8))117 void h6280SetWritePortHandler(void (*write)(UINT8, UINT8))
118 {
119 #if defined FBNEO_DEBUG
120 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280SetWritePortHandler called without init\n"));
121 	if (nh6280CpuActive == -1) bprintf(PRINT_ERROR, _T("h6280SetWritePortHandler called with no CPU open\n"));
122 #endif
123 
124 	sPointer->h6280WriteIO = write;
125 }
126 
h6280SetReadHandler(UINT8 (* read)(UINT32))127 void h6280SetReadHandler(UINT8 (*read)(UINT32))
128 {
129 #if defined FBNEO_DEBUG
130 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280SetReadHandler called without init\n"));
131 	if (nh6280CpuActive == -1) bprintf(PRINT_ERROR, _T("h6280SetReadPortHandler called with no CPU open\n"));
132 #endif
133 
134 	sPointer->h6280Read = read;
135 }
136 
h6280_write_rom(UINT32 address,UINT8 data)137 void h6280_write_rom(UINT32 address, UINT8 data)
138 {
139 #if defined FBNEO_DEBUG
140 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280_write_rom called without init\n"));
141 	if (nh6280CpuActive == -1) bprintf(PRINT_ERROR, _T("h6280_write_rom called with no CPU open\n"));
142 #endif
143 
144 	address &= 0x1fffff;
145 
146 	if (sPointer->mem[READ][address >> PAGE_SHIFT] != NULL) {
147 		sPointer->mem[READ][address >> PAGE_SHIFT][address & PAGE_MASK] = data;
148 	}
149 
150 	if (sPointer->mem[FETCH][address >> PAGE_SHIFT] != NULL) {
151 		sPointer->mem[FETCH][address >> PAGE_SHIFT][address & PAGE_MASK] = data;
152 	}
153 
154 	if (sPointer->mem[WRITE][address >> PAGE_SHIFT] != NULL) {
155 		sPointer->mem[WRITE][address >> PAGE_SHIFT][address & PAGE_MASK] = data;
156 	}
157 
158 	if (sPointer->h6280Write != NULL) {
159 		sPointer->h6280Write(address, data);
160 	}
161 }
162 
h6280WritePort(UINT8 port,UINT8 data)163 void h6280WritePort(UINT8 port, UINT8 data)
164 {
165 #if defined FBNEO_DEBUG
166 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280_write_port called without init\n"));
167 	if (nh6280CpuActive == -1) bprintf(PRINT_ERROR, _T("h6280_write_port called with no CPU open\n"));
168 #endif
169 
170 //	bprintf (0, _T("%5.5x write port\n"), port);
171 
172 	if (sPointer->h6280WriteIO != NULL) {
173 		sPointer->h6280WriteIO(port, data);
174 		return;
175 	}
176 
177 	return;
178 }
179 
h6280Write(UINT32 address,UINT8 data)180 void h6280Write(UINT32 address, UINT8 data)
181 {
182 #if defined FBNEO_DEBUG
183 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280_write called without init\n"));
184 	if (nh6280CpuActive == -1) bprintf(PRINT_ERROR, _T("h6280_write called with no CPU open\n"));
185 #endif
186 
187 	address &= 0x1fffff;
188 
189 //	bprintf (0, _T("%5.5x write\n"), address);
190 
191 	if (sPointer->mem[WRITE][address >> PAGE_SHIFT] != NULL) {
192 		sPointer->mem[WRITE][address >> PAGE_SHIFT][address & PAGE_MASK] = data;
193 		return;
194 	}
195 
196 	if (sPointer->h6280Write != NULL) {
197 		sPointer->h6280Write(address, data);
198 		return;
199 	}
200 
201 	return;
202 }
203 
h6280Read(UINT32 address)204 UINT8 h6280Read(UINT32 address)
205 {
206 #if defined FBNEO_DEBUG
207 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280_read called without init\n"));
208 	if (nh6280CpuActive == -1) bprintf(PRINT_ERROR, _T("h6280_read called with no CPU open\n"));
209 #endif
210 
211 	address &= 0x1fffff;
212 
213 //	bprintf (0, _T("%5.5x read\n"), address);
214 
215 	if (sPointer->mem[ READ][address >> PAGE_SHIFT] != NULL) {
216 		return sPointer->mem[ READ][address >> PAGE_SHIFT][address & PAGE_MASK];
217 	}
218 
219 	if (sPointer->h6280Read != NULL) {
220 		return sPointer->h6280Read(address);
221 	}
222 
223 	return 0;
224 }
225 
h6280Fetch(UINT32 address)226 UINT8 h6280Fetch(UINT32 address)
227 {
228 #if defined FBNEO_DEBUG
229 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280_fetch1 called without init\n"));
230 	if (nh6280CpuActive == -1) bprintf(PRINT_ERROR, _T("h6280_fetch1 called with no CPU open\n"));
231 #endif
232 
233 	address &= 0x1fffff;
234 
235 	if (sPointer->mem[FETCH][address >> PAGE_SHIFT] != NULL) {
236 		return sPointer->mem[FETCH][address >> PAGE_SHIFT][address & PAGE_MASK];
237 	}
238 
239 	if (sPointer->h6280Read != NULL) {
240 		return sPointer->h6280Read(address);
241 	}
242 
243 	return 0;
244 }
245 
h6280SetIRQLine(INT32 line,INT32 state)246 void h6280SetIRQLine(INT32 line, INT32 state)
247 {
248 #if defined FBNEO_DEBUG
249 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280SetIRQLine called without init\n"));
250 	if (nh6280CpuActive == -1) bprintf(PRINT_ERROR, _T("h6280SetIRQLine called with no CPU open\n"));
251 #endif
252 
253 	if (state == CPU_IRQSTATUS_AUTO) {
254 		h6280_set_irq_line(line, 1);
255 		h6280Run(10);
256 		h6280_set_irq_line(line, 0);
257 	} else {
258 		h6280_set_irq_line(line, state);
259 	}
260 }
261 
h6280Init(INT32 nCpu)262 void h6280Init(INT32 nCpu)
263 {
264 	DebugCPU_H6280Initted = 1;
265 
266 #if defined FBNEO_DEBUG
267 	if (nCpu >= MAX_H6280) bprintf(PRINT_ERROR, _T("h6280Init nCpu is more than MAX_CPU %d (MAX is %d)\n"), nCpu, MAX_H6280);
268 #endif
269 
270 	sPointer = &sHandler[nCpu];
271 
272 	sPointer->h6280 = (h6280_Regs*)BurnMalloc(sizeof(h6280_Regs));
273 
274 	if (nCpu >= nh6280CpuCount) nh6280CpuCount = nCpu+1;
275 
276 	for (INT32 i = 0; i < 3; i++) {
277 		for (INT32 j = 0; j < (MEMORY_SPACE / PAGE_SIZE); j++) {
278 			sPointer->mem[i][j] = NULL;
279 		}
280 	}
281 
282 	sPointer->h6280Write = NULL;
283 	sPointer->h6280Read = NULL;
284 	sPointer->h6280WriteIO = NULL;
285 
286 	CpuCheatRegister(nCpu, &H6280Config);
287 }
288 
h6280Exit()289 void h6280Exit()
290 {
291 #if defined FBNEO_DEBUG
292 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280Exit called without init\n"));
293 #endif
294 
295 	if (!DebugCPU_H6280Initted) return;
296 
297 	for (INT32 i = 0; i < MAX_H6280; i++) {
298 		sPointer = &sHandler[i];
299 
300 		sPointer->h6280Write = NULL;
301 		sPointer->h6280Read = NULL;
302 		sPointer->h6280WriteIO = NULL;
303 
304 		if (sPointer->h6280) {
305 			BurnFree(sPointer->h6280);
306 		}
307 	}
308 
309 	nh6280CpuCount = 0;
310 	DebugCPU_H6280Initted = 0;
311 }
312 
h6280Open(INT32 num)313 void h6280Open(INT32 num)
314 {
315 #if defined FBNEO_DEBUG
316 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280Open called without init\n"));
317 	if (num >= nh6280CpuCount) bprintf(PRINT_ERROR, _T("h6280Open called with invalid index %x\n"), num);
318 	if (nh6280CpuActive != -1) bprintf(PRINT_ERROR, _T("h6280Open called with CPU already open with index %x\n"), num);
319 #endif
320 
321 	sPointer = &sHandler[num % MAX_H6280];
322 
323 	h6280_set_context(sPointer->h6280);
324 
325 	nh6280CpuActive = num;
326 }
327 
h6280Close()328 void h6280Close()
329 {
330 #if defined FBNEO_DEBUG
331 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280Close called without init\n"));
332 	if (nh6280CpuActive == -1) bprintf(PRINT_ERROR, _T("h6280Close called with no CPU open\n"));
333 #endif
334 
335 	h6280_get_context(sPointer->h6280);
336 
337 //	sPointer = NULL; // not safe...
338 
339 	nh6280CpuActive = -1;
340 }
341 
h6280GetActive()342 INT32 h6280GetActive()
343 {
344 #if defined FBNEO_DEBUG
345 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280GetActive called without init\n"));
346 	if (nh6280CpuActive == -1) bprintf(PRINT_ERROR, _T("h6280GetActive called with no CPU open\n"));
347 #endif
348 
349 	return nh6280CpuActive;
350 }
351 
h6280NewFrame()352 void h6280NewFrame()
353 {
354 #if defined FBNEO_DEBUG
355 	if (!DebugCPU_H6280Initted) bprintf(PRINT_ERROR, _T("h6280NewFrame called without init\n"));
356 #endif
357 
358 	h6280_handler *ptr;
359 
360 	for (INT32 i = 0; i < MAX_H6280; i++)
361 	{
362 		ptr = &sHandler[i % MAX_H6280];
363 		sHandler->h6280->h6280_totalcycles = 0;
364 	}
365 }
366 
h6280Scan(INT32 nAction)367 INT32 h6280Scan(INT32 nAction)
368 {
369 	struct BurnArea ba;
370 
371 	char szName[64];
372 
373 	if (nAction & ACB_DRIVER_DATA) {
374 		for (INT32 i = 0; i < MAX_H6280; i++)
375 		{
376 			h6280_handler *ptr = &sHandler[i];
377 			h6280_Regs *p = ptr->h6280;
378 
379 			if (p == NULL) continue;
380 
381 			memset(&ba, 0, sizeof(ba));
382 			ba.Data	  = p;
383 			ba.nLen	  = STRUCT_SIZE_HELPER(h6280_Regs, io_buffer);
384 			sprintf (szName, "h6280 Registers for Chip #%d", i);
385 			ba.szName = szName;
386 			BurnAcb(&ba);
387 		}
388 	}
389 
390 	return 0;
391 }
392