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