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