forgotten credit..
[picodrive.git] / cpu / musashi / m68k.h
CommitLineData
cc68a136 1#ifndef M68K__HEADER\r
2#define M68K__HEADER\r
3\r
4/* ======================================================================== */\r
5/* ========================= LICENSING & COPYRIGHT ======================== */\r
6/* ======================================================================== */\r
7/*\r
8 * MUSASHI\r
c6a4c892 9 * Version 3.31\r
cc68a136 10 *\r
11 * A portable Motorola M680x0 processor emulation engine.\r
c6a4c892 12 * Copyright 1998-2007 Karl Stenerud. All rights reserved.\r
cc68a136 13 *\r
14 * This code may be freely used for non-commercial purposes as long as this\r
15 * copyright notice remains unaltered in the source code and any binary files\r
16 * containing this code in compiled form.\r
17 *\r
18 * All other lisencing terms must be negotiated with the author\r
19 * (Karl Stenerud).\r
20 *\r
21 * The latest version of this code can be obtained at:\r
22 * http://kstenerud.cjb.net\r
23 */\r
24\r
25/* ======================================================================== */\r
26/* ============================= CONFIGURATION ============================ */\r
27/* ======================================================================== */\r
28\r
29/* Import the configuration for this build */\r
30#include "m68kconf.h"\r
31\r
32\r
33/* ======================================================================== */\r
34/* ============================ GENERAL DEFINES =========================== */\r
35\r
36/* ======================================================================== */\r
37\r
38/* There are 7 levels of interrupt to the 68K.\r
39 * A transition from < 7 to 7 will cause a non-maskable interrupt (NMI).\r
40 */\r
41#define M68K_IRQ_NONE 0\r
42#define M68K_IRQ_1 1\r
43#define M68K_IRQ_2 2\r
44#define M68K_IRQ_3 3\r
45#define M68K_IRQ_4 4\r
46#define M68K_IRQ_5 5\r
47#define M68K_IRQ_6 6\r
48#define M68K_IRQ_7 7\r
49\r
50\r
51/* Special interrupt acknowledge values.\r
52 * Use these as special returns from the interrupt acknowledge callback\r
53 * (specified later in this header).\r
54 */\r
55\r
56/* Causes an interrupt autovector (0x18 + interrupt level) to be taken.\r
57 * This happens in a real 68K if VPA or AVEC is asserted during an interrupt\r
58 * acknowledge cycle instead of DTACK.\r
59 */\r
60#define M68K_INT_ACK_AUTOVECTOR 0xffffffff\r
61\r
62/* Causes the spurious interrupt vector (0x18) to be taken\r
63 * This happens in a real 68K if BERR is asserted during the interrupt\r
64 * acknowledge cycle (i.e. no devices responded to the acknowledge).\r
65 */\r
66#define M68K_INT_ACK_SPURIOUS 0xfffffffe\r
67\r
68\r
69/* CPU types for use in m68k_set_cpu_type() */\r
70enum\r
71{\r
72 M68K_CPU_TYPE_INVALID,\r
73 M68K_CPU_TYPE_68000,\r
74 M68K_CPU_TYPE_68008,\r
75 M68K_CPU_TYPE_68010,\r
76 M68K_CPU_TYPE_68EC020,\r
77 M68K_CPU_TYPE_68020,\r
78 M68K_CPU_TYPE_68030, /* Supported by disassembler ONLY */\r
79 M68K_CPU_TYPE_68040 /* Supported by disassembler ONLY */\r
80};\r
81\r
82/* Registers used by m68k_get_reg() and m68k_set_reg() */\r
83typedef enum\r
84{\r
85 /* Real registers */\r
86 M68K_REG_D0, /* Data registers */\r
87 M68K_REG_D1,\r
88 M68K_REG_D2,\r
89 M68K_REG_D3,\r
90 M68K_REG_D4,\r
91 M68K_REG_D5,\r
92 M68K_REG_D6,\r
93 M68K_REG_D7,\r
94 M68K_REG_A0, /* Address registers */\r
95 M68K_REG_A1,\r
96 M68K_REG_A2,\r
97 M68K_REG_A3,\r
98 M68K_REG_A4,\r
99 M68K_REG_A5,\r
100 M68K_REG_A6,\r
101 M68K_REG_A7,\r
102 M68K_REG_PC, /* Program Counter */\r
103 M68K_REG_SR, /* Status Register */\r
104 M68K_REG_SP, /* The current Stack Pointer (located in A7) */\r
105 M68K_REG_USP, /* User Stack Pointer */\r
106 M68K_REG_ISP, /* Interrupt Stack Pointer */\r
107 M68K_REG_MSP, /* Master Stack Pointer */\r
108 M68K_REG_SFC, /* Source Function Code */\r
109 M68K_REG_DFC, /* Destination Function Code */\r
110 M68K_REG_VBR, /* Vector Base Register */\r
111 M68K_REG_CACR, /* Cache Control Register */\r
112 M68K_REG_CAAR, /* Cache Address Register */\r
113\r
114 /* Assumed registers */\r
115 /* These are cheat registers which emulate the 1-longword prefetch\r
116 * present in the 68000 and 68010.\r
117 */\r
118 M68K_REG_PREF_ADDR, /* Last prefetch address */\r
119 M68K_REG_PREF_DATA, /* Last prefetch data */\r
120\r
121 /* Convenience registers */\r
122 M68K_REG_PPC, /* Previous value in the program counter */\r
123 M68K_REG_IR, /* Instruction register */\r
124 M68K_REG_CPU_TYPE /* Type of CPU being run */\r
125} m68k_register_t;\r
126\r
127/* ======================================================================== */\r
128/* ====================== FUNCTIONS CALLED BY THE CPU ===================== */\r
129/* ======================================================================== */\r
130\r
131/* You will have to implement these functions */\r
132\r
133/* read/write functions called by the CPU to access memory.\r
134 * while values used are 32 bits, only the appropriate number\r
135 * of bits are relevant (i.e. in write_memory_8, only the lower 8 bits\r
136 * of value should be written to memory).\r
137 *\r
138 * NOTE: I have separated the immediate and PC-relative memory fetches\r
139 * from the other memory fetches because some systems require\r
140 * differentiation between PROGRAM and DATA fetches (usually\r
141 * for security setups such as encryption).\r
142 * This separation can either be achieved by setting\r
143 * M68K_SEPARATE_READS in m68kconf.h and defining\r
144 * the read functions, or by setting M68K_EMULATE_FC and\r
145 * making a function code callback function.\r
146 * Using the callback offers better emulation coverage\r
147 * because you can also monitor whether the CPU is in SYSTEM or\r
148 * USER mode, but it is also slower.\r
149 */\r
150\r
151/* Read from anywhere */\r
152unsigned int m68k_read_memory_8(unsigned int address);\r
153unsigned int m68k_read_memory_16(unsigned int address);\r
154unsigned int m68k_read_memory_32(unsigned int address);\r
155\r
156/* Read data immediately following the PC */\r
157unsigned int m68k_read_immediate_16(unsigned int address);\r
158unsigned int m68k_read_immediate_32(unsigned int address);\r
159\r
160/* Read data relative to the PC */\r
161unsigned int m68k_read_pcrelative_8(unsigned int address);\r
162unsigned int m68k_read_pcrelative_16(unsigned int address);\r
163unsigned int m68k_read_pcrelative_32(unsigned int address);\r
164\r
165/* Memory access for the disassembler */\r
166unsigned int m68k_read_disassembler_8 (unsigned int address);\r
167unsigned int m68k_read_disassembler_16 (unsigned int address);\r
168unsigned int m68k_read_disassembler_32 (unsigned int address);\r
169\r
170/* Write to anywhere */\r
171void m68k_write_memory_8(unsigned int address, unsigned int value);\r
172void m68k_write_memory_16(unsigned int address, unsigned int value);\r
173void m68k_write_memory_32(unsigned int address, unsigned int value);\r
174\r
175/* Special call to simulate undocumented 68k behavior when move.l with a\r
176 * predecrement destination mode is executed.\r
177 * To simulate real 68k behavior, first write the high word to\r
178 * [address+2], and then write the low word to [address].\r
179 *\r
180 * Enable this functionality with M68K_SIMULATE_PD_WRITES in m68kconf.h.\r
181 */\r
182void m68k_write_memory_32_pd(unsigned int address, unsigned int value);\r
183\r
184\r
185\r
186/* ======================================================================== */\r
187/* ============================== CALLBACKS =============================== */\r
188/* ======================================================================== */\r
189\r
190/* These functions allow you to set callbacks to the host when specific events\r
191 * occur. Note that you must enable the corresponding value in m68kconf.h\r
192 * in order for these to do anything useful.\r
193 * Note: I have defined default callbacks which are used if you have enabled\r
194 * the corresponding #define in m68kconf.h but either haven't assigned a\r
195 * callback or have assigned a callback of NULL.\r
196 */\r
197\r
198/* Set the callback for an interrupt acknowledge.\r
199 * You must enable M68K_EMULATE_INT_ACK in m68kconf.h.\r
200 * The CPU will call the callback with the interrupt level being acknowledged.\r
201 * The host program must return either a vector from 0x02-0xff, or one of the\r
202 * special interrupt acknowledge values specified earlier in this header.\r
203 * If this is not implemented, the CPU will always assume an autovectored\r
204 * interrupt, and will automatically clear the interrupt request when it\r
205 * services the interrupt.\r
206 * Default behavior: return M68K_INT_ACK_AUTOVECTOR.\r
207 */\r
208void m68k_set_int_ack_callback(int (*callback)(int int_level));\r
209\r
210\r
211/* Set the callback for a breakpoint acknowledge (68010+).\r
212 * You must enable M68K_EMULATE_BKPT_ACK in m68kconf.h.\r
213 * The CPU will call the callback with whatever was in the data field of the\r
214 * BKPT instruction for 68020+, or 0 for 68010.\r
215 * Default behavior: do nothing.\r
216 */\r
217void m68k_set_bkpt_ack_callback(void (*callback)(unsigned int data));\r
218\r
219\r
220/* Set the callback for the RESET instruction.\r
221 * You must enable M68K_EMULATE_RESET in m68kconf.h.\r
222 * The CPU calls this callback every time it encounters a RESET instruction.\r
223 * Default behavior: do nothing.\r
224 */\r
225void m68k_set_reset_instr_callback(void (*callback)(void));\r
226\r
227\r
228/* Set the callback for the CMPI.L #v, Dn instruction.\r
229 * You must enable M68K_CMPILD_HAS_CALLBACK in m68kconf.h.\r
230 * The CPU calls this callback every time it encounters a CMPI.L #v, Dn instruction.\r
231 * Default behavior: do nothing.\r
232 */\r
233void m68k_set_cmpild_instr_callback(void (*callback)(unsigned int val, int reg));\r
234\r
235\r
236/* Set the callback for the RTE instruction.\r
237 * You must enable M68K_RTE_HAS_CALLBACK in m68kconf.h.\r
238 * The CPU calls this callback every time it encounters a RTE instruction.\r
239 * Default behavior: do nothing.\r
240 */\r
241void m68k_set_rte_instr_callback(void (*callback)(void));\r
242\r
c6a4c892 243/* Set the callback for the TAS instruction.\r
244 * You must enable M68K_TAS_HAS_CALLBACK in m68kconf.h.\r
245 * The CPU calls this callback every time it encounters a TAS instruction.\r
246 * Default behavior: return 1, allow writeback.\r
247 */\r
248void m68k_set_tas_instr_callback(int (*callback)(void));\r
249\r
250\r
cc68a136 251\r
252/* Set the callback for informing of a large PC change.\r
253 * You must enable M68K_MONITOR_PC in m68kconf.h.\r
254 * The CPU calls this callback with the new PC value every time the PC changes\r
255 * by a large value (currently set for changes by longwords).\r
256 * Default behavior: do nothing.\r
257 */\r
258void m68k_set_pc_changed_callback(void (*callback)(unsigned int new_pc));\r
259\r
260\r
261/* Set the callback for CPU function code changes.\r
262 * You must enable M68K_EMULATE_FC in m68kconf.h.\r
263 * The CPU calls this callback with the function code before every memory\r
264 * access to set the CPU's function code according to what kind of memory\r
265 * access it is (supervisor/user, program/data and such).\r
266 * Default behavior: do nothing.\r
267 */\r
268void m68k_set_fc_callback(void (*callback)(unsigned int new_fc));\r
269\r
270\r
271/* Set a callback for the instruction cycle of the CPU.\r
272 * You must enable M68K_INSTRUCTION_HOOK in m68kconf.h.\r
273 * The CPU calls this callback just before fetching the opcode in the\r
274 * instruction cycle.\r
275 * Default behavior: do nothing.\r
276 */\r
277void m68k_set_instr_hook_callback(void (*callback)(void));\r
278\r
279\r
280\r
281/* ======================================================================== */\r
282/* ====================== FUNCTIONS TO ACCESS THE CPU ===================== */\r
283/* ======================================================================== */\r
284\r
285/* Use this function to set the CPU type you want to emulate.\r
286 * Currently supported types are: M68K_CPU_TYPE_68000, M68K_CPU_TYPE_68008,\r
287 * M68K_CPU_TYPE_68010, M68K_CPU_TYPE_EC020, and M68K_CPU_TYPE_68020.\r
288 */\r
289void m68k_set_cpu_type(unsigned int cpu_type);\r
290\r
291/* Do whatever initialisations the core requires. Should be called\r
292 * at least once at init time.\r
293 */\r
294void m68k_init(void);\r
295\r
296/* Pulse the RESET pin on the CPU.\r
297 * You *MUST* reset the CPU at least once to initialize the emulation\r
298 * Note: If you didn't call m68k_set_cpu_type() before resetting\r
299 * the CPU for the first time, the CPU will be set to\r
300 * M68K_CPU_TYPE_68000.\r
301 */\r
302void m68k_pulse_reset(void);\r
303\r
304/* execute num_cycles worth of instructions. returns number of cycles used */\r
305int m68k_execute(int num_cycles);\r
306\r
307/* These functions let you read/write/modify the number of cycles left to run\r
308 * while m68k_execute() is running.\r
309 * These are useful if the 68k accesses a memory-mapped port on another device\r
310 * that requires immediate processing by another CPU.\r
311 */\r
312int m68k_cycles_run(void); /* Number of cycles run so far */\r
313int m68k_cycles_remaining(void); /* Number of cycles left */\r
314void m68k_modify_timeslice(int cycles); /* Modify cycles left */\r
315void m68k_end_timeslice(void); /* End timeslice now */\r
316\r
317/* Set the IPL0-IPL2 pins on the CPU (IRQ).\r
318 * A transition from < 7 to 7 will cause a non-maskable interrupt (NMI).\r
319 * Setting IRQ to 0 will clear an interrupt request.\r
320 */\r
321void m68k_set_irq(unsigned int int_level);\r
322\r
323\r
324/* Halt the CPU as if you pulsed the HALT pin. */\r
325void m68k_pulse_halt(void);\r
326\r
327\r
328/* Context switching to allow multiple CPUs */\r
329\r
330/* Get the size of the cpu context in bytes */\r
331unsigned int m68k_context_size(void);\r
332\r
333/* Get a cpu context */\r
334unsigned int m68k_get_context(void* dst);\r
335\r
336/* set the current cpu context */\r
337void m68k_set_context(void* dst);\r
338\r
339/* Register the CPU state information */\r
340void m68k_state_register(const char *type, int index);\r
341\r
342\r
343/* Peek at the internals of a CPU context. This can either be a context\r
344 * retrieved using m68k_get_context() or the currently running context.\r
345 * If context is NULL, the currently running CPU context will be used.\r
346 */\r
347unsigned int m68k_get_reg(void* context, m68k_register_t reg);\r
348\r
349/* Poke values into the internals of the currently running CPU context */\r
350void m68k_set_reg(m68k_register_t reg, unsigned int value);\r
351\r
352/* Check if an instruction is valid for the specified CPU type */\r
353unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type);\r
354\r
355/* Disassemble 1 instruction using the epecified CPU type at pc. Stores\r
356 * disassembly in str_buff and returns the size of the instruction in bytes.\r
357 */\r
358unsigned int m68k_disassemble(char* str_buff, unsigned int pc, unsigned int cpu_type);\r
359\r
360/* Same as above but accepts raw opcode data directly rather than fetching\r
361 * via the read/write interfaces.\r
362 */\r
c6a4c892 363unsigned int m68k_disassemble_raw(char* str_buff, unsigned int pc, const unsigned char* opdata, const unsigned char* argdata, unsigned int cpu_type);\r
cc68a136 364\r
365\r
366/* ======================================================================== */\r
367/* ============================== MAME STUFF ============================== */\r
368/* ======================================================================== */\r
369\r
370#if M68K_COMPILE_FOR_MAME == OPT_ON\r
371#include "m68kmame.h"\r
372#endif /* M68K_COMPILE_FOR_MAME */\r
373\r
374\r
375/* ======================================================================== */\r
376/* ============================== END OF FILE ============================= */\r
377/* ======================================================================== */\r
378\r
379#endif /* M68K__HEADER */\r