1 // 68000 (Sixty Eight K) Interface - header file
2 #include <stdint.h>
3 #ifndef FASTCALL
4 #undef __fastcall
5 #define __fastcall
6 #endif
7
8 #if defined BUILD_A68K
9 #define EMU_A68K // Use A68K Assembler 68000 emulator
10 #endif
11
12 #define EMU_M68K // Use Musashi 68000 emulator
13
14 #define SEK_MAX (5) // Maximum number of CPUs supported
15
16 #if defined EMU_M68K
17 #include "m68k/m68k.h"
18 #endif
19
20 // Number of bits used for each page in the fast memory map
21 #define SEK_BITS (10) // 10 = 0x0400 page size
22 #define SEK_PAGE_COUNT (1 << (24 - SEK_BITS)) // Number of pages
23 #define SEK_SHIFT (SEK_BITS) // Shift value = page bits
24 #define SEK_PAGE_SIZE (1 << SEK_BITS) // Page size
25 #define SEK_PAGEM (SEK_PAGE_SIZE - 1)
26 #define SEK_WADD (SEK_PAGE_COUNT) // Value to add for write section = Number of pages
27 #define SEK_MASK (SEK_WADD - 1)
28 #define SEK_MAXHANDLER (10) // Max. number of handlers for memory access
29
30 #if SEK_MAXHANDLER < 1
31 #error At least one set of handlers for memory access must be used.
32 #endif
33
34 #ifdef EMU_A68K
35 extern "C" void __cdecl M68000_RUN();
36 extern "C" void __cdecl M68000_RESET();
37 #endif
38
39 #ifdef EMU_A68K
40 // The format of the data in a68k.asm (at the _M68000_regs location)
41 struct A68KContext {
42 UINT32 d[8], a[8];
43 UINT32 isp, srh, ccr, xc, pc, irq, sr;
44 INT32 (*IrqCallback) (INT32 nIrq);
45 UINT32 ppc;
46 INT32 (*ResetCallback)();
47 INT32 (*RTECallback)();
48 INT32 (*CmpCallback)(UINT32 val, INT32 reg);
49 UINT32 sfc, dfc, usp, vbr;
50 UINT32 nAsmBank, nCpuVersion;
51 };
52 extern "C" struct A68KContext M68000_regs;
53 extern struct A68KContext* SekRegs[SEK_MAX];
54
55 extern "C" UINT8* OP_ROM;
56 extern "C" UINT8* OP_RAM;
57
58 void __fastcall AsekChangePc(UINT32 pc);
59 #endif
60
61 #ifdef EMU_M68K
62 extern "C" INT32 nSekM68KContextSize[SEK_MAX];
63 extern "C" INT8* SekM68KContext[SEK_MAX];
64 extern "C" INT32 m68k_ICount;
65 #endif
66
67 typedef UINT8 (__fastcall *pSekReadByteHandler)(UINT32 a);
68 typedef void (__fastcall *pSekWriteByteHandler)(UINT32 a, UINT8 d);
69 typedef UINT16 (__fastcall *pSekReadWordHandler)(UINT32 a);
70 typedef void (__fastcall *pSekWriteWordHandler)(UINT32 a, UINT16 d);
71 typedef UINT32 (__fastcall *pSekReadLongHandler)(UINT32 a);
72 typedef void (__fastcall *pSekWriteLongHandler)(UINT32 a, UINT32 d);
73
74 typedef INT32 (__fastcall *pSekResetCallback)();
75 typedef INT32 (__fastcall *pSekRTECallback)();
76 typedef INT32 (__fastcall *pSekIrqCallback)(INT32 irq);
77 typedef INT32 (__fastcall *pSekCmpCallback)(UINT32 val, INT32 reg);
78 typedef INT32 (__fastcall *pSekTASCallback)();
79
80 extern INT32 nSekCycles[SEK_MAX], nSekCPUType[SEK_MAX];
81
82 // Mapped memory pointers to Rom and Ram areas (Read then Write)
83 // These memory areas must be allocated multiples of the page size
84 // with a 4 byte over-run area lookup for each page (*3 for read, write and fetch)
85 struct SekExt {
86 UINT8* MemMap[SEK_PAGE_COUNT * 3];
87
88 // If MemMap[i] < SEK_MAXHANDLER, use the handler functions
89 pSekReadByteHandler ReadByte[SEK_MAXHANDLER];
90 pSekWriteByteHandler WriteByte[SEK_MAXHANDLER];
91 pSekReadWordHandler ReadWord[SEK_MAXHANDLER];
92 pSekWriteWordHandler WriteWord[SEK_MAXHANDLER];
93 pSekReadLongHandler ReadLong[SEK_MAXHANDLER];
94 pSekWriteLongHandler WriteLong[SEK_MAXHANDLER];
95
96 pSekResetCallback ResetCallback;
97 pSekRTECallback RTECallback;
98 pSekIrqCallback IrqCallback;
99 pSekCmpCallback CmpCallback;
100 pSekTASCallback TASCallback;
101 };
102
103 #define SEK_DEF_READ_WORD(i, a) { UINT16 d; d = (UINT16)(pSekExt->ReadByte[i](a) << 8); d |= (UINT16)(pSekExt->ReadByte[i]((a) + 1)); return d; }
104 #define SEK_DEF_WRITE_WORD(i, a, d) { pSekExt->WriteByte[i]((a),(UINT8)((d) >> 8)); pSekExt->WriteByte[i]((a) + 1, (UINT8)((d) & 0xff)); }
105 #define SEK_DEF_READ_LONG(i, a) { UINT32 d; d = pSekExt->ReadWord[i](a) << 16; d |= pSekExt->ReadWord[i]((a) + 2); return d; }
106 #define SEK_DEF_WRITE_LONG(i, a, d) { pSekExt->WriteWord[i]((a),(UINT16)((d) >> 16)); pSekExt->WriteWord[i]((a) + 2,(UINT16)((d) & 0xffff)); }
107
108 extern struct SekExt *SekExt[SEK_MAX], *pSekExt;
109 extern INT32 nSekActive; // The cpu which is currently being emulated
110 extern INT32 nSekCyclesTotal, nSekCyclesScanline, nSekCyclesSegment, nSekCyclesDone, nSekCyclesToDo;
111
112 UINT32 SekReadByte(UINT32 a);
113 UINT32 SekReadWord(UINT32 a);
114 UINT32 SekReadLong(UINT32 a);
115
116 UINT32 SekFetchByte(UINT32 a);
117 UINT32 SekFetchWord(UINT32 a);
118 UINT32 SekFetchLong(UINT32 a);
119
120 void SekWriteByte(UINT32 a, UINT8 d);
121 void SekWriteWord(UINT32 a, UINT16 d);
122 void SekWriteLong(UINT32 a, UINT32 d);
123
124 void SekWriteByteROM(UINT32 a, UINT8 d);
125 void SekWriteWordROM(UINT32 a, UINT16 d);
126 void SekWriteLongROM(UINT32 a, UINT32 d);
127
128 INT32 SekInit(INT32 nCount, INT32 nCPUType);
129 INT32 SekExit();
130
131 void SekNewFrame();
132 void SekSetCyclesScanline(INT32 nCycles);
133
134 void SekClose();
135 void SekOpen(const INT32 i);
136 INT32 SekGetActive();
137 INT32 SekShouldInterrupt(); // megadrive
138 void SekBurnUntilInt();
139
140 void SekCPUPush(INT32 nCPU);
141 void SekCPUPop();
142 INT32 SekCPUGetStackNum();
143
144 #define SEK_IRQSTATUS_NONE (0x0000)
145 #define SEK_IRQSTATUS_VAUTO (0x4000)
146 #define SEK_IRQSTATUS_AUTO (0x2000)
147 #define SEK_IRQSTATUS_ACK (0x1000)
148
149 void SekSetIRQLine(const INT32 line, INT32 status);
150 void SekSetIRQLine(INT32 nCPU, const INT32 line, INT32 status);
151 void SekSetVIRQLine(const INT32 line, INT32 nstatus);
152 void SekSetVIRQLine(INT32 nCPU, const INT32 line, INT32 status);
153
154 void SekReset();
155 void SekReset(INT32 nCPU);
156
157 void SekRunEnd();
158 void SekRunAdjust(const INT32 nCycles);
159 INT32 SekRun(const INT32 nCycles);
160 INT32 SekRun(INT32 nCPU, INT32 nCycles);
161 void SekSetRESETLine(INT32 nStatus);
162 void SekSetRESETLine(INT32 nCPU, INT32 nStatus);
163 INT32 SekGetRESETLine();
164 INT32 SekGetRESETLine(INT32 nCPU);
165
166 void SekSetHALT(INT32 nStatus);
167 void SekSetHALT(INT32 nCPU, INT32 nStatus);
168 INT32 SekGetHALT();
169 INT32 SekGetHALT(INT32 nCPU);
170
171 INT32 SekIdle(INT32 nCPU, INT32 nCycles);
172
SekIdle(INT32 nCycles)173 inline static INT32 SekIdle(INT32 nCycles)
174 {
175 #if defined FBNEO_DEBUG
176 extern UINT8 DebugCPU_SekInitted;
177 if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, (TCHAR*)_T("SekIdle called without init\n"));
178 if (nSekActive == -1) bprintf(PRINT_ERROR, (TCHAR*)_T("SekIdle called when no CPU open\n"));
179 #endif
180
181 nSekCyclesTotal += nCycles;
182
183 return nCycles;
184 }
185
SekSegmentCycles()186 inline static INT32 SekSegmentCycles()
187 {
188 #if defined FBNEO_DEBUG
189 extern UINT8 DebugCPU_SekInitted;
190 if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, (TCHAR*)_T("SekSegmentCycles called without init\n"));
191 if (nSekActive == -1) bprintf(PRINT_ERROR, (TCHAR*)_T("SekSegmentCycles called when no CPU open\n"));
192 #endif
193
194 #ifdef EMU_M68K
195 return nSekCyclesDone + nSekCyclesToDo - m68k_ICount;
196 #else
197 return nSekCyclesDone + nSekCyclesToDo;
198 #endif
199 }
200
201 INT32 SekTotalCycles(INT32 nCPU);
202
203 #if defined FBNEO_DEBUG
SekTotalCycles()204 static INT32 SekTotalCycles()
205 #else
206 inline static INT32 SekTotalCycles()
207 #endif
208 {
209 #if defined FBNEO_DEBUG
210 extern UINT8 DebugCPU_SekInitted;
211 if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, (TCHAR*)_T("SekTotalCycles called without init\n"));
212 if (nSekActive == -1) bprintf(PRINT_ERROR, (TCHAR*)_T("SekTotalCycles called when no CPU open\n"));
213 #endif
214
215 #ifdef EMU_M68K
216 return nSekCyclesTotal + nSekCyclesToDo - m68k_ICount;
217 #else
218 return nSekCyclesTotal + nSekCyclesToDo;
219 #endif
220 }
221
SekCurrentScanline()222 inline static INT32 SekCurrentScanline()
223 {
224 #if defined FBNEO_DEBUG
225 extern UINT8 DebugCPU_SekInitted;
226 if (!DebugCPU_SekInitted) bprintf(PRINT_ERROR, (TCHAR*)_T("SekCurrentScanline called without init\n"));
227 if (nSekActive == -1) bprintf(PRINT_ERROR, (TCHAR*)_T("SekCurrentScanline called when no CPU open\n"));
228 #endif
229
230 return SekTotalCycles() / nSekCyclesScanline;
231 }
232
233 // Mask off address bits (usually top, default is 0xffffff)
234 void SekSetAddressMask(UINT32 nAddressMask);
235
236 // Map areas of memory
237 INT32 SekMapMemory(UINT8* pMemory, UINT32 nStart, UINT32 nEnd, INT32 nType);
238 INT32 SekMapHandler(uintptr_t nHandler, UINT32 nStart, UINT32 nEnd, INT32 nType);
239
240 // Set handlers
241 INT32 SekSetReadByteHandler(INT32 i, pSekReadByteHandler pHandler);
242 INT32 SekSetWriteByteHandler(INT32 i, pSekWriteByteHandler pHandler);
243 INT32 SekSetReadWordHandler(INT32 i, pSekReadWordHandler pHandler);
244 INT32 SekSetWriteWordHandler(INT32 i, pSekWriteWordHandler pHandler);
245 INT32 SekSetReadLongHandler(INT32 i, pSekReadLongHandler pHandler);
246 INT32 SekSetWriteLongHandler(INT32 i, pSekWriteLongHandler pHandler);
247
248 // Set callbacks
249 INT32 SekSetResetCallback(pSekResetCallback pCallback);
250 INT32 SekSetRTECallback(pSekRTECallback pCallback);
251 INT32 SekSetIrqCallback(pSekIrqCallback pCallback);
252 INT32 SekSetCmpCallback(pSekCmpCallback pCallback);
253 INT32 SekSetTASCallback(pSekTASCallback pCallback);
254
255 // Get a CPU's PC
256 UINT32 SekGetPC(INT32 n);
257 UINT32 SekGetPPC(INT32);
258
259 INT32 SekScan(INT32 nAction);
260
261
262 UINT8 SekCheatRead(UINT32 a); // cheat core
263
264 extern struct cpu_core_config SekConfig;
265
266 // depreciate this and use BurnTimerAttach directly!
267 #define BurnTimerAttachSek(clock) \
268 BurnTimerAttach(&SekConfig, clock)
269