1 #ifndef M68K__HEADER 2 #define M68K__HEADER 3 4 /* ======================================================================== */ 5 /* ========================= LICENSING & COPYRIGHT ======================== */ 6 /* ======================================================================== */ 7 /* 8 * MUSASHI 9 * Version 3.1 10 * 11 * A portable Motorola M680x0 processor emulation engine. 12 * Copyright 1999,2000 Karl Stenerud. All rights reserved. 13 * 14 * This code may be freely used for non-commercial purposes as long as this 15 * copyright notice remains unaltered in the source code and any binary files 16 * containing this code in compiled form. 17 * 18 * Any commercial ventures wishing to use this code must contact the author 19 * (Karl Stenerud) for commercial licensing terms. 20 * 21 * The latest version of this code can be obtained at: 22 * http://members.xoom.com/kstenerud 23 */ 24 25 26 27 /* ======================================================================== */ 28 /* ============================ GENERAL DEFINES =========================== */ 29 30 /* ======================================================================== */ 31 32 /* There are 7 levels of interrupt to the 68K. 33 * A transition from < 7 to 7 will cause a non-maskable interrupt (NMI). 34 */ 35 #define M68K_IRQ_NONE 0 36 #define M68K_IRQ_1 1 37 #define M68K_IRQ_2 2 38 #define M68K_IRQ_3 3 39 #define M68K_IRQ_4 4 40 #define M68K_IRQ_5 5 41 #define M68K_IRQ_6 6 42 #define M68K_IRQ_7 7 43 44 45 /* Special interrupt acknowledge values. 46 * Use these as special returns from the interrupt acknowledge callback 47 * (specified later in this header). 48 */ 49 50 /* Causes an interrupt autovector (0x18 + interrupt level) to be taken. 51 * This happens in a real 68K if VPA or AVEC is asserted during an interrupt 52 * acknowledge cycle instead of DTACK. 53 */ 54 #define M68K_INT_ACK_AUTOVECTOR 0xffffffff 55 56 /* Causes the spurious interrupt vector (0x18) to be taken 57 * This happens in a real 68K if BERR is asserted during the interrupt 58 * acknowledge cycle (i.e. no devices responded to the acknowledge). 59 */ 60 #define M68K_INT_ACK_SPURIOUS 0xfffffffe 61 62 63 /* CPU types for use in m68k_set_cpu_type() */ 64 enum 65 { 66 M68K_CPU_TYPE_INVALID, 67 M68K_CPU_TYPE_68000, 68 M68K_CPU_TYPE_68010, 69 M68K_CPU_TYPE_68EC020, 70 M68K_CPU_TYPE_68020, 71 M68K_CPU_TYPE_68030, /* Supported by disassembler ONLY */ 72 M68K_CPU_TYPE_68040 /* Supported by disassembler ONLY */ 73 }; 74 75 /* Registers used by m68k_get_reg() and m68k_set_reg() */ 76 typedef enum 77 { 78 /* Real registers */ 79 M68K_REG_D0, /* Data registers */ 80 M68K_REG_D1, 81 M68K_REG_D2, 82 M68K_REG_D3, 83 M68K_REG_D4, 84 M68K_REG_D5, 85 M68K_REG_D6, 86 M68K_REG_D7, 87 M68K_REG_A0, /* Address registers */ 88 M68K_REG_A1, 89 M68K_REG_A2, 90 M68K_REG_A3, 91 M68K_REG_A4, 92 M68K_REG_A5, 93 M68K_REG_A6, 94 M68K_REG_A7, 95 M68K_REG_PC, /* Program Counter */ 96 M68K_REG_SR, /* Status Register */ 97 M68K_REG_SP, /* The current Stack Pointer (located in A7) */ 98 M68K_REG_USP, /* User Stack Pointer */ 99 M68K_REG_ISP, /* Interrupt Stack Pointer */ 100 M68K_REG_MSP, /* Master Stack Pointer */ 101 M68K_REG_SFC, /* Source Function Code */ 102 M68K_REG_DFC, /* Destination Function Code */ 103 M68K_REG_VBR, /* Vector Base Register */ 104 M68K_REG_CACR, /* Cache Control Register */ 105 M68K_REG_CAAR, /* Cache Address Register */ 106 107 /* Assumed registers */ 108 /* These are cheat registers which emulate the 1-longword prefetch 109 * present in the 68000 and 68010. 110 */ 111 M68K_REG_PREF_ADDR, /* Last prefetch address */ 112 M68K_REG_PREF_DATA, /* Last prefetch data */ 113 114 /* Convenience registers */ 115 M68K_REG_PPC, /* Previous program counter */ 116 M68K_REG_IR, /* Instruction register */ 117 M68K_REG_CPU_TYPE /* Type of CPU being run */ 118 } m68k_register_t; 119 120 /* ======================================================================== */ 121 /* ====================== FUNCTIONS CALLED BY THE CPU ===================== */ 122 /* ======================================================================== */ 123 124 /* You will have to implement these functions */ 125 126 /* read/write functions called by the CPU to access memory. 127 * while values used are 32 bits, only the appropriate number 128 * of bits are relevant (i.e. in write_memory_8, only the lower 8 bits 129 * of value should be written to memory). 130 */ 131 132 /* Read from anywhere */ 133 unsigned int m68k_read_memory_8(unsigned int address); 134 unsigned int m68k_read_memory_16(unsigned int address); 135 unsigned int m68k_read_memory_32(unsigned int address); 136 137 /* Read data immediately following the PC */ 138 unsigned int m68k_read_immediate_16(unsigned int address); 139 unsigned int m68k_read_immediate_32(unsigned int address); 140 141 /* Memory access for the disassembler */ 142 unsigned int m68k_read_disassembler_8 (unsigned int address); 143 unsigned int m68k_read_disassembler_16 (unsigned int address); 144 unsigned int m68k_read_disassembler_32 (unsigned int address); 145 146 /* Write to anywhere */ 147 void m68k_write_memory_8(unsigned int address, unsigned int value); 148 void m68k_write_memory_16(unsigned int address, unsigned int value); 149 void m68k_write_memory_32(unsigned int address, unsigned int value); 150 151 152 153 /* ======================================================================== */ 154 /* ============================== CALLBACKS =============================== */ 155 /* ======================================================================== */ 156 157 /* These functions allow you to set callbacks to the host when specific events 158 * occur. Note that you must enable the corresponding value in m68kconf.h 159 * in order for these to do anything useful. 160 * Note: I have defined default callbacks which are used if you have enabled 161 * the corresponding #define in m68kconf.h but either haven't assigned a 162 * callback or have assigned a callback of NULL. 163 */ 164 165 /* Set the callback for an interrupt acknowledge. 166 * You must enable M68K_EMULATE_INT_ACK in m68kconf.h. 167 * The CPU will call the callback with the interrupt level being acknowledged. 168 * The host program must return either a vector from 0x02-0xff, or one of the 169 * special interrupt acknowledge values specified earlier in this header. 170 * If this is not implemented, the CPU will always assume an autovectored 171 * interrupt, and will automatically clear the interrupt request when it 172 * services the interrupt. 173 * Default behavior: return M68K_INT_ACK_AUTOVECTOR. 174 */ 175 void m68k_set_int_ack_callback(int (*callback)(int int_level)); 176 177 178 /* Set the callback for a breakpoint acknowledge (68010+). 179 * You must enable M68K_EMULATE_BKPT_ACK in m68kconf.h. 180 * The CPU will call the callback with whatever was in the data field of the 181 * BKPT instruction for 68020+, or 0 for 68010. 182 * Default behavior: do nothing. 183 */ 184 void m68k_set_bkpt_ack_callback(void (*callback)(unsigned int data)); 185 186 187 /* Set the callback for the RESET instruction. 188 * You must enable M68K_EMULATE_RESET in m68kconf.h. 189 * The CPU calls this callback every time it encounters a RESET instruction. 190 * Default behavior: do nothing. 191 */ 192 void m68k_set_reset_instr_callback(void (*callback)(void)); 193 194 195 /* Set the callback for informing of a large PC change. 196 * You must enable M68K_MONITOR_PC in m68kconf.h. 197 * The CPU calls this callback with the new PC value every time the PC changes 198 * by a large value (currently set for changes by longwords). 199 * Default behavior: do nothing. 200 */ 201 void m68k_set_pc_changed_callback(void (*callback)(unsigned int new_pc)); 202 203 204 /* Set the callback for CPU function code changes. 205 * You must enable M68K_EMULATE_FC in m68kconf.h. 206 * The CPU calls this callback with the function code before every memory 207 * access to set the CPU's function code according to what kind of memory 208 * access it is (supervisor/user, program/data and such). 209 * Default behavior: do nothing. 210 */ 211 void m68k_set_fc_callback(void (*callback)(unsigned int new_fc)); 212 213 214 /* Set a callback for the instruction cycle of the CPU. 215 * You must enable M68K_INSTRUCTION_HOOK in m68kconf.h. 216 * The CPU calls this callback just before fetching the opcode in the 217 * instruction cycle. 218 * Default behavior: do nothing. 219 */ 220 void m68k_set_instr_hook_callback(void (*callback)(void)); 221 222 223 224 /* ======================================================================== */ 225 /* ====================== FUNCTIONS TO ACCESS THE CPU ===================== */ 226 /* ======================================================================== */ 227 228 int m68k_cycles_run(void); 229 int m68k_cycles_remaining(void); 230 void m68k_modify_timeslice(int cycles); 231 void m68k_end_timeslice(void); 232 233 /* Use this function to set the CPU type you want to emulate. 234 * Currently supported types are: M68K_CPU_TYPE_68000, M68K_CPU_TYPE_68010, 235 * M68K_CPU_TYPE_EC020, and M68K_CPU_TYPE_68020. 236 */ 237 void m68k_set_cpu_type(unsigned int cpu_type); 238 239 /* Pulse the RESET pin on the CPU. 240 * You *MUST* reset the CPU at least once to initialize the emulation 241 * Note: If you didn't call m68k_set_cpu_type() before resetting 242 * the CPU for the first time, the CPU will be set to 243 * M68K_CPU_TYPE_68000. 244 */ 245 void m68k_pulse_reset(void); 246 247 /* execute num_cycles worth of instructions. returns number of cycles used */ 248 int m68k_execute(int num_cycles); 249 250 /* Set the IPL0-IPL2 pins on the CPU (IRQ). 251 * A transition from < 7 to 7 will cause a non-maskable interrupt (NMI). 252 * Setting IRQ to 0 will clear an interrupt request. 253 */ 254 void m68k_set_irq(unsigned int int_level); 255 256 257 /* Halt the CPU as if you pulsed the HALT pin. */ 258 void m68k_pulse_halt(void); 259 260 261 /* Context switching to allow multiple CPUs */ 262 263 /* Get the size of the cpu context in bytes */ 264 unsigned int m68k_context_size(void); 265 266 /* Get a cpu context */ 267 unsigned int m68k_get_context(void* dst); 268 269 /* set the current cpu context */ 270 void m68k_set_context(void* dst); 271 272 /* Save the current cpu context to disk. 273 * You must provide a function pointer of the form: 274 * void save_value(char* identifier, unsigned int value) 275 */ 276 void m68k_save_context( void (*save_value)(char* identifier, unsigned int value)); 277 278 /* Load a cpu context from disk. 279 * You must provide a function pointer of the form: 280 * unsigned int load_value(char* identifier) 281 */ 282 void m68k_load_context(unsigned int (*load_value)(char* identifier)); 283 284 285 286 /* Peek at the internals of a CPU context. This can either be a context 287 * retrieved using m68k_get_context() or the currently running context. 288 * If context is NULL, the currently running CPU context will be used. 289 */ 290 unsigned int m68k_get_reg(void* context, m68k_register_t reg); 291 292 /* Poke values into the internals of the currently running CPU context */ 293 void m68k_set_reg(m68k_register_t reg, unsigned int value); 294 295 /* Check if an instruction is valid for the specified CPU type */ 296 unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type); 297 298 /* Disassemble 1 instructionat pc. Stores disassembly in str_buff and returns 299 * the size of the instruction in bytes. 300 */ 301 unsigned int m68k_disassemble(char* str_buff, unsigned int pc, unsigned int cpu_type); 302 303 304 /* ======================================================================== */ 305 /* ============================= CONFIGURATION ============================ */ 306 /* ======================================================================== */ 307 308 /* Import the configuration for this build */ 309 #include "m68kconf.h" 310 311 312 313 /* ======================================================================== */ 314 /* ============================== END OF FILE ============================= */ 315 /* ======================================================================== */ 316 317 #endif /* M68K__HEADER */ 318