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