initial import
[picodrive.git] / cpu / musashi / readme.txt
diff --git a/cpu/musashi/readme.txt b/cpu/musashi/readme.txt
new file mode 100644 (file)
index 0000000..48e603f
--- /dev/null
@@ -0,0 +1,315 @@
+                                    MUSASHI\r
+                                    =======\r
+\r
+                                  Version 3.3\r
+\r
+             A portable Motorola M680x0 processor emulation engine.\r
+            Copyright 1998-2001 Karl Stenerud.  All rights reserved.\r
+\r
+\r
+\r
+INTRODUCTION:\r
+------------\r
+\r
+Musashi is a Motorola 68000, 68010, 68EC020, and 68020 emulator written in C.\r
+This emulator was written with two goals in mind: portability and speed.\r
+\r
+The emulator is written to ANSI C specifications with the exception that I use\r
+inline functions.  This is not compliant to the ANSI spec, but will be\r
+compliant to the ANSI C9X spec.\r
+\r
+It has been successfully running in the MAME project (www.mame.net) for over 2\r
+years and so has had time to mature.\r
+\r
+\r
+\r
+LICENSE AND COPYRIGHT:\r
+---------------------\r
+\r
+The Musashi M680x0 emulator is copyright 1998-2001 Karl Stenerud.\r
+\r
+The source code included in this archive is provided AS-IS, free for any\r
+non-commercial purpose.\r
+\r
+If you build a program using this core, please give credit to the author.\r
+\r
+If you wish to use this core in a commercial environment, please contact\r
+the author to discuss commercial licensing.\r
+\r
+\r
+\r
+AVAILABILITY:\r
+------------\r
+The latest version of this code can be obtained at:\r
+http://kstenerud.cjb.net\r
+\r
+\r
+\r
+CONTACTING THE AUTHOR:\r
+---------------------\r
+I can be reached at kstenerud@mame.net\r
+\r
+\r
+\r
+BASIC CONFIGURATION:\r
+-------------------\r
+The basic configuration will give you a standard 68000 that has sufficient\r
+functionality to work in a primitive environment.\r
+\r
+This setup assumes that you only have 1 device interrupting it, that the\r
+device will always request an autovectored interrupt, and it will always clear\r
+the interrupt before the interrupt service routine finishes (but could\r
+possibly re-assert the interrupt).\r
+You will have only one address space, no tracing, and no instruction prefetch.\r
+\r
+To implement the basic configuration:\r
+\r
+- Open m68kconf.h and verify that the settings for INLINE and DECL_SPEC will\r
+  work with your compiler. (They are set for gcc)\r
+\r
+- In your host program, implement the following functions:\r
+    unsigned int  m68k_read_memory_8(unsigned int address);\r
+    unsigned int  m68k_read_memory_16(unsigned int address);\r
+    unsigned int  m68k_read_memory_32(unsigned int address);\r
+    void m68k_write_memory_8(unsigned int address, unsigned int value);\r
+    void m68k_write_memory_16(unsigned int address, unsigned int value);\r
+    void m68k_write_memory_32(unsigned int address, unsigned int value);\r
+\r
+- In your host program, be sure to call m68k_pulse_reset() once before calling\r
+  any of the other functions as this initializes the core.\r
+\r
+- Use m68k_execute() to execute instructions and m68k_set_irq() to cause an\r
+  interrupt.\r
+\r
+\r
+\r
+ADDING PROPER INTERRUPT HANDLING:\r
+--------------------------------\r
+The interrupt handling in the basic configuration doesn't emulate the\r
+interrupt acknowledge phase of the CPU and automatically clears an interrupt\r
+request during interrupt processing.\r
+While this works for most systems, you may need more accurate interrupt\r
+handling.\r
+\r
+To add proper interrupt handling:\r
+\r
+- In m68kconf.h, set M68K_EMULATE_INT_ACK to OPT_SPECIFY_HANDLER\r
+\r
+- In m68kconf.h, set M68K_INT_ACK_CALLBACK(A) to your interrupt acknowledge\r
+  routine\r
+\r
+- Your interrupt acknowledge routine must return an interrupt vector,\r
+  M68K_INT_ACK_AUTOVECTOR, or M68K_INT_ACK_SPURIOUS.  most m68k\r
+  implementations just use autovectored interrupts.\r
+\r
+- When the interrupting device is satisfied, you must call m68k_set_irq(0) to\r
+  remove the interrupt request.\r
+\r
+\r
+\r
+MULTIPLE INTERRUPTS:\r
+-------------------\r
+The above system will work if you have only one device interrupting the CPU,\r
+but if you have more than one device, you must do a bit more.\r
+\r
+To add multiple interrupts:\r
+\r
+- You must make an interrupt arbitration device that will take the highest\r
+  priority interrupt and encode it onto the IRQ pins on the CPU.\r
+\r
+- The interrupt arbitration device should use m68k_set_irq() to set the\r
+  highest pending interrupt, or 0 for no interrupts pending.\r
+\r
+\r
+\r
+SEPARATE IMMEDIATE AND PC-RELATIVE READS:\r
+----------------------------------------\r
+You can write faster memory access functions if you know whether you are\r
+fetching from ROM or RAM.  Immediate reads are always from the program space\r
+(Always in ROM unless it is running self-modifying code).\r
+This will also separate the pc-relative reads, since some systems treat\r
+PROGRAM mode reads and DATA mode reads differently (for program encryption,\r
+for instance).  See the section below (ADDRESS SPACE) for an explanation of\r
+PROGRAM and DATA mode.\r
+\r
+To enable separate reads:\r
+\r
+- In m68kconf.h, turn on M68K_SEPARATE_READS.\r
+\r
+- In your host program, implement the following functions:\r
+    unsigned int  m68k_read_immediate_16(unsigned int address);\r
+    unsigned int  m68k_read_immediate_32(unsigned int address);\r
+\r
+    unsigned int  m68k_read_pcrelative_8(unsigned int address);\r
+    unsigned int  m68k_read_pcrelative_16(unsigned int address);\r
+    unsigned int  m68k_read_pcrelative_32(unsigned int address);\r
+\r
+- If you need to know the current PC (for banking and such), set\r
+  M68K_MONITOR_PC to OPT_SPECIFY_HANDLER, and set M68K_SET_PC_CALLBACK(A) to\r
+  your routine.\r
+\r
+\r
+\r
+ADDRESS SPACES:\r
+--------------\r
+Most systems will only implement one address space, placing ROM at the lower\r
+addresses and RAM at the higher.  However, there is the possibility that a\r
+system will implement ROM and RAM in the same address range, but in different\r
+address spaces, or will have different mamory types that require different\r
+handling for the program and the data.\r
+\r
+The 68k accomodates this by allowing different program spaces, the most\r
+important to us being PROGRAM and DATA space.  Here is a breakdown of\r
+how information is fetched:\r
+\r
+- All immediate reads are fetched from PROGRAM space.\r
+\r
+- All PC-relative reads are fetched from PROGRAM space.\r
+\r
+- The initial stack pointer and program counter are fetched from PROGRAM space.\r
+\r
+- All other reads (except for those from the moves instruction for 68020)\r
+   are fetched from DATA space.\r
+\r
+The m68k deals with this by encoding the requested address space on the\r
+function code pins:\r
+\r
+                       FC\r
+    Address Space      210\r
+    ------------------ ---\r
+    USER DATA          001\r
+    USER PROGRAM       010\r
+    SUPERVISOR DATA    101\r
+    SUPERVISOR PROGRAM 110\r
+    CPU SPACE          111 <-- not emulated in this core since we emulate\r
+                               interrupt acknowledge in another way.\r
+\r
+Problems arise here if you need to emulate this distinction (if, for example,\r
+your ROM and RAM are at the same address range, with RAM and ROM enable\r
+wired to the function code pins).\r
+\r
+There are 2 ways to deal with this situation using Musashi:\r
+\r
+1. If you only need the distinction between PROGRAM and DATA (the most common),\r
+   you can just separate the reads (see the preceeding section).  This is the\r
+   faster solution.\r
+\r
+2. You can emulate the function code pins entirely.\r
+\r
+To emulate the function code pins:\r
+\r
+- In m68kconf.h, set M68K_EMULATE_FC to OPT_SPECIFY_HANDLER and set\r
+  M68K_SET_FC_CALLBACK(A) to your function code handler function.\r
+\r
+- Your function code handler should select the proper address space for\r
+  subsequent calls to m68k_read_xx (and m68k_write_xx for 68010+).\r
+\r
+Note: immediate reads are always done from program space, so technically you\r
+      don't need to implement the separate immediate reads, although you could\r
+      gain more speed improvements leaving them in and doing some clever\r
+      programming.\r
+\r
+\r
+\r
+USING DIFFERENT CPU TYPES:\r
+-------------------------\r
+The default is to enable only the 68000 cpu type.  To change this, change the\r
+settings for M68K_EMULATE_010 etc in m68kconf.h.\r
+\r
+To set the CPU type you want to use:\r
+\r
+- Make sure it is enabled in m68kconf.h.  Current switches are:\r
+    M68K_EMULATE_010\r
+    M68K_EMULATE_EC020\r
+    M68K_EMULATE_020\r
+\r
+- In your host program, call m68k_set_cpu_type() and then call\r
+  m68k_pulse_reset().  Valid CPU types are:\r
+    M68K_CPU_TYPE_68000,\r
+    M68K_CPU_TYPE_68010,\r
+    M68K_CPU_TYPE_68EC020,\r
+    M68K_CPU_TYPE_68020\r
+\r
+\r
+\r
+CLOCK FREQUENCY:\r
+---------------\r
+In order to emulate the correct clock frequency, you will have to calculate\r
+how long it takes the emulation to execute a certain number of "cycles" and\r
+vary your calls to m68k_execute() accordingly.\r
+As well, it is a good idea to take away the CPU's timeslice when it writes to\r
+a memory-mapped port in order to give the device it wrote to a chance to\r
+react.\r
+\r
+You can use the functions m68k_cycles_run(), m68k_cycles_remaining(),\r
+m68k_modify_timeslice(), and m68k_end_timeslice() to do this.\r
+Try to use large cycle values in your calls to m68k_execute() since it will\r
+increase throughput.  You can always take away the timeslice later.\r
+\r
+\r
+\r
+MORE CORRECT EMULATION:\r
+----------------------\r
+You may need to enable these in order to properly emulate some of the more\r
+obscure functions of the m68k:\r
+\r
+- M68K_EMULATE_BKPT_ACK causes the CPU to call a breakpoint handler on a BKPT\r
+  instruction\r
+\r
+- M68K_EMULATE_TRACE causes the CPU to generate trace exceptions when the\r
+  trace bits are set\r
+\r
+- M68K_EMULATE_RESET causes the CPU to call a reset handler on a RESET\r
+  instruction.\r
+\r
+- M68K_EMULATE_PREFETCH emulates the 4-word instruction prefetch that is part\r
+  of the 68000/68010 (needed for Amiga emulation).\r
+\r
+- call m68k_pulse_halt() to emulate the HALT pin.\r
+\r
+\r
+\r
+CONVENIENCE FUNCTIONS:\r
+---------------------\r
+These are in here for programmer convenience:\r
+\r
+- M68K_INSTRUCTION_HOOK lets you call a handler before each instruction.\r
+\r
+- M68K_LOG_ENABLE and M68K_LOG_1010_1111 lets you log illegal and A/F-line\r
+  instructions.\r
+\r
+\r
+\r
+MULTIPLE CPU EMULATION:\r
+----------------------\r
+The default is to use only one CPU.  To use more than one CPU in this core,\r
+there are some things to keep in mind:\r
+\r
+- To have different cpus call different functions, use OPT_ON instead of\r
+  OPT_SPECIFY_HANDLER, and use the m68k_set_xxx_callback() functions to set\r
+  your callback handlers on a per-cpu basis.\r
+\r
+- Be sure to call set_cpu_type() for each CPU you use.\r
+\r
+- Use m68k_set_context() and m68k_get_context() to switch to another CPU.\r
+\r
+\r
+\r
+LOAD AND SAVE CPU CONTEXTS FROM DISK:\r
+------------------------------------\r
+You can use them68k_load_context() and m68k_save_context() functions to load\r
+and save the CPU state to disk.\r
+\r
+\r
+\r
+GET/SET INFORMATION FROM THE CPU:\r
+--------------------------------\r
+You can use m68k_get_reg() and m68k_set_reg() to gain access to the internals\r
+of the CPU.\r
+\r
+\r
+\r
+EXAMPLE:\r
+-------\r
+\r
+I have included a file example.zip that contains a full example.\r