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