1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/musashi/example/readme.txt Sat Nov 27 01:13:12 2010 +0000 1.3 @@ -0,0 +1,315 @@ 1.4 + MUSASHI 1.5 + ======= 1.6 + 1.7 + Version 3.3 1.8 + 1.9 + A portable Motorola M680x0 processor emulation engine. 1.10 + Copyright 1998-2001 Karl Stenerud. All rights reserved. 1.11 + 1.12 + 1.13 + 1.14 +INTRODUCTION: 1.15 +------------ 1.16 + 1.17 +Musashi is a Motorola 68000, 68010, 68EC020, and 68020 emulator written in C. 1.18 +This emulator was written with two goals in mind: portability and speed. 1.19 + 1.20 +The emulator is written to ANSI C specifications with the exception that I use 1.21 +inline functions. This is not compliant to the ANSI spec, but will be 1.22 +compliant to the ANSI C9X spec. 1.23 + 1.24 +It has been successfully running in the MAME project (www.mame.net) for over 2 1.25 +years and so has had time to mature. 1.26 + 1.27 + 1.28 + 1.29 +LICENSE AND COPYRIGHT: 1.30 +--------------------- 1.31 + 1.32 +The Musashi M680x0 emulator is copyright 1998-2001 Karl Stenerud. 1.33 + 1.34 +The source code included in this archive is provided AS-IS, free for any 1.35 +non-commercial purpose. 1.36 + 1.37 +If you build a program using this core, please give credit to the author. 1.38 + 1.39 +If you wish to use this core in a commercial environment, please contact 1.40 +the author to discuss commercial licensing. 1.41 + 1.42 + 1.43 + 1.44 +AVAILABILITY: 1.45 +------------ 1.46 +The latest version of this code can be obtained at: 1.47 +http://kstenerud.cjb.net 1.48 + 1.49 + 1.50 + 1.51 +CONTACTING THE AUTHOR: 1.52 +--------------------- 1.53 +I can be reached at kstenerud@mame.net 1.54 + 1.55 + 1.56 + 1.57 +BASIC CONFIGURATION: 1.58 +------------------- 1.59 +The basic configuration will give you a standard 68000 that has sufficient 1.60 +functionality to work in a primitive environment. 1.61 + 1.62 +This setup assumes that you only have 1 device interrupting it, that the 1.63 +device will always request an autovectored interrupt, and it will always clear 1.64 +the interrupt before the interrupt service routine finishes (but could 1.65 +possibly re-assert the interrupt). 1.66 +You will have only one address space, no tracing, and no instruction prefetch. 1.67 + 1.68 +To implement the basic configuration: 1.69 + 1.70 +- Open m68kconf.h and verify that the settings for INLINE and DECL_SPEC will 1.71 + work with your compiler. (They are set for gcc) 1.72 + 1.73 +- In your host program, implement the following functions: 1.74 + unsigned int m68k_read_memory_8(unsigned int address); 1.75 + unsigned int m68k_read_memory_16(unsigned int address); 1.76 + unsigned int m68k_read_memory_32(unsigned int address); 1.77 + void m68k_write_memory_8(unsigned int address, unsigned int value); 1.78 + void m68k_write_memory_16(unsigned int address, unsigned int value); 1.79 + void m68k_write_memory_32(unsigned int address, unsigned int value); 1.80 + 1.81 +- In your host program, be sure to call m68k_pulse_reset() once before calling 1.82 + any of the other functions as this initializes the core. 1.83 + 1.84 +- Use m68k_execute() to execute instructions and m68k_set_irq() to cause an 1.85 + interrupt. 1.86 + 1.87 + 1.88 + 1.89 +ADDING PROPER INTERRUPT HANDLING: 1.90 +-------------------------------- 1.91 +The interrupt handling in the basic configuration doesn't emulate the 1.92 +interrupt acknowledge phase of the CPU and automatically clears an interrupt 1.93 +request during interrupt processing. 1.94 +While this works for most systems, you may need more accurate interrupt 1.95 +handling. 1.96 + 1.97 +To add proper interrupt handling: 1.98 + 1.99 +- In m68kconf.h, set M68K_EMULATE_INT_ACK to OPT_SPECIFY_HANDLER 1.100 + 1.101 +- In m68kconf.h, set M68K_INT_ACK_CALLBACK(A) to your interrupt acknowledge 1.102 + routine 1.103 + 1.104 +- Your interrupt acknowledge routine must return an interrupt vector, 1.105 + M68K_INT_ACK_AUTOVECTOR, or M68K_INT_ACK_SPURIOUS. most m68k 1.106 + implementations just use autovectored interrupts. 1.107 + 1.108 +- When the interrupting device is satisfied, you must call m68k_set_irq(0) to 1.109 + remove the interrupt request. 1.110 + 1.111 + 1.112 + 1.113 +MULTIPLE INTERRUPTS: 1.114 +------------------- 1.115 +The above system will work if you have only one device interrupting the CPU, 1.116 +but if you have more than one device, you must do a bit more. 1.117 + 1.118 +To add multiple interrupts: 1.119 + 1.120 +- You must make an interrupt arbitration device that will take the highest 1.121 + priority interrupt and encode it onto the IRQ pins on the CPU. 1.122 + 1.123 +- The interrupt arbitration device should use m68k_set_irq() to set the 1.124 + highest pending interrupt, or 0 for no interrupts pending. 1.125 + 1.126 + 1.127 + 1.128 +SEPARATE IMMEDIATE AND PC-RELATIVE READS: 1.129 +---------------------------------------- 1.130 +You can write faster memory access functions if you know whether you are 1.131 +fetching from ROM or RAM. Immediate reads are always from the program space 1.132 +(Always in ROM unless it is running self-modifying code). 1.133 +This will also separate the pc-relative reads, since some systems treat 1.134 +PROGRAM mode reads and DATA mode reads differently (for program encryption, 1.135 +for instance). See the section below (ADDRESS SPACE) for an explanation of 1.136 +PROGRAM and DATA mode. 1.137 + 1.138 +To enable separate reads: 1.139 + 1.140 +- In m68kconf.h, turn on M68K_SEPARATE_READS. 1.141 + 1.142 +- In your host program, implement the following functions: 1.143 + unsigned int m68k_read_immediate_16(unsigned int address); 1.144 + unsigned int m68k_read_immediate_32(unsigned int address); 1.145 + 1.146 + unsigned int m68k_read_pcrelative_8(unsigned int address); 1.147 + unsigned int m68k_read_pcrelative_16(unsigned int address); 1.148 + unsigned int m68k_read_pcrelative_32(unsigned int address); 1.149 + 1.150 +- If you need to know the current PC (for banking and such), set 1.151 + M68K_MONITOR_PC to OPT_SPECIFY_HANDLER, and set M68K_SET_PC_CALLBACK(A) to 1.152 + your routine. 1.153 + 1.154 + 1.155 + 1.156 +ADDRESS SPACES: 1.157 +-------------- 1.158 +Most systems will only implement one address space, placing ROM at the lower 1.159 +addresses and RAM at the higher. However, there is the possibility that a 1.160 +system will implement ROM and RAM in the same address range, but in different 1.161 +address spaces, or will have different mamory types that require different 1.162 +handling for the program and the data. 1.163 + 1.164 +The 68k accomodates this by allowing different program spaces, the most 1.165 +important to us being PROGRAM and DATA space. Here is a breakdown of 1.166 +how information is fetched: 1.167 + 1.168 +- All immediate reads are fetched from PROGRAM space. 1.169 + 1.170 +- All PC-relative reads are fetched from PROGRAM space. 1.171 + 1.172 +- The initial stack pointer and program counter are fetched from PROGRAM space. 1.173 + 1.174 +- All other reads (except for those from the moves instruction for 68020) 1.175 + are fetched from DATA space. 1.176 + 1.177 +The m68k deals with this by encoding the requested address space on the 1.178 +function code pins: 1.179 + 1.180 + FC 1.181 + Address Space 210 1.182 + ------------------ --- 1.183 + USER DATA 001 1.184 + USER PROGRAM 010 1.185 + SUPERVISOR DATA 101 1.186 + SUPERVISOR PROGRAM 110 1.187 + CPU SPACE 111 <-- not emulated in this core since we emulate 1.188 + interrupt acknowledge in another way. 1.189 + 1.190 +Problems arise here if you need to emulate this distinction (if, for example, 1.191 +your ROM and RAM are at the same address range, with RAM and ROM enable 1.192 +wired to the function code pins). 1.193 + 1.194 +There are 2 ways to deal with this situation using Musashi: 1.195 + 1.196 +1. If you only need the distinction between PROGRAM and DATA (the most common), 1.197 + you can just separate the reads (see the preceeding section). This is the 1.198 + faster solution. 1.199 + 1.200 +2. You can emulate the function code pins entirely. 1.201 + 1.202 +To emulate the function code pins: 1.203 + 1.204 +- In m68kconf.h, set M68K_EMULATE_FC to OPT_SPECIFY_HANDLER and set 1.205 + M68K_SET_FC_CALLBACK(A) to your function code handler function. 1.206 + 1.207 +- Your function code handler should select the proper address space for 1.208 + subsequent calls to m68k_read_xx (and m68k_write_xx for 68010+). 1.209 + 1.210 +Note: immediate reads are always done from program space, so technically you 1.211 + don't need to implement the separate immediate reads, although you could 1.212 + gain more speed improvements leaving them in and doing some clever 1.213 + programming. 1.214 + 1.215 + 1.216 + 1.217 +USING DIFFERENT CPU TYPES: 1.218 +------------------------- 1.219 +The default is to enable only the 68000 cpu type. To change this, change the 1.220 +settings for M68K_EMULATE_010 etc in m68kconf.h. 1.221 + 1.222 +To set the CPU type you want to use: 1.223 + 1.224 +- Make sure it is enabled in m68kconf.h. Current switches are: 1.225 + M68K_EMULATE_010 1.226 + M68K_EMULATE_EC020 1.227 + M68K_EMULATE_020 1.228 + 1.229 +- In your host program, call m68k_set_cpu_type() and then call 1.230 + m68k_pulse_reset(). Valid CPU types are: 1.231 + M68K_CPU_TYPE_68000, 1.232 + M68K_CPU_TYPE_68010, 1.233 + M68K_CPU_TYPE_68EC020, 1.234 + M68K_CPU_TYPE_68020 1.235 + 1.236 + 1.237 + 1.238 +CLOCK FREQUENCY: 1.239 +--------------- 1.240 +In order to emulate the correct clock frequency, you will have to calculate 1.241 +how long it takes the emulation to execute a certain number of "cycles" and 1.242 +vary your calls to m68k_execute() accordingly. 1.243 +As well, it is a good idea to take away the CPU's timeslice when it writes to 1.244 +a memory-mapped port in order to give the device it wrote to a chance to 1.245 +react. 1.246 + 1.247 +You can use the functions m68k_cycles_run(), m68k_cycles_remaining(), 1.248 +m68k_modify_timeslice(), and m68k_end_timeslice() to do this. 1.249 +Try to use large cycle values in your calls to m68k_execute() since it will 1.250 +increase throughput. You can always take away the timeslice later. 1.251 + 1.252 + 1.253 + 1.254 +MORE CORRECT EMULATION: 1.255 +---------------------- 1.256 +You may need to enable these in order to properly emulate some of the more 1.257 +obscure functions of the m68k: 1.258 + 1.259 +- M68K_EMULATE_BKPT_ACK causes the CPU to call a breakpoint handler on a BKPT 1.260 + instruction 1.261 + 1.262 +- M68K_EMULATE_TRACE causes the CPU to generate trace exceptions when the 1.263 + trace bits are set 1.264 + 1.265 +- M68K_EMULATE_RESET causes the CPU to call a reset handler on a RESET 1.266 + instruction. 1.267 + 1.268 +- M68K_EMULATE_PREFETCH emulates the 4-word instruction prefetch that is part 1.269 + of the 68000/68010 (needed for Amiga emulation). 1.270 + 1.271 +- call m68k_pulse_halt() to emulate the HALT pin. 1.272 + 1.273 + 1.274 + 1.275 +CONVENIENCE FUNCTIONS: 1.276 +--------------------- 1.277 +These are in here for programmer convenience: 1.278 + 1.279 +- M68K_INSTRUCTION_HOOK lets you call a handler before each instruction. 1.280 + 1.281 +- M68K_LOG_ENABLE and M68K_LOG_1010_1111 lets you log illegal and A/F-line 1.282 + instructions. 1.283 + 1.284 + 1.285 + 1.286 +MULTIPLE CPU EMULATION: 1.287 +---------------------- 1.288 +The default is to use only one CPU. To use more than one CPU in this core, 1.289 +there are some things to keep in mind: 1.290 + 1.291 +- To have different cpus call different functions, use OPT_ON instead of 1.292 + OPT_SPECIFY_HANDLER, and use the m68k_set_xxx_callback() functions to set 1.293 + your callback handlers on a per-cpu basis. 1.294 + 1.295 +- Be sure to call set_cpu_type() for each CPU you use. 1.296 + 1.297 +- Use m68k_set_context() and m68k_get_context() to switch to another CPU. 1.298 + 1.299 + 1.300 + 1.301 +LOAD AND SAVE CPU CONTEXTS FROM DISK: 1.302 +------------------------------------ 1.303 +You can use them68k_load_context() and m68k_save_context() functions to load 1.304 +and save the CPU state to disk. 1.305 + 1.306 + 1.307 + 1.308 +GET/SET INFORMATION FROM THE CPU: 1.309 +-------------------------------- 1.310 +You can use m68k_get_reg() and m68k_set_reg() to gain access to the internals 1.311 +of the CPU. 1.312 + 1.313 + 1.314 + 1.315 +EXAMPLE: 1.316 +------- 1.317 + 1.318 +I have included a file example.zip that contains a full example.