File: m68k.h

package info (click to toggle)
dgen 1.23-7
  • links: PTS
  • area: non-free
  • in suites: sarge
  • size: 2,168 kB
  • ctags: 3,086
  • sloc: ansic: 45,404; cpp: 4,405; sh: 1,960; makefile: 116
file content (320 lines) | stat: -rw-r--r-- 12,865 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
#ifndef M68K__HEADER
#define M68K__HEADER

/* ======================================================================== */
/* ========================= LICENSING & COPYRIGHT ======================== */
/* ======================================================================== */
/*
 *                                  MUSASHI
 *                                Version 2.0a
 *
 * A portable Motorola M680x0 processor emulation engine.
 * Copyright 1999 Karl Stenerud.  All rights reserved.
 *
 * This code may be freely used for non-commercial purpooses as long as this
 * copyright notice remains unaltered in the source code and any binary files
 * containing this code in compiled form.
 *
 * Any commercial ventures wishing to use this code must contact the author
 * (Karl Stenerud) to negotiate commercial licensing terms.
 *
 * The latest version of this code can be obtained at:
 * http://milliways.scas.bcit.bc.ca/~karl/musashi
 */


/* ======================================================================== */
/* ============================= INSTRUCTIONS ============================= */
/* ======================================================================== */
/* 1. edit m68kconf.h and modify according to your needs.
 * 2. Implement in your host program the functions defined in
 *    "FUNCTIONS CALLED BY THE CPU" located later in this file.
 * 3. You must call m68k_pulse_reset() first to initialize the emulation.
 * 4. If you don't call m68k_set_cpu_mode(), it will default to 68000 behavior.
 *
 * Requirements:
 * - All operations in this core are done using a default size which must be
 *   at least 32 bits wide.
 * - Because of signed/unsigned operations required for CPU emulation, this
 *   core will only work on a 2's complement machine.  I'm not about to add
 *   2's complement emulation =).  If you don't know what 2's complement is,
 *   you most likely have it.
 *
 * Notes:
 *
 * You must at least implement the m68k_read_memory_xx() and
 * m68k_write_memory_xx() functions in order to use the emulation core.
 * Unless you plan to implement more direct access to memory for immediate
 * reads and instruction fetches, you can just #define the
 * m68k_read_immediate_xx() and m68k_read_instruction() functions to
 * the m68k_read_memory_xx() functions.
 *
 * In order to use the emulation, you will need to call m68k_input_reset()
 * and m68k_execute().  All the other functions are just to let you poke
 * about with the internals of the CPU.
 */


/* ======================================================================== */
/* ============================ GENERAL DEFINES =========================== */
/* ======================================================================== */

/* There are 7 levels of interrupt to the 68000.  Level 7 cannot me masked */
#define M68K_IRQ_1    1
#define M68K_IRQ_2    2
#define M68K_IRQ_3    3
#define M68K_IRQ_4    4
#define M68K_IRQ_5    5
#define M68K_IRQ_6    6
#define M68K_IRQ_7    7


/* Special interrupt acknowledge values.
 * Use these as special returns from the interrupt acknowledge callback
 * (specified later in this header).
 */

/* Causes an interrupt autovector (0x18 + interrupt level) to be taken.
 * This happens in a real 68000 if VPA or AVEC is asserted during an interrupt
 * acknowledge cycle instead of DTACK.
 */
#define M68K_INT_ACK_AUTOVECTOR    -1

/* Causes the spurious interrupt vector (0x18) to be taken
 * This happens in a real 68000 if BERR is asserted during the interrupt
 * acknowledge cycle (i.e. no devices responded to the acknowledge).
 */
#define M68K_INT_ACK_SPURIOUS      -2


/* CPU types for use in m68k_set_cpu_type() */
#define M68K_CPU_MODE_68000 1
#define M68K_CPU_MODE_68010 2
#define M68K_CPU_MODE_68020 4


/* ======================================================================== */
/* ============================== STRUCTURES ============================== */
/* ======================================================================== */

