]> Shamusworld >> Repos - virtualjaguar/blob - src/m68kcpu.c
Support for new timer based execution
[virtualjaguar] / src / m68kcpu.c
1 /* ======================================================================== */
2 /* ========================= LICENSING & COPYRIGHT ======================== */
3 /* ======================================================================== */
4
5 #if 0
6 static const char* copyright_notice =
7 "MUSASHI\n"
8 "Version 3.3 (2001-01-29)\n"
9 "A portable Motorola M680x0 processor emulation engine.\n"
10 "Copyright 1998-2001 Karl Stenerud.  All rights reserved.\n"
11 "\n"
12 "This code may be freely used for non-commercial purpooses as long as this\n"
13 "copyright notice remains unaltered in the source code and any binary files\n"
14 "containing this code in compiled form.\n"
15 "\n"
16 "All other lisencing terms must be negotiated with the author\n"
17 "(Karl Stenerud).\n"
18 "\n"
19 "The latest version of this code can be obtained at:\n"
20 "http://kstenerud.cjb.net\n"
21 ;
22 #endif
23
24
25 /* ======================================================================== */
26 /* ================================= NOTES ================================ */
27 /* ======================================================================== */
28
29
30
31 /* ======================================================================== */
32 /* ================================ INCLUDES ============================== */
33 /* ======================================================================== */
34
35 #include "m68kops.h"
36 #include "m68kcpu.h"
37
38 /* ======================================================================== */
39 /* ================================= DATA ================================= */
40 /* ======================================================================== */
41
42 int  m68ki_initial_cycles;
43 int  m68ki_remaining_cycles = 0;                     /* Number of clocks remaining */
44 uint m68ki_tracing = 0;
45 uint m68ki_address_space;
46
47 #ifdef M68K_LOG_ENABLE
48 char* m68ki_cpu_names[9] =
49 {
50         "Invalid CPU",
51         "M68000",
52         "M68010",
53         "Invalid CPU",
54         "M68EC020"
55         "Invalid CPU",
56         "Invalid CPU",
57         "Invalid CPU",
58         "M68020"
59 };
60 #endif /* M68K_LOG_ENABLE */
61
62 /* The CPU core */
63 m68ki_cpu_core m68ki_cpu = {0};
64
65 #if M68K_EMULATE_ADDRESS_ERROR
66 jmp_buf m68ki_address_error_trap;
67 #endif /* M68K_EMULATE_ADDRESS_ERROR */
68
69 /* Used by shift & rotate instructions */
70 uint8 m68ki_shift_8_table[65] =
71 {
72         0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff,
73         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
74         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
75         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
76         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
77         0xff, 0xff, 0xff, 0xff, 0xff
78 };
79 uint16 m68ki_shift_16_table[65] =
80 {
81         0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00,
82         0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff,
83         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
84         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
85         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
86         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
87         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
88         0xffff, 0xffff
89 };
90 uint m68ki_shift_32_table[65] =
91 {
92         0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000,
93         0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
94         0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000,
95         0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
96         0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8,
97         0xfffffffc, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
98         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
99         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
100         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
101         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
102         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
103 };
104
105
106 /* Number of clock cycles to use for exception processing.
107  * I used 4 for any vectors that are undocumented for processing times.
108  */
109 uint8 m68ki_exception_cycle_table[3][256] =
110 {
111         { /* 000 */
112                   4, /*  0: Reset - Initial Stack Pointer                      */
113                   4, /*  1: Reset - Initial Program Counter                    */
114                  50, /*  2: Bus Error                             (unemulated) */
115                  50, /*  3: Address Error                         (unemulated) */
116                  34, /*  4: Illegal Instruction                                */
117                  38, /*  5: Divide by Zero -- ASG: changed from 42             */
118                  40, /*  6: CHK -- ASG: chanaged from 44                       */
119                  34, /*  7: TRAPV                                              */
120                  34, /*  8: Privilege Violation                                */
121                  34, /*  9: Trace                                              */
122                   4, /* 10: 1010                                               */
123                   4, /* 11: 1111                                               */
124                   4, /* 12: RESERVED                                           */
125                   4, /* 13: Coprocessor Protocol Violation        (unemulated) */
126                   4, /* 14: Format Error                                       */
127                  44, /* 15: Uninitialized Interrupt                            */
128                   4, /* 16: RESERVED                                           */
129                   4, /* 17: RESERVED                                           */
130                   4, /* 18: RESERVED                                           */
131                   4, /* 19: RESERVED                                           */
132                   4, /* 20: RESERVED                                           */
133                   4, /* 21: RESERVED                                           */
134                   4, /* 22: RESERVED                                           */
135                   4, /* 23: RESERVED                                           */
136                  44, /* 24: Spurious Interrupt                                 */
137                  44, /* 25: Level 1 Interrupt Autovector                       */
138                  44, /* 26: Level 2 Interrupt Autovector                       */
139                  44, /* 27: Level 3 Interrupt Autovector                       */
140                  44, /* 28: Level 4 Interrupt Autovector                       */
141                  44, /* 29: Level 5 Interrupt Autovector                       */
142                  44, /* 30: Level 6 Interrupt Autovector                       */
143                  44, /* 31: Level 7 Interrupt Autovector                       */
144                  34, /* 32: TRAP #0 -- ASG: chanaged from 38                   */
145                  34, /* 33: TRAP #1                                            */
146                  34, /* 34: TRAP #2                                            */
147                  34, /* 35: TRAP #3                                            */
148                  34, /* 36: TRAP #4                                            */
149                  34, /* 37: TRAP #5                                            */
150                  34, /* 38: TRAP #6                                            */
151                  34, /* 39: TRAP #7                                            */
152                  34, /* 40: TRAP #8                                            */
153                  34, /* 41: TRAP #9                                            */
154                  34, /* 42: TRAP #10                                           */
155                  34, /* 43: TRAP #11                                           */
156                  34, /* 44: TRAP #12                                           */
157                  34, /* 45: TRAP #13                                           */
158                  34, /* 46: TRAP #14                                           */
159                  34, /* 47: TRAP #15                                           */
160                   4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
161                   4, /* 49: FP Inexact Result                     (unemulated) */
162                   4, /* 50: FP Divide by Zero                     (unemulated) */
163                   4, /* 51: FP Underflow                          (unemulated) */
164                   4, /* 52: FP Operand Error                      (unemulated) */
165                   4, /* 53: FP Overflow                           (unemulated) */
166                   4, /* 54: FP Signaling NAN                      (unemulated) */
167                   4, /* 55: FP Unimplemented Data Type            (unemulated) */
168                   4, /* 56: MMU Configuration Error               (unemulated) */
169                   4, /* 57: MMU Illegal Operation Error           (unemulated) */
170                   4, /* 58: MMU Access Level Violation Error      (unemulated) */
171                   4, /* 59: RESERVED                                           */
172                   4, /* 60: RESERVED                                           */
173                   4, /* 61: RESERVED                                           */
174                   4, /* 62: RESERVED                                           */
175                   4, /* 63: RESERVED                                           */
176                      /* 64-255: User Defined                                   */
177                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
178                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
179                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
180                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
181                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
182                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
183         },
184         { /* 010 */
185                   4, /*  0: Reset - Initial Stack Pointer                      */
186                   4, /*  1: Reset - Initial Program Counter                    */
187                 126, /*  2: Bus Error                             (unemulated) */
188                 126, /*  3: Address Error                         (unemulated) */
189                  38, /*  4: Illegal Instruction                                */
190                  44, /*  5: Divide by Zero                                     */
191                  44, /*  6: CHK                                                */
192                  34, /*  7: TRAPV                                              */
193                  38, /*  8: Privilege Violation                                */
194                  38, /*  9: Trace                                              */
195                   4, /* 10: 1010                                               */
196                   4, /* 11: 1111                                               */
197                   4, /* 12: RESERVED                                           */
198                   4, /* 13: Coprocessor Protocol Violation        (unemulated) */
199                   4, /* 14: Format Error                                       */
200                  44, /* 15: Uninitialized Interrupt                            */
201                   4, /* 16: RESERVED                                           */
202                   4, /* 17: RESERVED                                           */
203                   4, /* 18: RESERVED                                           */
204                   4, /* 19: RESERVED                                           */
205                   4, /* 20: RESERVED                                           */
206                   4, /* 21: RESERVED                                           */
207                   4, /* 22: RESERVED                                           */
208                   4, /* 23: RESERVED                                           */
209                  46, /* 24: Spurious Interrupt                                 */
210                  46, /* 25: Level 1 Interrupt Autovector                       */
211                  46, /* 26: Level 2 Interrupt Autovector                       */
212                  46, /* 27: Level 3 Interrupt Autovector                       */
213                  46, /* 28: Level 4 Interrupt Autovector                       */
214                  46, /* 29: Level 5 Interrupt Autovector                       */
215                  46, /* 30: Level 6 Interrupt Autovector                       */
216                  46, /* 31: Level 7 Interrupt Autovector                       */
217                  38, /* 32: TRAP #0                                            */
218                  38, /* 33: TRAP #1                                            */
219                  38, /* 34: TRAP #2                                            */
220                  38, /* 35: TRAP #3                                            */
221                  38, /* 36: TRAP #4                                            */
222                  38, /* 37: TRAP #5                                            */
223                  38, /* 38: TRAP #6                                            */
224                  38, /* 39: TRAP #7                                            */
225                  38, /* 40: TRAP #8                                            */
226                  38, /* 41: TRAP #9                                            */
227                  38, /* 42: TRAP #10                                           */
228                  38, /* 43: TRAP #11                                           */
229                  38, /* 44: TRAP #12                                           */
230                  38, /* 45: TRAP #13                                           */
231                  38, /* 46: TRAP #14                                           */
232                  38, /* 47: TRAP #15                                           */
233                   4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
234                   4, /* 49: FP Inexact Result                     (unemulated) */
235                   4, /* 50: FP Divide by Zero                     (unemulated) */
236                   4, /* 51: FP Underflow                          (unemulated) */
237                   4, /* 52: FP Operand Error                      (unemulated) */
238                   4, /* 53: FP Overflow                           (unemulated) */
239                   4, /* 54: FP Signaling NAN                      (unemulated) */
240                   4, /* 55: FP Unimplemented Data Type            (unemulated) */
241                   4, /* 56: MMU Configuration Error               (unemulated) */
242                   4, /* 57: MMU Illegal Operation Error           (unemulated) */
243                   4, /* 58: MMU Access Level Violation Error      (unemulated) */
244                   4, /* 59: RESERVED                                           */
245                   4, /* 60: RESERVED                                           */
246                   4, /* 61: RESERVED                                           */
247                   4, /* 62: RESERVED                                           */
248                   4, /* 63: RESERVED                                           */
249                      /* 64-255: User Defined                                   */
250                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
251                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
252                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
253                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
254                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
255                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
256         },
257         { /* 020 */
258                   4, /*  0: Reset - Initial Stack Pointer                      */
259                   4, /*  1: Reset - Initial Program Counter                    */
260                  50, /*  2: Bus Error                             (unemulated) */
261                  50, /*  3: Address Error                         (unemulated) */
262                  20, /*  4: Illegal Instruction                                */
263                  38, /*  5: Divide by Zero                                     */
264                  40, /*  6: CHK                                                */
265                  20, /*  7: TRAPV                                              */
266                  34, /*  8: Privilege Violation                                */
267                  25, /*  9: Trace                                              */
268                  20, /* 10: 1010                                               */
269                  20, /* 11: 1111                                               */
270                   4, /* 12: RESERVED                                           */
271                   4, /* 13: Coprocessor Protocol Violation        (unemulated) */
272                   4, /* 14: Format Error                                       */
273                  30, /* 15: Uninitialized Interrupt                            */
274                   4, /* 16: RESERVED                                           */
275                   4, /* 17: RESERVED                                           */
276                   4, /* 18: RESERVED                                           */
277                   4, /* 19: RESERVED                                           */
278                   4, /* 20: RESERVED                                           */
279                   4, /* 21: RESERVED                                           */
280                   4, /* 22: RESERVED                                           */
281                   4, /* 23: RESERVED                                           */
282                  30, /* 24: Spurious Interrupt                                 */
283                  30, /* 25: Level 1 Interrupt Autovector                       */
284                  30, /* 26: Level 2 Interrupt Autovector                       */
285                  30, /* 27: Level 3 Interrupt Autovector                       */
286                  30, /* 28: Level 4 Interrupt Autovector                       */
287                  30, /* 29: Level 5 Interrupt Autovector                       */
288                  30, /* 30: Level 6 Interrupt Autovector                       */
289                  30, /* 31: Level 7 Interrupt Autovector                       */
290                  20, /* 32: TRAP #0                                            */
291                  20, /* 33: TRAP #1                                            */
292                  20, /* 34: TRAP #2                                            */
293                  20, /* 35: TRAP #3                                            */
294                  20, /* 36: TRAP #4                                            */
295                  20, /* 37: TRAP #5                                            */
296                  20, /* 38: TRAP #6                                            */
297                  20, /* 39: TRAP #7                                            */
298                  20, /* 40: TRAP #8                                            */
299                  20, /* 41: TRAP #9                                            */
300                  20, /* 42: TRAP #10                                           */
301                  20, /* 43: TRAP #11                                           */
302                  20, /* 44: TRAP #12                                           */
303                  20, /* 45: TRAP #13                                           */
304                  20, /* 46: TRAP #14                                           */
305                  20, /* 47: TRAP #15                                           */
306                   4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
307                   4, /* 49: FP Inexact Result                     (unemulated) */
308                   4, /* 50: FP Divide by Zero                     (unemulated) */
309                   4, /* 51: FP Underflow                          (unemulated) */
310                   4, /* 52: FP Operand Error                      (unemulated) */
311                   4, /* 53: FP Overflow                           (unemulated) */
312                   4, /* 54: FP Signaling NAN                      (unemulated) */
313                   4, /* 55: FP Unimplemented Data Type            (unemulated) */
314                   4, /* 56: MMU Configuration Error               (unemulated) */
315                   4, /* 57: MMU Illegal Operation Error           (unemulated) */
316                   4, /* 58: MMU Access Level Violation Error      (unemulated) */
317                   4, /* 59: RESERVED                                           */
318                   4, /* 60: RESERVED                                           */
319                   4, /* 61: RESERVED                                           */
320                   4, /* 62: RESERVED                                           */
321                   4, /* 63: RESERVED                                           */
322                      /* 64-255: User Defined                                   */
323                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
324                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
325                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
326                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
327                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
328                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
329         }
330 };
331
332 uint8 m68ki_ea_idx_cycle_table[64] =
333 {
334          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
335          0, /* ..01.000 no memory indirect, base NULL             */
336          5, /* ..01..01 memory indirect,    base NULL, outer NULL */
337          7, /* ..01..10 memory indirect,    base NULL, outer 16   */
338          7, /* ..01..11 memory indirect,    base NULL, outer 32   */
339          0,  5,  7,  7,  0,  5,  7,  7,  0,  5,  7,  7,
340          2, /* ..10.000 no memory indirect, base 16               */
341          7, /* ..10..01 memory indirect,    base 16,   outer NULL */
342          9, /* ..10..10 memory indirect,    base 16,   outer 16   */
343          9, /* ..10..11 memory indirect,    base 16,   outer 32   */
344          0,  7,  9,  9,  0,  7,  9,  9,  0,  7,  9,  9,
345          6, /* ..11.000 no memory indirect, base 32               */
346         11, /* ..11..01 memory indirect,    base 32,   outer NULL */
347         13, /* ..11..10 memory indirect,    base 32,   outer 16   */
348         13, /* ..11..11 memory indirect,    base 32,   outer 32   */
349          0, 11, 13, 13,  0, 11, 13, 13,  0, 11, 13, 13
350 };
351
352
353
354 /* ======================================================================== */
355 /* =============================== CALLBACKS ============================== */
356 /* ======================================================================== */
357
358 /* Default callbacks used if the callback hasn't been set yet, or if the
359  * callback is set to NULL
360  */
361
362 /* Interrupt acknowledge */
363 static int default_int_ack_callback_data;
364 static int default_int_ack_callback(int int_level)
365 {
366         default_int_ack_callback_data = int_level;
367         CPU_INT_LEVEL = 0;
368         return M68K_INT_ACK_AUTOVECTOR;
369 }
370
371 /* Breakpoint acknowledge */
372 static unsigned int default_bkpt_ack_callback_data;
373 static void default_bkpt_ack_callback(unsigned int data)
374 {
375         default_bkpt_ack_callback_data = data;
376 }
377
378 /* Called when a reset instruction is executed */
379 static void default_reset_instr_callback(void)
380 {
381 }
382
383 /* Called when the program counter changed by a large value */
384 static unsigned int default_pc_changed_callback_data;
385 static void default_pc_changed_callback(unsigned int new_pc)
386 {
387         default_pc_changed_callback_data = new_pc;
388 }
389
390 /* Called every time there's bus activity (read/write to/from memory */
391 static unsigned int default_set_fc_callback_data;
392 static void default_set_fc_callback(unsigned int new_fc)
393 {
394         default_set_fc_callback_data = new_fc;
395 }
396
397 /* Called every instruction cycle prior to execution */
398 static void default_instr_hook_callback(void)
399 {
400 }
401
402
403
404 /* ======================================================================== */
405 /* ================================= API ================================== */
406 /* ======================================================================== */
407
408 /* Access the internals of the CPU */
409 unsigned int m68k_get_reg(void* context, m68k_register_t regnum)
410 {
411         m68ki_cpu_core* cpu = context != NULL ?(m68ki_cpu_core*)context : &m68ki_cpu;
412
413         switch(regnum)
414         {
415                 case M68K_REG_D0:       return cpu->dar[0];
416                 case M68K_REG_D1:       return cpu->dar[1];
417                 case M68K_REG_D2:       return cpu->dar[2];
418                 case M68K_REG_D3:       return cpu->dar[3];
419                 case M68K_REG_D4:       return cpu->dar[4];
420                 case M68K_REG_D5:       return cpu->dar[5];
421                 case M68K_REG_D6:       return cpu->dar[6];
422                 case M68K_REG_D7:       return cpu->dar[7];
423                 case M68K_REG_A0:       return cpu->dar[8];
424                 case M68K_REG_A1:       return cpu->dar[9];
425                 case M68K_REG_A2:       return cpu->dar[10];
426                 case M68K_REG_A3:       return cpu->dar[11];
427                 case M68K_REG_A4:       return cpu->dar[12];
428                 case M68K_REG_A5:       return cpu->dar[13];
429                 case M68K_REG_A6:       return cpu->dar[14];
430                 case M68K_REG_A7:       return cpu->dar[15];
431                 case M68K_REG_PC:       return MASK_OUT_ABOVE_32(cpu->pc);
432                 case M68K_REG_SR:       return  cpu->t1_flag                                            |
433                                                                         cpu->t0_flag                                            |
434                                                                         (cpu->s_flag << 11)                                     |
435                                                                         (cpu->m_flag << 11)                                     |
436                                                                         cpu->int_mask                                           |
437                                                                         ((cpu->x_flag & XFLAG_SET) >> 4)        |
438                                                                         ((cpu->n_flag & NFLAG_SET) >> 4)        |
439                                                                         ((!cpu->not_z_flag) << 2)                       |
440                                                                         ((cpu->v_flag & VFLAG_SET) >> 6)        |
441                                                                         ((cpu->c_flag & CFLAG_SET) >> 8);
442                 case M68K_REG_SP:       return cpu->dar[15];
443                 case M68K_REG_USP:      return cpu->s_flag ? cpu->sp[0] : cpu->dar[15];
444                 case M68K_REG_ISP:      return cpu->s_flag && !cpu->m_flag ? cpu->dar[15] : cpu->sp[4];
445                 case M68K_REG_MSP:      return cpu->s_flag && cpu->m_flag ? cpu->dar[15] : cpu->sp[6];
446                 case M68K_REG_SFC:      return cpu->sfc;
447                 case M68K_REG_DFC:      return cpu->dfc;
448                 case M68K_REG_VBR:      return cpu->vbr;
449                 case M68K_REG_CACR:     return cpu->cacr;
450                 case M68K_REG_CAAR:     return cpu->caar;
451                 case M68K_REG_PREF_ADDR:        return cpu->pref_addr;
452                 case M68K_REG_PREF_DATA:        return cpu->pref_data;
453                 case M68K_REG_PPC:      return MASK_OUT_ABOVE_32(cpu->ppc);
454                 case M68K_REG_IR:       return cpu->ir;
455                 case M68K_REG_CPU_TYPE:
456                         switch(cpu->cpu_type)
457                         {
458                                 case CPU_TYPE_000:              return (unsigned int)M68K_CPU_TYPE_68000;
459                                 case CPU_TYPE_010:              return (unsigned int)M68K_CPU_TYPE_68010;
460                                 case CPU_TYPE_EC020:    return (unsigned int)M68K_CPU_TYPE_68EC020;
461                                 case CPU_TYPE_020:              return (unsigned int)M68K_CPU_TYPE_68020;
462                         }
463                         return M68K_CPU_TYPE_INVALID;
464                 default:                        return 0;
465         }
466         return 0;
467 }
468
469 void m68k_set_reg(m68k_register_t regnum, unsigned int value)
470 {
471         switch(regnum)
472         {
473                 case M68K_REG_D0:       REG_D[0] = MASK_OUT_ABOVE_32(value); return;
474                 case M68K_REG_D1:       REG_D[1] = MASK_OUT_ABOVE_32(value); return;
475                 case M68K_REG_D2:       REG_D[2] = MASK_OUT_ABOVE_32(value); return;
476                 case M68K_REG_D3:       REG_D[3] = MASK_OUT_ABOVE_32(value); return;
477                 case M68K_REG_D4:       REG_D[4] = MASK_OUT_ABOVE_32(value); return;
478                 case M68K_REG_D5:       REG_D[5] = MASK_OUT_ABOVE_32(value); return;
479                 case M68K_REG_D6:       REG_D[6] = MASK_OUT_ABOVE_32(value); return;
480                 case M68K_REG_D7:       REG_D[7] = MASK_OUT_ABOVE_32(value); return;
481                 case M68K_REG_A0:       REG_A[0] = MASK_OUT_ABOVE_32(value); return;
482                 case M68K_REG_A1:       REG_A[1] = MASK_OUT_ABOVE_32(value); return;
483                 case M68K_REG_A2:       REG_A[2] = MASK_OUT_ABOVE_32(value); return;
484                 case M68K_REG_A3:       REG_A[3] = MASK_OUT_ABOVE_32(value); return;
485                 case M68K_REG_A4:       REG_A[4] = MASK_OUT_ABOVE_32(value); return;
486                 case M68K_REG_A5:       REG_A[5] = MASK_OUT_ABOVE_32(value); return;
487                 case M68K_REG_A6:       REG_A[6] = MASK_OUT_ABOVE_32(value); return;
488                 case M68K_REG_A7:       REG_A[7] = MASK_OUT_ABOVE_32(value); return;
489                 case M68K_REG_PC:       m68ki_jump(MASK_OUT_ABOVE_32(value)); return;
490                 case M68K_REG_SR:       m68ki_set_sr(value); return;
491                 case M68K_REG_SP:       REG_SP = MASK_OUT_ABOVE_32(value); return;
492                 case M68K_REG_USP:      if(FLAG_S)
493                                                                 REG_USP = MASK_OUT_ABOVE_32(value);
494                                                         else
495                                                                 REG_SP = MASK_OUT_ABOVE_32(value);
496                                                         return;
497                 case M68K_REG_ISP:      if(FLAG_S && !FLAG_M)
498                                                                 REG_SP = MASK_OUT_ABOVE_32(value);
499                                                         else
500                                                                 REG_ISP = MASK_OUT_ABOVE_32(value);
501                                                         return;
502                 case M68K_REG_MSP:      if(FLAG_S && FLAG_M)
503                                                                 REG_SP = MASK_OUT_ABOVE_32(value);
504                                                         else
505                                                                 REG_MSP = MASK_OUT_ABOVE_32(value);
506                                                         return;
507                 case M68K_REG_VBR:      REG_VBR = MASK_OUT_ABOVE_32(value); return;
508                 case M68K_REG_SFC:      REG_SFC = value & 7; return;
509                 case M68K_REG_DFC:      REG_DFC = value & 7; return;
510                 case M68K_REG_CACR:     REG_CACR = MASK_OUT_ABOVE_32(value); return;
511                 case M68K_REG_CAAR:     REG_CAAR = MASK_OUT_ABOVE_32(value); return;
512                 case M68K_REG_PPC:      REG_PPC = MASK_OUT_ABOVE_32(value); return;
513                 case M68K_REG_IR:       REG_IR = MASK_OUT_ABOVE_16(value); return;
514                 case M68K_REG_CPU_TYPE: m68k_set_cpu_type(value); return;
515                 default:                        return;
516         }
517 }
518
519 /* Set the callbacks */
520 void m68k_set_int_ack_callback(int  (*callback)(int int_level))
521 {
522         CALLBACK_INT_ACK = callback ? callback : default_int_ack_callback;
523 }
524
525 void m68k_set_bkpt_ack_callback(void  (*callback)(unsigned int data))
526 {
527         CALLBACK_BKPT_ACK = callback ? callback : default_bkpt_ack_callback;
528 }
529
530 void m68k_set_reset_instr_callback(void  (*callback)(void))
531 {
532         CALLBACK_RESET_INSTR = callback ? callback : default_reset_instr_callback;
533 }
534
535 void m68k_set_pc_changed_callback(void  (*callback)(unsigned int new_pc))
536 {
537         CALLBACK_PC_CHANGED = callback ? callback : default_pc_changed_callback;
538 }
539
540 void m68k_set_fc_callback(void  (*callback)(unsigned int new_fc))
541 {
542         CALLBACK_SET_FC = callback ? callback : default_set_fc_callback;
543 }
544
545 void m68k_set_instr_hook_callback(void  (*callback)(void))
546 {
547         CALLBACK_INSTR_HOOK = callback ? callback : default_instr_hook_callback;
548 }
549
550 #include <stdio.h>
551 /* Set the CPU type. */
552 void m68k_set_cpu_type(unsigned int cpu_type)
553 {
554         switch(cpu_type)
555         {
556                 case M68K_CPU_TYPE_68000:
557                         CPU_TYPE         = CPU_TYPE_000;
558                         CPU_ADDRESS_MASK = 0x00ffffff;
559                         CPU_SR_MASK      = 0xa71f; /* T1 -- S  -- -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
560                         CYC_INSTRUCTION  = m68ki_cycles[0];
561                         CYC_EXCEPTION    = m68ki_exception_cycle_table[0];
562                         CYC_BCC_NOTAKE_B = -2;
563                         CYC_BCC_NOTAKE_W = 2;
564                         CYC_DBCC_F_NOEXP = -2;
565                         CYC_DBCC_F_EXP   = 2;
566                         CYC_SCC_R_FALSE  = 2;
567                         CYC_MOVEM_W      = 2;
568                         CYC_MOVEM_L      = 3;
569                         CYC_SHIFT        = 1;
570                         CYC_RESET        = 132;
571                         return;
572                 case M68K_CPU_TYPE_68010:
573                         CPU_TYPE         = CPU_TYPE_010;
574                         CPU_ADDRESS_MASK = 0x00ffffff;
575                         CPU_SR_MASK      = 0xa71f; /* T1 -- S  -- -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
576                         CYC_INSTRUCTION  = m68ki_cycles[1];
577                         CYC_EXCEPTION    = m68ki_exception_cycle_table[1];
578                         CYC_BCC_NOTAKE_B = -4;
579                         CYC_BCC_NOTAKE_W = 0;
580                         CYC_DBCC_F_NOEXP = 0;
581                         CYC_DBCC_F_EXP   = 6;
582                         CYC_SCC_R_FALSE  = 0;
583                         CYC_MOVEM_W      = 2;
584                         CYC_MOVEM_L      = 3;
585                         CYC_SHIFT        = 1;
586                         CYC_RESET        = 130;
587                         return;
588                 case M68K_CPU_TYPE_68EC020:
589                         CPU_TYPE         = CPU_TYPE_EC020;
590                         CPU_ADDRESS_MASK = 0x00ffffff;
591                         CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
592                         CYC_INSTRUCTION  = m68ki_cycles[2];
593                         CYC_EXCEPTION    = m68ki_exception_cycle_table[2];
594                         CYC_BCC_NOTAKE_B = -2;
595                         CYC_BCC_NOTAKE_W = 0;
596                         CYC_DBCC_F_NOEXP = 0;
597                         CYC_DBCC_F_EXP   = 4;
598                         CYC_SCC_R_FALSE  = 0;
599                         CYC_MOVEM_W      = 2;
600                         CYC_MOVEM_L      = 2; 
601                         CYC_SHIFT        = 0;
602                         CYC_RESET        = 518;
603                         return;
604                 case M68K_CPU_TYPE_68020:
605                         CPU_TYPE         = CPU_TYPE_020;
606                         CPU_ADDRESS_MASK = 0xffffffff;
607                         CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
608                         CYC_INSTRUCTION  = m68ki_cycles[2];
609                         CYC_EXCEPTION    = m68ki_exception_cycle_table[2];
610                         CYC_BCC_NOTAKE_B = -2;
611                         CYC_BCC_NOTAKE_W = 0;
612                         CYC_DBCC_F_NOEXP = 0;
613                         CYC_DBCC_F_EXP   = 4;
614                         CYC_SCC_R_FALSE  = 0;
615                         CYC_MOVEM_W      = 2;
616                         CYC_MOVEM_L      = 2;
617                         CYC_SHIFT        = 0;
618                         CYC_RESET        = 518;
619                         return;
620         }
621 }
622
623 /* Execute some instructions until we use up num_cycles clock cycles */
624 /* ASG: removed per-instruction interrupt checks */
625 int m68k_execute(int num_cycles)
626 {
627         /* Make sure we're not stopped */
628         if(!CPU_STOPPED)
629         {
630                 /* Set our pool of clock cycles available */
631                 SET_CYCLES(num_cycles);
632                 m68ki_initial_cycles = num_cycles;
633
634                 /* ASG: update cycles */
635                 USE_CYCLES(CPU_INT_CYCLES);
636                 CPU_INT_CYCLES = 0;
637
638                 /* Return point if we had an address error */
639                 m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */
640
641                 /* Main loop.  Keep going until we run out of clock cycles */
642                 do
643                 {
644                         /* Set tracing accodring to T1. (T0 is done inside instruction) */
645                         m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */
646
647                         /* Set the address space for reads */
648                         m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */
649
650                         /* Call external hook to peek at CPU */
651                         m68ki_instr_hook(); /* auto-disable (see m68kcpu.h) */
652
653                         /* Record previous program counter */
654                         REG_PPC = REG_PC;
655
656                         /* Read an instruction and call its handler */
657                         REG_IR = m68ki_read_imm_16();
658                         m68ki_instruction_jump_table[REG_IR]();
659                         USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
660
661                         /* Trace m68k_exception, if necessary */
662                         m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */
663                 } while(GET_CYCLES() > 0);
664
665                 /* set previous PC to current PC for the next entry into the loop */
666                 REG_PPC = REG_PC;
667
668                 /* ASG: update cycles */
669                 USE_CYCLES(CPU_INT_CYCLES);
670                 CPU_INT_CYCLES = 0;
671
672                 /* return how many clocks we used */
673                 return m68ki_initial_cycles - GET_CYCLES();
674         }
675
676         /* We get here if the CPU is stopped or halted */
677         SET_CYCLES(0);
678         CPU_INT_CYCLES = 0;
679
680         return num_cycles;
681 }
682
683
684 int m68k_cycles_run(void)
685 {
686         return m68ki_initial_cycles - GET_CYCLES();
687 }
688
689 int m68k_cycles_remaining(void)
690 {
691         return GET_CYCLES();
692 }
693
694 /* Change the timeslice */
695 void m68k_modify_timeslice(int cycles)
696 {
697         m68ki_initial_cycles += cycles;
698         ADD_CYCLES(cycles);
699 }
700
701
702 void m68k_end_timeslice(void)
703 {
704         m68ki_initial_cycles = GET_CYCLES();
705         SET_CYCLES(0);
706 }
707
708
709 /* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */
710 /* KS: Modified so that IPL* bits match with mask positions in the SR
711  *     and cleaned out remenants of the interrupt controller.
712  */
713 void m68k_set_irq(unsigned int int_level)
714 {
715         uint old_level = CPU_INT_LEVEL;
716         CPU_INT_LEVEL = int_level << 8;
717
718         /* A transition from < 7 to 7 always interrupts (NMI) */
719         /* Note: Level 7 can also level trigger like a normal IRQ */
720         if(old_level != 0x0700 && CPU_INT_LEVEL == 0x0700)
721                 m68ki_exception_interrupt(7); /* Edge triggered level 7 (NMI) */
722         else
723                 m68ki_check_interrupts(); /* Level triggered (IRQ) */
724 }
725
726
727 /* Pulse the RESET line on the CPU */
728 void m68k_pulse_reset(void)
729 {
730         static uint emulation_initialized = 0;
731
732         /* The first call to this function initializes the opcode handler jump table */
733         if(!emulation_initialized)
734         {
735                 m68ki_build_opcode_table();
736                 m68k_set_int_ack_callback(NULL);
737                 m68k_set_bkpt_ack_callback(NULL);
738                 m68k_set_reset_instr_callback(NULL);
739                 m68k_set_pc_changed_callback(NULL);
740                 m68k_set_fc_callback(NULL);
741                 m68k_set_instr_hook_callback(NULL);
742
743                 emulation_initialized = 1;
744         }
745
746
747         if(CPU_TYPE == 0)       /* KW 990319 */
748                 m68k_set_cpu_type(M68K_CPU_TYPE_68000);
749
750         /* Clear all stop levels and eat up all remaining cycles */
751         CPU_STOPPED = 0;
752         SET_CYCLES(0);
753
754         /* Turn off tracing */
755         FLAG_T1 = FLAG_T0 = 0;
756         m68ki_clear_trace();
757         /* Interrupt mask to level 7 */
758         FLAG_INT_MASK = 0x0700;
759         /* Reset VBR */
760         REG_VBR = 0;
761         /* Go to supervisor mode */
762         m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR);
763
764         /* Invalidate the prefetch queue */
765 #if M68K_EMULATE_PREFETCH
766         /* Set to arbitrary number since our first fetch is from 0 */
767         CPU_PREF_ADDR = 0x1000;
768 #endif /* M68K_EMULATE_PREFETCH */
769
770         /* Read the initial stack pointer and program counter */
771         m68ki_jump(0);
772         REG_SP = m68ki_read_imm_32();
773         REG_PC = m68ki_read_imm_32();
774         m68ki_jump(REG_PC);
775 }
776
777 /* Pulse the HALT line on the CPU */
778 void m68k_pulse_halt(void)
779 {
780         CPU_STOPPED |= STOP_LEVEL_HALT;
781 }
782
783
784 /* Get and set the current CPU context */
785 /* This is to allow for multiple CPUs */
786 unsigned int m68k_context_size()
787 {
788         return sizeof(m68ki_cpu_core);
789 }
790
791 unsigned int m68k_get_context(void* dst)
792 {
793         if(dst) *(m68ki_cpu_core*)dst = m68ki_cpu;
794         return sizeof(m68ki_cpu_core);
795 }
796
797 void m68k_set_context(void* src)
798 {
799         if(src) m68ki_cpu = *(m68ki_cpu_core*)src;
800 }
801
802 void m68k_save_context( void (*save_value)(char*, unsigned int))
803 {
804         if(!save_value)
805                 return;
806
807         save_value("CPU_TYPE"  , m68k_get_reg(NULL, M68K_REG_CPU_TYPE));
808         save_value("D0"        , REG_D[0]);
809         save_value("D1"        , REG_D[1]);
810         save_value("D2"        , REG_D[2]);
811         save_value("D3"        , REG_D[3]);
812         save_value("D4"        , REG_D[4]);
813         save_value("D5"        , REG_D[5]);
814         save_value("D6"        , REG_D[6]);
815         save_value("D7"        , REG_D[7]);
816         save_value("A0"        , REG_A[0]);
817         save_value("A1"        , REG_A[1]);
818         save_value("A2"        , REG_A[2]);
819         save_value("A3"        , REG_A[3]);
820         save_value("A4"        , REG_A[4]);
821         save_value("A5"        , REG_A[5]);
822         save_value("A6"        , REG_A[6]);
823         save_value("A7"        , REG_A[7]);
824         save_value("PPC"       , REG_PPC);
825         save_value("PC"        , REG_PC);
826         save_value("USP"       , REG_USP);
827         save_value("ISP"       , REG_ISP);
828         save_value("MSP"       , REG_MSP);
829         save_value("VBR"       , REG_VBR);
830         save_value("SFC"       , REG_SFC);
831         save_value("DFC"       , REG_DFC);
832         save_value("CACR"      , REG_CACR);
833         save_value("CAAR"      , REG_CAAR);
834         save_value("SR"        , m68ki_get_sr());
835         save_value("INT_LEVEL" , CPU_INT_LEVEL);
836         save_value("INT_CYCLES", CPU_INT_CYCLES);
837         save_value("STOPPED"   , (CPU_STOPPED & STOP_LEVEL_STOP) != 0);
838         save_value("HALTED"    , (CPU_STOPPED & STOP_LEVEL_HALT) != 0);
839         save_value("PREF_ADDR" , CPU_PREF_ADDR);
840         save_value("PREF_DATA" , CPU_PREF_DATA);
841 }
842
843 void m68k_load_context(unsigned int (*load_value)(char*))
844 {
845         unsigned int temp;
846
847         m68k_set_cpu_type(load_value("CPU_TYPE"));
848         REG_PPC = load_value("PPC");
849         REG_PC = load_value("PC");
850         m68ki_jump(REG_PC);
851         CPU_INT_LEVEL = 0;
852         m68ki_set_sr_noint(load_value("SR"));
853         REG_D[0]       = load_value("D0");
854         REG_D[1]       = load_value("D1");
855         REG_D[2]       = load_value("D2");
856         REG_D[3]       = load_value("D3");
857         REG_D[4]       = load_value("D4");
858         REG_D[5]       = load_value("D5");
859         REG_D[6]       = load_value("D6");
860         REG_D[7]       = load_value("D7");
861         REG_A[0]       = load_value("A0");
862         REG_A[1]       = load_value("A1");
863         REG_A[2]       = load_value("A2");
864         REG_A[3]       = load_value("A3");
865         REG_A[4]       = load_value("A4");
866         REG_A[5]       = load_value("A5");
867         REG_A[6]       = load_value("A6");
868         REG_A[7]       = load_value("A7");
869         REG_USP        = load_value("USP");
870         REG_ISP        = load_value("ISP");
871         REG_MSP        = load_value("MSP");
872         REG_VBR        = load_value("VBR");
873         REG_SFC        = load_value("SFC");
874         REG_DFC        = load_value("DFC");
875         REG_CACR       = load_value("CACR");
876         REG_CAAR       = load_value("CAAR");
877         CPU_INT_LEVEL  = load_value("INT_LEVEL");
878         CPU_INT_CYCLES = load_value("INT_CYCLES");
879
880         CPU_STOPPED = 0;
881         temp           = load_value("STOPPED");
882         if(temp) CPU_STOPPED |= STOP_LEVEL_STOP;
883         temp           = load_value("HALTED");
884         if(temp) CPU_STOPPED |= STOP_LEVEL_HALT;
885
886         CPU_PREF_ADDR  = load_value("PREF_ADDR");
887         CPU_PREF_DATA  = load_value("PREF_DATA");
888 }
889
890
891
892 /* ======================================================================== */
893 /* ============================== END OF FILE ============================= */
894 /* ======================================================================== */