src/musashi/m68k.h

Thu, 11 Apr 2013 09:37:11 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Thu, 11 Apr 2013 09:37:11 +0100
changeset 138
d744db15cdf7
parent 19
ea417ac1d83a
permissions
-rw-r--r--

Check return value of fread()

     1 #ifndef M68K__HEADER
     2 #define M68K__HEADER
     4 /* ======================================================================== */
     5 /* ========================= LICENSING & COPYRIGHT ======================== */
     6 /* ======================================================================== */
     7 /*
     8  *                                  MUSASHI
     9  *                                Version 3.3
    10  *
    11  * A portable Motorola M680x0 processor emulation engine.
    12  * Copyright 1998-2001 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  * All other lisencing terms must be negotiated with the author
    19  * (Karl Stenerud).
    20  *
    21  * The latest version of this code can be obtained at:
    22  * http://kstenerud.cjb.net
    23  */
    27 /* ======================================================================== */
    28 /* ============================ GENERAL DEFINES =========================== */
    30 /* ======================================================================== */
    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
    45 /* Special interrupt acknowledge values.
    46  * Use these as special returns from the interrupt acknowledge callback
    47  * (specified later in this header).
    48  */
    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
    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
    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 };
    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 */
   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 */
   114 	/* Convenience registers */
   115 	M68K_REG_PPC,		/* Previous value in the program counter */
   116 	M68K_REG_IR,		/* Instruction register */
   117 	M68K_REG_CPU_TYPE	/* Type of CPU being run */
   118 } m68k_register_t;
   120 /* ======================================================================== */
   121 /* ====================== FUNCTIONS CALLED BY THE CPU ===================== */
   122 /* ======================================================================== */
   124 /* You will have to implement these functions */
   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  * NOTE: I have separated the immediate and PC-relative memory fetches
   132  *       from the other memory fetches because some systems require
   133  *       differentiation between PROGRAM and DATA fetches (usually
   134  *       for security setups such as encryption).
   135  *       This separation can either be achieved by setting
   136  *       M68K_SEPARATE_READS in m68kconf.h and defining
   137  *       the read functions, or by setting M68K_EMULATE_FC and
   138  *       making a function code callback function.
   139  *       Using the callback offers better emulation coverage
   140  *       because you can also monitor whether the CPU is in SYSTEM or
   141  *       USER mode, but it is also slower.
   142  */
   144 /* Read from anywhere */
   145 unsigned int  m68k_read_memory_8(unsigned int address);
   146 unsigned int  m68k_read_memory_16(unsigned int address);
   147 unsigned int  m68k_read_memory_32(unsigned int address);
   149 /* Read data immediately following the PC */
   150 unsigned int  m68k_read_immediate_16(unsigned int address);
   151 unsigned int  m68k_read_immediate_32(unsigned int address);
   153 /* Read data relative to the PC */
   154 unsigned int  m68k_read_pcrelative_8(unsigned int address);
   155 unsigned int  m68k_read_pcrelative_16(unsigned int address);
   156 unsigned int  m68k_read_pcrelative_32(unsigned int address);
   158 /* Memory access for the disassembler */
   159 unsigned int m68k_read_disassembler_8  (unsigned int address);
   160 unsigned int m68k_read_disassembler_16 (unsigned int address);
   161 unsigned int m68k_read_disassembler_32 (unsigned int address);
   163 /* Write to anywhere */
   164 void m68k_write_memory_8(unsigned int address, unsigned int value);
   165 void m68k_write_memory_16(unsigned int address, unsigned int value);
   166 void m68k_write_memory_32(unsigned int address, unsigned int value);
   170 /* ======================================================================== */
   171 /* ============================== CALLBACKS =============================== */
   172 /* ======================================================================== */
   174 /* These functions allow you to set callbacks to the host when specific events
   175  * occur.  Note that you must enable the corresponding value in m68kconf.h
   176  * in order for these to do anything useful.
   177  * Note: I have defined default callbacks which are used if you have enabled
   178  * the corresponding #define in m68kconf.h but either haven't assigned a
   179  * callback or have assigned a callback of NULL.
   180  */
   182 /* Set the callback for an interrupt acknowledge.
   183  * You must enable M68K_EMULATE_INT_ACK in m68kconf.h.
   184  * The CPU will call the callback with the interrupt level being acknowledged.
   185  * The host program must return either a vector from 0x02-0xff, or one of the
   186  * special interrupt acknowledge values specified earlier in this header.
   187  * If this is not implemented, the CPU will always assume an autovectored
   188  * interrupt, and will automatically clear the interrupt request when it
   189  * services the interrupt.
   190  * Default behavior: return M68K_INT_ACK_AUTOVECTOR.
   191  */
   192 void m68k_set_int_ack_callback(int  (*callback)(int int_level));
   195 /* Set the callback for a breakpoint acknowledge (68010+).
   196  * You must enable M68K_EMULATE_BKPT_ACK in m68kconf.h.
   197  * The CPU will call the callback with whatever was in the data field of the
   198  * BKPT instruction for 68020+, or 0 for 68010.
   199  * Default behavior: do nothing.
   200  */
   201 void m68k_set_bkpt_ack_callback(void (*callback)(unsigned int data));
   204 /* Set the callback for the RESET instruction.
   205  * You must enable M68K_EMULATE_RESET in m68kconf.h.
   206  * The CPU calls this callback every time it encounters a RESET instruction.
   207  * Default behavior: do nothing.
   208  */
   209 void m68k_set_reset_instr_callback(void  (*callback)(void));
   212 /* Set the callback for informing of a large PC change.
   213  * You must enable M68K_MONITOR_PC in m68kconf.h.
   214  * The CPU calls this callback with the new PC value every time the PC changes
   215  * by a large value (currently set for changes by longwords).
   216  * Default behavior: do nothing.
   217  */
   218 void m68k_set_pc_changed_callback(void  (*callback)(unsigned int new_pc));
   221 /* Set the callback for CPU function code changes.
   222  * You must enable M68K_EMULATE_FC in m68kconf.h.
   223  * The CPU calls this callback with the function code before every memory
   224  * access to set the CPU's function code according to what kind of memory
   225  * access it is (supervisor/user, program/data and such).
   226  * Default behavior: do nothing.
   227  */
   228 void m68k_set_fc_callback(void  (*callback)(unsigned int new_fc));
   231 /* Set a callback for the instruction cycle of the CPU.
   232  * You must enable M68K_INSTRUCTION_HOOK in m68kconf.h.
   233  * The CPU calls this callback just before fetching the opcode in the
   234  * instruction cycle.
   235  * Default behavior: do nothing.
   236  */
   237 void m68k_set_instr_hook_callback(void  (*callback)(void));
   241 /* ======================================================================== */
   242 /* ====================== FUNCTIONS TO ACCESS THE CPU ===================== */
   243 /* ======================================================================== */
   245 /* Use this function to set the CPU type you want to emulate.
   246  * Currently supported types are: M68K_CPU_TYPE_68000, M68K_CPU_TYPE_68010,
   247  * M68K_CPU_TYPE_EC020, and M68K_CPU_TYPE_68020.
   248  */
   249 void m68k_set_cpu_type(unsigned int cpu_type);
   251 /* Pulse the RESET pin on the CPU.
   252  * You *MUST* reset the CPU at least once to initialize the emulation
   253  * Note: If you didn't call m68k_set_cpu_type() before resetting
   254  *       the CPU for the first time, the CPU will be set to
   255  *       M68K_CPU_TYPE_68000.
   256  */
   257 void m68k_pulse_reset(void);
   259 /* execute num_cycles worth of instructions.  returns number of cycles used */
   260 int m68k_execute(int num_cycles);
   262 /* These functions let you read/write/modify the number of cycles left to run
   263  * while m68k_execute() is running.
   264  * These are useful if the 68k accesses a memory-mapped port on another device
   265  * that requires immediate processing by another CPU.
   266  */
   267 int m68k_cycles_run(void);              /* Number of cycles run so far */
   268 int m68k_cycles_remaining(void);        /* Number of cycles left */
   269 void m68k_modify_timeslice(int cycles); /* Modify cycles left */
   270 void m68k_end_timeslice(void);          /* End timeslice now */
   272 /* Set the IPL0-IPL2 pins on the CPU (IRQ).
   273  * A transition from < 7 to 7 will cause a non-maskable interrupt (NMI).
   274  * Setting IRQ to 0 will clear an interrupt request.
   275  */
   276 void m68k_set_irq(unsigned int int_level);
   279 /* Halt the CPU as if you pulsed the HALT pin. */
   280 void m68k_pulse_halt(void);
   283 /* Trigger a bus error exception */
   284 void m68k_pulse_bus_error(void);
   287 /* Context switching to allow multiple CPUs */
   289 /* Get the size of the cpu context in bytes */
   290 unsigned int m68k_context_size(void);
   292 /* Get a cpu context */
   293 unsigned int m68k_get_context(void* dst);
   295 /* set the current cpu context */
   296 void m68k_set_context(void* dst);
   298 /* Save the current cpu context to disk.
   299  * You must provide a function pointer of the form:
   300  * void save_value(char* identifier, unsigned int value)
   301  */
   302 void m68k_save_context(	void (*save_value)(char* identifier, unsigned int value));
   304 /* Load a cpu context from disk.
   305  * You must provide a function pointer of the form:
   306  * unsigned int load_value(char* identifier)
   307  */
   308 void m68k_load_context(unsigned int (*load_value)(char* identifier));
   312 /* Peek at the internals of a CPU context.  This can either be a context
   313  * retrieved using m68k_get_context() or the currently running context.
   314  * If context is NULL, the currently running CPU context will be used.
   315  */
   316 unsigned int m68k_get_reg(void* context, m68k_register_t reg);
   318 /* Poke values into the internals of the currently running CPU context */
   319 void m68k_set_reg(m68k_register_t reg, unsigned int value);
   321 /* Check if an instruction is valid for the specified CPU type */
   322 unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type);
   324 /* Disassemble 1 instruction using the epecified CPU type at pc.  Stores
   325  * disassembly in str_buff and returns the size of the instruction in bytes.
   326  */
   327 unsigned int m68k_disassemble(char* str_buff, unsigned int pc, unsigned int cpu_type);
   330 /* ======================================================================== */
   331 /* ============================= CONFIGURATION ============================ */
   332 /* ======================================================================== */
   334 /* Import the configuration for this build */
   335 #include "m68kconf.h"
   339 /* ======================================================================== */
   340 /* ============================== END OF FILE ============================= */
   341 /* ======================================================================== */
   343 #endif /* M68K__HEADER */