1 // 680x0 (Sixty Eight K) Interface
2 // Interface picked from pfba (https://github.com/Cpasjuste/pfba)
3 #include "burnint.h"
4 #include "m68000_intf.h"
5 #include "m68000_debug.h"
6 
7 #define EMU_C68K
8 
9 #ifdef EMU_M68K
10 INT32 nSekM68KContextSize[SEK_MAX];
11 INT8* SekM68KContext[SEK_MAX];
12 #endif
13 
14 #ifdef EMU_C68K
15 #include "Cyclone.h"
16 struct Cyclone c68k[SEK_MAX];
17 static bool bCycloneInited = false;
18 #endif
19 
20 INT32 nSekCount = -1;							// Number of allocated 68000s
21 struct SekExt *SekExt[SEK_MAX] = { NULL, }, *pSekExt = NULL;
22 
23 INT32 nSekActive = -1;								// The cpu which is currently being emulated
24 INT32 nSekCyclesTotal, nSekCyclesScanline, nSekCyclesSegment, nSekCyclesDone, nSekCyclesToDo;
25 
26 INT32 nSekCPUType[SEK_MAX], nSekCycles[SEK_MAX], nSekIRQPending[SEK_MAX];
27 
28 cpu_core_config SekConfig =
29 {
30 	SekOpen,
31 	SekClose,
32 	SekCheatRead,
33 	SekWriteByteROM,
34 	SekGetActive,
35 	SekTotalCycles,
36 	SekNewFrame,
37 	SekRun,
38 	SekRunEnd,
39 	SekReset,
40 	0x1000000,
41 	0
42 };
43 
44 // ----------------------------------------------------------------------------
45 // Default memory access handlers
46 
DefReadByte(UINT32)47 UINT8 __fastcall DefReadByte(UINT32) { return 0; }
DefWriteByte(UINT32,UINT8)48 void __fastcall DefWriteByte(UINT32, UINT8) { }
49 
50 #define DEFWORDHANDLERS(i)																				\
51 	UINT16 __fastcall DefReadWord##i(UINT32 a) { SEK_DEF_READ_WORD(i, a) }				\
52 	void __fastcall DefWriteWord##i(UINT32 a, UINT16 d) { SEK_DEF_WRITE_WORD(i, a ,d) }
53 #define DEFLONGHANDLERS(i)																				\
54 	UINT32 __fastcall DefReadLong##i(UINT32 a) { SEK_DEF_READ_LONG(i, a) }					\
55 	void __fastcall DefWriteLong##i(UINT32 a, UINT32 d) { SEK_DEF_WRITE_LONG(i, a , d) }
56 
57 DEFWORDHANDLERS(0)
58 DEFLONGHANDLERS(0)
59 
60 #if SEK_MAXHANDLER >= 2
61  DEFWORDHANDLERS(1)
62  DEFLONGHANDLERS(1)
63 #endif
64 
65 #if SEK_MAXHANDLER >= 3
66  DEFWORDHANDLERS(2)
67  DEFLONGHANDLERS(2)
68 #endif
69 
70 #if SEK_MAXHANDLER >= 4
71  DEFWORDHANDLERS(3)
72  DEFLONGHANDLERS(3)
73 #endif
74 
75 #if SEK_MAXHANDLER >= 5
76  DEFWORDHANDLERS(4)
77  DEFLONGHANDLERS(4)
78 #endif
79 
80 #if SEK_MAXHANDLER >= 6
81  DEFWORDHANDLERS(5)
82  DEFLONGHANDLERS(5)
83 #endif
84 
85 #if SEK_MAXHANDLER >= 7
86  DEFWORDHANDLERS(6)
87  DEFLONGHANDLERS(6)
88 #endif
89 
90 #if SEK_MAXHANDLER >= 8
91  DEFWORDHANDLERS(7)
92  DEFLONGHANDLERS(7)
93 #endif
94 
95 #if SEK_MAXHANDLER >= 9
96  DEFWORDHANDLERS(8)
97  DEFLONGHANDLERS(8)
98 #endif
99 
100 #if SEK_MAXHANDLER >= 10
101  DEFWORDHANDLERS(9)
102  DEFLONGHANDLERS(9)
103 #endif
104 
105 // ----------------------------------------------------------------------------
106 // Memory access functions
107 
108 // Mapped Memory lookup (               for read)
109 #define FIND_R(x) pSekExt->MemMap[ x >> SEK_SHIFT]
110 // Mapped Memory lookup (+ SEK_WADD     for write)
111 #define FIND_W(x) pSekExt->MemMap[(x >> SEK_SHIFT) + SEK_WADD]
112 // Mapped Memory lookup (+ SEK_WADD * 2 for fetch)
113 #define FIND_F(x) pSekExt->MemMap[(x >> SEK_SHIFT) + SEK_WADD * 2]
114 
115 // Normal memory access functions
116 extern "C" {
m68k_read8(unsigned int a)117 unsigned int m68k_read8(unsigned int a)
118 {
119 	UINT8* pr;
120 
121 	a &= 0xFFFFFF;
122 
123 //	bprintf(PRINT_NORMAL, _T("read8 0x%08X\n"), a);
124 
125 	pr = FIND_R(a);
126 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
127 		a ^= 1;
128 		return pr[a & SEK_PAGEM];
129 	}
130 	return pSekExt->ReadByte[(uintptr_t)pr](a);
131 }
132 
m68k_fetch8(unsigned int a)133 unsigned int m68k_fetch8(unsigned int a)
134 {
135 	UINT8* pr;
136 
137 	a &= 0xFFFFFF;
138 
139 //	bprintf(PRINT_NORMAL, _T("fetch8 0x%08X\n"), a);
140 
141 	pr = FIND_F(a);
142 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
143 		a ^= 1;
144 		return pr[a & SEK_PAGEM];
145 	}
146 	return pSekExt->ReadByte[(uintptr_t)pr](a);
147 }
148 
m68k_write8(unsigned int a,unsigned char d)149 void m68k_write8(unsigned int a, unsigned char d)
150 {
151 	UINT8* pr;
152 
153 	a &= 0xFFFFFF;
154 
155 //	bprintf(PRINT_NORMAL, _T("write8 0x%08X\n"), a);
156 
157 	pr = FIND_W(a);
158 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
159 		a ^= 1;
160 		pr[a & SEK_PAGEM] = (UINT8)d;
161 		return;
162 	}
163 	pSekExt->WriteByte[(uintptr_t)pr](a, d);
164 }
165 
WriteByteROM(UINT32 a,UINT8 d)166 inline static void WriteByteROM(UINT32 a, UINT8 d)
167 {
168 	UINT8* pr;
169 
170 	a &= 0xFFFFFF;
171 
172 	pr = FIND_R(a);
173 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
174 		a ^= 1;
175 		pr[a & SEK_PAGEM] = (UINT8)d;
176 		return;
177 	}
178 	pSekExt->WriteByte[(uintptr_t)pr](a, d);
179 }
180 
m68k_read16(unsigned int a)181 unsigned int m68k_read16(unsigned int a)
182 {
183 	UINT8* pr;
184 
185 	a &= 0xFFFFFF;
186 
187 //	bprintf(PRINT_NORMAL, _T("read16 0x%08X\n"), a);
188 
189 	pr = FIND_R(a);
190 	if ((uintptr_t)pr >= SEK_MAXHANDLER)
191 	{
192 		if (a & 1)
193 		{
194 			return BURN_ENDIAN_SWAP_INT16((M68KReadByte(a + 0) * 256) + M68KReadByte(a + 1));
195 		}
196 		else
197 		{
198 			return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(pr + (a & SEK_PAGEM))));
199 		}
200 	}
201 	return pSekExt->ReadWord[(uintptr_t)pr](a);
202 }
203 
m68k_fetch16(unsigned int a)204 unsigned int m68k_fetch16(unsigned int a)
205 {
206 	UINT8* pr;
207 
208 	a &= 0xFFFFFF;
209 
210 //	bprintf(PRINT_NORMAL, _T("fetch16 0x%08X\n"), a);
211 
212 	pr = FIND_F(a);
213 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
214 		return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(pr + (a & SEK_PAGEM))));
215 	}
216 	return pSekExt->ReadWord[(uintptr_t)pr](a);
217 }
218 
m68k_write16(unsigned int a,unsigned short d)219 void m68k_write16(unsigned int a, unsigned short d)
220 {
221 	UINT8* pr;
222 
223 	a &= 0xFFFFFF;
224 
225 //	bprintf(PRINT_NORMAL, _T("write16 0x%08X\n"), a);
226 
227 	pr = FIND_W(a);
228 	if ((uintptr_t)pr >= SEK_MAXHANDLER)
229 	{
230 		if (a & 1)
231 		{
232 			//	bprintf(PRINT_NORMAL, _T("write16 0x%08X\n"), a);
233 			d = BURN_ENDIAN_SWAP_INT16(d);
234 			M68KWriteByte(a + 0, d / 0x100);
235 			M68KWriteByte(a + 1, d);
236 			return;
237 		}
238 		else
239 		{
240 			*((UINT16 *) (pr + (a & SEK_PAGEM))) = (UINT16) BURN_ENDIAN_SWAP_INT16(d);
241 			return;
242 		}
243 	}
244 	pSekExt->WriteWord[(uintptr_t)pr](a, d);
245 }
246 
WriteWordROM(UINT32 a,UINT16 d)247 inline static void WriteWordROM(UINT32 a, UINT16 d)
248 {
249 	UINT8* pr;
250 
251 	a &= 0xFFFFFF;
252 
253 	pr = FIND_R(a);
254 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
255 		*((UINT16*)(pr + (a & SEK_PAGEM))) = (UINT16)d;
256 		return;
257 	}
258 	pSekExt->WriteWord[(uintptr_t)pr](a, d);
259 }
260 
m68k_read32(unsigned int a)261 unsigned int m68k_read32(unsigned int a)
262 {
263 	UINT8* pr;
264 
265 	a &= 0xFFFFFF;
266 
267 //	bprintf(PRINT_NORMAL, _T("read32 0x%08X\n"), a);
268 
269 	pr = FIND_R(a);
270 	if ((uintptr_t)pr >= SEK_MAXHANDLER)
271 	{
272 		UINT32 r = 0;
273 
274 		if (a & 1)
275 		{
276 			r  = M68KReadByte((a + 0)) * 0x1000000;
277 			r += M68KReadByte((a + 1)) * 0x10000;
278 			r += M68KReadByte((a + 2)) * 0x100;
279 			r += M68KReadByte((a + 3));
280 
281 			return BURN_ENDIAN_SWAP_INT32(r);
282 		}
283 		else
284 		{
285 			r = *((UINT32*)(pr + (a & SEK_PAGEM)));
286 			r = (r >> 16) | (r << 16);
287 
288 			return BURN_ENDIAN_SWAP_INT32(r);
289 		}
290 	}
291 	return pSekExt->ReadLong[(uintptr_t)pr](a);
292 }
293 
m68k_fetch32(unsigned int a)294 unsigned int m68k_fetch32(unsigned int a)
295 {
296 	UINT8* pr;
297 
298 	a &= 0xFFFFFF;
299 
300 //	bprintf(PRINT_NORMAL, _T("fetch32 0x%08X\n"), a);
301 
302 	pr = FIND_F(a);
303 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
304 		UINT32 r = *((UINT32*)(pr + (a & SEK_PAGEM)));
305 		r = (r >> 16) | (r << 16);
306 		return BURN_ENDIAN_SWAP_INT32(r);
307 	}
308 	return pSekExt->ReadLong[(uintptr_t)pr](a);
309 }
310 
m68k_write32(unsigned int a,unsigned int d)311 void m68k_write32(unsigned int a, unsigned int d)
312 {
313 	UINT8* pr;
314 
315 	a &= 0xFFFFFF;
316 
317 //	bprintf(PRINT_NORMAL, _T("write32 0x%08X\n"), a);
318 
319 	pr = FIND_W(a);
320 	if ((uintptr_t)pr >= SEK_MAXHANDLER)
321 	{
322 		if (a & 1)
323 		{
324 			//	bprintf(PRINT_NORMAL, _T("write32 0x%08X 0x%8.8x\n"), a,d);
325 
326 			d = BURN_ENDIAN_SWAP_INT32(d);
327 
328 			M68KWriteByte((a + 0), d / 0x1000000);
329 			M68KWriteByte((a + 1), d / 0x10000);
330 			M68KWriteByte((a + 2), d / 0x100);
331 			M68KWriteByte((a + 3), d);
332 
333 			return;
334 		}
335 		else
336 		{
337 			d = (d >> 16) | (d << 16);
338 			*((UINT32*)(pr + (a & SEK_PAGEM))) = BURN_ENDIAN_SWAP_INT32(d);
339 
340 			return;
341 		}
342 	}
343 	pSekExt->WriteLong[(uintptr_t)pr](a, d);
344 }
345 
WriteLongROM(UINT32 a,UINT32 d)346 inline static void WriteLongROM(UINT32 a, UINT32 d)
347 {
348 	UINT8* pr;
349 
350 	a &= 0xFFFFFF;
351 
352 	pr = FIND_R(a);
353 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
354 		d = (d >> 16) | (d << 16);
355 		*((UINT32*)(pr + (a & SEK_PAGEM))) = d;
356 		return;
357 	}
358 	pSekExt->WriteLong[(uintptr_t)pr](a, d);
359 }
360 }
361 
362 #ifdef EMU_M68K
363 extern "C" {
M68KReadByte(UINT32 a)364 UINT32 __fastcall M68KReadByte(UINT32 a) { return (UINT32)m68k_read8(a); }
M68KReadWord(UINT32 a)365 UINT32 __fastcall M68KReadWord(UINT32 a) { return (UINT32)m68k_read16(a); }
M68KReadLong(UINT32 a)366 UINT32 __fastcall M68KReadLong(UINT32 a) { return m68k_read32(a); }
367 
M68KFetchByte(UINT32 a)368 UINT32 __fastcall M68KFetchByte(UINT32 a) { return (UINT32)m68k_fetch8(a); }
M68KFetchWord(UINT32 a)369 UINT32 __fastcall M68KFetchWord(UINT32 a) { return (UINT32)m68k_fetch16(a); }
M68KFetchLong(UINT32 a)370 UINT32 __fastcall M68KFetchLong(UINT32 a) { return m68k_fetch32(a); }
371 
M68KWriteByte(UINT32 a,UINT32 d)372 void __fastcall M68KWriteByte(UINT32 a, UINT32 d) { m68k_write8(a, d); }
M68KWriteWord(UINT32 a,UINT32 d)373 void __fastcall M68KWriteWord(UINT32 a, UINT32 d) { m68k_write16(a, d); }
M68KWriteLong(UINT32 a,UINT32 d)374 void __fastcall M68KWriteLong(UINT32 a, UINT32 d) { m68k_write32(a, d); }
375 }
376 #endif
377 
378 // ----------------------------------------------------------------------------
379 // Memory accesses (non-emu specific)
380 
SekReadByte(UINT32 a)381 UINT32 SekReadByte(UINT32 a) { return (UINT32)m68k_read8(a); }
SekReadWord(UINT32 a)382 UINT32 SekReadWord(UINT32 a) { return (UINT32)m68k_read16(a); }
SekReadLong(UINT32 a)383 UINT32 SekReadLong(UINT32 a) { return m68k_read32(a); }
384 
SekFetchByte(UINT32 a)385 UINT32 SekFetchByte(UINT32 a) { return (UINT32)m68k_fetch8(a); }
SekFetchWord(UINT32 a)386 UINT32 SekFetchWord(UINT32 a) { return (UINT32)m68k_fetch16(a); }
SekFetchLong(UINT32 a)387 UINT32 SekFetchLong(UINT32 a) { return m68k_fetch32(a); }
388 
SekWriteByte(UINT32 a,UINT8 d)389 void SekWriteByte(UINT32 a, UINT8 d) { m68k_write8(a, d); }
SekWriteWord(UINT32 a,UINT16 d)390 void SekWriteWord(UINT32 a, UINT16 d) { m68k_write16(a, d); }
SekWriteLong(UINT32 a,UINT32 d)391 void SekWriteLong(UINT32 a, UINT32 d) { m68k_write32(a, d); }
392 
SekWriteByteROM(UINT32 a,UINT8 d)393 void SekWriteByteROM(UINT32 a, UINT8 d) { WriteByteROM(a, d); }
SekWriteWordROM(UINT32 a,UINT16 d)394 void SekWriteWordROM(UINT32 a, UINT16 d) { WriteWordROM(a, d); }
SekWriteLongROM(UINT32 a,UINT32 d)395 void SekWriteLongROM(UINT32 a, UINT32 d) { WriteLongROM(a, d); }
396 
397 // ----------------------------------------------------------------------------
398 // Callbacks for C68K
399 
400 #ifdef EMU_C68K
m68k_checkpc(UINT32 pc)401 extern "C" unsigned int m68k_checkpc(UINT32 pc)
402 {
403 	pc -= c68k[nSekActive].membase; // Get real pc
404 	pc &= 0xffffff;
405 
406 	c68k[nSekActive].membase = (uintptr_t)FIND_F(pc) - (pc & ~SEK_PAGEM);
407 
408 	return c68k[nSekActive].membase + pc;
409 }
410 
C68KIRQAcknowledge(INT32 nIRQ)411 extern "C" INT32 C68KIRQAcknowledge(INT32 nIRQ)
412 {
413 	if (nSekIRQPending[nSekActive] & SEK_IRQSTATUS_AUTO) {
414 		c68k[nSekActive].irq = 0;
415 		nSekIRQPending[nSekActive] = 0;
416 	}
417 
418 	if (pSekExt->IrqCallback) {
419 		return pSekExt->IrqCallback(nIRQ);
420 	}
421 
422 	return CYCLONE_INT_ACK_AUTOVECTOR;
423 }
424 
C68KResetCallback()425 extern "C" void C68KResetCallback()
426 {
427 	if (pSekExt->ResetCallback) {
428 		pSekExt->ResetCallback();
429 	}
430 }
431 
C68KUnrecognizedCallback()432 extern "C" int C68KUnrecognizedCallback()
433 {
434 #if defined (FBA_DEBUG)
435 	bprintf(PRINT_NORMAL, _T("UnrecognizedCallback();\n"));
436 #endif
437 	return 0;
438 }
439 
C68KRTECallback()440 extern "C" void C68KRTECallback()
441 {
442 	if (pSekExt->RTECallback) {
443 		pSekExt->RTECallback();
444 	}
445 }
446 
C68KcmpildCallback(UINT32 val,INT32 reg)447 extern "C" void C68KcmpildCallback(UINT32 val, INT32 reg)
448 {
449 	if (pSekExt->CmpCallback) {
450 		pSekExt->CmpCallback(val, reg);
451 	}
452 }
453 
C68KTASCallback()454 extern "C" INT32 C68KTASCallback()
455 {
456 	if (pSekExt->TASCallback) {
457 		return pSekExt->TASCallback();
458 	}
459 
460 	return 0; // disabled by default
461 }
462 #endif
463 
464 // ----------------------------------------------------------------------------
465 // Callbacks for Musashi
466 
467 #ifdef EMU_M68K
M68KIRQAcknowledge(INT32 nIRQ)468 extern "C" INT32 M68KIRQAcknowledge(INT32 nIRQ)
469 {
470 	if (nSekIRQPending[nSekActive] & SEK_IRQSTATUS_AUTO) {
471 		m68k_set_irq(0);
472 		nSekIRQPending[nSekActive] = 0;
473 	}
474 
475 	if (pSekExt->IrqCallback) {
476 		return pSekExt->IrqCallback(nIRQ);
477 	}
478 
479 	return M68K_INT_ACK_AUTOVECTOR;
480 }
481 
M68KResetCallback()482 extern "C" void M68KResetCallback()
483 {
484 	if (pSekExt->ResetCallback) {
485 		pSekExt->ResetCallback();
486 	}
487 }
488 
M68KRTECallback()489 extern "C" void M68KRTECallback()
490 {
491 	if (pSekExt->RTECallback) {
492 		pSekExt->RTECallback();
493 	}
494 }
495 
M68KcmpildCallback(UINT32 val,INT32 reg)496 extern "C" void M68KcmpildCallback(UINT32 val, INT32 reg)
497 {
498 	if (pSekExt->CmpCallback) {
499 		pSekExt->CmpCallback(val, reg);
500 	}
501 }
502 
M68KTASCallback()503 extern "C" INT32 M68KTASCallback()
504 {
505 	if (pSekExt->TASCallback) {
506 		return pSekExt->TASCallback();
507 	}
508 
509 	return 1; // enable by default
510 }
511 #endif
512 
513 // ----------------------------------------------------------------------------
514 // Initialisation/exit/reset
515 
516 #ifdef EMU_C68K
SekInitCPUC68K(INT32 nCount,INT32 nCPUType)517 static INT32 SekInitCPUC68K(INT32 nCount, INT32 nCPUType)
518 {
519 #if defined (FBA_DEBUG)
520 	bprintf(PRINT_NORMAL, _T("EMU_C68K: SekInitCPUC68K(%i, %x)\n"), nCount, nCPUType);
521 #endif
522 	if (nCPUType != 0x68000) {
523 		return 1;
524 	}
525 
526 	nSekCPUType[nCount] = nCPUType;
527 
528 	if (!bCycloneInited) {
529 #if defined (FBA_DEBUG)
530 		bprintf(PRINT_NORMAL, _T("EMU_C68K: CycloneInit\n"));
531 #endif
532 		CycloneInit();
533 #if defined (FBA_DEBUG)
534 		bprintf(PRINT_NORMAL, _T("EMU_C68K: CycloneInit OK\n"));
535 #endif
536 		bCycloneInited = true;
537 	}
538 	memset(&c68k[nCount], 0, sizeof(Cyclone));
539 	c68k[nCount].checkpc = m68k_checkpc;
540 	c68k[nCount].IrqCallback = C68KIRQAcknowledge;
541 	c68k[nCount].ResetCallback = C68KResetCallback;
542 	c68k[nCount].UnrecognizedCallback = C68KUnrecognizedCallback;
543 
544 	return 0;
545 }
546 #endif
547 
548 #ifdef EMU_M68K
SekInitCPUM68K(INT32 nCount,INT32 nCPUType)549 static INT32 SekInitCPUM68K(INT32 nCount, INT32 nCPUType)
550 {
551 #if defined (FBA_DEBUG)
552 	bprintf(PRINT_NORMAL, _T("EMU_M68K: SekInitCPUM68K(%i, %x)\n"), nCount, nCPUType);
553 #endif
554 	nSekCPUType[nCount] = nCPUType;
555 
556 	switch (nCPUType) {
557 		case 0x68000:
558 			m68k_set_cpu_type(M68K_CPU_TYPE_68000);
559 			break;
560 		case 0x68010:
561 			m68k_set_cpu_type(M68K_CPU_TYPE_68010);
562 			break;
563 		case 0x68EC020:
564 			m68k_set_cpu_type(M68K_CPU_TYPE_68EC020);
565 			break;
566 		default:
567 			return 1;
568 	}
569 
570 	nSekM68KContextSize[nCount] = m68k_context_size();
571 	SekM68KContext[nCount] = (INT8*)malloc(nSekM68KContextSize[nCount]);
572 	if (SekM68KContext[nCount] == NULL) {
573 		return 1;
574 	}
575 	memset(SekM68KContext[nCount], 0, nSekM68KContextSize[nCount]);
576 	m68k_get_context(SekM68KContext[nCount]);
577 
578 	return 0;
579 }
580 #endif
581 
SekNewFrame()582 void SekNewFrame()
583 {
584 #if defined FBA_DEBUG
585 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekNewFrame called without init\n"));
586 #endif
587 
588 	for (INT32 i = 0; i <= nSekCount; i++) {
589 		nSekCycles[i] = 0;
590 	}
591 
592 	nSekCyclesTotal = 0;
593 }
594 
SekSetCyclesScanline(INT32 nCycles)595 void SekSetCyclesScanline(INT32 nCycles)
596 {
597 #if defined FBA_DEBUG
598 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekSetCyclesScanline called without init\n"));
599 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekSetCyclesScanline called when no CPU open\n"));
600 #endif
601 
602 	nSekCyclesScanline = nCycles;
603 }
604 
SekCheatRead(UINT32 a)605 UINT8 SekCheatRead(UINT32 a)
606 {
607 	return SekReadByte(a);
608 }
609 
SekInit(INT32 nCount,INT32 nCPUType)610 INT32 SekInit(INT32 nCount, INT32 nCPUType)
611 {
612 	DebugCPU_SekInitted = 1;
613 
614 	struct SekExt* ps = NULL;
615 
616 /*#if !defined BUILD_A68K
617 	bBurnUseASMCPUEmulation = false;
618 #endif*/
619 
620 	if (nSekActive >= 0) {
621 		SekClose();
622 		nSekActive = -1;
623 	}
624 
625 	if (nCount > nSekCount) {
626 		nSekCount = nCount;
627 	}
628 
629 	// Allocate cpu extenal data (memory map etc)
630 	SekExt[nCount] = (struct SekExt*)malloc(sizeof(struct SekExt));
631 	if (SekExt[nCount] == NULL) {
632 		SekExit();
633 		return 1;
634 	}
635 	memset(SekExt[nCount], 0, sizeof(struct SekExt));
636 
637 	// Put in default memory handlers
638 	ps = SekExt[nCount];
639 
640 	for (INT32 j = 0; j < SEK_MAXHANDLER; j++) {
641 		ps->ReadByte[j]  = DefReadByte;
642 		ps->WriteByte[j] = DefWriteByte;
643 	}
644 
645 	ps->ReadWord[0]  = DefReadWord0;
646 	ps->WriteWord[0] = DefWriteWord0;
647 	ps->ReadLong[0]  = DefReadLong0;
648 	ps->WriteLong[0] = DefWriteLong0;
649 
650 #if SEK_MAXHANDLER >= 2
651 	ps->ReadWord[1]  = DefReadWord1;
652 	ps->WriteWord[1] = DefWriteWord1;
653 	ps->ReadLong[1]  = DefReadLong1;
654 	ps->WriteLong[1] = DefWriteLong1;
655 #endif
656 
657 #if SEK_MAXHANDLER >= 3
658 	ps->ReadWord[2]  = DefReadWord2;
659 	ps->WriteWord[2] = DefWriteWord2;
660 	ps->ReadLong[2]  = DefReadLong2;
661 	ps->WriteLong[2] = DefWriteLong2;
662 #endif
663 
664 #if SEK_MAXHANDLER >= 4
665 	ps->ReadWord[3]  = DefReadWord3;
666 	ps->WriteWord[3] = DefWriteWord3;
667 	ps->ReadLong[3]  = DefReadLong3;
668 	ps->WriteLong[3] = DefWriteLong3;
669 #endif
670 
671 #if SEK_MAXHANDLER >= 5
672 	ps->ReadWord[4]  = DefReadWord4;
673 	ps->WriteWord[4] = DefWriteWord4;
674 	ps->ReadLong[4]  = DefReadLong4;
675 	ps->WriteLong[4] = DefWriteLong4;
676 #endif
677 
678 #if SEK_MAXHANDLER >= 6
679 	ps->ReadWord[5]  = DefReadWord5;
680 	ps->WriteWord[5] = DefWriteWord5;
681 	ps->ReadLong[5]  = DefReadLong5;
682 	ps->WriteLong[5] = DefWriteLong5;
683 #endif
684 
685 #if SEK_MAXHANDLER >= 7
686 	ps->ReadWord[6]  = DefReadWord6;
687 	ps->WriteWord[6] = DefWriteWord6;
688 	ps->ReadLong[6]  = DefReadLong6;
689 	ps->WriteLong[6] = DefWriteLong6;
690 #endif
691 
692 #if SEK_MAXHANDLER >= 8
693 	ps->ReadWord[7]  = DefReadWord7;
694 	ps->WriteWord[7] = DefWriteWord7;
695 	ps->ReadLong[7]  = DefReadLong7;
696 	ps->WriteLong[7] = DefWriteLong7;
697 #endif
698 
699 #if SEK_MAXHANDLER >= 9
700 	ps->ReadWord[8]  = DefReadWord8;
701 	ps->WriteWord[8] = DefWriteWord8;
702 	ps->ReadLong[8]  = DefReadLong8;
703 	ps->WriteLong[8] = DefWriteLong8;
704 #endif
705 
706 #if SEK_MAXHANDLER >= 10
707 	ps->ReadWord[9]  = DefReadWord9;
708 	ps->WriteWord[9] = DefWriteWord9;
709 	ps->ReadLong[9]  = DefReadLong9;
710 	ps->WriteLong[9] = DefWriteLong9;
711 #endif
712 
713 #if SEK_MAXHANDLER >= 11
714 	for (int j = 10; j < SEK_MAXHANDLER; j++) {
715 		ps->ReadWord[j]  = DefReadWord0;
716 		ps->WriteWord[j] = DefWriteWord0;
717 		ps->ReadLong[j]  = DefReadLong0;
718 		ps->WriteLong[j] = DefWriteLong0;
719 	}
720 #endif
721 
722 	// Map the normal memory handlers
723 	SekDbgDisableBreakpoints();
724 
725 #ifdef EMU_C68K
726 	if ((nSekCpuCore == SEK_CORE_C68K) && nCPUType == 0x68000) {
727 		if (SekInitCPUC68K(nCount, nCPUType)) {
728 			SekExit();
729 			return 1;
730 		}
731 	} else {
732 #endif
733 
734 #ifdef EMU_M68K
735 		m68k_init();
736 		if (SekInitCPUM68K(nCount, nCPUType)) {
737 			SekExit();
738 			return 1;
739 		}
740 #endif
741 
742 #ifdef EMU_C68K
743 	}
744 #endif
745 
746 	nSekCycles[nCount] = 0;
747 	nSekIRQPending[nCount] = 0;
748 
749 	nSekCyclesTotal = 0;
750 	nSekCyclesScanline = 0;
751 
752 	CpuCheatRegister(nCount, &SekConfig);
753 
754 	return 0;
755 }
756 
757 #ifdef EMU_M68K
SekCPUExitM68K(INT32 i)758 static void SekCPUExitM68K(INT32 i)
759 {
760 		if(SekM68KContext[i]) {
761 			free(SekM68KContext[i]);
762 			SekM68KContext[i] = NULL;
763 		}
764 }
765 #endif
766 
SekExit()767 INT32 SekExit()
768 {
769 	// Deallocate cpu extenal data (memory map etc)
770 	for (INT32 i = 0; i <= nSekCount; i++) {
771 
772 #ifdef EMU_M68K
773 		if ((nSekCpuCore == SEK_CORE_C68K) && nSekCPUType[i] == 0x68000) {
774 #if defined (FBA_DEBUG)
775 			bprintf(PRINT_NORMAL, _T("EMU_C68K: SekExit\n"));
776 #endif
777 		} else {
778 #if defined (FBA_DEBUG)
779 			bprintf(PRINT_NORMAL, _T("EMU_M68K: SekExit\n"));
780 #endif
781 			SekCPUExitM68K(i);
782 		}
783 #endif
784 
785 		// Deallocate other context data
786 		if (SekExt[i]) {
787 			free(SekExt[i]);
788 			SekExt[i] = NULL;
789 		}
790 	}
791 
792 	pSekExt = NULL;
793 
794 	nSekActive = -1;
795 	nSekCount = -1;
796 
797 	DebugCPU_SekInitted = 0;
798 
799 	return 0;
800 }
801 
SekReset()802 void SekReset()
803 {
804 #ifdef EMU_C68K
805 	if ((nSekCpuCore == SEK_CORE_C68K) && nSekCPUType[nSekActive] == 0x68000) {
806 #if defined (FBA_DEBUG)
807 		bprintf(PRINT_NORMAL, _T("EMU_C68K: SekReset\n"));
808 #endif
809 		memset(&c68k[nSekActive], 0, 22 * 4); // clear all regs
810 		c68k[nSekActive].state_flags	= 0;
811 		c68k[nSekActive].srh			= 0x27; // Supervisor mode
812 		c68k[nSekActive].a[7]			= m68k_fetch32(0); // Stack Pointer
813 		c68k[nSekActive].membase		= 0;
814 		c68k[nSekActive].pc				= c68k[nSekActive].checkpc(m68k_fetch32(4));
815 	} else {
816 #endif
817 
818 #ifdef EMU_M68K
819 #if defined (FBA_DEBUG)
820 		bprintf(PRINT_NORMAL, _T("EMU_M68K: SekReset\n"));
821 #endif
822 		m68k_pulse_reset();
823 #endif
824 
825 #ifdef EMU_C68K
826 	}
827 #endif
828 
829 }
830 
831 // ----------------------------------------------------------------------------
832 // Control the active CPU
833 
834 // Open a CPU
SekOpen(const INT32 i)835 void SekOpen(const INT32 i)
836 {
837 	if (i != nSekActive) {
838 		nSekActive = i;
839 
840 		pSekExt = SekExt[nSekActive];						// Point to cpu context
841 
842 #ifdef EMU_C68K
843 		if ((nSekCpuCore == SEK_CORE_C68K) && nSekCPUType[nSekActive] == 0x68000) {
844 			//...
845 		} else {
846 #endif
847 
848 #ifdef EMU_M68K
849 			m68k_set_context(SekM68KContext[nSekActive]);
850 #endif
851 
852 #ifdef EMU_C68K
853 		}
854 #endif
855 
856 		nSekCyclesTotal = nSekCycles[nSekActive];
857 	}
858 }
859 
860 // Close the active cpu
SekClose()861 void SekClose()
862 {
863 #ifdef EMU_C68K
864 	if ((nSekCpuCore == SEK_CORE_C68K) && nSekCPUType[nSekActive] == 0x68000) {
865 		//...
866 	} else {
867 #endif
868 
869 #ifdef EMU_M68K
870 		m68k_get_context(SekM68KContext[nSekActive]);
871 #endif
872 
873 #ifdef EMU_C68K
874 	}
875 #endif
876 
877 	nSekCycles[nSekActive] = nSekCyclesTotal;
878 
879 	nSekActive = -1;
880 }
881 
882 // Get the current CPU
SekGetActive()883 INT32 SekGetActive()
884 {
885 	return nSekActive;
886 }
887 
888 // For Megadrive - check if the vdp controlport should set IRQ
SekShouldInterrupt(void)889 INT32 SekShouldInterrupt(void)
890 {
891 	if(nSekCpuCore == SEK_CORE_M68K) {
892 		return m68k_check_shouldinterrupt();
893 	} else {
894 		return 0;
895 	}
896 }
897 
898 // Set the status of an IRQ line on the active CPU
SekSetIRQLine(const INT32 line,const INT32 nstatus)899 void SekSetIRQLine(const INT32 line, const INT32 nstatus)
900 {
901 	INT32 status = nstatus << 12; // needed for compatibility
902 
903 	if (status) {
904 		nSekIRQPending[nSekActive] = line | status;
905 
906 #ifdef EMU_C68K
907 		//printf("EMU_C68K: SekSetIRQLine\n");
908 		if ((nSekCpuCore == SEK_CORE_C68K) && nSekCPUType[nSekActive] == 0x68000) {
909 			nSekCyclesTotal += (nSekCyclesToDo - nSekCyclesDone) - c68k[nSekActive].cycles;
910 			nSekCyclesDone += (nSekCyclesToDo - nSekCyclesDone) - c68k[nSekActive].cycles;
911 
912 			c68k[nSekActive].irq = line;
913 			c68k[nSekActive].cycles = nSekCyclesToDo = -1;
914 		} else {
915 #endif
916 
917 #ifdef EMU_M68K
918 			//printf("EMU_M68K: SekSetIRQLine\n");
919 			m68k_set_irq(line);
920 #endif
921 
922 #ifdef EMU_C68K
923 		}
924 #endif
925 
926 		return;
927 	}
928 
929 	nSekIRQPending[nSekActive] = 0;
930 
931 #ifdef EMU_C68K
932 	if ((nSekCpuCore == SEK_CORE_C68K) && nSekCPUType[nSekActive] == 0x68000) {
933 		c68k[nSekActive].irq = 0;
934 	} else {
935 #endif
936 
937 #ifdef EMU_M68K
938 		m68k_set_irq(0);
939 #endif
940 
941 #ifdef EMU_C68K
942 	}
943 #endif
944 
945 }
946 
947 // Adjust the active CPU's timeslice
SekRunAdjust(const INT32 nCycles)948 void SekRunAdjust(const INT32 nCycles)
949 {
950 #ifndef EMU_C68K
951 	INT32 count = m68k_ICount;
952 #else
953 	INT32 count = nSekCpuCore ==
954 				  SEK_CORE_C68K && nSekCPUType[nSekActive] == 0x68000 ?
955 				  c68k[nSekActive].cycles : m68k_ICount;
956 #endif
957 	if (nCycles < 0 && count < -nCycles) {
958 		SekRunEnd();
959 		return;
960 	}
961 
962 #ifdef EMU_C68K
963 	if ((nSekCpuCore == SEK_CORE_C68K) && nSekCPUType[nSekActive] == 0x68000) {
964 		//printf("EMU_C68K: SekRunAdjust\n");
965 		c68k[nSekActive].cycles += nCycles;
966 		nSekCyclesToDo += nCycles;
967 		nSekCyclesSegment += nCycles;
968 	} else {
969 #endif
970 
971 #ifdef EMU_M68K
972 		//printf("EMU_M68K: SekRunAdjust\n");
973 		nSekCyclesToDo += nCycles;
974 		m68k_modify_timeslice(nCycles);
975 #endif
976 
977 #ifdef EMU_C68K
978 	}
979 #endif
980 
981 }
982 
983 // End the active CPU's timeslice
SekRunEnd()984 void SekRunEnd()
985 {
986 #ifdef EMU_C68K
987 	if ((nSekCpuCore == SEK_CORE_C68K) && nSekCPUType[nSekActive] == 0x68000) {
988 		nSekCyclesTotal += (nSekCyclesToDo - nSekCyclesDone) - c68k[nSekActive].cycles;
989 		nSekCyclesDone += (nSekCyclesToDo - nSekCyclesDone) - c68k[nSekActive].cycles;
990 		nSekCyclesSegment = nSekCyclesDone;
991 		c68k[nSekActive].cycles = nSekCyclesToDo = -1;
992 	} else {
993 #endif
994 
995 #ifdef EMU_M68K
996 		m68k_end_timeslice();
997 #endif
998 
999 #ifdef EMU_C68K
1000 	}
1001 #endif
1002 
1003 }
1004 
1005 // Run the active CPU
SekRun(const INT32 nCycles)1006 INT32 SekRun(const INT32 nCycles)
1007 {
1008 #ifdef EMU_C68K
1009 	if ((nSekCpuCore == SEK_CORE_C68K) && nSekCPUType[nSekActive] == 0x68000) {
1010 		//printf("EMU_C68K: SekRun\n");
1011 		nSekCyclesDone = 0;
1012 		nSekCyclesSegment = nCycles;
1013 		do {
1014 			c68k[nSekActive].cycles = nSekCyclesToDo = nSekCyclesSegment - nSekCyclesDone;
1015 
1016 			if (c68k[nSekActive].irq == 0x80) {						// Cpu is in stopped state till interrupt
1017 				nSekCyclesDone = nSekCyclesSegment;
1018 				nSekCyclesTotal += nSekCyclesSegment;
1019 			} else {
1020 				CycloneRun(&c68k[nSekActive]);
1021 				nSekCyclesDone += nSekCyclesToDo - c68k[nSekActive].cycles;
1022 				nSekCyclesTotal += nSekCyclesToDo - c68k[nSekActive].cycles;
1023 			}
1024 		} while (nSekCyclesDone < nSekCyclesSegment);
1025 
1026 		nSekCyclesSegment = nSekCyclesDone;
1027 		nSekCyclesToDo = c68k[nSekActive].cycles = -1;
1028 		nSekCyclesDone = 0;
1029 
1030 		return nSekCyclesSegment;								// Return the number of cycles actually done
1031 	} else {
1032 #endif
1033 
1034 #ifdef EMU_M68K
1035 		//printf("EMU_M68K: SekRun\n");
1036 		nSekCyclesToDo = nCycles;
1037 		nSekCyclesSegment = m68k_execute(nCycles);
1038 		nSekCyclesTotal += nSekCyclesSegment;
1039 		nSekCyclesToDo = m68k_ICount = -1;
1040 		return nSekCyclesSegment;
1041 #endif
1042 
1043 #ifdef EMU_C68K
1044 	}
1045 #endif
1046 
1047 }
1048 
1049 // ----------------------------------------------------------------------------
1050 // Breakpoint support
1051 
SekDbgDisableBreakpoints()1052 void SekDbgDisableBreakpoints()
1053 {
1054 #if defined FBA_DEBUG && defined EMU_M68K
1055 		m68k_set_instr_hook_callback(NULL);
1056 
1057 		M68KReadByteDebug = M68KReadByte;
1058 		M68KReadWordDebug = M68KReadWord;
1059 		M68KReadLongDebug = M68KReadLong;
1060 
1061 		M68KWriteByteDebug = M68KWriteByte;
1062 		M68KWriteWordDebug = M68KWriteWord;
1063 		M68KWriteLongDebug = M68KWriteLong;
1064 #endif
1065 
1066 #ifdef EMU_A68K
1067 	a68k_memory_intf = a68k_inter_normal;
1068 #endif
1069 
1070 	//mame_debug = 0;
1071 }
1072 
1073 // ----------------------------------------------------------------------------
1074 // Memory map setup
1075 
1076 // Note - each page is 1 << SEK_BITS.
SekMapMemory(UINT8 * pMemory,UINT32 nStart,UINT32 nEnd,INT32 nType)1077 INT32 SekMapMemory(UINT8* pMemory, UINT32 nStart, UINT32 nEnd, INT32 nType)
1078 {
1079 	UINT8* Ptr = pMemory - nStart;
1080 	UINT8** pMemMap = pSekExt->MemMap + (nStart >> SEK_SHIFT);
1081 
1082 	// Special case for ROM banks
1083 	if (nType == MAP_ROM) {
1084 		for (UINT32 i = (nStart & ~SEK_PAGEM); i <= nEnd; i += SEK_PAGE_SIZE, pMemMap++) {
1085 			pMemMap[0]			  = Ptr + i;
1086 			pMemMap[SEK_WADD * 2] = Ptr + i;
1087 		}
1088 
1089 		return 0;
1090 	}
1091 
1092 	for (UINT32 i = (nStart & ~SEK_PAGEM); i <= nEnd; i += SEK_PAGE_SIZE, pMemMap++) {
1093 
1094 		if (nType & MAP_READ) {					// Read
1095 			pMemMap[0]			  = Ptr + i;
1096 		}
1097 		if (nType & MAP_WRITE) {					// Write
1098 			pMemMap[SEK_WADD]	  = Ptr + i;
1099 		}
1100 		if (nType & MAP_FETCH) {					// Fetch
1101 			pMemMap[SEK_WADD * 2] = Ptr + i;
1102 		}
1103 	}
1104 
1105 	return 0;
1106 }
1107 
SekMapHandler(uintptr_t nHandler,UINT32 nStart,UINT32 nEnd,INT32 nType)1108 INT32 SekMapHandler(uintptr_t nHandler, UINT32 nStart, UINT32 nEnd, INT32 nType)
1109 {
1110 	UINT8** pMemMap = pSekExt->MemMap + (nStart >> SEK_SHIFT);
1111 
1112 	// Add to memory map
1113 	for (UINT32 i = (nStart & ~SEK_PAGEM); i <= nEnd; i += SEK_PAGE_SIZE, pMemMap++) {
1114 
1115 		if (nType & MAP_READ) {					// Read
1116 			pMemMap[0]			  = (UINT8*)nHandler;
1117 		}
1118 		if (nType & MAP_WRITE) {					// Write
1119 			pMemMap[SEK_WADD]	  = (UINT8*)nHandler;
1120 		}
1121 		if (nType & MAP_FETCH) {					// Fetch
1122 			pMemMap[SEK_WADD * 2] = (UINT8*)nHandler;
1123 		}
1124 	}
1125 
1126 	return 0;
1127 }
1128 
1129 // Set callbacks
SekSetResetCallback(pSekResetCallback pCallback)1130 INT32 SekSetResetCallback(pSekResetCallback pCallback)
1131 {
1132 	pSekExt->ResetCallback = pCallback;
1133 
1134 	return 0;
1135 }
1136 
SekSetRTECallback(pSekRTECallback pCallback)1137 INT32 SekSetRTECallback(pSekRTECallback pCallback)
1138 {
1139 	pSekExt->RTECallback = pCallback;
1140 
1141 	return 0;
1142 }
1143 
SekSetIrqCallback(pSekIrqCallback pCallback)1144 INT32 SekSetIrqCallback(pSekIrqCallback pCallback)
1145 {
1146 	pSekExt->IrqCallback = pCallback;
1147 
1148 	return 0;
1149 }
1150 
SekSetCmpCallback(pSekCmpCallback pCallback)1151 INT32 SekSetCmpCallback(pSekCmpCallback pCallback)
1152 {
1153 	pSekExt->CmpCallback = pCallback;
1154 
1155 	return 0;
1156 }
1157 
SekSetTASCallback(pSekTASCallback pCallback)1158 INT32 SekSetTASCallback(pSekTASCallback pCallback)
1159 {
1160 	pSekExt->TASCallback = pCallback;
1161 
1162 	return 0;
1163 }
1164 
1165 // Set handlers
SekSetReadByteHandler(INT32 i,pSekReadByteHandler pHandler)1166 INT32 SekSetReadByteHandler(INT32 i, pSekReadByteHandler pHandler)
1167 {
1168 	if (i >= SEK_MAXHANDLER) {
1169 		return 1;
1170 	}
1171 
1172 	pSekExt->ReadByte[i] = pHandler;
1173 
1174 	return 0;
1175 }
1176 
SekSetWriteByteHandler(INT32 i,pSekWriteByteHandler pHandler)1177 INT32 SekSetWriteByteHandler(INT32 i, pSekWriteByteHandler pHandler)
1178 {
1179 	if (i >= SEK_MAXHANDLER) {
1180 		return 1;
1181 	}
1182 
1183 	pSekExt->WriteByte[i] = pHandler;
1184 
1185 	return 0;
1186 }
1187 
SekSetReadWordHandler(INT32 i,pSekReadWordHandler pHandler)1188 INT32 SekSetReadWordHandler(INT32 i, pSekReadWordHandler pHandler)
1189 {
1190 	if (i >= SEK_MAXHANDLER) {
1191 		return 1;
1192 	}
1193 
1194 	pSekExt->ReadWord[i] = pHandler;
1195 
1196 	return 0;
1197 }
1198 
SekSetWriteWordHandler(INT32 i,pSekWriteWordHandler pHandler)1199 INT32 SekSetWriteWordHandler(INT32 i, pSekWriteWordHandler pHandler)
1200 {
1201 	if (i >= SEK_MAXHANDLER) {
1202 		return 1;
1203 	}
1204 
1205 	pSekExt->WriteWord[i] = pHandler;
1206 
1207 	return 0;
1208 }
1209 
SekSetReadLongHandler(INT32 i,pSekReadLongHandler pHandler)1210 INT32 SekSetReadLongHandler(INT32 i, pSekReadLongHandler pHandler)
1211 {
1212 	if (i >= SEK_MAXHANDLER) {
1213 		return 1;
1214 	}
1215 
1216 	pSekExt->ReadLong[i] = pHandler;
1217 
1218 	return 0;
1219 }
1220 
SekSetWriteLongHandler(INT32 i,pSekWriteLongHandler pHandler)1221 INT32 SekSetWriteLongHandler(INT32 i, pSekWriteLongHandler pHandler)
1222 {
1223 	if (i >= SEK_MAXHANDLER) {
1224 		return 1;
1225 	}
1226 
1227 	pSekExt->WriteLong[i] = pHandler;
1228 
1229 	return 0;
1230 }
1231 
1232 // ----------------------------------------------------------------------------
1233 // Query register values
1234 
1235 #ifdef EMU_C68K
SekGetPC(INT32 n)1236 UINT32 SekGetPC(INT32 n)
1237 #else
1238 UINT32 SekGetPC(INT32)
1239 #endif
1240 {
1241 #ifdef EMU_C68K
1242 	if ((nSekCpuCore == SEK_CORE_C68K) && nSekCPUType[nSekActive] == 0x68000) {
1243 		return c68k[nSekActive].pc-c68k[nSekActive].membase;
1244 	} else {
1245 #endif
1246 
1247 #ifdef EMU_M68K
1248 		return m68k_get_reg(NULL, M68K_REG_PC);
1249 #else
1250 		return 0;
1251 #endif
1252 
1253 #ifdef EMU_C68K
1254 	}
1255 #endif
1256 
1257 }
1258 
SekDbgGetCPUType()1259 INT32 SekDbgGetCPUType()
1260 {
1261 	switch (nSekCPUType[nSekActive]) {
1262 		case 0:
1263 		case 0x68000:
1264 			return M68K_CPU_TYPE_68000;
1265 		case 0x68010:
1266 			return M68K_CPU_TYPE_68010;
1267 		case 0x68EC020:
1268 			return M68K_CPU_TYPE_68EC020;
1269 	}
1270 
1271 	return 0;
1272 }
1273 
SekDbgGetPendingIRQ()1274 INT32 SekDbgGetPendingIRQ()
1275 {
1276 	return nSekIRQPending[nSekActive] & 7;
1277 }
1278 
SekDbgGetRegister(SekRegister nRegister)1279 UINT32 SekDbgGetRegister(SekRegister nRegister)
1280 {
1281 	return 0;
1282 }
1283 
SekDbgSetRegister(SekRegister nRegister,UINT32 nValue)1284 bool SekDbgSetRegister(SekRegister nRegister, UINT32 nValue)
1285 {
1286 	return false;
1287 }
1288 
1289 // ----------------------------------------------------------------------------
1290 // Savestate support
1291 
1292 UINT8 cyclone_buffer[128];
1293 
SekScan(INT32 nAction)1294 INT32 SekScan(INT32 nAction)
1295 {
1296 	// Scan the 68000 states
1297 	struct BurnArea ba;
1298 
1299 	if ((nAction & ACB_DRIVER_DATA) == 0) {
1300 		return 1;
1301 	}
1302 
1303 	memset(&ba, 0, sizeof(ba));
1304 
1305 	nSekActive = -1;
1306 
1307 	for (INT32 i = 0; i <= nSekCount; i++) {
1308 
1309 		char szName[] = "MC68000 #n";
1310 		szName[9] = '0' + i;
1311 
1312 		SCAN_VAR(nSekCPUType[i]);
1313 		SCAN_VAR(nSekIRQPending[i]);
1314 		SCAN_VAR(nSekCycles[i]);
1315 
1316 #ifdef EMU_C68K
1317 		if ((nSekCpuCore == SEK_CORE_C68K) && nSekCPUType[i] == 0x68000) {
1318 
1319 			ba.nLen = 128;
1320 			ba.szName = szName;
1321 
1322 			if (nAction & ACB_READ) { // save
1323 				memset(cyclone_buffer, 0, 128);
1324 				CyclonePack(&c68k[i], cyclone_buffer);
1325 				ba.Data = &cyclone_buffer;
1326 				BurnAcb(&ba);
1327 			} else if (nAction & ACB_WRITE) { // load
1328 				memset(cyclone_buffer, 0, 128);
1329 				ba.Data = &cyclone_buffer;
1330 				BurnAcb(&ba);
1331 				int sekActive = nSekActive; // CycloneUnpack needs m68k_checkpc which needs nSekActive set to current cpu
1332 				nSekActive = i; // CycloneUnpack needs m68k_checkpc which needs nSekActive set to current cpu
1333 				CycloneUnpack(&c68k[i], cyclone_buffer);
1334 				nSekActive = sekActive;
1335 			}
1336 		} else {
1337 #endif
1338 #ifdef EMU_M68K
1339 			if (nSekCPUType[i] != 0) {
1340 				ba.Data = SekM68KContext[i];
1341 				// for savestate portability: preserve our cpu's pointers, they are set up in DrvInit() and can be specific to different systems.
1342 				// Therefore we scan the cpu context structure up until right before the pointers
1343 				ba.nLen = m68k_context_size_no_pointers();
1344 				ba.szName = szName;
1345 				BurnAcb(&ba);
1346 			}
1347 #endif
1348 #ifdef EMU_C68K
1349 		}
1350 #endif
1351 	}
1352 
1353 	return 0;
1354 }
1355