typedef struct                 /* CPU Context */
{
   unsigned int  mode;         /* CPU Operation Mode (68000, 68010, or 68020) */
   unsigned int  sr;           /* Status Register */
   unsigned int  ppc;		   /* Previous program counter */
   unsigned int  pc;           /* Program Counter */
   unsigned int  d[8];         /* Data Registers */
   unsigned int  a[8];         /* Address Registers */
   unsigned int  usp;          /* User Stack Pointer */
   unsigned int  isp;          /* Interrupt Stack Pointer */
   unsigned int  msp;          /* Master Stack Pointer */
   unsigned int  vbr;          /* Vector Base Register.  Used in 68010+ */
   unsigned int  sfc;          /* Source Function Code.  Used in 68010+ */
   unsigned int  dfc;          /* Destination Function Code.  Used in 68010+ */
   unsigned int  stopped;      /* Stopped state: only interrupt can restart */
   unsigned int  halted;       /* Halted state: only reset can restart */
   unsigned int  int_state;	   /* Current interrupt line states -- ASG: changed from ints_pending */
   unsigned int  int_cycles;   /* Extra cycles taken due to interrupts -- ASG: added */
   int  (*int_ack_callback)(int int_level); /* Interrupt Acknowledge */
   void (*bkpt_ack_callback)(int data);     /* Breakpoint Acknowledge */
   void (*reset_instr_callback)(void);      /* Called when a RESET instruction is encountered */
   void (*pc_changed_callback)(int new_pc); /* Called when the PC changes by a large amount */
   void (*set_fc_callback)(int new_fc);     /* Called when the CPU function code changes */
   void (*instr_hook_callback)(void);       /* Called every instruction cycle prior to execution */
} m68k_cpu_context;

/* ======================================================================== */
/* ====================== FUNCTIONS CALLED BY THE CPU ===================== */
/* ======================================================================== */

/* You will have to implement these functions */

/* read/write functions called by the CPU to access memory.
 * while values used are 32 bits, only the appropriate number
 * of bits are relevant (i.e. in write_memory_8, only the lower 8 bits
 * of value should be written to memory).
 * address will be a 24-bit value.
 */

/* Read from anywhere */
int  m68k_read_memory_8(int address);
int  m68k_read_memory_16(int address);
int  m68k_read_memory_32(int address);

/* Read data immediately following the PC */
int  m68k_read_immediate_8(int address);
int  m68k_read_immediate_16(int address);
int  m68k_read_immediate_32(int address);

/* Read an instruction (16-bit word immeditately after PC) */
int  m68k_read_instruction(int address);

/* Write to anywhere */
void m68k_write_memory_8(int address, int value);
void m68k_write_memory_16(int address, int value);
void m68k_write_memory_32(int address, int value);



/* ======================================================================== */
/* ============================== CALLBACKS =============================== */
/* ======================================================================== */

/* These functions allow you to set callbacks to the host when specific events
 * occur.  Note that you must enable the corresponding value in m68kconf.h
 * in order for these to do anything useful.
 * Note: I have defined default callbacks which are used if you have enabled
 * the corresponding #define in m68kconf.h but either haven't assigned a
 * callback or have assigned a callback of NULL.
 */

/* Set the callback for an interrupt acknowledge.
 * You must enable M68K_INT_ACK in m68kconf.h.
 * The CPU will call the callback with the interrupt level being acknowledged.
 * The host program must return either a vector from 0x02-0xff, or one of the
 * special interrupt acknowledge values specified earlier in this header.
 * If this is not implemented, the CPU will always assume an autovectored
 * interrupt.
 * Default behavior: return M68K_INT_ACK_AUTOVECTOR.
 */
void m68k_set_int_ack_callback(int  (*callback)(int int_level));


/* Set the callback for a breakpoint acknowledge (68010+).
 * You must enable M68K_BKPT_ACK in m68kconf.h.
 * The CPU will call the callback with whatever was in the data field of the
 * BKPT instruction for 68020+, or 0 for 68010.
 * Default behavior: do nothing.
 */
void m68k_set_bkpt_ack_callback(void (*callback)(int data));


/* Set the callback for the RESET instruction.
 * You must enable M68K_OUTPUT_RESET in m68kconf.h.
 * The CPU calls this callback every time it encounters a RESET instruction.
 * Default behavior: do nothing.
 */
void m68k_set_reset_instr_callback(void  (*callback)(void));


