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