src/musashi/readme.txt

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 0
8bf1bf91a36d
permissions
-rw-r--r--

Check return value of fread()

philpem@0 1 MUSASHI
philpem@0 2 =======
philpem@0 3
philpem@0 4 Version 3.3
philpem@0 5
philpem@0 6 A portable Motorola M680x0 processor emulation engine.
philpem@0 7 Copyright 1998-2001 Karl Stenerud. All rights reserved.
philpem@0 8
philpem@0 9
philpem@0 10
philpem@0 11 INTRODUCTION:
philpem@0 12 ------------
philpem@0 13
philpem@0 14 Musashi is a Motorola 68000, 68010, 68EC020, and 68020 emulator written in C.
philpem@0 15 This emulator was written with two goals in mind: portability and speed.
philpem@0 16
philpem@0 17 The emulator is written to ANSI C specifications with the exception that I use
philpem@0 18 inline functions. This is not compliant to the ANSI spec, but will be
philpem@0 19 compliant to the ANSI C9X spec.
philpem@0 20
philpem@0 21 It has been successfully running in the MAME project (www.mame.net) for over 2
philpem@0 22 years and so has had time to mature.
philpem@0 23
philpem@0 24
philpem@0 25
philpem@0 26 LICENSE AND COPYRIGHT:
philpem@0 27 ---------------------
philpem@0 28
philpem@0 29 The Musashi M680x0 emulator is copyright 1998-2001 Karl Stenerud.
philpem@0 30
philpem@0 31 The source code included in this archive is provided AS-IS, free for any
philpem@0 32 non-commercial purpose.
philpem@0 33
philpem@0 34 If you build a program using this core, please give credit to the author.
philpem@0 35
philpem@0 36 If you wish to use this core in a commercial environment, please contact
philpem@0 37 the author to discuss commercial licensing.
philpem@0 38
philpem@0 39
philpem@0 40
philpem@0 41 AVAILABILITY:
philpem@0 42 ------------
philpem@0 43 The latest version of this code can be obtained at:
philpem@0 44 http://kstenerud.cjb.net
philpem@0 45
philpem@0 46
philpem@0 47
philpem@0 48 CONTACTING THE AUTHOR:
philpem@0 49 ---------------------
philpem@0 50 I can be reached at kstenerud@mame.net
philpem@0 51
philpem@0 52
philpem@0 53
philpem@0 54 BASIC CONFIGURATION:
philpem@0 55 -------------------
philpem@0 56 The basic configuration will give you a standard 68000 that has sufficient
philpem@0 57 functionality to work in a primitive environment.
philpem@0 58
philpem@0 59 This setup assumes that you only have 1 device interrupting it, that the
philpem@0 60 device will always request an autovectored interrupt, and it will always clear
philpem@0 61 the interrupt before the interrupt service routine finishes (but could
philpem@0 62 possibly re-assert the interrupt).
philpem@0 63 You will have only one address space, no tracing, and no instruction prefetch.
philpem@0 64
philpem@0 65 To implement the basic configuration:
philpem@0 66
philpem@0 67 - Open m68kconf.h and verify that the settings for INLINE and DECL_SPEC will
philpem@0 68 work with your compiler. (They are set for gcc)
philpem@0 69
philpem@0 70 - In your host program, implement the following functions:
philpem@0 71 unsigned int m68k_read_memory_8(unsigned int address);
philpem@0 72 unsigned int m68k_read_memory_16(unsigned int address);
philpem@0 73 unsigned int m68k_read_memory_32(unsigned int address);
philpem@0 74 void m68k_write_memory_8(unsigned int address, unsigned int value);
philpem@0 75 void m68k_write_memory_16(unsigned int address, unsigned int value);
philpem@0 76 void m68k_write_memory_32(unsigned int address, unsigned int value);
philpem@0 77
philpem@0 78 - In your host program, be sure to call m68k_pulse_reset() once before calling
philpem@0 79 any of the other functions as this initializes the core.
philpem@0 80
philpem@0 81 - Use m68k_execute() to execute instructions and m68k_set_irq() to cause an
philpem@0 82 interrupt.
philpem@0 83
philpem@0 84
philpem@0 85
philpem@0 86 ADDING PROPER INTERRUPT HANDLING:
philpem@0 87 --------------------------------
philpem@0 88 The interrupt handling in the basic configuration doesn't emulate the
philpem@0 89 interrupt acknowledge phase of the CPU and automatically clears an interrupt
philpem@0 90 request during interrupt processing.
philpem@0 91 While this works for most systems, you may need more accurate interrupt
philpem@0 92 handling.
philpem@0 93
philpem@0 94 To add proper interrupt handling:
philpem@0 95
philpem@0 96 - In m68kconf.h, set M68K_EMULATE_INT_ACK to OPT_SPECIFY_HANDLER
philpem@0 97
philpem@0 98 - In m68kconf.h, set M68K_INT_ACK_CALLBACK(A) to your interrupt acknowledge
philpem@0 99 routine
philpem@0 100
philpem@0 101 - Your interrupt acknowledge routine must return an interrupt vector,
philpem@0 102 M68K_INT_ACK_AUTOVECTOR, or M68K_INT_ACK_SPURIOUS. most m68k
philpem@0 103 implementations just use autovectored interrupts.
philpem@0 104
philpem@0 105 - When the interrupting device is satisfied, you must call m68k_set_irq(0) to
philpem@0 106 remove the interrupt request.
philpem@0 107
philpem@0 108
philpem@0 109
philpem@0 110 MULTIPLE INTERRUPTS:
philpem@0 111 -------------------
philpem@0 112 The above system will work if you have only one device interrupting the CPU,
philpem@0 113 but if you have more than one device, you must do a bit more.
philpem@0 114
philpem@0 115 To add multiple interrupts:
philpem@0 116
philpem@0 117 - You must make an interrupt arbitration device that will take the highest
philpem@0 118 priority interrupt and encode it onto the IRQ pins on the CPU.
philpem@0 119
philpem@0 120 - The interrupt arbitration device should use m68k_set_irq() to set the
philpem@0 121 highest pending interrupt, or 0 for no interrupts pending.
philpem@0 122
philpem@0 123
philpem@0 124
philpem@0 125 SEPARATE IMMEDIATE AND PC-RELATIVE READS:
philpem@0 126 ----------------------------------------
philpem@0 127 You can write faster memory access functions if you know whether you are
philpem@0 128 fetching from ROM or RAM. Immediate reads are always from the program space
philpem@0 129 (Always in ROM unless it is running self-modifying code).
philpem@0 130 This will also separate the pc-relative reads, since some systems treat
philpem@0 131 PROGRAM mode reads and DATA mode reads differently (for program encryption,
philpem@0 132 for instance). See the section below (ADDRESS SPACE) for an explanation of
philpem@0 133 PROGRAM and DATA mode.
philpem@0 134
philpem@0 135 To enable separate reads:
philpem@0 136
philpem@0 137 - In m68kconf.h, turn on M68K_SEPARATE_READS.
philpem@0 138
philpem@0 139 - In your host program, implement the following functions:
philpem@0 140 unsigned int m68k_read_immediate_16(unsigned int address);
philpem@0 141 unsigned int m68k_read_immediate_32(unsigned int address);
philpem@0 142
philpem@0 143 unsigned int m68k_read_pcrelative_8(unsigned int address);
philpem@0 144 unsigned int m68k_read_pcrelative_16(unsigned int address);
philpem@0 145 unsigned int m68k_read_pcrelative_32(unsigned int address);
philpem@0 146
philpem@0 147 - If you need to know the current PC (for banking and such), set
philpem@0 148 M68K_MONITOR_PC to OPT_SPECIFY_HANDLER, and set M68K_SET_PC_CALLBACK(A) to
philpem@0 149 your routine.
philpem@0 150
philpem@0 151
philpem@0 152
philpem@0 153 ADDRESS SPACES:
philpem@0 154 --------------
philpem@0 155 Most systems will only implement one address space, placing ROM at the lower
philpem@0 156 addresses and RAM at the higher. However, there is the possibility that a
philpem@0 157 system will implement ROM and RAM in the same address range, but in different
philpem@0 158 address spaces, or will have different mamory types that require different
philpem@0 159 handling for the program and the data.
philpem@0 160
philpem@0 161 The 68k accomodates this by allowing different program spaces, the most
philpem@0 162 important to us being PROGRAM and DATA space. Here is a breakdown of
philpem@0 163 how information is fetched:
philpem@0 164
philpem@0 165 - All immediate reads are fetched from PROGRAM space.
philpem@0 166
philpem@0 167 - All PC-relative reads are fetched from PROGRAM space.
philpem@0 168
philpem@0 169 - The initial stack pointer and program counter are fetched from PROGRAM space.
philpem@0 170
philpem@0 171 - All other reads (except for those from the moves instruction for 68020)
philpem@0 172 are fetched from DATA space.
philpem@0 173
philpem@0 174 The m68k deals with this by encoding the requested address space on the
philpem@0 175 function code pins:
philpem@0 176
philpem@0 177 FC
philpem@0 178 Address Space 210
philpem@0 179 ------------------ ---
philpem@0 180 USER DATA 001
philpem@0 181 USER PROGRAM 010
philpem@0 182 SUPERVISOR DATA 101
philpem@0 183 SUPERVISOR PROGRAM 110
philpem@0 184 CPU SPACE 111 <-- not emulated in this core since we emulate
philpem@0 185 interrupt acknowledge in another way.
philpem@0 186
philpem@0 187 Problems arise here if you need to emulate this distinction (if, for example,
philpem@0 188 your ROM and RAM are at the same address range, with RAM and ROM enable
philpem@0 189 wired to the function code pins).
philpem@0 190
philpem@0 191 There are 2 ways to deal with this situation using Musashi:
philpem@0 192
philpem@0 193 1. If you only need the distinction between PROGRAM and DATA (the most common),
philpem@0 194 you can just separate the reads (see the preceeding section). This is the
philpem@0 195 faster solution.
philpem@0 196
philpem@0 197 2. You can emulate the function code pins entirely.
philpem@0 198
philpem@0 199 To emulate the function code pins:
philpem@0 200
philpem@0 201 - In m68kconf.h, set M68K_EMULATE_FC to OPT_SPECIFY_HANDLER and set
philpem@0 202 M68K_SET_FC_CALLBACK(A) to your function code handler function.
philpem@0 203
philpem@0 204 - Your function code handler should select the proper address space for
philpem@0 205 subsequent calls to m68k_read_xx (and m68k_write_xx for 68010+).
philpem@0 206
philpem@0 207 Note: immediate reads are always done from program space, so technically you
philpem@0 208 don't need to implement the separate immediate reads, although you could
philpem@0 209 gain more speed improvements leaving them in and doing some clever
philpem@0 210 programming.
philpem@0 211
philpem@0 212
philpem@0 213
philpem@0 214 USING DIFFERENT CPU TYPES:
philpem@0 215 -------------------------
philpem@0 216 The default is to enable only the 68000 cpu type. To change this, change the
philpem@0 217 settings for M68K_EMULATE_010 etc in m68kconf.h.
philpem@0 218
philpem@0 219 To set the CPU type you want to use:
philpem@0 220
philpem@0 221 - Make sure it is enabled in m68kconf.h. Current switches are:
philpem@0 222 M68K_EMULATE_010
philpem@0 223 M68K_EMULATE_EC020
philpem@0 224 M68K_EMULATE_020
philpem@0 225
philpem@0 226 - In your host program, call m68k_set_cpu_type() and then call
philpem@0 227 m68k_pulse_reset(). Valid CPU types are:
philpem@0 228 M68K_CPU_TYPE_68000,
philpem@0 229 M68K_CPU_TYPE_68010,
philpem@0 230 M68K_CPU_TYPE_68EC020,
philpem@0 231 M68K_CPU_TYPE_68020
philpem@0 232
philpem@0 233
philpem@0 234
philpem@0 235 CLOCK FREQUENCY:
philpem@0 236 ---------------
philpem@0 237 In order to emulate the correct clock frequency, you will have to calculate
philpem@0 238 how long it takes the emulation to execute a certain number of "cycles" and
philpem@0 239 vary your calls to m68k_execute() accordingly.
philpem@0 240 As well, it is a good idea to take away the CPU's timeslice when it writes to
philpem@0 241 a memory-mapped port in order to give the device it wrote to a chance to
philpem@0 242 react.
philpem@0 243
philpem@0 244 You can use the functions m68k_cycles_run(), m68k_cycles_remaining(),
philpem@0 245 m68k_modify_timeslice(), and m68k_end_timeslice() to do this.
philpem@0 246 Try to use large cycle values in your calls to m68k_execute() since it will
philpem@0 247 increase throughput. You can always take away the timeslice later.
philpem@0 248
philpem@0 249
philpem@0 250
philpem@0 251 MORE CORRECT EMULATION:
philpem@0 252 ----------------------
philpem@0 253 You may need to enable these in order to properly emulate some of the more
philpem@0 254 obscure functions of the m68k:
philpem@0 255
philpem@0 256 - M68K_EMULATE_BKPT_ACK causes the CPU to call a breakpoint handler on a BKPT
philpem@0 257 instruction
philpem@0 258
philpem@0 259 - M68K_EMULATE_TRACE causes the CPU to generate trace exceptions when the
philpem@0 260 trace bits are set
philpem@0 261
philpem@0 262 - M68K_EMULATE_RESET causes the CPU to call a reset handler on a RESET
philpem@0 263 instruction.
philpem@0 264
philpem@0 265 - M68K_EMULATE_PREFETCH emulates the 4-word instruction prefetch that is part
philpem@0 266 of the 68000/68010 (needed for Amiga emulation).
philpem@0 267
philpem@0 268 - call m68k_pulse_halt() to emulate the HALT pin.
philpem@0 269
philpem@0 270
philpem@0 271
philpem@0 272 CONVENIENCE FUNCTIONS:
philpem@0 273 ---------------------
philpem@0 274 These are in here for programmer convenience:
philpem@0 275
philpem@0 276 - M68K_INSTRUCTION_HOOK lets you call a handler before each instruction.
philpem@0 277
philpem@0 278 - M68K_LOG_ENABLE and M68K_LOG_1010_1111 lets you log illegal and A/F-line
philpem@0 279 instructions.
philpem@0 280
philpem@0 281
philpem@0 282
philpem@0 283 MULTIPLE CPU EMULATION:
philpem@0 284 ----------------------
philpem@0 285 The default is to use only one CPU. To use more than one CPU in this core,
philpem@0 286 there are some things to keep in mind:
philpem@0 287
philpem@0 288 - To have different cpus call different functions, use OPT_ON instead of
philpem@0 289 OPT_SPECIFY_HANDLER, and use the m68k_set_xxx_callback() functions to set
philpem@0 290 your callback handlers on a per-cpu basis.
philpem@0 291
philpem@0 292 - Be sure to call set_cpu_type() for each CPU you use.
philpem@0 293
philpem@0 294 - Use m68k_set_context() and m68k_get_context() to switch to another CPU.
philpem@0 295
philpem@0 296
philpem@0 297
philpem@0 298 LOAD AND SAVE CPU CONTEXTS FROM DISK:
philpem@0 299 ------------------------------------
philpem@0 300 You can use them68k_load_context() and m68k_save_context() functions to load
philpem@0 301 and save the CPU state to disk.
philpem@0 302
philpem@0 303
philpem@0 304
philpem@0 305 GET/SET INFORMATION FROM THE CPU:
philpem@0 306 --------------------------------
philpem@0 307 You can use m68k_get_reg() and m68k_set_reg() to gain access to the internals
philpem@0 308 of the CPU.
philpem@0 309
philpem@0 310
philpem@0 311
philpem@0 312 EXAMPLE:
philpem@0 313 -------
philpem@0 314
philpem@0 315 I have included a file example.zip that contains a full example.