1 // Z80 (Zed Eight-Ty) Interface
2 #include "burnint.h"
3 #include "z80_intf.h"
4 #include <stddef.h>
5
6 #define MAX_Z80 8
7 static struct ZetExt * ZetCPUContext[MAX_Z80] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
8
9 typedef UINT8 (__fastcall *pZetInHandler)(UINT16 a);
10 typedef void (__fastcall *pZetOutHandler)(UINT16 a, UINT8 d);
11 typedef UINT8 (__fastcall *pZetReadHandler)(UINT16 a);
12 typedef void (__fastcall *pZetWriteHandler)(UINT16 a, UINT8 d);
13
14 struct ZetExt {
15 Z80_Regs reg;
16
17 UINT8* pZetMemMap[0x100 * 4];
18
19 pZetInHandler ZetIn;
20 pZetOutHandler ZetOut;
21 pZetReadHandler ZetRead;
22 pZetWriteHandler ZetWrite;
23
24 UINT32 BusReq;
25 UINT32 ResetLine;
26 };
27
28 static INT32 nZetCyclesDone[MAX_Z80];
29 static INT32 nZetCyclesDelayed[MAX_Z80];
30 static INT32 nZetCyclesTotal;
31 static INT32 nZ80ICount[MAX_Z80];
32 static UINT32 Z80EA[MAX_Z80];
33
34 static INT32 nOpenedCPU = -1;
35 static INT32 nCPUCount = 0;
36 INT32 nHasZet = -1;
37
38 cpu_core_config ZetConfig =
39 {
40 ZetOpen,
41 ZetClose,
42 ZetCheatRead,
43 ZetCheatWriteROM,
44 ZetGetActive,
45 ZetTotalCycles,
46 ZetNewFrame,
47 ZetRun,
48 ZetRunEnd,
49 ZetReset,
50 0x10000,
51 0
52 };
53
ZetDummyReadHandler(UINT16)54 UINT8 __fastcall ZetDummyReadHandler(UINT16) { return 0; }
ZetDummyWriteHandler(UINT16,UINT8)55 void __fastcall ZetDummyWriteHandler(UINT16, UINT8) { }
ZetDummyInHandler(UINT16)56 UINT8 __fastcall ZetDummyInHandler(UINT16) { return 0; }
ZetDummyOutHandler(UINT16,UINT8)57 void __fastcall ZetDummyOutHandler(UINT16, UINT8) { }
58
ZetReadIO(UINT32 a)59 UINT8 __fastcall ZetReadIO(UINT32 a)
60 {
61 return ZetCPUContext[nOpenedCPU]->ZetIn(a);
62 }
63
ZetWriteIO(UINT32 a,UINT8 d)64 void __fastcall ZetWriteIO(UINT32 a, UINT8 d)
65 {
66 ZetCPUContext[nOpenedCPU]->ZetOut(a, d);
67 }
68
ZetReadProg(UINT32 a)69 UINT8 __fastcall ZetReadProg(UINT32 a)
70 {
71 // check mem map
72 UINT8 * pr = ZetCPUContext[nOpenedCPU]->pZetMemMap[0x000 | (a >> 8)];
73 if (pr != NULL) {
74 return pr[a & 0xff];
75 }
76
77 // check handler
78 if (ZetCPUContext[nOpenedCPU]->ZetRead != NULL) {
79 return ZetCPUContext[nOpenedCPU]->ZetRead(a);
80 }
81
82 return 0;
83 }
84
ZetWriteProg(UINT32 a,UINT8 d)85 void __fastcall ZetWriteProg(UINT32 a, UINT8 d)
86 {
87 // check mem map
88 UINT8 * pr = ZetCPUContext[nOpenedCPU]->pZetMemMap[0x100 | (a >> 8)];
89 if (pr != NULL) {
90 pr[a & 0xff] = d;
91 return;
92 }
93
94 // check handler
95 if (ZetCPUContext[nOpenedCPU]->ZetWrite != NULL) {
96 ZetCPUContext[nOpenedCPU]->ZetWrite(a, d);
97 return;
98 }
99 }
100
ZetReadOp(UINT32 a)101 UINT8 __fastcall ZetReadOp(UINT32 a)
102 {
103 // check mem map
104 UINT8 * pr = ZetCPUContext[nOpenedCPU]->pZetMemMap[0x200 | (a >> 8)];
105 if (pr != NULL) {
106 return pr[a & 0xff];
107 }
108
109 // check read handler
110 if (ZetCPUContext[nOpenedCPU]->ZetRead != NULL) {
111 return ZetCPUContext[nOpenedCPU]->ZetRead(a);
112 }
113
114 return 0;
115 }
116
ZetReadOpArg(UINT32 a)117 UINT8 __fastcall ZetReadOpArg(UINT32 a)
118 {
119 // check mem map
120 UINT8 * pr = ZetCPUContext[nOpenedCPU]->pZetMemMap[0x300 | (a >> 8)];
121 if (pr != NULL) {
122 return pr[a & 0xff];
123 }
124
125 // check read handler
126 if (ZetCPUContext[nOpenedCPU]->ZetRead != NULL) {
127 return ZetCPUContext[nOpenedCPU]->ZetRead(a);
128 }
129
130 return 0;
131 }
132
ZetSetReadHandler(UINT8 (__fastcall * pHandler)(UINT16))133 void ZetSetReadHandler(UINT8 (__fastcall *pHandler)(UINT16))
134 {
135 #if defined FBA_DEBUG
136 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSetReadHandler called without init\n"));
137 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetSetReadHandler called when no CPU open\n"));
138 #endif
139
140 ZetCPUContext[nOpenedCPU]->ZetRead = pHandler;
141 }
142
ZetSetWriteHandler(void (__fastcall * pHandler)(UINT16,UINT8))143 void ZetSetWriteHandler(void (__fastcall *pHandler)(UINT16, UINT8))
144 {
145 #if defined FBA_DEBUG
146 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSetWriteHandler called without init\n"));
147 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetSetWriteHandler called when no CPU open\n"));
148 #endif
149
150 ZetCPUContext[nOpenedCPU]->ZetWrite = pHandler;
151 }
152
ZetSetInHandler(UINT8 (__fastcall * pHandler)(UINT16))153 void ZetSetInHandler(UINT8 (__fastcall *pHandler)(UINT16))
154 {
155 #if defined FBA_DEBUG
156 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSetInHandler called without init\n"));
157 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetSetInHandler called when no CPU open\n"));
158 #endif
159
160 ZetCPUContext[nOpenedCPU]->ZetIn = pHandler;
161 }
162
ZetSetOutHandler(void (__fastcall * pHandler)(UINT16,UINT8))163 void ZetSetOutHandler(void (__fastcall *pHandler)(UINT16, UINT8))
164 {
165 #if defined FBA_DEBUG
166 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSetOutHandler called without init\n"));
167 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetSetOutHandler called when no CPU open\n"));
168 #endif
169
170 ZetCPUContext[nOpenedCPU]->ZetOut = pHandler;
171 }
172
ZetSetEDFECallback(void (* pCallback)(Z80_Regs *))173 void ZetSetEDFECallback(void (*pCallback)(Z80_Regs*))
174 {
175 // Can be set before init. it's cleared at exit.
176 z80edfe_callback = pCallback;
177 }
178
ZetNewFrame()179 void ZetNewFrame()
180 {
181 #if defined FBA_DEBUG
182 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetNewFrame called without init\n"));
183 #endif
184
185 for (INT32 i = 0; i < nCPUCount; i++) {
186 nZetCyclesDone[i] = 0;
187 }
188 nZetCyclesTotal = 0;
189 }
190
ZetCheatWriteROM(UINT32 a,UINT8 d)191 void ZetCheatWriteROM(UINT32 a, UINT8 d)
192 {
193 ZetWriteRom(a, d);
194 }
195
ZetCheatRead(UINT32 a)196 UINT8 ZetCheatRead(UINT32 a)
197 {
198 return ZetReadByte(a);
199 }
200
ZetInit(INT32 nCPU)201 INT32 ZetInit(INT32 nCPU)
202 {
203 DebugCPU_ZetInitted = 1;
204
205 nOpenedCPU = -1;
206
207 ZetCPUContext[nCPU] = (struct ZetExt*)BurnMalloc(sizeof(ZetExt));
208 memset (ZetCPUContext[nCPU], 0, sizeof(ZetExt));
209
210 Z80Init(); // clear/init next z80 slot (internal to z80.cpp)
211
212 {
213 ZetCPUContext[nCPU]->ZetIn = ZetDummyInHandler;
214 ZetCPUContext[nCPU]->ZetOut = ZetDummyOutHandler;
215 ZetCPUContext[nCPU]->ZetRead = ZetDummyReadHandler;
216 ZetCPUContext[nCPU]->ZetWrite = ZetDummyWriteHandler;
217 ZetCPUContext[nCPU]->BusReq = 0;
218 ZetCPUContext[nCPU]->ResetLine = 0;
219 // Z80Init() will set IX IY F regs with default value, so get them ...
220 Z80GetContext(&ZetCPUContext[nCPU]->reg);
221
222 nZetCyclesDone[nCPU] = 0;
223 nZetCyclesDelayed[nCPU] = 0;
224 nZ80ICount[nCPU] = 0;
225
226 for (INT32 j = 0; j < (0x0100 * 4); j++) {
227 ZetCPUContext[nCPU]->pZetMemMap[j] = NULL;
228 }
229 }
230
231 nZetCyclesTotal = 0;
232
233 Z80SetIOReadHandler(ZetReadIO);
234 Z80SetIOWriteHandler(ZetWriteIO);
235 Z80SetProgramReadHandler(ZetReadProg);
236 Z80SetProgramWriteHandler(ZetWriteProg);
237 Z80SetCPUOpReadHandler(ZetReadOp);
238 Z80SetCPUOpArgReadHandler(ZetReadOpArg);
239
240 nCPUCount = (nCPU+1) % MAX_Z80;
241
242 nHasZet = nCPU+1;
243
244 CpuCheatRegister(nCPU, &ZetConfig);
245
246 return 0;
247 }
248
ZetReadByte(UINT16 address)249 UINT8 ZetReadByte(UINT16 address)
250 {
251 if (nOpenedCPU < 0) return 0;
252
253 return ZetReadProg(address);
254 }
255
ZetWriteByte(UINT16 address,UINT8 data)256 void ZetWriteByte(UINT16 address, UINT8 data)
257 {
258 if (nOpenedCPU < 0) return;
259
260 ZetWriteProg(address, data);
261 }
262
ZetWriteRom(UINT16 address,UINT8 data)263 void ZetWriteRom(UINT16 address, UINT8 data)
264 {
265 #if defined FBA_DEBUG
266 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetWriteRom called without init\n"));
267 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetWriteRom called when no CPU open\n"));
268 #endif
269
270 if (nOpenedCPU < 0) return;
271
272 if (ZetCPUContext[nOpenedCPU]->pZetMemMap[0x200 | (address >> 8)] != NULL) {
273 ZetCPUContext[nOpenedCPU]->pZetMemMap[0x200 | (address >> 8)][address & 0xff] = data;
274 }
275
276 if (ZetCPUContext[nOpenedCPU]->pZetMemMap[0x300 | (address >> 8)] != NULL) {
277 ZetCPUContext[nOpenedCPU]->pZetMemMap[0x300 | (address >> 8)][address & 0xff] = data;
278 }
279
280 ZetWriteProg(address, data);
281 }
282
ZetClose()283 void ZetClose()
284 {
285 #if defined FBA_DEBUG
286 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetClose called without init\n"));
287 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetClose called when no CPU open\n"));
288 #endif
289
290 Z80GetContext(&ZetCPUContext[nOpenedCPU]->reg);
291 nZetCyclesDone[nOpenedCPU] = nZetCyclesTotal;
292 nZ80ICount[nOpenedCPU] = z80_ICount;
293 Z80EA[nOpenedCPU] = EA;
294
295 nOpenedCPU = -1;
296 }
297
ZetOpen(INT32 nCPU)298 void ZetOpen(INT32 nCPU)
299 {
300 #if defined FBA_DEBUG
301 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetOpen called without init\n"));
302 if (nCPU >= nCPUCount) bprintf(PRINT_ERROR, _T("ZetOpen called with invalid index %x\n"), nCPU);
303 if (nOpenedCPU != -1) bprintf(PRINT_ERROR, _T("ZetOpen called when CPU already open with index %x\n"), nCPU);
304 if (ZetCPUContext[nCPU] == NULL) bprintf (PRINT_ERROR, _T("ZetOpen called for uninitialized cpu %x\n"), nCPU);
305 #endif
306
307 Z80SetContext(&ZetCPUContext[nCPU]->reg);
308 nZetCyclesTotal = nZetCyclesDone[nCPU];
309 z80_ICount = nZ80ICount[nCPU];
310 EA = Z80EA[nCPU];
311
312 nOpenedCPU = nCPU;
313 }
314
ZetSwapActive(INT32 nCPU)315 void ZetSwapActive(INT32 nCPU)
316 {
317 #if defined FBA_DEBUG
318 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSwapActive called without init\n"));
319 if (nCPU >= nCPUCount) bprintf(PRINT_ERROR, _T("ZetSwapActive called with invalid index %x\n"), nCPU);
320 #endif
321
322 if (ZetGetActive() != -1)
323 ZetClose();
324
325 ZetOpen(nCPU);
326 }
327
ZetGetActive()328 INT32 ZetGetActive()
329 {
330 #if defined FBA_DEBUG
331 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetGetActive called without init\n"));
332 //if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetGetActive called when no CPU open\n"));
333 #endif
334
335 return nOpenedCPU;
336 }
337
338 // ## ZetCPUPush() / ZetCPUPop() ## internal helpers for sending signals to other Z80's
339 static INT32 nHostCPU;
340
ZetCPUPush(INT32 nCPU)341 static void ZetCPUPush(INT32 nCPU)
342 {
343 nHostCPU = ZetGetActive();
344 if (nHostCPU != -1) ZetClose();
345
346 ZetOpen(nCPU);
347 }
348
ZetCPUPop()349 static void ZetCPUPop()
350 {
351 ZetClose();
352 if (nHostCPU != -1) ZetOpen(nHostCPU);
353 }
354
ZetRun(INT32 nCycles)355 INT32 ZetRun(INT32 nCycles)
356 {
357 #if defined FBA_DEBUG
358 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetRun called without init\n"));
359 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetRun called when no CPU open\n"));
360 #endif
361
362 if (nCycles <= 0) return 0;
363
364 INT32 nDelayed = 0; // handle delayed cycle counts (from nmi / irq)
365 if (nZetCyclesDelayed[nOpenedCPU]) {
366 nDelayed = nZetCyclesDelayed[nOpenedCPU];
367 nZetCyclesDelayed[nOpenedCPU] = 0;
368 nCycles -= nDelayed;
369 }
370
371 if (!ZetCPUContext[nOpenedCPU]->BusReq && !ZetCPUContext[nOpenedCPU]->ResetLine) {
372 nCycles = Z80Execute(nCycles);
373 }
374
375 nCycles += nDelayed;
376
377 nZetCyclesTotal += nCycles;
378
379 return nCycles;
380 }
381
ZetRun(INT32 nCPU,INT32 nCycles)382 INT32 ZetRun(INT32 nCPU, INT32 nCycles)
383 {
384 #if defined FBA_DEBUG
385 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetRun called without init\n"));
386 #endif
387
388 ZetCPUPush(nCPU);
389
390 INT32 nRet = ZetRun(nCycles);
391
392 ZetCPUPop();
393
394 return nRet;
395 }
396
ZetRunAdjust(INT32)397 void ZetRunAdjust(INT32 /*nCycles*/)
398 {
399 #if defined FBA_DEBUG
400 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetRunAdjust called without init\n"));
401 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetRunAdjust called when no CPU open\n"));
402 #endif
403 }
404
ZetRunEnd()405 void ZetRunEnd()
406 {
407 #if defined FBA_DEBUG
408 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetRunEnd called without init\n"));
409 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetRunEnd called when no CPU open\n"));
410 #endif
411
412 Z80StopExecute();
413 }
414
415 // This function will make an area callback ZetRead/ZetWrite
ZetMemCallback(INT32 nStart,INT32 nEnd,INT32 nMode)416 INT32 ZetMemCallback(INT32 nStart, INT32 nEnd, INT32 nMode)
417 {
418 #if defined FBA_DEBUG
419 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetMemCallback called without init\n"));
420 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetMemCallback called when no CPU open\n"));
421 #endif
422
423 UINT8 cStart = (nStart >> 8);
424 UINT8 **pMemMap = ZetCPUContext[nOpenedCPU]->pZetMemMap;
425
426 for (UINT16 i = cStart; i <= (nEnd >> 8); i++) {
427 switch (nMode) {
428 case 0:
429 pMemMap[0 + i] = NULL;
430 break;
431 case 1:
432 pMemMap[0x100 + i] = NULL;
433 break;
434 case 2:
435 pMemMap[0x200 + i] = NULL;
436 pMemMap[0x300 + i] = NULL;
437 break;
438 }
439 }
440
441 return 0;
442 }
443
ZetExit()444 void ZetExit()
445 {
446 #if defined FBA_DEBUG
447 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetExit called without init\n"));
448 #endif
449
450 if (!DebugCPU_ZetInitted) return;
451
452 for (INT32 i = 0; i < nCPUCount; i++) {
453 ZetOpen(i);
454 Z80Exit(); // exit daisy chain & peripherals attached to this cpu.
455 ZetClose();
456 }
457
458 for (INT32 i = 0; i < MAX_Z80; i++) {
459 if (ZetCPUContext[i]) {
460 BurnFree (ZetCPUContext[i]);
461 ZetCPUContext[i] = NULL;
462 }
463 }
464
465 nCPUCount = 0;
466 nHasZet = -1;
467
468 DebugCPU_ZetInitted = 0;
469 }
470
471
472 // This function will make an area callback ZetRead/ZetWrite
ZetUnmapMemory(INT32 nStart,INT32 nEnd,INT32 nFlags)473 INT32 ZetUnmapMemory(INT32 nStart, INT32 nEnd, INT32 nFlags)
474 {
475 #if defined FBA_DEBUG
476 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetUnmapMemory called without init\n"));
477 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetUnmapMemory called when no CPU open\n"));
478 #endif
479
480 UINT8 cStart = (nStart >> 8);
481 UINT8 **pMemMap = ZetCPUContext[nOpenedCPU]->pZetMemMap;
482
483 for (UINT16 i = cStart; i <= (nEnd >> 8); i++) {
484 if (nFlags & (1 << 0)) pMemMap[0 + i] = NULL; // READ
485 if (nFlags & (1 << 1)) pMemMap[0x100 + i] = NULL; // WRITE
486 if (nFlags & (1 << 2)) pMemMap[0x200 + i] = NULL; // OP
487 if (nFlags & (1 << 3)) pMemMap[0x300 + i] = NULL; // ARG
488 }
489
490 return 0;
491 }
492
ZetMapMemory(UINT8 * Mem,INT32 nStart,INT32 nEnd,INT32 nFlags)493 void ZetMapMemory(UINT8 *Mem, INT32 nStart, INT32 nEnd, INT32 nFlags)
494 {
495 #if defined FBA_DEBUG
496 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetMapMemory called without init\n"));
497 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetMapMemory called when no CPU open\n"));
498 #endif
499
500 UINT8 cStart = (nStart >> 8);
501 UINT8 **pMemMap = ZetCPUContext[nOpenedCPU]->pZetMemMap;
502
503 for (UINT16 i = cStart; i <= (nEnd >> 8); i++) {
504 if (nFlags & (1 << 0)) pMemMap[0 + i] = Mem + ((i - cStart) << 8); // READ
505 if (nFlags & (1 << 1)) pMemMap[0x100 + i] = Mem + ((i - cStart) << 8); // WRITE
506 if (nFlags & (1 << 2)) pMemMap[0x200 + i] = Mem + ((i - cStart) << 8); // OP
507 if (nFlags & (1 << 3)) pMemMap[0x300 + i] = Mem + ((i - cStart) << 8); // ARG
508 }
509 }
510
ZetMapArea(INT32 nStart,INT32 nEnd,INT32 nMode,UINT8 * Mem)511 INT32 ZetMapArea(INT32 nStart, INT32 nEnd, INT32 nMode, UINT8 *Mem)
512 {
513 #if defined FBA_DEBUG
514 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetMapArea called without init\n"));
515 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetMapArea called when no CPU open\n"));
516 #endif
517
518 UINT8 cStart = (nStart >> 8);
519 UINT8 **pMemMap = ZetCPUContext[nOpenedCPU]->pZetMemMap;
520
521 for (UINT16 i = cStart; i <= (nEnd >> 8); i++) {
522 switch (nMode) {
523 case 0: {
524 pMemMap[0 + i] = Mem + ((i - cStart) << 8);
525 break;
526 }
527
528 case 1: {
529 pMemMap[0x100 + i] = Mem + ((i - cStart) << 8);
530 break;
531 }
532
533 case 2: {
534 pMemMap[0x200 + i] = Mem + ((i - cStart) << 8);
535 pMemMap[0x300 + i] = Mem + ((i - cStart) << 8);
536 break;
537 }
538 }
539 }
540
541 return 0;
542 }
543
ZetMapArea(INT32 nStart,INT32 nEnd,INT32 nMode,UINT8 * Mem01,UINT8 * Mem02)544 INT32 ZetMapArea(INT32 nStart, INT32 nEnd, INT32 nMode, UINT8 *Mem01, UINT8 *Mem02)
545 {
546 #if defined FBA_DEBUG
547 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetMapArea called without init\n"));
548 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetMapArea called when no CPU open\n"));
549 #endif
550
551 UINT8 cStart = (nStart >> 8);
552 UINT8 **pMemMap = ZetCPUContext[nOpenedCPU]->pZetMemMap;
553
554 if (nMode != 2) {
555 return 1;
556 }
557
558 for (UINT16 i = cStart; i <= (nEnd >> 8); i++) {
559 pMemMap[0x200 + i] = Mem01 + ((i - cStart) << 8);
560 pMemMap[0x300 + i] = Mem02 + ((i - cStart) << 8);
561 }
562
563 return 0;
564 }
565
ZetReset()566 void ZetReset()
567 {
568 #if defined FBA_DEBUG
569 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetReset called without init\n"));
570 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetReset called when no CPU open\n"));
571 #endif
572
573 nZetCyclesDelayed[nOpenedCPU] = 0;
574 Z80Reset();
575 }
576
ZetReset(INT32 nCPU)577 void ZetReset(INT32 nCPU)
578 {
579 #if defined FBA_DEBUG
580 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetReset called without init\n"));
581 #endif
582
583 ZetCPUPush(nCPU);
584
585 ZetReset();
586
587 ZetCPUPop();
588 }
589
ZetGetPC(INT32 n)590 UINT32 ZetGetPC(INT32 n)
591 {
592 #if defined FBA_DEBUG
593 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetGetPC called without init\n"));
594 if (nOpenedCPU == -1 && n < 0) bprintf(PRINT_ERROR, _T("ZetGetPC called when no CPU open\n"));
595 #endif
596
597 if (n < 0) {
598 return ActiveZ80GetPC();
599 } else {
600 return ZetCPUContext[n]->reg.pc.w.l;
601 }
602 }
603
ZetGetPrevPC(INT32 n)604 INT32 ZetGetPrevPC(INT32 n)
605 {
606 #if defined FBA_DEBUG
607 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetGetPrvPC called without init\n"));
608 if (nOpenedCPU == -1 && n < 0) bprintf(PRINT_ERROR, _T("ZetGetPrevPC called when no CPU open\n"));
609 #endif
610
611 if (n < 0) {
612 return ActiveZ80GetPrevPC();
613 } else {
614 return ZetCPUContext[n]->reg.prvpc.d;
615 }
616 }
617
ZetBc(INT32 n)618 INT32 ZetBc(INT32 n)
619 {
620 #if defined FBA_DEBUG
621 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetBc called without init\n"));
622 if (nOpenedCPU == -1 && n < 0) bprintf(PRINT_ERROR, _T("ZetBc called when no CPU open\n"));
623 #endif
624
625 if (n < 0) {
626 return ActiveZ80GetBC();
627 } else {
628 return ZetCPUContext[n]->reg.bc.w.l;
629 }
630 }
631
ZetDe(INT32 n)632 INT32 ZetDe(INT32 n)
633 {
634 #if defined FBA_DEBUG
635 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetDe called without init\n"));
636 if (nOpenedCPU == -1 && n < 0) bprintf(PRINT_ERROR, _T("ZetDe called when no CPU open\n"));
637 #endif
638
639 if (n < 0) {
640 return ActiveZ80GetDE();
641 } else {
642 return ZetCPUContext[n]->reg.de.w.l;
643 }
644 }
645
ZetHL(INT32 n)646 INT32 ZetHL(INT32 n)
647 {
648 #if defined FBA_DEBUG
649 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetHL called without init\n"));
650 if (nOpenedCPU == -1 && n < 0) bprintf(PRINT_ERROR, _T("ZetHL called when no CPU open\n"));
651 #endif
652
653 if (n < 0) {
654 return ActiveZ80GetHL();
655 } else {
656 return ZetCPUContext[n]->reg.hl.w.l;
657 }
658 }
659
ZetI(INT32 n)660 INT32 ZetI(INT32 n)
661 {
662 #if defined FBA_DEBUG
663 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetI called without init\n"));
664 if (nOpenedCPU == -1 && n < 0) bprintf(PRINT_ERROR, _T("ZetI called when no CPU open\n"));
665 #endif
666
667 if (n < 0) {
668 return ActiveZ80GetI();
669 } else {
670 return ZetCPUContext[n]->reg.i;
671 }
672 }
673
ZetSP(INT32 n)674 INT32 ZetSP(INT32 n)
675 {
676 #if defined FBA_DEBUG
677 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSP called without init\n"));
678 if (nOpenedCPU == -1 && n < 0) bprintf(PRINT_ERROR, _T("ZetSP called when no CPU open\n"));
679 #endif
680
681 if (n < 0) {
682 return ActiveZ80GetSP();
683 } else {
684 return ZetCPUContext[n]->reg.sp.w.l;
685 }
686 }
687
ZetScan(INT32 nAction)688 INT32 ZetScan(INT32 nAction)
689 {
690 #if defined FBA_DEBUG
691 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetScan called without init\n"));
692 #endif
693
694 if ((nAction & ACB_DRIVER_DATA) == 0) {
695 return 0;
696 }
697
698 char szText[] = "Z80 #0";
699
700 for (INT32 i = 0; i < nCPUCount; i++) {
701 szText[5] = '1' + i;
702
703 ScanVar(&ZetCPUContext[i]->reg, STRUCT_SIZE_HELPER(Z80_Regs, hold_irq), szText);
704 SCAN_VAR(Z80EA[i]);
705 SCAN_VAR(nZ80ICount[i]);
706 SCAN_VAR(nZetCyclesDone[i]);
707 SCAN_VAR(nZetCyclesDelayed[i]);
708 SCAN_VAR(ZetCPUContext[i]->BusReq);
709 SCAN_VAR(ZetCPUContext[i]->ResetLine);
710 }
711
712 SCAN_VAR(nZetCyclesTotal);
713
714 for (INT32 i = 0; i < nCPUCount; i++) {
715 ZetOpen(i);
716 Z80Scan(nAction); // scan daisy chain & peripherals attached to this cpu.
717 ZetClose();
718 }
719
720 return 0;
721 }
722
ZetDaisyInit(INT32 dev0,INT32 dev1)723 void ZetDaisyInit(INT32 dev0, INT32 dev1)
724 {
725 #if defined FBA_DEBUG
726 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetDaisyInit called without init\n"));
727 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetDaisyInit called when no CPU open\n"));
728 #endif
729
730 z80daisy_init(dev0, dev1);
731 }
732
ZetSetIRQLine(const INT32 line,const INT32 status)733 void ZetSetIRQLine(const INT32 line, const INT32 status)
734 {
735 #if defined FBA_DEBUG
736 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSetIRQLine called without init\n"));
737 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetSetIRQLine called when no CPU open\n"));
738 #endif
739
740 switch ( status ) {
741 case CPU_IRQSTATUS_NONE:
742 Z80SetIrqLine(line, 0);
743 break;
744 case CPU_IRQSTATUS_ACK:
745 Z80SetIrqLine(line, 1);
746 break;
747 case CPU_IRQSTATUS_AUTO:
748 Z80SetIrqLine(line, 1);
749 nZetCyclesDelayed[nOpenedCPU] += Z80Execute(0);
750 Z80SetIrqLine(0, 0);
751 nZetCyclesDelayed[nOpenedCPU] += Z80Execute(0);
752 break;
753 case CPU_IRQSTATUS_HOLD:
754 ActiveZ80SetIRQHold();
755 Z80SetIrqLine(line, 1);
756 break;
757 }
758 }
759
ZetSetIRQLine(INT32 nCPU,const INT32 line,const INT32 status)760 void ZetSetIRQLine(INT32 nCPU, const INT32 line, const INT32 status)
761 {
762 #if defined FBA_DEBUG
763 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSetIRQLine called without init\n"));
764 #endif
765
766 ZetCPUPush(nCPU);
767
768 ZetSetIRQLine(line, status);
769
770 ZetCPUPop();
771 }
772
ZetSetVector(INT32 nCPU,INT32 vector)773 void ZetSetVector(INT32 nCPU, INT32 vector)
774 {
775 #if defined FBA_DEBUG
776 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSetVector called without init\n"));
777 #endif
778
779 ZetCPUPush(nCPU);
780
781 ZetSetVector(vector);
782
783 ZetCPUPop();
784 }
785
ZetSetVector(INT32 vector)786 void ZetSetVector(INT32 vector)
787 {
788 #if defined FBA_DEBUG
789 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSetVector called without init\n"));
790 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetSetVector called when no CPU open\n"));
791 #endif
792
793 ActiveZ80SetVector(vector);
794 }
795
ZetGetVector()796 UINT8 ZetGetVector()
797 {
798 #if defined FBA_DEBUG
799 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetGetVector called without init\n"));
800 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetGetVector called when no CPU open\n"));
801 #endif
802
803 return ActiveZ80GetVector();
804 }
805
ZetNmi()806 INT32 ZetNmi()
807 {
808 #if defined FBA_DEBUG
809 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetNmi called without init\n"));
810 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetNmi called when no CPU open\n"));
811 #endif
812
813 Z80SetIrqLine(Z80_INPUT_LINE_NMI, 1);
814 nZetCyclesDelayed[nOpenedCPU] += Z80Execute(0);
815 Z80SetIrqLine(Z80_INPUT_LINE_NMI, 0);
816 nZetCyclesDelayed[nOpenedCPU] += Z80Execute(0);
817
818 return 0;
819 }
820
ZetNmi(INT32 nCPU)821 INT32 ZetNmi(INT32 nCPU)
822 {
823 #if defined FBA_DEBUG
824 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetNmi called without init\n"));
825 #endif
826
827 ZetCPUPush(nCPU);
828
829 ZetNmi();
830
831 ZetCPUPop();
832
833 return 0;
834 }
835
ZetIdle(INT32 nCycles)836 INT32 ZetIdle(INT32 nCycles)
837 {
838 #if defined FBA_DEBUG
839 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetIdle called without init\n"));
840 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetIdle called when no CPU open\n"));
841 #endif
842
843 nZetCyclesTotal += nCycles;
844
845 return nCycles;
846 }
847
ZetSegmentCycles()848 INT32 ZetSegmentCycles()
849 {
850 #if defined FBA_DEBUG
851 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSegmentCycles called without init\n"));
852 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetSegmentCycles called when no CPU open\n"));
853 #endif
854
855 return z80TotalCycles();
856 }
857
ZetTotalCycles()858 INT32 ZetTotalCycles()
859 {
860 #if defined FBA_DEBUG
861 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetTotalCycles called without init\n"));
862 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetTotalCycles called when no CPU open\n"));
863 #endif
864
865 return nZetCyclesTotal + z80TotalCycles();
866 }
867
ZetSetBUSREQLine(INT32 nStatus)868 void ZetSetBUSREQLine(INT32 nStatus)
869 {
870 #if defined FBA_DEBUG
871 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSetBUSREQLine called without init\n"));
872 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetSetBUSREQLine called when no CPU open\n"));
873 #endif
874
875 if (nOpenedCPU < 0) return;
876
877 ZetCPUContext[nOpenedCPU]->BusReq = nStatus;
878 }
879
ZetGetBUSREQLine()880 INT32 ZetGetBUSREQLine()
881 {
882 #if defined FBA_DEBUG
883 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetGetBUSREQ called without init\n"));
884 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetGetBUSREQ called when no CPU open\n"));
885 #endif
886
887 return ZetCPUContext[nOpenedCPU]->BusReq;
888 }
889
ZetSetRESETLine(INT32 nStatus)890 void ZetSetRESETLine(INT32 nStatus)
891 {
892 #if defined FBA_DEBUG
893 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSetRESETLine called without init\n"));
894 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetSetRESETLine called when no CPU open\n"));
895 #endif
896
897 if (nOpenedCPU < 0) return;
898
899 if (ZetCPUContext[nOpenedCPU]->ResetLine && nStatus == 0) {
900 ZetReset();
901 }
902
903 ZetCPUContext[nOpenedCPU]->ResetLine = nStatus;
904 }
905
ZetSetRESETLine(INT32 nCPU,INT32 nStatus)906 void ZetSetRESETLine(INT32 nCPU, INT32 nStatus)
907 {
908 #if defined FBA_DEBUG
909 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSetRESETLine called without init\n"));
910 #endif
911
912 ZetCPUPush(nCPU);
913
914 ZetSetRESETLine(nStatus);
915
916 ZetCPUPop();
917 }
918
ZetGetRESETLine()919 INT32 ZetGetRESETLine()
920 {
921 #if defined FBA_DEBUG
922 if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetGetRESET called without init\n"));
923 if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetGetRESET called when no CPU open\n"));
924 #endif
925
926 return ZetCPUContext[nOpenedCPU]->ResetLine;
927 }
928
ZetSetAF(INT32 n,UINT16 value)929 void ZetSetAF(INT32 n, UINT16 value)
930 {
931 ZetCPUContext[n]->reg.af.w.l = value;
932 }
933
ZetSetAF2(INT32 n,UINT16 value)934 void ZetSetAF2(INT32 n, UINT16 value)
935 {
936 ZetCPUContext[n]->reg.af2.w.l = value;
937 }
938
ZetSetBC(INT32 n,UINT16 value)939 void ZetSetBC(INT32 n, UINT16 value)
940 {
941 ZetCPUContext[n]->reg.bc.w.l = value;
942 }
943
ZetSetBC2(INT32 n,UINT16 value)944 void ZetSetBC2(INT32 n, UINT16 value)
945 {
946 ZetCPUContext[n]->reg.bc2.w.l = value;
947 }
948
ZetSetDE(INT32 n,UINT16 value)949 void ZetSetDE(INT32 n, UINT16 value)
950 {
951 ZetCPUContext[n]->reg.de.w.l = value;
952 }
953
ZetSetDE2(INT32 n,UINT16 value)954 void ZetSetDE2(INT32 n, UINT16 value)
955 {
956 ZetCPUContext[n]->reg.de2.w.l = value;
957 }
958
ZetSetHL(INT32 n,UINT16 value)959 void ZetSetHL(INT32 n, UINT16 value)
960 {
961 ZetCPUContext[n]->reg.hl.w.l = value;
962 }
963
ZetSetHL2(INT32 n,UINT16 value)964 void ZetSetHL2(INT32 n, UINT16 value)
965 {
966 ZetCPUContext[n]->reg.hl2.w.l = value;
967 }
968
ZetSetI(INT32 n,UINT16 value)969 void ZetSetI(INT32 n, UINT16 value)
970 {
971 ZetCPUContext[n]->reg.i = value;
972 }
973
ZetSetIFF1(INT32 n,UINT16 value)974 void ZetSetIFF1(INT32 n, UINT16 value)
975 {
976 ZetCPUContext[n]->reg.iff1 = value;
977 }
978
ZetSetIFF2(INT32 n,UINT16 value)979 void ZetSetIFF2(INT32 n, UINT16 value)
980 {
981 ZetCPUContext[n]->reg.iff2 = value;
982 }
983
ZetSetIM(INT32 n,UINT16 value)984 void ZetSetIM(INT32 n, UINT16 value)
985 {
986 ZetCPUContext[n]->reg.im = value;
987 }
988
ZetSetIX(INT32 n,UINT16 value)989 void ZetSetIX(INT32 n, UINT16 value)
990 {
991 ZetCPUContext[n]->reg.ix.w.l = value;
992 }
993
ZetSetIY(INT32 n,UINT16 value)994 void ZetSetIY(INT32 n, UINT16 value)
995 {
996 ZetCPUContext[n]->reg.iy.w.l = value;
997 }
998
ZetSetPC(INT32 n,UINT16 value)999 void ZetSetPC(INT32 n, UINT16 value)
1000 {
1001 ZetCPUContext[n]->reg.pc.w.l = value;
1002 }
1003
ZetSetR(INT32 n,UINT16 value)1004 void ZetSetR(INT32 n, UINT16 value)
1005 {
1006 ZetCPUContext[n]->reg.r = value;
1007 ZetCPUContext[n]->reg.r2 = value & 0x80;
1008 }
1009
ZetSetSP(INT32 n,UINT16 value)1010 void ZetSetSP(INT32 n, UINT16 value)
1011 {
1012 ZetCPUContext[n]->reg.sp.w.l = value;
1013 }
1014
1015 #undef MAX_Z80
1016