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