1 // 680x0 (Sixty Eight K) Interface
2 #include "burnint.h"
3 #include "m68000_intf.h"
4 #include "m68000_debug.h"
5 
6 #ifdef EMU_M68K
7 INT32 nSekM68KContextSize[SEK_MAX];
8 INT8* SekM68KContext[SEK_MAX];
9 #endif
10 
11 INT32 nSekCount = -1;							// Number of allocated 68000s
12 struct SekExt *SekExt[SEK_MAX] = { NULL, }, *pSekExt = NULL;
13 
14 INT32 nSekActive = -1;								// The cpu which is currently being emulated
15 INT32 nSekCyclesTotal, nSekCyclesScanline, nSekCyclesSegment, nSekCyclesDone, nSekCyclesToDo;
16 
17 INT32 nSekCPUType[SEK_MAX], nSekCycles[SEK_MAX], nSekIRQPending[SEK_MAX];
18 
19 cpu_core_config SekConfig =
20 {
21 	SekOpen,
22 	SekClose,
23 	SekCheatRead,
24 	SekWriteByteROM,
25 	SekGetActive,
26 	SekTotalCycles,
27 	SekNewFrame,
28 	SekRun,
29 	SekRunEnd,
30 	SekReset,
31 	0x1000000,
32 	0
33 };
34 
35 #if defined (FBA_DEBUG)
36 
37 void (*SekDbgBreakpointHandlerRead)(UINT32, INT32);
38 void (*SekDbgBreakpointHandlerFetch)(UINT32, INT32);
39 void (*SekDbgBreakpointHandlerWrite)(UINT32, INT32);
40 
41 UINT32 (*SekDbgFetchByteDisassembler)(UINT32);
42 UINT32 (*SekDbgFetchWordDisassembler)(UINT32);
43 UINT32 (*SekDbgFetchLongDisassembler)(UINT32);
44 
45 static struct { UINT32 address; INT32 id; } BreakpointDataRead[9]  = { { 0, 0 }, };
46 static struct { UINT32 address; INT32 id; } BreakpointDataWrite[9] = { { 0, 0 }, };
47 static struct { UINT32 address; INT32 id; } BreakpointFetch[9] = { { 0, 0 }, };
48 
49 #endif
50 
51 #if defined (EMU_A68K)
UpdateA68KContext()52 static void UpdateA68KContext()
53 {
54 	if (M68000_regs.srh & 20) {		// Supervisor mode
55 		M68000_regs.isp = M68000_regs.a[7];
56 	} else {						// User mode
57 		M68000_regs.usp = M68000_regs.a[7];
58 	}
59 
60 	M68000_regs.sr  = (M68000_regs.srh <<  8) & 0xFF00;	// T, S, M, I
61 	M68000_regs.sr |= (M68000_regs.xc  <<  4) & 0x0010;	// X
62 	M68000_regs.sr |= (M68000_regs.ccr >>  4) & 0x0008;	// N
63 	M68000_regs.sr |= (M68000_regs.ccr >>  4) & 0x0004;	// Z
64 	M68000_regs.sr |= (M68000_regs.ccr >> 10) & 0x0002;	// V
65 	M68000_regs.sr |= (M68000_regs.ccr      ) & 0x0001;	// C
66 }
67 
GetA68KSR()68 static UINT32 GetA68KSR()
69 {
70 	UpdateA68KContext();
71 
72 	return M68000_regs.sr;
73 }
74 
GetA68KISP()75 static UINT32 GetA68KISP()
76 {
77 	UpdateA68KContext();
78 
79 	return M68000_regs.isp;
80 }
81 
GetA68KUSP()82 static UINT32 GetA68KUSP()
83 {
84 	UpdateA68KContext();
85 
86 	return M68000_regs.usp;
87 }
88 #endif
89 
90 #if defined (FBA_DEBUG)
91 
CheckBreakpoint_R(UINT32 a,const UINT32 m)92 inline static void CheckBreakpoint_R(UINT32 a, const UINT32 m)
93 {
94 	a &= m;
95 
96 	for (INT32 i = 0; BreakpointDataRead[i].address; i++) {
97 		if ((BreakpointDataRead[i].address & m) == a) {
98 
99 #ifdef EMU_A68K
100 			UpdateA68KContext();
101 #endif
102 
103 			SekDbgBreakpointHandlerRead(a, BreakpointDataRead[i].id);
104 			return;
105 		}
106 	}
107 }
108 
CheckBreakpoint_W(UINT32 a,const UINT32 m)109 inline static void CheckBreakpoint_W(UINT32 a, const UINT32 m)
110 {
111 	a &= m;
112 
113 	for (INT32 i = 0; BreakpointDataWrite[i].address; i++) {
114 		if ((BreakpointDataWrite[i].address & m) == a) {
115 
116 #ifdef EMU_A68K
117 			UpdateA68KContext();
118 #endif
119 
120 			SekDbgBreakpointHandlerWrite(a, BreakpointDataWrite[i].id);
121 			return;
122 		}
123 	}
124 }
125 
CheckBreakpoint_PC(unsigned int)126 inline static void CheckBreakpoint_PC(unsigned int /*pc*/)
127 {
128 	for (INT32 i = 0; BreakpointFetch[i].address; i++) {
129 		if (BreakpointFetch[i].address == (UINT32)SekGetPC(-1)) {
130 
131 #ifdef EMU_A68K
132 			UpdateA68KContext();
133 #endif
134 
135 			SekDbgBreakpointHandlerFetch(SekGetPC(-1), BreakpointFetch[i].id);
136 			return;
137 		}
138 	}
139 }
140 
SingleStep_PC(unsigned int)141 inline static void SingleStep_PC(unsigned int /*pc*/)
142 {
143 #ifdef EMU_A68K
144 	UpdateA68KContext();
145 #endif
146 
147 	SekDbgBreakpointHandlerFetch(SekGetPC(-1), 0);
148 }
149 
150 #endif
151 
152 // ----------------------------------------------------------------------------
153 // Default memory access handlers
154 
DefReadByte(UINT32)155 UINT8 __fastcall DefReadByte(UINT32) { return 0; }
DefWriteByte(UINT32,UINT8)156 void __fastcall DefWriteByte(UINT32, UINT8) { }
157 
158 #define DEFWORDHANDLERS(i)																				\
159 	UINT16 __fastcall DefReadWord##i(UINT32 a) { SEK_DEF_READ_WORD(i, a) }				\
160 	void __fastcall DefWriteWord##i(UINT32 a, UINT16 d) { SEK_DEF_WRITE_WORD(i, a ,d) }
161 #define DEFLONGHANDLERS(i)																				\
162 	UINT32 __fastcall DefReadLong##i(UINT32 a) { SEK_DEF_READ_LONG(i, a) }					\
163 	void __fastcall DefWriteLong##i(UINT32 a, UINT32 d) { SEK_DEF_WRITE_LONG(i, a , d) }
164 
165 DEFWORDHANDLERS(0)
166 DEFLONGHANDLERS(0)
167 
168 #if SEK_MAXHANDLER >= 2
169  DEFWORDHANDLERS(1)
170  DEFLONGHANDLERS(1)
171 #endif
172 
173 #if SEK_MAXHANDLER >= 3
174  DEFWORDHANDLERS(2)
175  DEFLONGHANDLERS(2)
176 #endif
177 
178 #if SEK_MAXHANDLER >= 4
179  DEFWORDHANDLERS(3)
180  DEFLONGHANDLERS(3)
181 #endif
182 
183 #if SEK_MAXHANDLER >= 5
184  DEFWORDHANDLERS(4)
185  DEFLONGHANDLERS(4)
186 #endif
187 
188 #if SEK_MAXHANDLER >= 6
189  DEFWORDHANDLERS(5)
190  DEFLONGHANDLERS(5)
191 #endif
192 
193 #if SEK_MAXHANDLER >= 7
194  DEFWORDHANDLERS(6)
195  DEFLONGHANDLERS(6)
196 #endif
197 
198 #if SEK_MAXHANDLER >= 8
199  DEFWORDHANDLERS(7)
200  DEFLONGHANDLERS(7)
201 #endif
202 
203 #if SEK_MAXHANDLER >= 9
204  DEFWORDHANDLERS(8)
205  DEFLONGHANDLERS(8)
206 #endif
207 
208 #if SEK_MAXHANDLER >= 10
209  DEFWORDHANDLERS(9)
210  DEFLONGHANDLERS(9)
211 #endif
212 
213 // ----------------------------------------------------------------------------
214 // Memory access functions
215 
216 // Mapped Memory lookup (               for read)
217 #define FIND_R(x) pSekExt->MemMap[ x >> SEK_SHIFT]
218 // Mapped Memory lookup (+ SEK_WADD     for write)
219 #define FIND_W(x) pSekExt->MemMap[(x >> SEK_SHIFT) + SEK_WADD]
220 // Mapped Memory lookup (+ SEK_WADD * 2 for fetch)
221 #define FIND_F(x) pSekExt->MemMap[(x >> SEK_SHIFT) + SEK_WADD * 2]
222 
223 // Normal memory access functions
ReadByte(UINT32 a)224 inline static UINT8 ReadByte(UINT32 a)
225 {
226 	UINT8* pr;
227 
228 	a &= 0xFFFFFF;
229 
230 //	bprintf(PRINT_NORMAL, _T("read8 0x%08X\n"), a);
231 
232 	pr = FIND_R(a);
233 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
234 		a ^= 1;
235 		return pr[a & SEK_PAGEM];
236 	}
237 	return pSekExt->ReadByte[(uintptr_t)pr](a);
238 }
239 
FetchByte(UINT32 a)240 inline static UINT8 FetchByte(UINT32 a)
241 {
242 	UINT8* pr;
243 
244 	a &= 0xFFFFFF;
245 
246 //	bprintf(PRINT_NORMAL, _T("fetch8 0x%08X\n"), a);
247 
248 	pr = FIND_F(a);
249 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
250 		a ^= 1;
251 		return pr[a & SEK_PAGEM];
252 	}
253 	return pSekExt->ReadByte[(uintptr_t)pr](a);
254 }
255 
WriteByte(UINT32 a,UINT8 d)256 inline static void WriteByte(UINT32 a, UINT8 d)
257 {
258 	UINT8* pr;
259 
260 	a &= 0xFFFFFF;
261 
262 //	bprintf(PRINT_NORMAL, _T("write8 0x%08X\n"), a);
263 
264 	pr = FIND_W(a);
265 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
266 		a ^= 1;
267 		pr[a & SEK_PAGEM] = (UINT8)d;
268 		return;
269 	}
270 	pSekExt->WriteByte[(uintptr_t)pr](a, d);
271 }
272 
WriteByteROM(UINT32 a,UINT8 d)273 inline static void WriteByteROM(UINT32 a, UINT8 d)
274 {
275 	UINT8* pr;
276 
277 	a &= 0xFFFFFF;
278 
279 	pr = FIND_R(a);
280 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
281 		a ^= 1;
282 		pr[a & SEK_PAGEM] = (UINT8)d;
283 		return;
284 	}
285 	pSekExt->WriteByte[(uintptr_t)pr](a, d);
286 }
287 
ReadWord(UINT32 a)288 inline static UINT16 ReadWord(UINT32 a)
289 {
290 	UINT8* pr;
291 
292 	a &= 0xFFFFFF;
293 
294 //	bprintf(PRINT_NORMAL, _T("read16 0x%08X\n"), a);
295 
296 	pr = FIND_R(a);
297 	if ((uintptr_t)pr >= SEK_MAXHANDLER)
298 	{
299 		if (a & 1)
300 		{
301 			return BURN_ENDIAN_SWAP_INT16((ReadByte(a + 0) * 256) + ReadByte(a + 1));
302 		}
303 		else
304 		{
305 			return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(pr + (a & SEK_PAGEM))));
306 		}
307 	}
308 
309 	return pSekExt->ReadWord[(uintptr_t)pr](a);
310 }
311 
FetchWord(UINT32 a)312 inline static UINT16 FetchWord(UINT32 a)
313 {
314 	UINT8* pr;
315 
316 	a &= 0xFFFFFF;
317 
318 //	bprintf(PRINT_NORMAL, _T("fetch16 0x%08X\n"), a);
319 
320 	pr = FIND_F(a);
321 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
322 		return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(pr + (a & SEK_PAGEM))));
323 	}
324 
325 	return pSekExt->ReadWord[(uintptr_t)pr](a);
326 }
327 
WriteWord(UINT32 a,UINT16 d)328 inline static void WriteWord(UINT32 a, UINT16 d)
329 {
330 	UINT8* pr;
331 
332 	a &= 0xFFFFFF;
333 
334 //	bprintf(PRINT_NORMAL, _T("write16 0x%08X\n"), a);
335 
336 	pr = FIND_W(a);
337 	if ((uintptr_t)pr >= SEK_MAXHANDLER)
338 	{
339 		if (a & 1)
340 		{
341 		//	bprintf(PRINT_NORMAL, _T("write16 0x%08X\n"), a);
342 
343 			d = BURN_ENDIAN_SWAP_INT16(d);
344 
345 			WriteByte(a + 0, d / 0x100);
346 			WriteByte(a + 1, d);
347 
348 			return;
349 		}
350 		else
351 		{
352 			*((UINT16*)(pr + (a & SEK_PAGEM))) = (UINT16)BURN_ENDIAN_SWAP_INT16(d);
353 			return;
354 		}
355 	}
356 
357 	pSekExt->WriteWord[(uintptr_t)pr](a, d);
358 }
359 
WriteWordROM(UINT32 a,UINT16 d)360 inline static void WriteWordROM(UINT32 a, UINT16 d)
361 {
362 	UINT8* pr;
363 
364 	a &= 0xFFFFFF;
365 
366 	pr = FIND_R(a);
367 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
368 		*((UINT16*)(pr + (a & SEK_PAGEM))) = (UINT16)d;
369 		return;
370 	}
371 	pSekExt->WriteWord[(uintptr_t)pr](a, d);
372 }
373 
374 // be [3210] -> (r >> 16) | (r << 16) -> [1032] -> UINT32(le) = -> [0123]
375 // le [0123]
376 
ReadLong(UINT32 a)377 inline static UINT32 ReadLong(UINT32 a)
378 {
379 	UINT8* pr;
380 
381 	a &= 0xFFFFFF;
382 
383 //	bprintf(PRINT_NORMAL, _T("read32 0x%08X\n"), a);
384 
385 	pr = FIND_R(a);
386 	if ((uintptr_t)pr >= SEK_MAXHANDLER)
387 	{
388 		UINT32 r = 0;
389 
390 		if (a & 1)
391 		{
392 			r  = ReadByte((a + 0)) * 0x1000000;
393 			r += ReadByte((a + 1)) * 0x10000;
394 			r += ReadByte((a + 2)) * 0x100;
395 			r += ReadByte((a + 3));
396 
397 			return BURN_ENDIAN_SWAP_INT32(r);
398 		}
399 		else
400 		{
401 			r = *((UINT32*)(pr + (a & SEK_PAGEM)));
402 			r = (r >> 16) | (r << 16);
403 
404 			return BURN_ENDIAN_SWAP_INT32(r);
405 		}
406 	}
407 
408 	return pSekExt->ReadLong[(uintptr_t)pr](a);
409 }
410 
FetchLong(UINT32 a)411 inline static UINT32 FetchLong(UINT32 a)
412 {
413 	UINT8* pr;
414 
415 	a &= 0xFFFFFF;
416 
417 //	bprintf(PRINT_NORMAL, _T("fetch32 0x%08X\n"), a);
418 
419 	pr = FIND_F(a);
420 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
421 		UINT32 r = *((UINT32*)(pr + (a & SEK_PAGEM)));
422 		r = (r >> 16) | (r << 16);
423 		return BURN_ENDIAN_SWAP_INT32(r);
424 	}
425 	return pSekExt->ReadLong[(uintptr_t)pr](a);
426 }
427 
WriteLong(UINT32 a,UINT32 d)428 inline static void WriteLong(UINT32 a, UINT32 d)
429 {
430 	UINT8* pr;
431 
432 	a &= 0xFFFFFF;
433 
434 //	bprintf(PRINT_NORMAL, _T("write32 0x%08X\n"), a);
435 
436 	pr = FIND_W(a);
437 	if ((uintptr_t)pr >= SEK_MAXHANDLER)
438 	{
439 		if (a & 1)
440 		{
441 		//	bprintf(PRINT_NORMAL, _T("write32 0x%08X 0x%8.8x\n"), a,d);
442 
443 			d = BURN_ENDIAN_SWAP_INT32(d);
444 
445 			WriteByte((a + 0), d / 0x1000000);
446 			WriteByte((a + 1), d / 0x10000);
447 			WriteByte((a + 2), d / 0x100);
448 			WriteByte((a + 3), d);
449 
450 			return;
451 		}
452 		else
453 		{
454 			d = (d >> 16) | (d << 16);
455 			*((UINT32*)(pr + (a & SEK_PAGEM))) = BURN_ENDIAN_SWAP_INT32(d);
456 
457 			return;
458 		}
459 	}
460 	pSekExt->WriteLong[(uintptr_t)pr](a, d);
461 }
462 
WriteLongROM(UINT32 a,UINT32 d)463 inline static void WriteLongROM(UINT32 a, UINT32 d)
464 {
465 	UINT8* pr;
466 
467 	a &= 0xFFFFFF;
468 
469 	pr = FIND_R(a);
470 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
471 		d = (d >> 16) | (d << 16);
472 		*((UINT32*)(pr + (a & SEK_PAGEM))) = d;
473 		return;
474 	}
475 	pSekExt->WriteLong[(uintptr_t)pr](a, d);
476 }
477 
478 #if defined (FBA_DEBUG)
479 
480 // Breakpoint checking memory access functions
ReadByteBP(UINT32 a)481 UINT8 __fastcall ReadByteBP(UINT32 a)
482 {
483 	UINT8* pr;
484 
485 	a &= 0xFFFFFF;
486 
487 	pr = FIND_R(a);
488 
489 	CheckBreakpoint_R(a, ~0);
490 
491 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
492 		a ^= 1;
493 		return pr[a & SEK_PAGEM];
494 	}
495 	return pSekExt->ReadByte[(uintptr_t)pr](a);
496 }
497 
WriteByteBP(UINT32 a,UINT8 d)498 void __fastcall WriteByteBP(UINT32 a, UINT8 d)
499 {
500 	UINT8* pr;
501 
502 	a &= 0xFFFFFF;
503 
504 	pr = FIND_W(a);
505 
506 	CheckBreakpoint_W(a, ~0);
507 
508 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
509 		a ^= 1;
510 		pr[a & SEK_PAGEM] = (UINT8)d;
511 		return;
512 	}
513 	pSekExt->WriteByte[(uintptr_t)pr](a, d);
514 }
515 
ReadWordBP(UINT32 a)516 UINT16 __fastcall ReadWordBP(UINT32 a)
517 {
518 	UINT8* pr;
519 
520 	a &= 0xFFFFFF;
521 
522 	pr = FIND_R(a);
523 
524 	CheckBreakpoint_R(a, ~1);
525 
526 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
527 		return *((UINT16*)(pr + (a & SEK_PAGEM)));
528 	}
529 	return pSekExt->ReadWord[(uintptr_t)pr](a);
530 }
531 
WriteWordBP(UINT32 a,UINT16 d)532 void __fastcall WriteWordBP(UINT32 a, UINT16 d)
533 {
534 	UINT8* pr;
535 
536 	a &= 0xFFFFFF;
537 
538 	pr = FIND_W(a);
539 
540 	CheckBreakpoint_W(a, ~1);
541 
542 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
543 		*((UINT16*)(pr + (a & SEK_PAGEM))) = (UINT16)d;
544 		return;
545 	}
546 	pSekExt->WriteWord[(uintptr_t)pr](a, d);
547 }
548 
ReadLongBP(UINT32 a)549 UINT32 __fastcall ReadLongBP(UINT32 a)
550 {
551 	UINT8* pr;
552 
553 	a &= 0xFFFFFF;
554 
555 	pr = FIND_R(a);
556 
557 	CheckBreakpoint_R(a, ~1);
558 
559 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
560 		UINT32 r = *((UINT32*)(pr + (a & SEK_PAGEM)));
561 		r = (r >> 16) | (r << 16);
562 		return r;
563 	}
564 	return pSekExt->ReadLong[(uintptr_t)pr](a);
565 }
566 
WriteLongBP(UINT32 a,UINT32 d)567 void __fastcall WriteLongBP(UINT32 a, UINT32 d)
568 {
569 	UINT8* pr;
570 
571 	a &= 0xFFFFFF;
572 
573 	pr = FIND_W(a);
574 
575 	CheckBreakpoint_W(a, ~1);
576 
577 	if ((uintptr_t)pr >= SEK_MAXHANDLER) {
578 		d = (d >> 16) | (d << 16);
579 		*((UINT32*)(pr + (a & SEK_PAGEM))) = d;
580 		return;
581 	}
582 	pSekExt->WriteLong[(uintptr_t)pr](a, d);
583 }
584 
585 #endif
586 
587 // ----------------------------------------------------------------------------
588 // A68K variables
589 
590 #ifdef EMU_A68K
591 struct A68KContext* SekRegs[SEK_MAX] = { NULL, };
592 #endif
593 
594 struct A68KInter {
595 	void (__fastcall *DebugCallback) (unsigned int pc);
596 	UINT8  (__fastcall *Read8) (UINT32 a);
597 	UINT16 (__fastcall *Read16)(UINT32 a);
598 	UINT32   (__fastcall *Read32)(UINT32 a);
599 	void (__fastcall *Write8)  (UINT32 a, UINT8 d);
600 	void (__fastcall *Write16) (UINT32 a, UINT16 d);
601 	void (__fastcall *Write32) (UINT32 a, UINT32 d);
602 	void (__fastcall *ChangePc)(UINT32 a);
603 	UINT8  (__fastcall *PcRel8) (UINT32 a);
604 	UINT16 (__fastcall *PcRel16)(UINT32 a);
605 	UINT32   (__fastcall *PcRel32)(UINT32 a);
606 	UINT16 (__fastcall *Dir16)(UINT32 a);
607 	UINT32   (__fastcall *Dir32)(UINT32 a);
608 };
609 
610 extern "C" {
611 
612 #ifdef EMU_A68K
613  UINT8* OP_ROM = NULL;
614  UINT8* OP_RAM = NULL;
615 
616 #ifndef EMU_M68K
617  INT32 m68k_ICount = 0;
618 #endif
619 
620  UINT32 mem_amask = 0xFFFFFF;			// 24-bit bus
621 #endif
622 
623  UINT32 mame_debug = 0, cur_mrhard = 0, m68k_illegal_opcode = 0, illegal_op = 0, illegal_pc = 0, opcode_entry = 0;
624 
625  struct A68KInter a68k_memory_intf;
626 }
627 
A68KRead8(UINT32 a)628 UINT8  __fastcall A68KRead8 (UINT32 a) { return ReadByte(a);}
A68KRead16(UINT32 a)629 UINT16 __fastcall A68KRead16(UINT32 a) { return ReadWord(a);}
A68KRead32(UINT32 a)630 UINT32   __fastcall A68KRead32(UINT32 a) { return ReadLong(a);}
A68KFetch8(UINT32 a)631 UINT8  __fastcall A68KFetch8 (UINT32 a) { return FetchByte(a);}
A68KFetch16(UINT32 a)632 UINT16 __fastcall A68KFetch16(UINT32 a) { return FetchWord(a);}
A68KFetch32(UINT32 a)633 UINT32   __fastcall A68KFetch32(UINT32 a) { return FetchLong(a);}
A68KWrite8(UINT32 a,UINT8 d)634 void __fastcall A68KWrite8 (UINT32 a,UINT8 d)  { WriteByte(a,d);}
A68KWrite16(UINT32 a,UINT16 d)635 void __fastcall A68KWrite16(UINT32 a,UINT16 d) { WriteWord(a,d);}
A68KWrite32(UINT32 a,UINT32 d)636 void __fastcall A68KWrite32(UINT32 a,UINT32 d)   { WriteLong(a,d);}
637 
638 #if defined (FBA_DEBUG)
A68KCheckBreakpoint(unsigned int pc)639 void __fastcall A68KCheckBreakpoint(unsigned int pc) { CheckBreakpoint_PC(pc); }
A68KSingleStep(unsigned int pc)640 void __fastcall A68KSingleStep(unsigned int pc) { SingleStep_PC(pc); }
641 #endif
642 
643 #ifdef EMU_A68K
A68KChangePC(UINT32 pc)644 void __fastcall A68KChangePC(UINT32 pc)
645 {
646 	pc &= 0xFFFFFF;
647 
648 	// Adjust OP_ROM to the current bank
649 	OP_ROM = FIND_F(pc) - (pc & ~SEK_PAGEM);
650 
651 	// Set the current bank number
652 	M68000_regs.nAsmBank = pc >> SEK_BITS;
653 }
654 #endif
655 
656 #ifdef EMU_M68K
657 extern "C" {
M68KReadByte(UINT32 a)658 UINT32 __fastcall M68KReadByte(UINT32 a) { return (UINT32)ReadByte(a); }
M68KReadWord(UINT32 a)659 UINT32 __fastcall M68KReadWord(UINT32 a) { return (UINT32)ReadWord(a); }
M68KReadLong(UINT32 a)660 UINT32 __fastcall M68KReadLong(UINT32 a) { return               ReadLong(a); }
661 
M68KFetchByte(UINT32 a)662 UINT32 __fastcall M68KFetchByte(UINT32 a) { return (UINT32)FetchByte(a); }
M68KFetchWord(UINT32 a)663 UINT32 __fastcall M68KFetchWord(UINT32 a) { return (UINT32)FetchWord(a); }
M68KFetchLong(UINT32 a)664 UINT32 __fastcall M68KFetchLong(UINT32 a) { return               FetchLong(a); }
665 
666 #ifdef FBA_DEBUG
M68KReadByteBP(UINT32 a)667 UINT32 __fastcall M68KReadByteBP(UINT32 a) { return (UINT32)ReadByteBP(a); }
M68KReadWordBP(UINT32 a)668 UINT32 __fastcall M68KReadWordBP(UINT32 a) { return (UINT32)ReadWordBP(a); }
M68KReadLongBP(UINT32 a)669 UINT32 __fastcall M68KReadLongBP(UINT32 a) { return               ReadLongBP(a); }
670 
M68KWriteByteBP(UINT32 a,UINT32 d)671 void __fastcall M68KWriteByteBP(UINT32 a, UINT32 d) { WriteByteBP(a, d); }
M68KWriteWordBP(UINT32 a,UINT32 d)672 void __fastcall M68KWriteWordBP(UINT32 a, UINT32 d) { WriteWordBP(a, d); }
M68KWriteLongBP(UINT32 a,UINT32 d)673 void __fastcall M68KWriteLongBP(UINT32 a, UINT32 d) { WriteLongBP(a, d); }
674 
M68KCheckBreakpoint(unsigned int pc)675 void M68KCheckBreakpoint(unsigned int pc) { CheckBreakpoint_PC(pc); }
M68KSingleStep(unsigned int pc)676 void M68KSingleStep(unsigned int pc) { SingleStep_PC(pc); }
677 
678 UINT32 (__fastcall *M68KReadByteDebug)(UINT32);
679 UINT32 (__fastcall *M68KReadWordDebug)(UINT32);
680 UINT32 (__fastcall *M68KReadLongDebug)(UINT32);
681 
682 void (__fastcall *M68KWriteByteDebug)(UINT32, UINT32);
683 void (__fastcall *M68KWriteWordDebug)(UINT32, UINT32);
684 void (__fastcall *M68KWriteLongDebug)(UINT32, UINT32);
685 #endif
686 
M68KWriteByte(UINT32 a,UINT32 d)687 void __fastcall M68KWriteByte(UINT32 a, UINT32 d) { WriteByte(a, d); }
M68KWriteWord(UINT32 a,UINT32 d)688 void __fastcall M68KWriteWord(UINT32 a, UINT32 d) { WriteWord(a, d); }
M68KWriteLong(UINT32 a,UINT32 d)689 void __fastcall M68KWriteLong(UINT32 a, UINT32 d) { WriteLong(a, d); }
690 }
691 #endif
692 
693 #if defined EMU_A68K
694 struct A68KInter a68k_inter_normal = {
695 	NULL,
696 	A68KRead8,
697 	A68KRead16,
698 	A68KRead32,
699 	A68KWrite8,
700 	A68KWrite16,
701 	A68KWrite32,
702 	A68KChangePC,
703 	A68KFetch8,
704 	A68KFetch16,
705 	A68KFetch32,
706 	A68KRead16,	// unused
707 	A68KRead32,	// unused
708 };
709 
710 #if defined (FBA_DEBUG)
711 
712 struct A68KInter a68k_inter_breakpoint = {
713 	NULL,
714 	ReadByteBP,
715 	ReadWordBP,
716 	ReadLongBP,
717 	WriteByteBP,
718 	WriteWordBP,
719 	WriteLongBP,
720 	A68KChangePC,
721 	A68KFetch8,
722 	A68KFetch16,
723 	A68KFetch32,
724 	A68KRead16,	// unused
725 	A68KRead32,	// unused
726 };
727 
728 #endif
729 
730 #endif
731 
732 // ----------------------------------------------------------------------------
733 // Memory accesses (non-emu specific)
734 
SekReadByte(UINT32 a)735 UINT32 SekReadByte(UINT32 a) { return (UINT32)ReadByte(a); }
SekReadWord(UINT32 a)736 UINT32 SekReadWord(UINT32 a) { return (UINT32)ReadWord(a); }
SekReadLong(UINT32 a)737 UINT32 SekReadLong(UINT32 a) { return ReadLong(a); }
738 
SekFetchByte(UINT32 a)739 UINT32 SekFetchByte(UINT32 a) { return (UINT32)FetchByte(a); }
SekFetchWord(UINT32 a)740 UINT32 SekFetchWord(UINT32 a) { return (UINT32)FetchWord(a); }
SekFetchLong(UINT32 a)741 UINT32 SekFetchLong(UINT32 a) { return FetchLong(a); }
742 
SekWriteByte(UINT32 a,UINT8 d)743 void SekWriteByte(UINT32 a, UINT8 d) { WriteByte(a, d); }
SekWriteWord(UINT32 a,UINT16 d)744 void SekWriteWord(UINT32 a, UINT16 d) { WriteWord(a, d); }
SekWriteLong(UINT32 a,UINT32 d)745 void SekWriteLong(UINT32 a, UINT32 d) { WriteLong(a, d); }
746 
SekWriteByteROM(UINT32 a,UINT8 d)747 void SekWriteByteROM(UINT32 a, UINT8 d) { WriteByteROM(a, d); }
SekWriteWordROM(UINT32 a,UINT16 d)748 void SekWriteWordROM(UINT32 a, UINT16 d) { WriteWordROM(a, d); }
SekWriteLongROM(UINT32 a,UINT32 d)749 void SekWriteLongROM(UINT32 a, UINT32 d) { WriteLongROM(a, d); }
750 
751 // ----------------------------------------------------------------------------
752 // Callbacks for A68K
753 
754 #ifdef EMU_A68K
A68KIRQAcknowledge(INT32 nIRQ)755 static INT32 A68KIRQAcknowledge(INT32 nIRQ)
756 {
757 	if (nSekIRQPending[nSekActive] & SEK_IRQSTATUS_AUTO) {
758 		M68000_regs.irq &= 0x78;
759 		nSekIRQPending[nSekActive] = 0;
760 	}
761 
762 	nSekIRQPending[nSekActive] = 0;
763 
764 	if (pSekExt->IrqCallback) {
765 		return pSekExt->IrqCallback(nIRQ);
766 	}
767 
768 	return -1;
769 }
770 
A68KResetCallback()771 static INT32 A68KResetCallback()
772 {
773 	if (pSekExt->ResetCallback == NULL) {
774 		return 0;
775 	}
776 	return pSekExt->ResetCallback();
777 }
778 
A68KRTECallback()779 static INT32 A68KRTECallback()
780 {
781 	if (pSekExt->RTECallback == NULL) {
782 		return 0;
783 	}
784 	return pSekExt->RTECallback();
785 }
786 
A68KCmpCallback(UINT32 val,INT32 reg)787 static INT32 A68KCmpCallback(UINT32 val, INT32 reg)
788 {
789 	if (pSekExt->CmpCallback == NULL) {
790 		return 0;
791 	}
792 	return pSekExt->CmpCallback(val, reg);
793 }
794 
SekSetup(struct A68KContext * psr)795 static INT32 SekSetup(struct A68KContext* psr)
796 {
797 	psr->IrqCallback = A68KIRQAcknowledge;
798 	psr->ResetCallback = A68KResetCallback;
799 	psr->RTECallback = A68KRTECallback;
800 	psr->CmpCallback = A68KCmpCallback;
801 
802 	return 0;
803 }
804 #endif
805 
806 // ----------------------------------------------------------------------------
807 // Callbacks for Musashi
808 
809 #ifdef EMU_M68K
M68KIRQAcknowledge(INT32 nIRQ)810 extern "C" INT32 M68KIRQAcknowledge(INT32 nIRQ)
811 {
812 	if (nSekIRQPending[nSekActive] & SEK_IRQSTATUS_AUTO) {
813 		m68k_set_irq(0);
814 		nSekIRQPending[nSekActive] = 0;
815 	}
816 
817 	if (pSekExt->IrqCallback) {
818 		return pSekExt->IrqCallback(nIRQ);
819 	}
820 
821 	return M68K_INT_ACK_AUTOVECTOR;
822 }
823 
M68KResetCallback()824 extern "C" void M68KResetCallback()
825 {
826 	if (pSekExt->ResetCallback) {
827 		pSekExt->ResetCallback();
828 	}
829 }
830 
M68KRTECallback()831 extern "C" void M68KRTECallback()
832 {
833 	if (pSekExt->RTECallback) {
834 		pSekExt->RTECallback();
835 	}
836 }
837 
M68KcmpildCallback(UINT32 val,INT32 reg)838 extern "C" void M68KcmpildCallback(UINT32 val, INT32 reg)
839 {
840 	if (pSekExt->CmpCallback) {
841 		pSekExt->CmpCallback(val, reg);
842 	}
843 }
844 
M68KTASCallback()845 extern "C" INT32 M68KTASCallback()
846 {
847 	if (pSekExt->TASCallback) {
848 		return pSekExt->TASCallback();
849 	}
850 
851 	return 1; // enable by default
852 }
853 #endif
854 
855 // ----------------------------------------------------------------------------
856 // Initialisation/exit/reset
857 
858 #ifdef EMU_A68K
SekInitCPUA68K(INT32 nCount,INT32 nCPUType)859 static INT32 SekInitCPUA68K(INT32 nCount, INT32 nCPUType)
860 {
861 	if (nCPUType != 0x68000) {
862 		return 1;
863 	}
864 
865 	nSekCPUType[nCount] = 0;
866 
867 	// Allocate emu-specific cpu states
868 	SekRegs[nCount] = (struct A68KContext*)malloc(sizeof(struct A68KContext));
869 	if (SekRegs[nCount] == NULL) {
870 		return 1;
871 	}
872 
873 	// Setup each cpu context
874 	memset(SekRegs[nCount], 0, sizeof(struct A68KContext));
875 	SekSetup(SekRegs[nCount]);
876 
877 	// Init cpu emulator
878 	M68000_RESET();
879 
880 	return 0;
881 }
882 #endif
883 
884 #ifdef EMU_M68K
SekInitCPUM68K(INT32 nCount,INT32 nCPUType)885 static INT32 SekInitCPUM68K(INT32 nCount, INT32 nCPUType)
886 {
887 	nSekCPUType[nCount] = nCPUType;
888 
889 	switch (nCPUType) {
890 		case 0x68000:
891 			m68k_set_cpu_type(M68K_CPU_TYPE_68000);
892 			break;
893 		case 0x68010:
894 			m68k_set_cpu_type(M68K_CPU_TYPE_68010);
895 			break;
896 		case 0x68EC020:
897 			m68k_set_cpu_type(M68K_CPU_TYPE_68EC020);
898 			break;
899 		default:
900 			return 1;
901 	}
902 
903 	nSekM68KContextSize[nCount] = m68k_context_size();
904 	SekM68KContext[nCount] = (INT8*)malloc(nSekM68KContextSize[nCount]);
905 	if (SekM68KContext[nCount] == NULL) {
906 		return 1;
907 	}
908 	memset(SekM68KContext[nCount], 0, nSekM68KContextSize[nCount]);
909 	m68k_get_context(SekM68KContext[nCount]);
910 
911 	return 0;
912 }
913 #endif
914 
SekNewFrame()915 void SekNewFrame()
916 {
917 #if defined FBA_DEBUG
918 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekNewFrame called without init\n"));
919 #endif
920 
921 	for (INT32 i = 0; i <= nSekCount; i++) {
922 		nSekCycles[i] = 0;
923 	}
924 
925 	nSekCyclesTotal = 0;
926 }
927 
SekSetCyclesScanline(INT32 nCycles)928 void SekSetCyclesScanline(INT32 nCycles)
929 {
930 #if defined FBA_DEBUG
931 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekSetCyclesScanline called without init\n"));
932 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekSetCyclesScanline called when no CPU open\n"));
933 #endif
934 
935 	nSekCyclesScanline = nCycles;
936 }
937 
SekCheatRead(UINT32 a)938 UINT8 SekCheatRead(UINT32 a)
939 {
940 	return SekReadByte(a);
941 }
942 
SekInit(INT32 nCount,INT32 nCPUType)943 INT32 SekInit(INT32 nCount, INT32 nCPUType)
944 {
945 	DebugCPU_SekInitted = 1;
946 
947 	struct SekExt* ps = NULL;
948 
949 /*#if !defined BUILD_A68K
950 	bBurnUseASMCPUEmulation = false;
951 #endif*/
952 
953 	if (nSekActive >= 0) {
954 		SekClose();
955 		nSekActive = -1;
956 	}
957 
958 	if (nCount > nSekCount) {
959 		nSekCount = nCount;
960 	}
961 
962 	// Allocate cpu extenal data (memory map etc)
963 	SekExt[nCount] = (struct SekExt*)malloc(sizeof(struct SekExt));
964 	if (SekExt[nCount] == NULL) {
965 		SekExit();
966 		return 1;
967 	}
968 	memset(SekExt[nCount], 0, sizeof(struct SekExt));
969 
970 	// Put in default memory handlers
971 	ps = SekExt[nCount];
972 
973 	for (INT32 j = 0; j < SEK_MAXHANDLER; j++) {
974 		ps->ReadByte[j]  = DefReadByte;
975 		ps->WriteByte[j] = DefWriteByte;
976 	}
977 
978 	ps->ReadWord[0]  = DefReadWord0;
979 	ps->WriteWord[0] = DefWriteWord0;
980 	ps->ReadLong[0]  = DefReadLong0;
981 	ps->WriteLong[0] = DefWriteLong0;
982 
983 #if SEK_MAXHANDLER >= 2
984 	ps->ReadWord[1]  = DefReadWord1;
985 	ps->WriteWord[1] = DefWriteWord1;
986 	ps->ReadLong[1]  = DefReadLong1;
987 	ps->WriteLong[1] = DefWriteLong1;
988 #endif
989 
990 #if SEK_MAXHANDLER >= 3
991 	ps->ReadWord[2]  = DefReadWord2;
992 	ps->WriteWord[2] = DefWriteWord2;
993 	ps->ReadLong[2]  = DefReadLong2;
994 	ps->WriteLong[2] = DefWriteLong2;
995 #endif
996 
997 #if SEK_MAXHANDLER >= 4
998 	ps->ReadWord[3]  = DefReadWord3;
999 	ps->WriteWord[3] = DefWriteWord3;
1000 	ps->ReadLong[3]  = DefReadLong3;
1001 	ps->WriteLong[3] = DefWriteLong3;
1002 #endif
1003 
1004 #if SEK_MAXHANDLER >= 5
1005 	ps->ReadWord[4]  = DefReadWord4;
1006 	ps->WriteWord[4] = DefWriteWord4;
1007 	ps->ReadLong[4]  = DefReadLong4;
1008 	ps->WriteLong[4] = DefWriteLong4;
1009 #endif
1010 
1011 #if SEK_MAXHANDLER >= 6
1012 	ps->ReadWord[5]  = DefReadWord5;
1013 	ps->WriteWord[5] = DefWriteWord5;
1014 	ps->ReadLong[5]  = DefReadLong5;
1015 	ps->WriteLong[5] = DefWriteLong5;
1016 #endif
1017 
1018 #if SEK_MAXHANDLER >= 7
1019 	ps->ReadWord[6]  = DefReadWord6;
1020 	ps->WriteWord[6] = DefWriteWord6;
1021 	ps->ReadLong[6]  = DefReadLong6;
1022 	ps->WriteLong[6] = DefWriteLong6;
1023 #endif
1024 
1025 #if SEK_MAXHANDLER >= 8
1026 	ps->ReadWord[7]  = DefReadWord7;
1027 	ps->WriteWord[7] = DefWriteWord7;
1028 	ps->ReadLong[7]  = DefReadLong7;
1029 	ps->WriteLong[7] = DefWriteLong7;
1030 #endif
1031 
1032 #if SEK_MAXHANDLER >= 9
1033 	ps->ReadWord[8]  = DefReadWord8;
1034 	ps->WriteWord[8] = DefWriteWord8;
1035 	ps->ReadLong[8]  = DefReadLong8;
1036 	ps->WriteLong[8] = DefWriteLong8;
1037 #endif
1038 
1039 #if SEK_MAXHANDLER >= 10
1040 	ps->ReadWord[9]  = DefReadWord9;
1041 	ps->WriteWord[9] = DefWriteWord9;
1042 	ps->ReadLong[9]  = DefReadLong9;
1043 	ps->WriteLong[9] = DefWriteLong9;
1044 #endif
1045 
1046 #if SEK_MAXHANDLER >= 11
1047 	for (int j = 10; j < SEK_MAXHANDLER; j++) {
1048 		ps->ReadWord[j]  = DefReadWord0;
1049 		ps->WriteWord[j] = DefWriteWord0;
1050 		ps->ReadLong[j]  = DefReadLong0;
1051 		ps->WriteLong[j] = DefWriteLong0;
1052 	}
1053 #endif
1054 
1055 	// Map the normal memory handlers
1056 	SekDbgDisableBreakpoints();
1057 
1058 #ifdef EMU_A68K
1059 	if (bBurnUseASMCPUEmulation && nCPUType == 0x68000) {
1060 		if (SekInitCPUA68K(nCount, nCPUType)) {
1061 			SekExit();
1062 			return 1;
1063 		}
1064 	} else {
1065 #endif
1066 
1067 #ifdef EMU_M68K
1068 		m68k_init();
1069 		if (SekInitCPUM68K(nCount, nCPUType)) {
1070 			SekExit();
1071 			return 1;
1072 		}
1073 #endif
1074 
1075 #ifdef EMU_A68K
1076 	}
1077 #endif
1078 
1079 	nSekCycles[nCount] = 0;
1080 	nSekIRQPending[nCount] = 0;
1081 
1082 	nSekCyclesTotal = 0;
1083 	nSekCyclesScanline = 0;
1084 
1085 	CpuCheatRegister(nCount, &SekConfig);
1086 
1087 	return 0;
1088 }
1089 
1090 #ifdef EMU_A68K
SekCPUExitA68K(INT32 i)1091 static void SekCPUExitA68K(INT32 i)
1092 {
1093 	if (SekRegs[i]) {
1094 		free(SekRegs[i]);
1095 		SekRegs[i] = NULL;
1096 	}
1097 }
1098 #endif
1099 
1100 #ifdef EMU_M68K
SekCPUExitM68K(INT32 i)1101 static void SekCPUExitM68K(INT32 i)
1102 {
1103 		if(SekM68KContext[i]) {
1104 			free(SekM68KContext[i]);
1105 			SekM68KContext[i] = NULL;
1106 		}
1107 }
1108 #endif
1109 
SekExit()1110 INT32 SekExit()
1111 {
1112 #if defined FBA_DEBUG
1113 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekExit called without init\n"));
1114 #endif
1115 
1116 	if (!DebugCPU_SekInitted) return 1;
1117 
1118 	// Deallocate cpu extenal data (memory map etc)
1119 	for (INT32 i = 0; i <= nSekCount; i++) {
1120 
1121 #ifdef EMU_A68K
1122 		SekCPUExitA68K(i);
1123 #endif
1124 
1125 #ifdef EMU_M68K
1126 		SekCPUExitM68K(i);
1127 #endif
1128 
1129 		// Deallocate other context data
1130 		if (SekExt[i]) {
1131 			free(SekExt[i]);
1132 			SekExt[i] = NULL;
1133 		}
1134 	}
1135 
1136 	pSekExt = NULL;
1137 
1138 	nSekActive = -1;
1139 	nSekCount = -1;
1140 
1141 	DebugCPU_SekInitted = 0;
1142 
1143 	return 0;
1144 }
1145 
SekReset()1146 void SekReset()
1147 {
1148 #if defined FBA_DEBUG
1149 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekReset called without init\n"));
1150 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekReset called when no CPU open\n"));
1151 #endif
1152 
1153 #ifdef EMU_A68K
1154 	if (nSekCPUType[nSekActive] == 0) {
1155 		// A68K has no internal support for resetting the processor, so do what's needed ourselves
1156 		M68000_regs.a[7] = FetchLong(0);	// Get initial stackpointer (register A7)
1157 		M68000_regs.pc = FetchLong(4);		// Get initial PC
1158 		M68000_regs.srh = 0x27;				// start in supervisor state
1159 		A68KChangePC(M68000_regs.pc);
1160 	} else {
1161 #endif
1162 
1163 #ifdef EMU_M68K
1164 		m68k_pulse_reset();
1165 #endif
1166 
1167 #ifdef EMU_A68K
1168 	}
1169 #endif
1170 
1171 }
1172 
1173 // ----------------------------------------------------------------------------
1174 // Control the active CPU
1175 
1176 // Open a CPU
SekOpen(const INT32 i)1177 void SekOpen(const INT32 i)
1178 {
1179 #if defined FBA_DEBUG
1180 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekOpen called without init\n"));
1181 	if (i > nSekCount) bprintf(PRINT_ERROR, _T("SekOpen called with invalid index %x\n"), i);
1182 	if (nSekActive != -1) bprintf(PRINT_ERROR, _T("SekOpen called when CPU already open with index %x\n"), i);
1183 #endif
1184 
1185 	if (i != nSekActive) {
1186 		nSekActive = i;
1187 
1188 		pSekExt = SekExt[nSekActive];						// Point to cpu context
1189 
1190 #ifdef EMU_A68K
1191 		if (nSekCPUType[nSekActive] == 0) {
1192 			memcpy(&M68000_regs, SekRegs[nSekActive], sizeof(M68000_regs));
1193 			A68KChangePC(M68000_regs.pc);
1194 		} else {
1195 #endif
1196 
1197 #ifdef EMU_M68K
1198 			m68k_set_context(SekM68KContext[nSekActive]);
1199 #endif
1200 
1201 #ifdef EMU_A68K
1202 		}
1203 #endif
1204 
1205 		nSekCyclesTotal = nSekCycles[nSekActive];
1206 	}
1207 }
1208 
1209 // Close the active cpu
SekClose()1210 void SekClose()
1211 {
1212 #if defined FBA_DEBUG
1213 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekClose called without init\n"));
1214 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekClose called when no CPU open\n"));
1215 #endif
1216 
1217 #ifdef EMU_A68K
1218 	if (nSekCPUType[nSekActive] == 0) {
1219 		memcpy(SekRegs[nSekActive], &M68000_regs, sizeof(M68000_regs));
1220 	} else {
1221 #endif
1222 
1223 #ifdef EMU_M68K
1224 		m68k_get_context(SekM68KContext[nSekActive]);
1225 #endif
1226 
1227 #ifdef EMU_A68K
1228 	}
1229 #endif
1230 
1231 	nSekCycles[nSekActive] = nSekCyclesTotal;
1232 
1233 	nSekActive = -1;
1234 }
1235 
1236 // Get the current CPU
SekGetActive()1237 INT32 SekGetActive()
1238 {
1239 #if defined FBA_DEBUG
1240 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekGetActive called without init\n"));
1241 #endif
1242 
1243 	return nSekActive;
1244 }
1245 
1246 // For Megadrive - check if the vdp controlport should set IRQ
SekShouldInterrupt()1247 INT32 SekShouldInterrupt()
1248 {
1249 	return m68k_check_shouldinterrupt();
1250 }
1251 
SekBurnUntilInt()1252 void SekBurnUntilInt()
1253 {
1254 	m68k_burn_until_irq(1);
1255 }
1256 
1257 // Set the status of an IRQ line on the active CPU
SekSetIRQLine(const INT32 line,const INT32 nstatus)1258 void SekSetIRQLine(const INT32 line, const INT32 nstatus)
1259 {
1260 #if defined FBA_DEBUG
1261 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekSetIRQLine called without init\n"));
1262 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekSetIRQLine called when no CPU open\n"));
1263 #endif
1264 
1265 	INT32 status = nstatus << 12; // needed for compatibility
1266 
1267 //	bprintf(PRINT_NORMAL, _T("  - irq line %i -> %i\n"), line, status);
1268 
1269 	if (status) {
1270 		nSekIRQPending[nSekActive] = line | status;
1271 
1272 #ifdef EMU_A68K
1273 		if (nSekCPUType[nSekActive] == 0) {
1274 			nSekCyclesTotal += (nSekCyclesToDo - nSekCyclesDone) - m68k_ICount;
1275 			nSekCyclesDone += (nSekCyclesToDo - nSekCyclesDone) - m68k_ICount;
1276 
1277 			M68000_regs.irq = line;
1278 			m68k_ICount = nSekCyclesToDo = -1;					// Force A68K to exit
1279 		} else {
1280 #endif
1281 
1282 #ifdef EMU_M68K
1283 			m68k_set_irq(line);
1284 #endif
1285 
1286 #ifdef EMU_A68K
1287 		}
1288 #endif
1289 
1290 		return;
1291 	}
1292 
1293 	nSekIRQPending[nSekActive] = 0;
1294 
1295 #ifdef EMU_A68K
1296 	if (nSekCPUType[nSekActive] == 0) {
1297 		M68000_regs.irq &= 0x78;
1298 	} else {
1299 #endif
1300 
1301 #ifdef EMU_M68K
1302 		m68k_set_irq(0);
1303 #endif
1304 
1305 #ifdef EMU_A68K
1306 	}
1307 #endif
1308 
1309 }
1310 
1311 // Adjust the active CPU's timeslice
SekRunAdjust(const INT32 nCycles)1312 void SekRunAdjust(const INT32 nCycles)
1313 {
1314 #if defined FBA_DEBUG
1315 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekRunAdjust called without init\n"));
1316 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekRunAdjust called when no CPU open\n"));
1317 #endif
1318 
1319 	if (nCycles < 0 && m68k_ICount < -nCycles) {
1320 		SekRunEnd();
1321 		return;
1322 	}
1323 
1324 #ifdef EMU_A68K
1325 	if (nSekCPUType[nSekActive] == 0) {
1326 		m68k_ICount += nCycles;
1327 		nSekCyclesToDo += nCycles;
1328 		nSekCyclesSegment += nCycles;
1329 	} else {
1330 #endif
1331 
1332 #ifdef EMU_M68K
1333 		nSekCyclesToDo += nCycles;
1334 		m68k_modify_timeslice(nCycles);
1335 #endif
1336 
1337 #ifdef EMU_A68K
1338 	}
1339 #endif
1340 
1341 }
1342 
1343 // End the active CPU's timeslice
SekRunEnd()1344 void SekRunEnd()
1345 {
1346 #if defined FBA_DEBUG
1347 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekRunEnd called without init\n"));
1348 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekRunEnd called when no CPU open\n"));
1349 #endif
1350 
1351 #ifdef EMU_A68K
1352 	if (nSekCPUType[nSekActive] == 0) {
1353 		nSekCyclesTotal += (nSekCyclesToDo - nSekCyclesDone) - m68k_ICount;
1354 		nSekCyclesDone += (nSekCyclesToDo - nSekCyclesDone) - m68k_ICount;
1355 		nSekCyclesSegment = nSekCyclesDone;
1356 		m68k_ICount = nSekCyclesToDo = -1;						// Force A68K to exit
1357 	} else {
1358 #endif
1359 
1360 #ifdef EMU_M68K
1361 		m68k_end_timeslice();
1362 #endif
1363 
1364 #ifdef EMU_A68K
1365 	}
1366 #endif
1367 
1368 }
1369 
1370 // Run the active CPU
SekRun(const INT32 nCycles)1371 INT32 SekRun(const INT32 nCycles)
1372 {
1373 #if defined FBA_DEBUG
1374 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekRun called without init\n"));
1375 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekRun called when no CPU open\n"));
1376 #endif
1377 
1378 #ifdef EMU_A68K
1379 	if (nSekCPUType[nSekActive] == 0) {
1380 		nSekCyclesDone = 0;
1381 		nSekCyclesSegment = nCycles;
1382 		do {
1383 			m68k_ICount = nSekCyclesToDo = nSekCyclesSegment - nSekCyclesDone;
1384 
1385 			if (M68000_regs.irq == 0x80) {						// Cpu is in stopped state till interrupt
1386 				nSekCyclesDone = nSekCyclesSegment;
1387 				nSekCyclesTotal += nSekCyclesSegment;
1388 			} else {
1389 				M68000_RUN();
1390 				nSekCyclesDone += nSekCyclesToDo - m68k_ICount;
1391 				nSekCyclesTotal += nSekCyclesToDo - m68k_ICount;
1392 			}
1393 		} while (nSekCyclesDone < nSekCyclesSegment);
1394 
1395 		nSekCyclesSegment = nSekCyclesDone;
1396 		nSekCyclesToDo = m68k_ICount = -1;
1397 		nSekCyclesDone = 0;
1398 
1399 		return nSekCyclesSegment;								// Return the number of cycles actually done
1400 	} else {
1401 #endif
1402 
1403 #ifdef EMU_M68K
1404 		nSekCyclesToDo = nCycles;
1405 
1406 		nSekCyclesSegment = m68k_execute(nCycles);
1407 
1408 		nSekCyclesTotal += nSekCyclesSegment;
1409 		nSekCyclesToDo = m68k_ICount = -1;
1410 
1411 		return nSekCyclesSegment;
1412 #else
1413 		return 0;
1414 #endif
1415 
1416 #ifdef EMU_A68K
1417 	}
1418 #endif
1419 
1420 }
1421 
1422 // ----------------------------------------------------------------------------
1423 // Breakpoint support
1424 
SekDbgDisableBreakpoints()1425 void SekDbgDisableBreakpoints()
1426 {
1427 #if defined FBA_DEBUG && defined EMU_M68K
1428 		m68k_set_instr_hook_callback(NULL);
1429 
1430 		M68KReadByteDebug = M68KReadByte;
1431 		M68KReadWordDebug = M68KReadWord;
1432 		M68KReadLongDebug = M68KReadLong;
1433 
1434 		M68KWriteByteDebug = M68KWriteByte;
1435 		M68KWriteWordDebug = M68KWriteWord;
1436 		M68KWriteLongDebug = M68KWriteLong;
1437 #endif
1438 
1439 #ifdef EMU_A68K
1440 	a68k_memory_intf = a68k_inter_normal;
1441 #endif
1442 
1443 	mame_debug = 0;
1444 }
1445 
1446 #if defined (FBA_DEBUG)
1447 
SekDbgEnableBreakpoints()1448 void SekDbgEnableBreakpoints()
1449 {
1450 	if (BreakpointDataRead[0].address || BreakpointDataWrite[0].address || BreakpointFetch[0].address) {
1451 #if defined FBA_DEBUG && defined EMU_M68K
1452 		SekDbgDisableBreakpoints();
1453 
1454 		if (BreakpointFetch[0].address) {
1455 			m68k_set_instr_hook_callback(M68KCheckBreakpoint);
1456 		}
1457 
1458 		if (BreakpointDataRead[0].address) {
1459 			M68KReadByteDebug = M68KReadByteBP;
1460 			M68KReadWordDebug = M68KReadWordBP;
1461 			M68KReadLongDebug = M68KReadLongBP;
1462 		}
1463 
1464 		if (BreakpointDataWrite[0].address) {
1465 			M68KWriteByteDebug = M68KWriteByteBP;
1466 			M68KWriteWordDebug = M68KWriteWordBP;
1467 			M68KWriteLongDebug = M68KWriteLongBP;
1468 		}
1469 #endif
1470 
1471 #ifdef EMU_A68K
1472 		a68k_memory_intf = a68k_inter_breakpoint;
1473 		if (BreakpointFetch[0].address) {
1474 			a68k_memory_intf.DebugCallback = A68KCheckBreakpoint;
1475 			mame_debug = 255;
1476 		} else {
1477 			a68k_memory_intf.DebugCallback = NULL;
1478 			mame_debug = 0;
1479 		}
1480 #endif
1481 	} else {
1482 		SekDbgDisableBreakpoints();
1483 	}
1484 }
1485 
SekDbgEnableSingleStep()1486 void SekDbgEnableSingleStep()
1487 {
1488 #if defined FBA_DEBUG && defined EMU_M68K
1489 	m68k_set_instr_hook_callback(M68KSingleStep);
1490 #endif
1491 
1492 #ifdef EMU_A68K
1493 	a68k_memory_intf.DebugCallback = A68KSingleStep;
1494 	mame_debug = 254;
1495 #endif
1496 }
1497 
SekDbgSetBreakpointDataRead(UINT32 nAddress,INT32 nIdentifier)1498 INT32 SekDbgSetBreakpointDataRead(UINT32 nAddress, INT32 nIdentifier)
1499 {
1500 	for (INT32 i = 0; i < 8; i++) {
1501 		if (BreakpointDataRead[i].id == nIdentifier) {
1502 
1503 			if	(nAddress) {							// Change breakpoint
1504 				BreakpointDataRead[i].address = nAddress;
1505 			} else {									// Delete breakpoint
1506 				for ( ; i < 8; i++) {
1507 					BreakpointDataRead[i] = BreakpointDataRead[i + 1];
1508 				}
1509 			}
1510 
1511 			SekDbgEnableBreakpoints();
1512 			return 0;
1513 		}
1514 	}
1515 
1516 	// No breakpoints present, add it to the 1st slot
1517 	BreakpointDataRead[0].address = nAddress;
1518 	BreakpointDataRead[0].id = nIdentifier;
1519 
1520 	SekDbgEnableBreakpoints();
1521 	return 0;
1522 }
1523 
SekDbgSetBreakpointDataWrite(UINT32 nAddress,INT32 nIdentifier)1524 INT32 SekDbgSetBreakpointDataWrite(UINT32 nAddress, INT32 nIdentifier)
1525 {
1526 	for (INT32 i = 0; i < 8; i++) {
1527 		if (BreakpointDataWrite[i].id == nIdentifier) {
1528 
1529 			if (nAddress) {								// Change breakpoint
1530 				BreakpointDataWrite[i].address = nAddress;
1531 			} else {									// Delete breakpoint
1532 				for ( ; i < 8; i++) {
1533 					BreakpointDataWrite[i] = BreakpointDataWrite[i + 1];
1534 				}
1535 			}
1536 
1537 			SekDbgEnableBreakpoints();
1538 			return 0;
1539 		}
1540 	}
1541 
1542 	// No breakpoints present, add it to the 1st slot
1543 	BreakpointDataWrite[0].address = nAddress;
1544 	BreakpointDataWrite[0].id = nIdentifier;
1545 
1546 	SekDbgEnableBreakpoints();
1547 	return 0;
1548 }
1549 
SekDbgSetBreakpointFetch(UINT32 nAddress,INT32 nIdentifier)1550 INT32 SekDbgSetBreakpointFetch(UINT32 nAddress, INT32 nIdentifier)
1551 {
1552 	for (INT32 i = 0; i < 8; i++) {
1553 		if (BreakpointFetch[i].id == nIdentifier) {
1554 
1555 			if (nAddress) {								// Change breakpoint
1556 				BreakpointFetch[i].address = nAddress;
1557 			} else {									// Delete breakpoint
1558 				for ( ; i < 8; i++) {
1559 					BreakpointFetch[i] = BreakpointFetch[i + 1];
1560 				}
1561 			}
1562 
1563 			SekDbgEnableBreakpoints();
1564 			return 0;
1565 		}
1566 	}
1567 
1568 	// No breakpoints present, add it to the 1st slot
1569 	BreakpointFetch[0].address = nAddress;
1570 	BreakpointFetch[0].id = nIdentifier;
1571 
1572 	SekDbgEnableBreakpoints();
1573 	return 0;
1574 }
1575 
1576 #endif
1577 
1578 // ----------------------------------------------------------------------------
1579 // Memory map setup
1580 
1581 // Note - each page is 1 << SEK_BITS.
SekMapMemory(UINT8 * pMemory,UINT32 nStart,UINT32 nEnd,INT32 nType)1582 INT32 SekMapMemory(UINT8* pMemory, UINT32 nStart, UINT32 nEnd, INT32 nType)
1583 {
1584 #if defined FBA_DEBUG
1585 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekMapMemory called without init\n"));
1586 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekMapMemory called when no CPU open\n"));
1587 #endif
1588 
1589 	UINT8* Ptr = pMemory - nStart;
1590 	UINT8** pMemMap = pSekExt->MemMap + (nStart >> SEK_SHIFT);
1591 
1592 	// Special case for ROM banks
1593 	if (nType == MAP_ROM) {
1594 		for (UINT32 i = (nStart & ~SEK_PAGEM); i <= nEnd; i += SEK_PAGE_SIZE, pMemMap++) {
1595 			pMemMap[0]			  = Ptr + i;
1596 			pMemMap[SEK_WADD * 2] = Ptr + i;
1597 		}
1598 
1599 		return 0;
1600 	}
1601 
1602 	for (UINT32 i = (nStart & ~SEK_PAGEM); i <= nEnd; i += SEK_PAGE_SIZE, pMemMap++) {
1603 
1604 		if (nType & MAP_READ) {					// Read
1605 			pMemMap[0]			  = Ptr + i;
1606 		}
1607 		if (nType & MAP_WRITE) {					// Write
1608 			pMemMap[SEK_WADD]	  = Ptr + i;
1609 		}
1610 		if (nType & MAP_FETCH) {					// Fetch
1611 			pMemMap[SEK_WADD * 2] = Ptr + i;
1612 		}
1613 	}
1614 
1615 	return 0;
1616 }
1617 
SekMapHandler(uintptr_t nHandler,UINT32 nStart,UINT32 nEnd,INT32 nType)1618 INT32 SekMapHandler(uintptr_t nHandler, UINT32 nStart, UINT32 nEnd, INT32 nType)
1619 {
1620 #if defined FBA_DEBUG
1621 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekMapHander called without init\n"));
1622 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekMapHandler called when no CPU open\n"));
1623 #endif
1624 
1625 	UINT8** pMemMap = pSekExt->MemMap + (nStart >> SEK_SHIFT);
1626 
1627 	// Add to memory map
1628 	for (UINT32 i = (nStart & ~SEK_PAGEM); i <= nEnd; i += SEK_PAGE_SIZE, pMemMap++) {
1629 
1630 		if (nType & MAP_READ) {					// Read
1631 			pMemMap[0]			  = (UINT8*)nHandler;
1632 		}
1633 		if (nType & MAP_WRITE) {					// Write
1634 			pMemMap[SEK_WADD]	  = (UINT8*)nHandler;
1635 		}
1636 		if (nType & MAP_FETCH) {					// Fetch
1637 			pMemMap[SEK_WADD * 2] = (UINT8*)nHandler;
1638 		}
1639 	}
1640 
1641 	return 0;
1642 }
1643 
1644 // Set callbacks
SekSetResetCallback(pSekResetCallback pCallback)1645 INT32 SekSetResetCallback(pSekResetCallback pCallback)
1646 {
1647 #if defined FBA_DEBUG
1648 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekSetResetCallback called without init\n"));
1649 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekSetResetCallback called when no CPU open\n"));
1650 #endif
1651 
1652 	pSekExt->ResetCallback = pCallback;
1653 
1654 	return 0;
1655 }
1656 
SekSetRTECallback(pSekRTECallback pCallback)1657 INT32 SekSetRTECallback(pSekRTECallback pCallback)
1658 {
1659 #if defined FBA_DEBUG
1660 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekSetRTECallback called without init\n"));
1661 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekSetRTECallback called when no CPU open\n"));
1662 #endif
1663 
1664 	pSekExt->RTECallback = pCallback;
1665 
1666 	return 0;
1667 }
1668 
SekSetIrqCallback(pSekIrqCallback pCallback)1669 INT32 SekSetIrqCallback(pSekIrqCallback pCallback)
1670 {
1671 #if defined FBA_DEBUG
1672 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekSetIrqCallback called without init\n"));
1673 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekSetIrqCallback called when no CPU open\n"));
1674 #endif
1675 
1676 	pSekExt->IrqCallback = pCallback;
1677 
1678 	return 0;
1679 }
1680 
SekSetCmpCallback(pSekCmpCallback pCallback)1681 INT32 SekSetCmpCallback(pSekCmpCallback pCallback)
1682 {
1683 #if defined FBA_DEBUG
1684 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekSetCmpCallback called without init\n"));
1685 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekSetCmpCallback called when no CPU open\n"));
1686 #endif
1687 
1688 	pSekExt->CmpCallback = pCallback;
1689 
1690 	return 0;
1691 }
1692 
SekSetTASCallback(pSekTASCallback pCallback)1693 INT32 SekSetTASCallback(pSekTASCallback pCallback)
1694 {
1695 #if defined FBA_DEBUG
1696 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekSetTASCallback called without init\n"));
1697 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekSetTASCallback called when no CPU open\n"));
1698 #endif
1699 
1700 	pSekExt->TASCallback = pCallback;
1701 
1702 	return 0;
1703 }
1704 
1705 // Set handlers
SekSetReadByteHandler(INT32 i,pSekReadByteHandler pHandler)1706 INT32 SekSetReadByteHandler(INT32 i, pSekReadByteHandler pHandler)
1707 {
1708 #if defined FBA_DEBUG
1709 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekSetReadByteHandler called without init\n"));
1710 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekSetReadByteHandler called when no CPU open\n"));
1711 #endif
1712 
1713 	if (i >= SEK_MAXHANDLER) {
1714 		return 1;
1715 	}
1716 
1717 	pSekExt->ReadByte[i] = pHandler;
1718 
1719 	return 0;
1720 }
1721 
SekSetWriteByteHandler(INT32 i,pSekWriteByteHandler pHandler)1722 INT32 SekSetWriteByteHandler(INT32 i, pSekWriteByteHandler pHandler)
1723 {
1724 #if defined FBA_DEBUG
1725 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekSetWriteByteHandler called without init\n"));
1726 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekSetWriteByteHandler called when no CPU open\n"));
1727 #endif
1728 
1729 	if (i >= SEK_MAXHANDLER) {
1730 		return 1;
1731 	}
1732 
1733 	pSekExt->WriteByte[i] = pHandler;
1734 
1735 	return 0;
1736 }
1737 
SekSetReadWordHandler(INT32 i,pSekReadWordHandler pHandler)1738 INT32 SekSetReadWordHandler(INT32 i, pSekReadWordHandler pHandler)
1739 {
1740 #if defined FBA_DEBUG
1741 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekSetReadWordHandler called without init\n"));
1742 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekSetReadWordHandler called when no CPU open\n"));
1743 #endif
1744 
1745 	if (i >= SEK_MAXHANDLER) {
1746 		return 1;
1747 	}
1748 
1749 	pSekExt->ReadWord[i] = pHandler;
1750 
1751 	return 0;
1752 }
1753 
SekSetWriteWordHandler(INT32 i,pSekWriteWordHandler pHandler)1754 INT32 SekSetWriteWordHandler(INT32 i, pSekWriteWordHandler pHandler)
1755 {
1756 #if defined FBA_DEBUG
1757 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekSetWriteWordHandler called without init\n"));
1758 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekSetWriteWordHandler called when no CPU open\n"));
1759 #endif
1760 
1761 	if (i >= SEK_MAXHANDLER) {
1762 		return 1;
1763 	}
1764 
1765 	pSekExt->WriteWord[i] = pHandler;
1766 
1767 	return 0;
1768 }
1769 
SekSetReadLongHandler(INT32 i,pSekReadLongHandler pHandler)1770 INT32 SekSetReadLongHandler(INT32 i, pSekReadLongHandler pHandler)
1771 {
1772 #if defined FBA_DEBUG
1773 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekSetReadLongHandler called without init\n"));
1774 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekSetReadLongHandler called when no CPU open\n"));
1775 #endif
1776 
1777 	if (i >= SEK_MAXHANDLER) {
1778 		return 1;
1779 	}
1780 
1781 	pSekExt->ReadLong[i] = pHandler;
1782 
1783 	return 0;
1784 }
1785 
SekSetWriteLongHandler(INT32 i,pSekWriteLongHandler pHandler)1786 INT32 SekSetWriteLongHandler(INT32 i, pSekWriteLongHandler pHandler)
1787 {
1788 #if defined FBA_DEBUG
1789 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekSetWriteLongHandler called without init\n"));
1790 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekSetWriteLongHandler called when no CPU open\n"));
1791 #endif
1792 
1793 	if (i >= SEK_MAXHANDLER) {
1794 		return 1;
1795 	}
1796 
1797 	pSekExt->WriteLong[i] = pHandler;
1798 
1799 	return 0;
1800 }
1801 
1802 // ----------------------------------------------------------------------------
1803 // Query register values
1804 
1805 #ifdef EMU_A68K
SekGetPC(INT32 n)1806 UINT32 SekGetPC(INT32 n)
1807 #else
1808 UINT32 SekGetPC(INT32)
1809 #endif
1810 {
1811 #if defined FBA_DEBUG
1812 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekGetPC called without init\n"));
1813 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekGetPC called when no CPU open\n"));
1814 #endif
1815 
1816 #ifdef EMU_A68K
1817 	if (nSekCPUType[nSekActive] == 0) {
1818 		if (n < 0) {								// Currently active CPU
1819 		  return M68000_regs.pc;
1820 		} else {
1821 			return SekRegs[n]->pc;					// Any CPU
1822 		}
1823 	} else {
1824 #endif
1825 
1826 #ifdef EMU_M68K
1827 		return m68k_get_reg(NULL, M68K_REG_PC);
1828 #else
1829 		return 0;
1830 #endif
1831 
1832 #ifdef EMU_A68K
1833 	}
1834 #endif
1835 
1836 }
1837 
SekDbgGetCPUType()1838 INT32 SekDbgGetCPUType()
1839 {
1840 #if defined FBA_DEBUG
1841 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekDbgGetCPUType called without init\n"));
1842 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekDbgGetCPUType called when no CPU open\n"));
1843 #endif
1844 
1845 	switch (nSekCPUType[nSekActive]) {
1846 		case 0:
1847 		case 0x68000:
1848 			return M68K_CPU_TYPE_68000;
1849 		case 0x68010:
1850 			return M68K_CPU_TYPE_68010;
1851 		case 0x68EC020:
1852 			return M68K_CPU_TYPE_68EC020;
1853 	}
1854 
1855 	return 0;
1856 }
1857 
SekDbgGetPendingIRQ()1858 INT32 SekDbgGetPendingIRQ()
1859 {
1860 #if defined FBA_DEBUG
1861 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekDbgGetPendingIRQ called without init\n"));
1862 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekDbgGetPendingIRQ called when no CPU open\n"));
1863 #endif
1864 
1865 	return nSekIRQPending[nSekActive] & 7;
1866 }
1867 
SekDbgGetRegister(SekRegister nRegister)1868 UINT32 SekDbgGetRegister(SekRegister nRegister)
1869 {
1870 #if defined FBA_DEBUG
1871 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekDbgGetRegister called without init\n"));
1872 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekDbgGetRegister called when no CPU open\n"));
1873 #endif
1874 
1875 #if defined EMU_A68K
1876 	if (nSekCPUType[nSekActive] == 0) {
1877 		switch (nRegister) {
1878 			case SEK_REG_D0:
1879 				return M68000_regs.d[0];
1880 			case SEK_REG_D1:
1881 				return M68000_regs.d[1];
1882 			case SEK_REG_D2:
1883 				return M68000_regs.d[2];
1884 			case SEK_REG_D3:
1885 				return M68000_regs.d[3];
1886 			case SEK_REG_D4:
1887 				return M68000_regs.d[4];
1888 			case SEK_REG_D5:
1889 				return M68000_regs.d[5];
1890 			case SEK_REG_D6:
1891 				return M68000_regs.d[6];
1892 			case SEK_REG_D7:
1893 				return M68000_regs.d[7];
1894 
1895 			case SEK_REG_A0:
1896 				return M68000_regs.a[0];
1897 			case SEK_REG_A1:
1898 				return M68000_regs.a[1];
1899 			case SEK_REG_A2:
1900 				return M68000_regs.a[2];
1901 			case SEK_REG_A3:
1902 				return M68000_regs.a[3];
1903 			case SEK_REG_A4:
1904 				return M68000_regs.a[4];
1905 			case SEK_REG_A5:
1906 				return M68000_regs.a[5];
1907 			case SEK_REG_A6:
1908 				return M68000_regs.a[6];
1909 			case SEK_REG_A7:
1910 				return M68000_regs.a[7];
1911 
1912 			case SEK_REG_PC:
1913 				return M68000_regs.pc;
1914 
1915 			case SEK_REG_SR:
1916 				return GetA68KSR();
1917 
1918 			case SEK_REG_SP:
1919 				return M68000_regs.a[7];
1920 			case SEK_REG_USP:
1921 				return GetA68KUSP();
1922 			case SEK_REG_ISP:
1923 				return GetA68KISP();
1924 
1925 			default:
1926 				return 0;
1927 		}
1928 	}
1929 #endif
1930 
1931 	switch (nRegister) {
1932 		case SEK_REG_D0:
1933 			return m68k_get_reg(NULL, M68K_REG_D0);
1934 		case SEK_REG_D1:
1935 			return m68k_get_reg(NULL, M68K_REG_D1);
1936 		case SEK_REG_D2:
1937 			return m68k_get_reg(NULL, M68K_REG_D2);
1938 		case SEK_REG_D3:
1939 			return m68k_get_reg(NULL, M68K_REG_D3);
1940 		case SEK_REG_D4:
1941 			return m68k_get_reg(NULL, M68K_REG_D4);
1942 		case SEK_REG_D5:
1943 			return m68k_get_reg(NULL, M68K_REG_D5);
1944 		case SEK_REG_D6:
1945 			return m68k_get_reg(NULL, M68K_REG_D6);
1946 		case SEK_REG_D7:
1947 			return m68k_get_reg(NULL, M68K_REG_D7);
1948 
1949 		case SEK_REG_A0:
1950 			return m68k_get_reg(NULL, M68K_REG_A0);
1951 		case SEK_REG_A1:
1952 			return m68k_get_reg(NULL, M68K_REG_A1);
1953 		case SEK_REG_A2:
1954 			return m68k_get_reg(NULL, M68K_REG_A2);
1955 		case SEK_REG_A3:
1956 			return m68k_get_reg(NULL, M68K_REG_A3);
1957 		case SEK_REG_A4:
1958 			return m68k_get_reg(NULL, M68K_REG_A4);
1959 		case SEK_REG_A5:
1960 			return m68k_get_reg(NULL, M68K_REG_A5);
1961 		case SEK_REG_A6:
1962 			return m68k_get_reg(NULL, M68K_REG_A6);
1963 		case SEK_REG_A7:
1964 			return m68k_get_reg(NULL, M68K_REG_A7);
1965 
1966 		case SEK_REG_PC:
1967 			return m68k_get_reg(NULL, M68K_REG_PC);
1968 		case SEK_REG_PPC:
1969 			return m68k_get_reg(NULL, M68K_REG_PPC);
1970 
1971 		case SEK_REG_SR:
1972 			return m68k_get_reg(NULL, M68K_REG_SR);
1973 
1974 		case SEK_REG_SP:
1975 			return m68k_get_reg(NULL, M68K_REG_SP);
1976 		case SEK_REG_USP:
1977 			return m68k_get_reg(NULL, M68K_REG_USP);
1978 		case SEK_REG_ISP:
1979 			return m68k_get_reg(NULL, M68K_REG_ISP);
1980 		case SEK_REG_MSP:
1981 			return m68k_get_reg(NULL, M68K_REG_MSP);
1982 
1983 		case SEK_REG_VBR:
1984 			return m68k_get_reg(NULL, M68K_REG_VBR);
1985 
1986 		case SEK_REG_SFC:
1987 			return m68k_get_reg(NULL, M68K_REG_SFC);
1988 		case SEK_REG_DFC:
1989 			return m68k_get_reg(NULL, M68K_REG_DFC);
1990 
1991 		case SEK_REG_CACR:
1992 			return m68k_get_reg(NULL, M68K_REG_CACR);
1993 		case SEK_REG_CAAR:
1994 			return m68k_get_reg(NULL, M68K_REG_CAAR);
1995 
1996 		default:
1997 			return 0;
1998 	}
1999 }
2000 
SekDbgSetRegister(SekRegister nRegister,UINT32 nValue)2001 bool SekDbgSetRegister(SekRegister nRegister, UINT32 nValue)
2002 {
2003 #if defined FBA_DEBUG
2004 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekDbgSetRegister called without init\n"));
2005 	if (nSekActive == -1) bprintf(PRINT_ERROR, _T("SekDbgSetRegister called when no CPU open\n"));
2006 #endif
2007 
2008 	switch (nRegister) {
2009 		case SEK_REG_D0:
2010 		case SEK_REG_D1:
2011 		case SEK_REG_D2:
2012 		case SEK_REG_D3:
2013 		case SEK_REG_D4:
2014 		case SEK_REG_D5:
2015 		case SEK_REG_D6:
2016 		case SEK_REG_D7:
2017 			break;
2018 
2019 		case SEK_REG_A0:
2020 		case SEK_REG_A1:
2021 		case SEK_REG_A2:
2022 		case SEK_REG_A3:
2023 		case SEK_REG_A4:
2024 		case SEK_REG_A5:
2025 		case SEK_REG_A6:
2026 		case SEK_REG_A7:
2027 			break;
2028 
2029 		case SEK_REG_PC:
2030 			if (nSekCPUType[nSekActive] == 0) {
2031 #if defined EMU_A68K
2032 				M68000_regs.pc = nValue;
2033 				A68KChangePC(M68000_regs.pc);
2034 #endif
2035 			} else {
2036 				m68k_set_reg(M68K_REG_PC, nValue);
2037 			}
2038 			SekClose();
2039 			return true;
2040 
2041 		case SEK_REG_SR:
2042 			break;
2043 
2044 		case SEK_REG_SP:
2045 		case SEK_REG_USP:
2046 		case SEK_REG_ISP:
2047 		case SEK_REG_MSP:
2048 			break;
2049 
2050 		case SEK_REG_VBR:
2051 			break;
2052 
2053 		case SEK_REG_SFC:
2054 		case SEK_REG_DFC:
2055 			break;
2056 
2057 		case SEK_REG_CACR:
2058 		case SEK_REG_CAAR:
2059 			break;
2060 
2061 		default:
2062 			break;
2063 	}
2064 
2065 	return false;
2066 }
2067 
2068 // ----------------------------------------------------------------------------
2069 // Savestate support
2070 
SekScan(INT32 nAction)2071 INT32 SekScan(INT32 nAction)
2072 {
2073 #if defined FBA_DEBUG
2074 	if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, _T("SekScan called without init\n"));
2075 #endif
2076 
2077 	// Scan the 68000 states
2078 	struct BurnArea ba;
2079 
2080 	if ((nAction & ACB_DRIVER_DATA) == 0) {
2081 		return 1;
2082 	}
2083 
2084 	memset(&ba, 0, sizeof(ba));
2085 
2086 	nSekActive = -1;
2087 
2088 	for (INT32 i = 0; i <= nSekCount; i++) {
2089 		char szName[] = "MC68000 #n";
2090 #if defined EMU_A68K && defined EMU_M68K
2091 		INT32 nType = nSekCPUType[i];
2092 #endif
2093 
2094 		szName[9] = '0' + i;
2095 
2096 		SCAN_VAR(nSekCPUType[i]);
2097 		SCAN_VAR(nSekIRQPending[i]);
2098 		SCAN_VAR(nSekCycles[i]);
2099 
2100 #if defined EMU_A68K && defined EMU_M68K
2101 		// Switch to another core if needed
2102 		if ((nAction & ACB_WRITE) && nType != nSekCPUType[i]) {
2103 			if (nType != 0 && nType != 0x68000 && nSekCPUType[i] != 0 && nSekCPUType[i] != 0x68000) {
2104 				continue;
2105 			}
2106 
2107 			if (nSekCPUType[i] == 0x68000) {
2108 				SekCPUExitA68K(i);
2109 				if (SekInitCPUM68K(i, 0x68000)) {
2110 					return 1;
2111 				}
2112 			} else {
2113 				SekCPUExitM68K(i);
2114 				if (SekInitCPUA68K(i, 0x68000)) {
2115 					return 1;
2116 				}
2117 			}
2118 		}
2119 #endif
2120 
2121 #ifdef EMU_A68K
2122 		if (nSekCPUType[i] == 0) {
2123 			ba.Data = SekRegs[i];
2124 			ba.nLen = sizeof(A68KContext);
2125 			ba.szName = szName;
2126 
2127 			if (nAction & ACB_READ) {
2128 				// Blank pointers
2129 				SekRegs[i]->IrqCallback = NULL;
2130 				SekRegs[i]->ResetCallback = NULL;
2131 			}
2132 
2133 			BurnAcb(&ba);
2134 
2135 			// Re-setup each cpu on read/write
2136 			if (nAction & ACB_ACCESSMASK) {
2137 				SekSetup(SekRegs[i]);
2138 			}
2139 		} else {
2140 #endif
2141 
2142 #ifdef EMU_M68K
2143 			if (nSekCPUType[i] != 0) {
2144 				ba.Data = SekM68KContext[i];
2145 				// for savestate portability: preserve our cpu's pointers, they are set up in DrvInit() and can be specific to different systems.
2146 				// Therefore we scan the cpu context structure up until right before the pointers
2147 				ba.nLen = m68k_context_size_no_pointers();
2148 				ba.szName = szName;
2149 				BurnAcb(&ba);
2150 			}
2151 #endif
2152 
2153 #ifdef EMU_A68K
2154 		}
2155 #endif
2156 
2157 	}
2158 
2159 	return 0;
2160 }
2161