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