Import Upstream version 1.23
[debian-dgen.git] / m68k.h
blob10dbc23534bef212f22828ea749ac4a298056100
1 #ifndef M68K__HEADER
2 #define M68K__HEADER
4 /* ======================================================================== */
5 /* ========================= LICENSING & COPYRIGHT ======================== */
6 /* ======================================================================== */
7 /*
8 * MUSASHI
9 * Version 2.0a
11 * A portable Motorola M680x0 processor emulation engine.
12 * Copyright 1999 Karl Stenerud. All rights reserved.
14 * This code may be freely used for non-commercial purpooses as long as this
15 * copyright notice remains unaltered in the source code and any binary files
16 * containing this code in compiled form.
18 * Any commercial ventures wishing to use this code must contact the author
19 * (Karl Stenerud) to negotiate commercial licensing terms.
21 * The latest version of this code can be obtained at:
22 * http://milliways.scas.bcit.bc.ca/~karl/musashi
26 /* ======================================================================== */
27 /* ============================= INSTRUCTIONS ============================= */
28 /* ======================================================================== */
29 /* 1. edit m68kconf.h and modify according to your needs.
30 * 2. Implement in your host program the functions defined in
31 * "FUNCTIONS CALLED BY THE CPU" located later in this file.
32 * 3. You must call m68k_pulse_reset() first to initialize the emulation.
33 * 4. If you don't call m68k_set_cpu_mode(), it will default to 68000 behavior.
35 * Requirements:
36 * - All operations in this core are done using a default size which must be
37 * at least 32 bits wide.
38 * - Because of signed/unsigned operations required for CPU emulation, this
39 * core will only work on a 2's complement machine. I'm not about to add
40 * 2's complement emulation =). If you don't know what 2's complement is,
41 * you most likely have it.
43 * Notes:
45 * You must at least implement the m68k_read_memory_xx() and
46 * m68k_write_memory_xx() functions in order to use the emulation core.
47 * Unless you plan to implement more direct access to memory for immediate
48 * reads and instruction fetches, you can just #define the
49 * m68k_read_immediate_xx() and m68k_read_instruction() functions to
50 * the m68k_read_memory_xx() functions.
52 * In order to use the emulation, you will need to call m68k_input_reset()
53 * and m68k_execute(). All the other functions are just to let you poke
54 * about with the internals of the CPU.
58 /* ======================================================================== */
59 /* ============================ GENERAL DEFINES =========================== */
60 /* ======================================================================== */
62 /* There are 7 levels of interrupt to the 68000. Level 7 cannot me masked */
63 #define M68K_IRQ_1 1
64 #define M68K_IRQ_2 2
65 #define M68K_IRQ_3 3
66 #define M68K_IRQ_4 4
67 #define M68K_IRQ_5 5
68 #define M68K_IRQ_6 6
69 #define M68K_IRQ_7 7
72 /* Special interrupt acknowledge values.
73 * Use these as special returns from the interrupt acknowledge callback
74 * (specified later in this header).
77 /* Causes an interrupt autovector (0x18 + interrupt level) to be taken.
78 * This happens in a real 68000 if VPA or AVEC is asserted during an interrupt
79 * acknowledge cycle instead of DTACK.
81 #define M68K_INT_ACK_AUTOVECTOR -1
83 /* Causes the spurious interrupt vector (0x18) to be taken
84 * This happens in a real 68000 if BERR is asserted during the interrupt
85 * acknowledge cycle (i.e. no devices responded to the acknowledge).
87 #define M68K_INT_ACK_SPURIOUS -2
90 /* CPU types for use in m68k_set_cpu_type() */
91 #define M68K_CPU_MODE_68000 1
92 #define M68K_CPU_MODE_68010 2
93 #define M68K_CPU_MODE_68020 4
96 /* ======================================================================== */
97 /* ============================== STRUCTURES ============================== */
98 /* ======================================================================== */
100 typedef struct /* CPU Context */
102 unsigned int mode; /* CPU Operation Mode (68000, 68010, or 68020) */
103 unsigned int sr; /* Status Register */
104 unsigned int ppc; /* Previous program counter */
105 unsigned int pc; /* Program Counter */
106 unsigned int d[8]; /* Data Registers */
107 unsigned int a[8]; /* Address Registers */
108 unsigned int usp; /* User Stack Pointer */
109 unsigned int isp; /* Interrupt Stack Pointer */
110 unsigned int msp; /* Master Stack Pointer */
111 unsigned int vbr; /* Vector Base Register. Used in 68010+ */
112 unsigned int sfc; /* Source Function Code. Used in 68010+ */
113 unsigned int dfc; /* Destination Function Code. Used in 68010+ */
114 unsigned int stopped; /* Stopped state: only interrupt can restart */
115 unsigned int halted; /* Halted state: only reset can restart */
116 unsigned int int_state; /* Current interrupt line states -- ASG: changed from ints_pending */
117 unsigned int int_cycles; /* Extra cycles taken due to interrupts -- ASG: added */
118 int (*int_ack_callback)(int int_level); /* Interrupt Acknowledge */
119 void (*bkpt_ack_callback)(int data); /* Breakpoint Acknowledge */
120 void (*reset_instr_callback)(void); /* Called when a RESET instruction is encountered */
121 void (*pc_changed_callback)(int new_pc); /* Called when the PC changes by a large amount */
122 void (*set_fc_callback)(int new_fc); /* Called when the CPU function code changes */
123 void (*instr_hook_callback)(void); /* Called every instruction cycle prior to execution */
124 } m68k_cpu_context;
126 /* ======================================================================== */
127 /* ====================== FUNCTIONS CALLED BY THE CPU ===================== */
128 /* ======================================================================== */
130 /* You will have to implement these functions */
132 /* read/write functions called by the CPU to access memory.
133 * while values used are 32 bits, only the appropriate number
134 * of bits are relevant (i.e. in write_memory_8, only the lower 8 bits
135 * of value should be written to memory).
136 * address will be a 24-bit value.
139 /* Read from anywhere */
140 int m68k_read_memory_8(int address);
141 int m68k_read_memory_16(int address);
142 int m68k_read_memory_32(int address);
144 /* Read data immediately following the PC */
145 int m68k_read_immediate_8(int address);
146 int m68k_read_immediate_16(int address);
147 int m68k_read_immediate_32(int address);
149 /* Read an instruction (16-bit word immeditately after PC) */
150 int m68k_read_instruction(int address);
152 /* Write to anywhere */
153 void m68k_write_memory_8(int address, int value);
154 void m68k_write_memory_16(int address, int value);
155 void m68k_write_memory_32(int address, int value);
159 /* ======================================================================== */
160 /* ============================== CALLBACKS =============================== */
161 /* ======================================================================== */
163 /* These functions allow you to set callbacks to the host when specific events
164 * occur. Note that you must enable the corresponding value in m68kconf.h
165 * in order for these to do anything useful.
166 * Note: I have defined default callbacks which are used if you have enabled
167 * the corresponding #define in m68kconf.h but either haven't assigned a
168 * callback or have assigned a callback of NULL.
171 /* Set the callback for an interrupt acknowledge.
172 * You must enable M68K_INT_ACK in m68kconf.h.
173 * The CPU will call the callback with the interrupt level being acknowledged.
174 * The host program must return either a vector from 0x02-0xff, or one of the
175 * special interrupt acknowledge values specified earlier in this header.
176 * If this is not implemented, the CPU will always assume an autovectored
177 * interrupt.
178 * Default behavior: return M68K_INT_ACK_AUTOVECTOR.
180 void m68k_set_int_ack_callback(int (*callback)(int int_level));
183 /* Set the callback for a breakpoint acknowledge (68010+).
184 * You must enable M68K_BKPT_ACK in m68kconf.h.
185 * The CPU will call the callback with whatever was in the data field of the
186 * BKPT instruction for 68020+, or 0 for 68010.
187 * Default behavior: do nothing.
189 void m68k_set_bkpt_ack_callback(void (*callback)(int data));
192 /* Set the callback for the RESET instruction.
193 * You must enable M68K_OUTPUT_RESET in m68kconf.h.
194 * The CPU calls this callback every time it encounters a RESET instruction.
195 * Default behavior: do nothing.
197 void m68k_set_reset_instr_callback(void (*callback)(void));
200 /* Set the callback for informing of a large PC change.
201 * You must enable M68K_PC_CHANGED in m68kconf.h.
202 * The CPU calls this callback with the new PC value every time the PC changes
203 * by a large value (currently set for changes by longwords).
204 * Default behavior: do nothing.
206 void m68k_set_pc_changed_callback(void (*callback)(int new_pc));
209 /* Set the callback for CPU function code changes.
210 * You must enable M68K_SET_FC in m68kconf.h.
211 * The CPU calls this callback with the function code before every memory
212 * access to set the CPU's function code according to what kind of memory
213 * access it is (supervisor/user, program/data and such).
214 * Default behavior: do nothing.
216 void m68k_set_fc_callback(void (*callback)(int new_fc));
219 /* Set a callback for the instruction cycle of the CPU.
220 * You must enable M68K_INSTR_HOOK in m68kconf.h.
221 * The CPU calls this callback just before fetching the opcode in the
222 * instruction cycle.
223 * Default behavior: do nothing.
225 void m68k_set_instr_hook_callback(void (*callback)(void));
229 /* ======================================================================== */
230 /* ====================== FUNCTIONS TO ACCESS THE CPU ===================== */
231 /* =======================================================<================ */
233 /* Use this function to set the CPU type ypu want to emulate.
234 * Currently supported types are: M68K_CPU_MODE_68000, M68K_CPU_MODE_68010,
235 * and M68K_CPU_MODE_68020.
237 void m68k_set_cpu_mode(int cpu_mode);
239 /* Reset the CPU as if you asserted RESET */
240 /* You *MUST* call this at least once to initialize the emulation */
241 void m68k_pulse_reset(void *param);
243 /* execute num_clks worth of instructions. returns number of clks used */
244 int m68k_execute(int num_clks);
246 /* The following 2 functions simulate an interrupt controller attached to the
247 * CPU since the 68000 needs an interrupt controller attached to work
248 * properly. Valid interrupt lines are 1, 2, 3, 4, 5, 6, and 7 (7 is a non-
249 * maskable interrupt)
251 void m68k_assert_irq(int int_line);
252 void m68k_clear_irq(int int_line);
254 /* Halt the CPU as if you asserted the HALT pin */
255 void m68k_pulse_halt(void);
257 /* look at the internals of the CPU */
258 int m68k_peek_dr(int reg_num);
259 int m68k_peek_ar(int reg_num);
260 unsigned int m68k_peek_pc(void);
261 unsigned int m68k_peek_ppc(void);
262 int m68k_peek_sr(void);
263 int m68k_peek_ir(void);
264 int m68k_peek_t1_flag(void);
265 int m68k_peek_t0_flag(void);
266 int m68k_peek_s_flag(void);
267 int m68k_peek_m_flag(void);
268 int m68k_peek_int_mask(void);
269 int m68k_peek_x_flag(void);
270 int m68k_peek_n_flag(void);
271 int m68k_peek_z_flag(void);
272 int m68k_peek_v_flag(void);
273 int m68k_peek_c_flag(void);
274 int m68k_peek_usp(void);
275 int m68k_peek_isp(void);
276 int m68k_peek_msp(void);
278 /* poke values into the internals of the CPU */
279 void m68k_poke_dr(int reg_num, int value);
280 void m68k_poke_ar(int reg_num, int value);
281 void m68k_poke_pc(unsigned int value);
282 void m68k_poke_sr(int value);
283 void m68k_poke_ir(int value);
284 void m68k_poke_t1_flag(int value);
285 void m68k_poke_t0_flag(int value);
286 void m68k_poke_s_flag(int value);
287 void m68k_poke_m_flag(int value);
288 void m68k_poke_int_mask(int value);
289 void m68k_poke_x_flag(int value);
290 void m68k_poke_n_flag(int value);
291 void m68k_poke_z_flag(int value);
292 void m68k_poke_v_flag(int value);
293 void m68k_poke_c_flag(int value);
294 void m68k_poke_usp(int value);
295 void m68k_poke_isp(int value);
296 void m68k_poke_msp(int value);
298 /* context switching to allow multiple CPUs */
299 unsigned m68k_get_context(void* dst);
300 void m68k_set_context(void* dst);
302 /* check if an instruction is valid for the specified CPU mode */
303 int m68k_is_valid_instruction(int instruction, int cpu_mode);
307 /* ======================================================================== */
308 /* ============================= CONFIGURATION ============================ */
309 /* ======================================================================== */
311 /* Import the configuration for this build */
312 #include "m68kconf.h"
316 /* ======================================================================== */
317 /* ============================== END OF FILE ============================= */
318 /* ======================================================================== */
320 #endif /* M68K__HEADER */