/* Set the callback for informing of a large PC change.
 * You must enable M68K_PC_CHANGED in m68kconf.h.
 * The CPU calls this callback with the new PC value every time the PC changes
 * by a large value (currently set for changes by longwords).
 * Default behavior: do nothing.
 */
void m68k_set_pc_changed_callback(void  (*callback)(int new_pc));


/* Set the callback for CPU function code changes.
 * You must enable M68K_SET_FC in m68kconf.h.
 * The CPU calls this callback with the function code before every memory
 * access to set the CPU's function code according to what kind of memory
 * access it is (supervisor/user, program/data and such).
 * Default behavior: do nothing.
 */
void m68k_set_fc_callback(void  (*callback)(int new_fc));


/* Set a callback for the instruction cycle of the CPU.
 * You must enable M68K_INSTR_HOOK in m68kconf.h.
 * The CPU calls this callback just before fetching the opcode in the
 * instruction cycle.
 * Default behavior: do nothing.
 */
void m68k_set_instr_hook_callback(void  (*callback)(void));



/* ======================================================================== */
/* ====================== FUNCTIONS TO ACCESS THE CPU ===================== */
/* =======================================================<================ */

/* Use this function to set the CPU type ypu want to emulate.
 * Currently supported types are: M68K_CPU_MODE_68000, M68K_CPU_MODE_68010,
 * and M68K_CPU_MODE_68020.
 */
void m68k_set_cpu_mode(int cpu_mode);

/* Reset the CPU as if you asserted RESET */
/* You *MUST* call this at least once to initialize the emulation */
void m68k_pulse_reset(void *param);

/* execute num_clks worth of instructions.  returns number of clks used */
int m68k_execute(int num_clks);

/* The following 2 functions simulate an interrupt controller attached to the
 * CPU since the 68000 needs an interrupt controller attached to work
 * properly.  Valid interrupt lines are 1, 2, 3, 4, 5, 6, and 7 (7 is a non-
 * maskable interrupt)
 */
void m68k_assert_irq(int int_line);
void m68k_clear_irq(int int_line);

/* Halt the CPU as if you asserted the HALT pin */
void m68k_pulse_halt(void);

/* look at the internals of the CPU */
int m68k_peek_dr(int reg_num);
int m68k_peek_ar(int reg_num);
unsigned int m68k_peek_pc(void);
unsigned int m68k_peek_ppc(void);
int m68k_peek_sr(void);
int m68k_peek_ir(void);
int m68k_peek_t1_flag(void);
int m68k_peek_t0_flag(void);
int m68k_peek_s_flag(void);
int m68k_peek_m_flag(void);
int m68k_peek_int_mask(void);
int m68k_peek_x_flag(void);
int m68k_peek_n_flag(void);
int m68k_peek_z_flag(void);
int m68k_peek_v_flag(void);
int m68k_peek_c_flag(void);
int m68k_peek_usp(void);
int m68k_peek_isp(void);
int m68k_peek_msp(void);

/* poke values into the internals of the CPU */
void m68k_poke_dr(int reg_num, int value);
void m68k_poke_ar(int reg_num, int value);
void m68k_poke_pc(unsigned int value);
void m68k_poke_sr(int value);
void m68k_poke_ir(int value);
void m68k_poke_t1_flag(int value);
void m68k_poke_t0_flag(int value);
void m68k_poke_s_flag(int value);
void m68k_poke_m_flag(int value);
void m68k_poke_int_mask(int value);
void m68k_poke_x_flag(int value);
void m68k_poke_n_flag(int value);
void m68k_poke_z_flag(int value);
void m68k_poke_v_flag(int value);
void m68k_poke_c_flag(int value);
void m68k_poke_usp(int value);
void m68k_poke_isp(int value);
void m68k_poke_msp(int value);

/* context switching to allow multiple CPUs */
unsigned m68k_get_context(void* dst);
void m68k_set_context(void* dst);

/* check if an instruction is valid for the specified CPU mode */
int m68k_is_valid_instruction(int instruction, int cpu_mode);



/* ======================================================================== */
/* ============================= CONFIGURATION ============================ */
/* ======================================================================== */

/* Import the configuration for this build */
#include "m68kconf.h"



/* ======================================================================== */
/* ============================== END OF FILE ============================= */
/* ======================================================================== */

#endif /* M68K__HEADER */