z80 timing change
[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
9 * Version 3.3\r
10 *\r
11 * A portable Motorola M680x0 processor emulation engine.\r
12 * Copyright 1998-2001 Karl Stenerud. All rights reserved.\r
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
243\r
244/* Set the callback for informing of a large PC change.\r
245 * You must enable M68K_MONITOR_PC in m68kconf.h.\r
246 * The CPU calls this callback with the new PC value every time the PC changes\r
247 * by a large value (currently set for changes by longwords).\r
248 * Default behavior: do nothing.\r
249 */\r
250void m68k_set_pc_changed_callback(void (*callback)(unsigned int new_pc));\r
251\r
252\r
253/* Set the callback for CPU function code changes.\r
254 * You must enable M68K_EMULATE_FC in m68kconf.h.\r
255 * The CPU calls this callback with the function code before every memory\r
256 * access to set the CPU's function code according to what kind of memory\r
257 * access it is (supervisor/user, program/data and such).\r
258 * Default behavior: do nothing.\r
259 */\r
260void m68k_set_fc_callback(void (*callback)(unsigned int new_fc));\r
261\r
262\r
263/* Set a callback for the instruction cycle of the CPU.\r
264 * You must enable M68K_INSTRUCTION_HOOK in m68kconf.h.\r
265 * The CPU calls this callback just before fetching the opcode in the\r
266 * instruction cycle.\r
267 * Default behavior: do nothing.\r
268 */\r
269void m68k_set_instr_hook_callback(void (*callback)(void));\r
270\r
271\r
272\r
273/* ======================================================================== */\r
274/* ====================== FUNCTIONS TO ACCESS THE CPU ===================== */\r
275/* ======================================================================== */\r
276\r
277/* Use this function to set the CPU type you want to emulate.\r
278 * Currently supported types are: M68K_CPU_TYPE_68000, M68K_CPU_TYPE_68008,\r
279 * M68K_CPU_TYPE_68010, M68K_CPU_TYPE_EC020, and M68K_CPU_TYPE_68020.\r
280 */\r
281void m68k_set_cpu_type(unsigned int cpu_type);\r
282\r
283/* Do whatever initialisations the core requires. Should be called\r
284 * at least once at init time.\r
285 */\r
286void m68k_init(void);\r
287\r
288/* Pulse the RESET pin on the CPU.\r
289 * You *MUST* reset the CPU at least once to initialize the emulation\r
290 * Note: If you didn't call m68k_set_cpu_type() before resetting\r
291 * the CPU for the first time, the CPU will be set to\r
292 * M68K_CPU_TYPE_68000.\r
293 */\r
294void m68k_pulse_reset(void);\r
295\r
296/* execute num_cycles worth of instructions. returns number of cycles used */\r
297int m68k_execute(int num_cycles);\r
298\r
299/* These functions let you read/write/modify the number of cycles left to run\r
300 * while m68k_execute() is running.\r
301 * These are useful if the 68k accesses a memory-mapped port on another device\r
302 * that requires immediate processing by another CPU.\r
303 */\r
304int m68k_cycles_run(void); /* Number of cycles run so far */\r
305int m68k_cycles_remaining(void); /* Number of cycles left */\r
306void m68k_modify_timeslice(int cycles); /* Modify cycles left */\r
307void m68k_end_timeslice(void); /* End timeslice now */\r
308\r
309/* Set the IPL0-IPL2 pins on the CPU (IRQ).\r
310 * A transition from < 7 to 7 will cause a non-maskable interrupt (NMI).\r
311 * Setting IRQ to 0 will clear an interrupt request.\r
312 */\r
313void m68k_set_irq(unsigned int int_level);\r
314\r
315\r
316/* Halt the CPU as if you pulsed the HALT pin. */\r
317void m68k_pulse_halt(void);\r
318\r
319\r
320/* Context switching to allow multiple CPUs */\r
321\r
322/* Get the size of the cpu context in bytes */\r
323unsigned int m68k_context_size(void);\r
324\r
325/* Get a cpu context */\r
326unsigned int m68k_get_context(void* dst);\r
327\r
328/* set the current cpu context */\r
329void m68k_set_context(void* dst);\r
330\r
331/* Register the CPU state information */\r
332void m68k_state_register(const char *type, int index);\r
333\r
334\r
335/* Peek at the internals of a CPU context. This can either be a context\r
336 * retrieved using m68k_get_context() or the currently running context.\r
337 * If context is NULL, the currently running CPU context will be used.\r
338 */\r
339unsigned int m68k_get_reg(void* context, m68k_register_t reg);\r
340\r
341/* Poke values into the internals of the currently running CPU context */\r
342void m68k_set_reg(m68k_register_t reg, unsigned int value);\r
343\r
344/* Check if an instruction is valid for the specified CPU type */\r
345unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type);\r
346\r
347/* Disassemble 1 instruction using the epecified CPU type at pc. Stores\r
348 * disassembly in str_buff and returns the size of the instruction in bytes.\r
349 */\r
350unsigned int m68k_disassemble(char* str_buff, unsigned int pc, unsigned int cpu_type);\r
351\r
352/* Same as above but accepts raw opcode data directly rather than fetching\r
353 * via the read/write interfaces.\r
354 */\r
355unsigned int m68k_disassemble_raw(char* str_buff, unsigned int pc, unsigned char* opdata, unsigned char* argdata, int length, unsigned int cpu_type);\r
356\r
357\r
358/* ======================================================================== */\r
359/* ============================== MAME STUFF ============================== */\r
360/* ======================================================================== */\r
361\r
362#if M68K_COMPILE_FOR_MAME == OPT_ON\r
363#include "m68kmame.h"\r
364#endif /* M68K_COMPILE_FOR_MAME */\r
365\r
366\r
367/* ======================================================================== */\r
368/* ============================== END OF FILE ============================= */\r
369/* ======================================================================== */\r
370\r
371#endif /* M68K__HEADER */\r