initial import
[picodrive.git] / cpu / musashi / m68kcpu.c
diff --git a/cpu/musashi/m68kcpu.c b/cpu/musashi/m68kcpu.c
new file mode 100644 (file)
index 0000000..b3cd36d
--- /dev/null
@@ -0,0 +1,1015 @@
+/* ======================================================================== */\r
+/* ========================= LICENSING & COPYRIGHT ======================== */\r
+/* ======================================================================== */\r
+\r
+#if 0\r
+static const char* copyright_notice =\r
+"MUSASHI\n"\r
+"Version 3.3 (2001-01-29)\n"\r
+"A portable Motorola M680x0 processor emulation engine.\n"\r
+"Copyright 1998-2001 Karl Stenerud.  All rights reserved.\n"\r
+"\n"\r
+"This code may be freely used for non-commercial purpooses as long as this\n"\r
+"copyright notice remains unaltered in the source code and any binary files\n"\r
+"containing this code in compiled form.\n"\r
+"\n"\r
+"All other lisencing terms must be negotiated with the author\n"\r
+"(Karl Stenerud).\n"\r
+"\n"\r
+"The latest version of this code can be obtained at:\n"\r
+"http://kstenerud.cjb.net\n"\r
+;\r
+#endif\r
+\r
+\r
+/* ======================================================================== */\r
+/* ================================= NOTES ================================ */\r
+/* ======================================================================== */\r
+\r
+\r
+\r
+/* ======================================================================== */\r
+/* ================================ INCLUDES ============================== */\r
+/* ======================================================================== */\r
+\r
+#include "m68kops.h"\r
+#include "m68kcpu.h"\r
+\r
+/* ======================================================================== */\r
+/* ================================= DATA ================================= */\r
+/* ======================================================================== */\r
+\r
+int  m68ki_initial_cycles;\r
+int  m68ki_remaining_cycles = 0;                     /* Number of clocks remaining */\r
+uint m68ki_tracing = 0;\r
+uint m68ki_address_space;\r
+\r
+#ifdef M68K_LOG_ENABLE\r
+const char* m68ki_cpu_names[] =\r
+{\r
+       "Invalid CPU",\r
+       "M68000",\r
+       "M68008",\r
+       "Invalid CPU",\r
+       "M68010",\r
+       "Invalid CPU",\r
+       "Invalid CPU",\r
+       "Invalid CPU",\r
+       "M68EC020",\r
+       "Invalid CPU",\r
+       "Invalid CPU",\r
+       "Invalid CPU",\r
+       "Invalid CPU",\r
+       "Invalid CPU",\r
+       "Invalid CPU",\r
+       "Invalid CPU",\r
+       "M68020"\r
+};\r
+#endif /* M68K_LOG_ENABLE */\r
+\r
+/* The CPU core */\r
+// m68ki_cpu_core m68ki_cpu = {0};\r
+m68ki_cpu_core *m68ki_cpu_p = NULL;\r
+\r
+\r
+#if M68K_EMULATE_ADDRESS_ERROR\r
+jmp_buf m68ki_aerr_trap;\r
+#endif /* M68K_EMULATE_ADDRESS_ERROR */\r
+\r
+uint    m68ki_aerr_address;\r
+uint    m68ki_aerr_write_mode;\r
+uint    m68ki_aerr_fc;\r
+\r
+/* Used by shift & rotate instructions */\r
+uint8 m68ki_shift_8_table[65] =\r
+{\r
+       0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff,\r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+       0xff, 0xff, 0xff, 0xff, 0xff\r
+};\r
+uint16 m68ki_shift_16_table[65] =\r
+{\r
+       0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00,\r
+       0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff,\r
+       0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,\r
+       0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,\r
+       0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,\r
+       0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,\r
+       0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,\r
+       0xffff, 0xffff\r
+};\r
+uint m68ki_shift_32_table[65] =\r
+{\r
+       0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000,\r
+       0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000,\r
+       0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000,\r
+       0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,\r
+       0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8,\r
+       0xfffffffc, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\r
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\r
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\r
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\r
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\r
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff\r
+};\r
+\r
+\r
+/* Number of clock cycles to use for exception processing.\r
+ * I used 4 for any vectors that are undocumented for processing times.\r
+ */\r
+uint8 m68ki_exception_cycle_table[4][256] =\r
+{\r
+       { /* 000 */\r
+                 4, /*  0: Reset - Initial Stack Pointer                      */\r
+                 4, /*  1: Reset - Initial Program Counter                    */\r
+                50, /*  2: Bus Error                             (unemulated) */\r
+                50, /*  3: Address Error                         (unemulated) */\r
+                34, /*  4: Illegal Instruction                                */\r
+                38, /*  5: Divide by Zero -- ASG: changed from 42             */\r
+                40, /*  6: CHK -- ASG: chanaged from 44                       */\r
+                34, /*  7: TRAPV                                              */\r
+                34, /*  8: Privilege Violation                                */\r
+                34, /*  9: Trace                                              */\r
+                 4, /* 10: 1010                                               */\r
+                 4, /* 11: 1111                                               */\r
+                 4, /* 12: RESERVED                                           */\r
+                 4, /* 13: Coprocessor Protocol Violation        (unemulated) */\r
+                 4, /* 14: Format Error                                       */\r
+                44, /* 15: Uninitialized Interrupt                            */\r
+                 4, /* 16: RESERVED                                           */\r
+                 4, /* 17: RESERVED                                           */\r
+                 4, /* 18: RESERVED                                           */\r
+                 4, /* 19: RESERVED                                           */\r
+                 4, /* 20: RESERVED                                           */\r
+                 4, /* 21: RESERVED                                           */\r
+                 4, /* 22: RESERVED                                           */\r
+                 4, /* 23: RESERVED                                           */\r
+                44, /* 24: Spurious Interrupt                                 */\r
+                44, /* 25: Level 1 Interrupt Autovector                       */\r
+                44, /* 26: Level 2 Interrupt Autovector                       */\r
+                44, /* 27: Level 3 Interrupt Autovector                       */\r
+                44, /* 28: Level 4 Interrupt Autovector                       */\r
+                44, /* 29: Level 5 Interrupt Autovector                       */\r
+                44, /* 30: Level 6 Interrupt Autovector                       */\r
+                44, /* 31: Level 7 Interrupt Autovector                       */\r
+                34, /* 32: TRAP #0 -- ASG: chanaged from 38                   */\r
+                34, /* 33: TRAP #1                                            */\r
+                34, /* 34: TRAP #2                                            */\r
+                34, /* 35: TRAP #3                                            */\r
+                34, /* 36: TRAP #4                                            */\r
+                34, /* 37: TRAP #5                                            */\r
+                34, /* 38: TRAP #6                                            */\r
+                34, /* 39: TRAP #7                                            */\r
+                34, /* 40: TRAP #8                                            */\r
+                34, /* 41: TRAP #9                                            */\r
+                34, /* 42: TRAP #10                                           */\r
+                34, /* 43: TRAP #11                                           */\r
+                34, /* 44: TRAP #12                                           */\r
+                34, /* 45: TRAP #13                                           */\r
+                34, /* 46: TRAP #14                                           */\r
+                34, /* 47: TRAP #15                                           */\r
+                 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */\r
+                 4, /* 49: FP Inexact Result                     (unemulated) */\r
+                 4, /* 50: FP Divide by Zero                     (unemulated) */\r
+                 4, /* 51: FP Underflow                          (unemulated) */\r
+                 4, /* 52: FP Operand Error                      (unemulated) */\r
+                 4, /* 53: FP Overflow                           (unemulated) */\r
+                 4, /* 54: FP Signaling NAN                      (unemulated) */\r
+                 4, /* 55: FP Unimplemented Data Type            (unemulated) */\r
+                 4, /* 56: MMU Configuration Error               (unemulated) */\r
+                 4, /* 57: MMU Illegal Operation Error           (unemulated) */\r
+                 4, /* 58: MMU Access Level Violation Error      (unemulated) */\r
+                 4, /* 59: RESERVED                                           */\r
+                 4, /* 60: RESERVED                                           */\r
+                 4, /* 61: RESERVED                                           */\r
+                 4, /* 62: RESERVED                                           */\r
+                 4, /* 63: RESERVED                                           */\r
+                    /* 64-255: User Defined                                   */\r
+                 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,\r
+                 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,\r
+                 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,\r
+                 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,\r
+                 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,\r
+                 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\r
+       },\r
+       { /* 010 */\r
+                 4, /*  0: Reset - Initial Stack Pointer                      */\r
+                 4, /*  1: Reset - Initial Program Counter                    */\r
+               126, /*  2: Bus Error                             (unemulated) */\r
+               126, /*  3: Address Error                         (unemulated) */\r
+                38, /*  4: Illegal Instruction                                */\r
+                44, /*  5: Divide by Zero                                     */\r
+                44, /*  6: CHK                                                */\r
+                34, /*  7: TRAPV                                              */\r
+                38, /*  8: Privilege Violation                                */\r
+                38, /*  9: Trace                                              */\r
+                 4, /* 10: 1010                                               */\r
+                 4, /* 11: 1111                                               */\r
+                 4, /* 12: RESERVED                                           */\r
+                 4, /* 13: Coprocessor Protocol Violation        (unemulated) */\r
+                 4, /* 14: Format Error                                       */\r
+                44, /* 15: Uninitialized Interrupt                            */\r
+                 4, /* 16: RESERVED                                           */\r
+                 4, /* 17: RESERVED                                           */\r
+                 4, /* 18: RESERVED                                           */\r
+                 4, /* 19: RESERVED                                           */\r
+                 4, /* 20: RESERVED                                           */\r
+                 4, /* 21: RESERVED                                           */\r
+                 4, /* 22: RESERVED                                           */\r
+                 4, /* 23: RESERVED                                           */\r
+                46, /* 24: Spurious Interrupt                                 */\r
+                46, /* 25: Level 1 Interrupt Autovector                       */\r
+                46, /* 26: Level 2 Interrupt Autovector                       */\r
+                46, /* 27: Level 3 Interrupt Autovector                       */\r
+                46, /* 28: Level 4 Interrupt Autovector                       */\r
+                46, /* 29: Level 5 Interrupt Autovector                       */\r
+                46, /* 30: Level 6 Interrupt Autovector                       */\r
+                46, /* 31: Level 7 Interrupt Autovector                       */\r
+                38, /* 32: TRAP #0                                            */\r
+                38, /* 33: TRAP #1                                            */\r
+                38, /* 34: TRAP #2                                            */\r
+                38, /* 35: TRAP #3                                            */\r
+                38, /* 36: TRAP #4                                            */\r
+                38, /* 37: TRAP #5                                            */\r
+                38, /* 38: TRAP #6                                            */\r
+                38, /* 39: TRAP #7                                            */\r
+                38, /* 40: TRAP #8                                            */\r
+                38, /* 41: TRAP #9                                            */\r
+                38, /* 42: TRAP #10                                           */\r
+                38, /* 43: TRAP #11                                           */\r
+                38, /* 44: TRAP #12                                           */\r
+                38, /* 45: TRAP #13                                           */\r
+                38, /* 46: TRAP #14                                           */\r
+                38, /* 47: TRAP #15                                           */\r
+                 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */\r
+                 4, /* 49: FP Inexact Result                     (unemulated) */\r
+                 4, /* 50: FP Divide by Zero                     (unemulated) */\r
+                 4, /* 51: FP Underflow                          (unemulated) */\r
+                 4, /* 52: FP Operand Error                      (unemulated) */\r
+                 4, /* 53: FP Overflow                           (unemulated) */\r
+                 4, /* 54: FP Signaling NAN                      (unemulated) */\r
+                 4, /* 55: FP Unimplemented Data Type            (unemulated) */\r
+                 4, /* 56: MMU Configuration Error               (unemulated) */\r
+                 4, /* 57: MMU Illegal Operation Error           (unemulated) */\r
+                 4, /* 58: MMU Access Level Violation Error      (unemulated) */\r
+                 4, /* 59: RESERVED                                           */\r
+                 4, /* 60: RESERVED                                           */\r
+                 4, /* 61: RESERVED                                           */\r
+                 4, /* 62: RESERVED                                           */\r
+                 4, /* 63: RESERVED                                           */\r
+                    /* 64-255: User Defined                                   */\r
+                 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,\r
+                 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,\r
+                 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,\r
+                 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,\r
+                 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,\r
+                 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\r
+       },\r
+       { /* 020 */\r
+                 4, /*  0: Reset - Initial Stack Pointer                      */\r
+                 4, /*  1: Reset - Initial Program Counter                    */\r
+                50, /*  2: Bus Error                             (unemulated) */\r
+                50, /*  3: Address Error                         (unemulated) */\r
+                20, /*  4: Illegal Instruction                                */\r
+                38, /*  5: Divide by Zero                                     */\r
+                40, /*  6: CHK                                                */\r
+                20, /*  7: TRAPV                                              */\r
+                34, /*  8: Privilege Violation                                */\r
+                25, /*  9: Trace                                              */\r
+                20, /* 10: 1010                                               */\r
+                20, /* 11: 1111                                               */\r
+                 4, /* 12: RESERVED                                           */\r
+                 4, /* 13: Coprocessor Protocol Violation        (unemulated) */\r
+                 4, /* 14: Format Error                                       */\r
+                30, /* 15: Uninitialized Interrupt                            */\r
+                 4, /* 16: RESERVED                                           */\r
+                 4, /* 17: RESERVED                                           */\r
+                 4, /* 18: RESERVED                                           */\r
+                 4, /* 19: RESERVED                                           */\r
+                 4, /* 20: RESERVED                                           */\r
+                 4, /* 21: RESERVED                                           */\r
+                 4, /* 22: RESERVED                                           */\r
+                 4, /* 23: RESERVED                                           */\r
+                30, /* 24: Spurious Interrupt                                 */\r
+                30, /* 25: Level 1 Interrupt Autovector                       */\r
+                30, /* 26: Level 2 Interrupt Autovector                       */\r
+                30, /* 27: Level 3 Interrupt Autovector                       */\r
+                30, /* 28: Level 4 Interrupt Autovector                       */\r
+                30, /* 29: Level 5 Interrupt Autovector                       */\r
+                30, /* 30: Level 6 Interrupt Autovector                       */\r
+                30, /* 31: Level 7 Interrupt Autovector                       */\r
+                20, /* 32: TRAP #0                                            */\r
+                20, /* 33: TRAP #1                                            */\r
+                20, /* 34: TRAP #2                                            */\r
+                20, /* 35: TRAP #3                                            */\r
+                20, /* 36: TRAP #4                                            */\r
+                20, /* 37: TRAP #5                                            */\r
+                20, /* 38: TRAP #6                                            */\r
+                20, /* 39: TRAP #7                                            */\r
+                20, /* 40: TRAP #8                                            */\r
+                20, /* 41: TRAP #9                                            */\r
+                20, /* 42: TRAP #10                                           */\r
+                20, /* 43: TRAP #11                                           */\r
+                20, /* 44: TRAP #12                                           */\r
+                20, /* 45: TRAP #13                                           */\r
+                20, /* 46: TRAP #14                                           */\r
+                20, /* 47: TRAP #15                                           */\r
+                 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */\r
+                 4, /* 49: FP Inexact Result                     (unemulated) */\r
+                 4, /* 50: FP Divide by Zero                     (unemulated) */\r
+                 4, /* 51: FP Underflow                          (unemulated) */\r
+                 4, /* 52: FP Operand Error                      (unemulated) */\r
+                 4, /* 53: FP Overflow                           (unemulated) */\r
+                 4, /* 54: FP Signaling NAN                      (unemulated) */\r
+                 4, /* 55: FP Unimplemented Data Type            (unemulated) */\r
+                 4, /* 56: MMU Configuration Error               (unemulated) */\r
+                 4, /* 57: MMU Illegal Operation Error           (unemulated) */\r
+                 4, /* 58: MMU Access Level Violation Error      (unemulated) */\r
+                 4, /* 59: RESERVED                                           */\r
+                 4, /* 60: RESERVED                                           */\r
+                 4, /* 61: RESERVED                                           */\r
+                 4, /* 62: RESERVED                                           */\r
+                 4, /* 63: RESERVED                                           */\r
+                    /* 64-255: User Defined                                   */\r
+                 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,\r
+                 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,\r
+                 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,\r
+                 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,\r
+                 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,\r
+                 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\r
+       },\r
+       { /* 040 */ // TODO: these values are not correct\r
+                 4, /*  0: Reset - Initial Stack Pointer                      */\r
+                 4, /*  1: Reset - Initial Program Counter                    */\r
+                50, /*  2: Bus Error                             (unemulated) */\r
+                50, /*  3: Address Error                         (unemulated) */\r
+                20, /*  4: Illegal Instruction                                */\r
+                38, /*  5: Divide by Zero                                     */\r
+                40, /*  6: CHK                                                */\r
+                20, /*  7: TRAPV                                              */\r
+                34, /*  8: Privilege Violation                                */\r
+                25, /*  9: Trace                                              */\r
+                20, /* 10: 1010                                               */\r
+                20, /* 11: 1111                                               */\r
+                 4, /* 12: RESERVED                                           */\r
+                 4, /* 13: Coprocessor Protocol Violation        (unemulated) */\r
+                 4, /* 14: Format Error                                       */\r
+                30, /* 15: Uninitialized Interrupt                            */\r
+                 4, /* 16: RESERVED                                           */\r
+                 4, /* 17: RESERVED                                           */\r
+                 4, /* 18: RESERVED                                           */\r
+                 4, /* 19: RESERVED                                           */\r
+                 4, /* 20: RESERVED                                           */\r
+                 4, /* 21: RESERVED                                           */\r
+                 4, /* 22: RESERVED                                           */\r
+                 4, /* 23: RESERVED                                           */\r
+                30, /* 24: Spurious Interrupt                                 */\r
+                30, /* 25: Level 1 Interrupt Autovector                       */\r
+                30, /* 26: Level 2 Interrupt Autovector                       */\r
+                30, /* 27: Level 3 Interrupt Autovector                       */\r
+                30, /* 28: Level 4 Interrupt Autovector                       */\r
+                30, /* 29: Level 5 Interrupt Autovector                       */\r
+                30, /* 30: Level 6 Interrupt Autovector                       */\r
+                30, /* 31: Level 7 Interrupt Autovector                       */\r
+                20, /* 32: TRAP #0                                            */\r
+                20, /* 33: TRAP #1                                            */\r
+                20, /* 34: TRAP #2                                            */\r
+                20, /* 35: TRAP #3                                            */\r
+                20, /* 36: TRAP #4                                            */\r
+                20, /* 37: TRAP #5                                            */\r
+                20, /* 38: TRAP #6                                            */\r
+                20, /* 39: TRAP #7                                            */\r
+                20, /* 40: TRAP #8                                            */\r
+                20, /* 41: TRAP #9                                            */\r
+                20, /* 42: TRAP #10                                           */\r
+                20, /* 43: TRAP #11                                           */\r
+                20, /* 44: TRAP #12                                           */\r
+                20, /* 45: TRAP #13                                           */\r
+                20, /* 46: TRAP #14                                           */\r
+                20, /* 47: TRAP #15                                           */\r
+                 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */\r
+                 4, /* 49: FP Inexact Result                     (unemulated) */\r
+                 4, /* 50: FP Divide by Zero                     (unemulated) */\r
+                 4, /* 51: FP Underflow                          (unemulated) */\r
+                 4, /* 52: FP Operand Error                      (unemulated) */\r
+                 4, /* 53: FP Overflow                           (unemulated) */\r
+                 4, /* 54: FP Signaling NAN                      (unemulated) */\r
+                 4, /* 55: FP Unimplemented Data Type            (unemulated) */\r
+                 4, /* 56: MMU Configuration Error               (unemulated) */\r
+                 4, /* 57: MMU Illegal Operation Error           (unemulated) */\r
+                 4, /* 58: MMU Access Level Violation Error      (unemulated) */\r
+                 4, /* 59: RESERVED                                           */\r
+                 4, /* 60: RESERVED                                           */\r
+                 4, /* 61: RESERVED                                           */\r
+                 4, /* 62: RESERVED                                           */\r
+                 4, /* 63: RESERVED                                           */\r
+                    /* 64-255: User Defined                                   */\r
+                 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,\r
+                 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,\r
+                 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,\r
+                 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,\r
+                 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,\r
+                 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\r
+       }\r
+};\r
+\r
+uint8 m68ki_ea_idx_cycle_table[64] =\r
+{\r
+        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\r
+        0, /* ..01.000 no memory indirect, base NULL             */\r
+        5, /* ..01..01 memory indirect,    base NULL, outer NULL */\r
+        7, /* ..01..10 memory indirect,    base NULL, outer 16   */\r
+        7, /* ..01..11 memory indirect,    base NULL, outer 32   */\r
+        0,  5,  7,  7,  0,  5,  7,  7,  0,  5,  7,  7,\r
+        2, /* ..10.000 no memory indirect, base 16               */\r
+        7, /* ..10..01 memory indirect,    base 16,   outer NULL */\r
+        9, /* ..10..10 memory indirect,    base 16,   outer 16   */\r
+        9, /* ..10..11 memory indirect,    base 16,   outer 32   */\r
+        0,  7,  9,  9,  0,  7,  9,  9,  0,  7,  9,  9,\r
+        6, /* ..11.000 no memory indirect, base 32               */\r
+       11, /* ..11..01 memory indirect,    base 32,   outer NULL */\r
+       13, /* ..11..10 memory indirect,    base 32,   outer 16   */\r
+       13, /* ..11..11 memory indirect,    base 32,   outer 32   */\r
+        0, 11, 13, 13,  0, 11, 13, 13,  0, 11, 13, 13\r
+};\r
+\r
+\r
+\r
+/* ======================================================================== */\r
+/* =============================== CALLBACKS ============================== */\r
+/* ======================================================================== */\r
+\r
+/* Default callbacks used if the callback hasn't been set yet, or if the\r
+ * callback is set to NULL\r
+ */\r
+\r
+/* Interrupt acknowledge */\r
+static int default_int_ack_callback_data;\r
+static int default_int_ack_callback(int int_level)\r
+{\r
+       default_int_ack_callback_data = int_level;\r
+       CPU_INT_LEVEL = 0;\r
+       return M68K_INT_ACK_AUTOVECTOR;\r
+}\r
+\r
+/* Breakpoint acknowledge */\r
+static unsigned int default_bkpt_ack_callback_data;\r
+static void default_bkpt_ack_callback(unsigned int data)\r
+{\r
+       default_bkpt_ack_callback_data = data;\r
+}\r
+\r
+/* Called when a reset instruction is executed */\r
+static void default_reset_instr_callback(void)\r
+{\r
+}\r
+\r
+/* Called when a cmpi.l #v, dn instruction is executed */\r
+static void default_cmpild_instr_callback(unsigned int val, int reg)\r
+{\r
+}\r
+\r
+/* Called when a rte instruction is executed */\r
+static void default_rte_instr_callback(void)\r
+{\r
+}\r
+\r
+/* Called when the program counter changed by a large value */\r
+static unsigned int default_pc_changed_callback_data;\r
+static void default_pc_changed_callback(unsigned int new_pc)\r
+{\r
+       default_pc_changed_callback_data = new_pc;\r
+}\r
+\r
+/* Called every time there's bus activity (read/write to/from memory */\r
+static unsigned int default_set_fc_callback_data;\r
+static void default_set_fc_callback(unsigned int new_fc)\r
+{\r
+       default_set_fc_callback_data = new_fc;\r
+}\r
+\r
+/* Called every instruction cycle prior to execution */\r
+static void default_instr_hook_callback(void)\r
+{\r
+}\r
+\r
+\r
+#if M68K_EMULATE_ADDRESS_ERROR\r
+       #include <setjmp.h>\r
+       jmp_buf m68ki_aerr_trap;\r
+#endif /* M68K_EMULATE_ADDRESS_ERROR */\r
+\r
+\r
+/* ======================================================================== */\r
+/* ================================= API ================================== */\r
+/* ======================================================================== */\r
+\r
+/* Access the internals of the CPU */\r
+unsigned int m68k_get_reg(void* context, m68k_register_t regnum)\r
+{\r
+       m68ki_cpu_core* cpu = context != NULL ?(m68ki_cpu_core*)context : &m68ki_cpu;\r
+\r
+       switch(regnum)\r
+       {\r
+               case M68K_REG_D0:       return cpu->dar[0];\r
+               case M68K_REG_D1:       return cpu->dar[1];\r
+               case M68K_REG_D2:       return cpu->dar[2];\r
+               case M68K_REG_D3:       return cpu->dar[3];\r
+               case M68K_REG_D4:       return cpu->dar[4];\r
+               case M68K_REG_D5:       return cpu->dar[5];\r
+               case M68K_REG_D6:       return cpu->dar[6];\r
+               case M68K_REG_D7:       return cpu->dar[7];\r
+               case M68K_REG_A0:       return cpu->dar[8];\r
+               case M68K_REG_A1:       return cpu->dar[9];\r
+               case M68K_REG_A2:       return cpu->dar[10];\r
+               case M68K_REG_A3:       return cpu->dar[11];\r
+               case M68K_REG_A4:       return cpu->dar[12];\r
+               case M68K_REG_A5:       return cpu->dar[13];\r
+               case M68K_REG_A6:       return cpu->dar[14];\r
+               case M68K_REG_A7:       return cpu->dar[15];\r
+               case M68K_REG_PC:       return MASK_OUT_ABOVE_32(cpu->pc);\r
+               case M68K_REG_SR:       return  cpu->t1_flag                                            |\r
+                                                                       cpu->t0_flag                                            |\r
+                                                                       (cpu->s_flag << 11)                                     |\r
+                                                                       (cpu->m_flag << 11)                                     |\r
+                                                                       cpu->int_mask                                           |\r
+                                                                       ((cpu->x_flag & XFLAG_SET) >> 4)        |\r
+                                                                       ((cpu->n_flag & NFLAG_SET) >> 4)        |\r
+                                                                       ((!cpu->not_z_flag) << 2)                       |\r
+                                                                       ((cpu->v_flag & VFLAG_SET) >> 6)        |\r
+                                                                       ((cpu->c_flag & CFLAG_SET) >> 8);\r
+               case M68K_REG_SP:       return cpu->dar[15];\r
+               case M68K_REG_USP:      return cpu->s_flag ? cpu->sp[0] : cpu->dar[15];\r
+               case M68K_REG_ISP:      return cpu->s_flag && !cpu->m_flag ? cpu->dar[15] : cpu->sp[4];\r
+               case M68K_REG_MSP:      return cpu->s_flag && cpu->m_flag ? cpu->dar[15] : cpu->sp[6];\r
+               case M68K_REG_SFC:      return cpu->sfc;\r
+               case M68K_REG_DFC:      return cpu->dfc;\r
+               case M68K_REG_VBR:      return cpu->vbr;\r
+               case M68K_REG_CACR:     return cpu->cacr;\r
+               case M68K_REG_CAAR:     return cpu->caar;\r
+               case M68K_REG_PREF_ADDR:        return cpu->pref_addr;\r
+               case M68K_REG_PREF_DATA:        return cpu->pref_data;\r
+               case M68K_REG_PPC:      return MASK_OUT_ABOVE_32(cpu->ppc);\r
+               case M68K_REG_IR:       return cpu->ir;\r
+               case M68K_REG_CPU_TYPE:\r
+                       switch(cpu->cpu_type)\r
+                       {\r
+                               case CPU_TYPE_000:              return (unsigned int)M68K_CPU_TYPE_68000;\r
+                               case CPU_TYPE_008:              return (unsigned int)M68K_CPU_TYPE_68008;\r
+                               case CPU_TYPE_010:              return (unsigned int)M68K_CPU_TYPE_68010;\r
+                               case CPU_TYPE_EC020:    return (unsigned int)M68K_CPU_TYPE_68EC020;\r
+                               case CPU_TYPE_020:              return (unsigned int)M68K_CPU_TYPE_68020;\r
+                               case CPU_TYPE_040:              return (unsigned int)M68K_CPU_TYPE_68040;\r
+                       }\r
+                       return M68K_CPU_TYPE_INVALID;\r
+               default:                        return 0;\r
+       }\r
+       return 0;\r
+}\r
+\r
+void m68k_set_reg(m68k_register_t regnum, unsigned int value)\r
+{\r
+       switch(regnum)\r
+       {\r
+               case M68K_REG_D0:       REG_D[0] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_D1:       REG_D[1] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_D2:       REG_D[2] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_D3:       REG_D[3] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_D4:       REG_D[4] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_D5:       REG_D[5] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_D6:       REG_D[6] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_D7:       REG_D[7] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_A0:       REG_A[0] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_A1:       REG_A[1] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_A2:       REG_A[2] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_A3:       REG_A[3] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_A4:       REG_A[4] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_A5:       REG_A[5] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_A6:       REG_A[6] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_A7:       REG_A[7] = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_PC:       m68ki_jump(MASK_OUT_ABOVE_32(value)); return;\r
+               case M68K_REG_SR:       m68ki_set_sr(value); return;\r
+               case M68K_REG_SP:       REG_SP = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_USP:      if(FLAG_S)\r
+                                                               REG_USP = MASK_OUT_ABOVE_32(value);\r
+                                                       else\r
+                                                               REG_SP = MASK_OUT_ABOVE_32(value);\r
+                                                       return;\r
+               case M68K_REG_ISP:      if(FLAG_S && !FLAG_M)\r
+                                                               REG_SP = MASK_OUT_ABOVE_32(value);\r
+                                                       else\r
+                                                               REG_ISP = MASK_OUT_ABOVE_32(value);\r
+                                                       return;\r
+               case M68K_REG_MSP:      if(FLAG_S && FLAG_M)\r
+                                                               REG_SP = MASK_OUT_ABOVE_32(value);\r
+                                                       else\r
+                                                               REG_MSP = MASK_OUT_ABOVE_32(value);\r
+                                                       return;\r
+               case M68K_REG_VBR:      REG_VBR = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_SFC:      REG_SFC = value & 7; return;\r
+               case M68K_REG_DFC:      REG_DFC = value & 7; return;\r
+               case M68K_REG_CACR:     REG_CACR = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_CAAR:     REG_CAAR = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_PPC:      REG_PPC = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_IR:       REG_IR = MASK_OUT_ABOVE_16(value); return;\r
+               case M68K_REG_PREF_ADDR:        CPU_PREF_ADDR = MASK_OUT_ABOVE_32(value); return;\r
+               case M68K_REG_CPU_TYPE: m68k_set_cpu_type(value); return;\r
+               default:                        return;\r
+       }\r
+}\r
+\r
+/* Set the callbacks */\r
+void m68k_set_int_ack_callback(int  (*callback)(int int_level))\r
+{\r
+       CALLBACK_INT_ACK = callback ? callback : default_int_ack_callback;\r
+}\r
+\r
+void m68k_set_bkpt_ack_callback(void  (*callback)(unsigned int data))\r
+{\r
+       CALLBACK_BKPT_ACK = callback ? callback : default_bkpt_ack_callback;\r
+}\r
+\r
+void m68k_set_reset_instr_callback(void  (*callback)(void))\r
+{\r
+       CALLBACK_RESET_INSTR = callback ? callback : default_reset_instr_callback;\r
+}\r
+\r
+void m68k_set_cmpild_instr_callback(void  (*callback)(unsigned int, int))\r
+{\r
+       CALLBACK_CMPILD_INSTR = callback ? callback : default_cmpild_instr_callback;\r
+}\r
+\r
+void m68k_set_rte_instr_callback(void  (*callback)(void))\r
+{\r
+       CALLBACK_RTE_INSTR = callback ? callback : default_rte_instr_callback;\r
+}\r
+\r
+void m68k_set_pc_changed_callback(void  (*callback)(unsigned int new_pc))\r
+{\r
+       CALLBACK_PC_CHANGED = callback ? callback : default_pc_changed_callback;\r
+}\r
+\r
+void m68k_set_fc_callback(void  (*callback)(unsigned int new_fc))\r
+{\r
+       CALLBACK_SET_FC = callback ? callback : default_set_fc_callback;\r
+}\r
+\r
+void m68k_set_instr_hook_callback(void  (*callback)(void))\r
+{\r
+       CALLBACK_INSTR_HOOK = callback ? callback : default_instr_hook_callback;\r
+}\r
+\r
+#include <stdio.h>\r
+/* Set the CPU type. */\r
+void m68k_set_cpu_type(unsigned int cpu_type)\r
+{\r
+       switch(cpu_type)\r
+       {\r
+               case M68K_CPU_TYPE_68000:\r
+                       CPU_TYPE         = CPU_TYPE_000;\r
+                       CPU_ADDRESS_MASK = 0x00ffffff;\r
+                       CPU_SR_MASK      = 0xa71f; /* T1 -- S  -- -- I2 I1 I0 -- -- -- X  N  Z  V  C  */\r
+                       CYC_INSTRUCTION  = m68ki_cycles[0];\r
+                       CYC_EXCEPTION    = m68ki_exception_cycle_table[0];\r
+                       CYC_BCC_NOTAKE_B = -2;\r
+                       CYC_BCC_NOTAKE_W = 2;\r
+                       CYC_DBCC_F_NOEXP = -2;\r
+                       CYC_DBCC_F_EXP   = 2;\r
+                       CYC_SCC_R_TRUE   = 2;\r
+                       CYC_MOVEM_W      = 2;\r
+                       CYC_MOVEM_L      = 3;\r
+                       CYC_SHIFT        = 1;\r
+                       CYC_RESET        = 132;\r
+                       return;\r
+               case M68K_CPU_TYPE_68008:\r
+                       CPU_TYPE         = CPU_TYPE_008;\r
+                       CPU_ADDRESS_MASK = 0x003fffff;\r
+                       CPU_SR_MASK      = 0xa71f; /* T1 -- S  -- -- I2 I1 I0 -- -- -- X  N  Z  V  C  */\r
+                       CYC_INSTRUCTION  = m68ki_cycles[0];\r
+                       CYC_EXCEPTION    = m68ki_exception_cycle_table[0];\r
+                       CYC_BCC_NOTAKE_B = -2;\r
+                       CYC_BCC_NOTAKE_W = 2;\r
+                       CYC_DBCC_F_NOEXP = -2;\r
+                       CYC_DBCC_F_EXP   = 2;\r
+                       CYC_SCC_R_TRUE   = 2;\r
+                       CYC_MOVEM_W      = 2;\r
+                       CYC_MOVEM_L      = 3;\r
+                       CYC_SHIFT        = 1;\r
+                       CYC_RESET        = 132;\r
+                       return;\r
+               case M68K_CPU_TYPE_68010:\r
+                       CPU_TYPE         = CPU_TYPE_010;\r
+                       CPU_ADDRESS_MASK = 0x00ffffff;\r
+                       CPU_SR_MASK      = 0xa71f; /* T1 -- S  -- -- I2 I1 I0 -- -- -- X  N  Z  V  C  */\r
+                       CYC_INSTRUCTION  = m68ki_cycles[1];\r
+                       CYC_EXCEPTION    = m68ki_exception_cycle_table[1];\r
+                       CYC_BCC_NOTAKE_B = -4;\r
+                       CYC_BCC_NOTAKE_W = 0;\r
+                       CYC_DBCC_F_NOEXP = 0;\r
+                       CYC_DBCC_F_EXP   = 6;\r
+                       CYC_SCC_R_TRUE   = 0;\r
+                       CYC_MOVEM_W      = 2;\r
+                       CYC_MOVEM_L      = 3;\r
+                       CYC_SHIFT        = 1;\r
+                       CYC_RESET        = 130;\r
+                       return;\r
+               case M68K_CPU_TYPE_68EC020:\r
+                       CPU_TYPE         = CPU_TYPE_EC020;\r
+                       CPU_ADDRESS_MASK = 0x00ffffff;\r
+                       CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */\r
+                       CYC_INSTRUCTION  = m68ki_cycles[2];\r
+                       CYC_EXCEPTION    = m68ki_exception_cycle_table[2];\r
+                       CYC_BCC_NOTAKE_B = -2;\r
+                       CYC_BCC_NOTAKE_W = 0;\r
+                       CYC_DBCC_F_NOEXP = 0;\r
+                       CYC_DBCC_F_EXP   = 4;\r
+                       CYC_SCC_R_TRUE   = 0;\r
+                       CYC_MOVEM_W      = 2;\r
+                       CYC_MOVEM_L      = 2;\r
+                       CYC_SHIFT        = 0;\r
+                       CYC_RESET        = 518;\r
+                       return;\r
+               case M68K_CPU_TYPE_68020:\r
+                       CPU_TYPE         = CPU_TYPE_020;\r
+                       CPU_ADDRESS_MASK = 0xffffffff;\r
+                       CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */\r
+                       CYC_INSTRUCTION  = m68ki_cycles[2];\r
+                       CYC_EXCEPTION    = m68ki_exception_cycle_table[2];\r
+                       CYC_BCC_NOTAKE_B = -2;\r
+                       CYC_BCC_NOTAKE_W = 0;\r
+                       CYC_DBCC_F_NOEXP = 0;\r
+                       CYC_DBCC_F_EXP   = 4;\r
+                       CYC_SCC_R_TRUE   = 0;\r
+                       CYC_MOVEM_W      = 2;\r
+                       CYC_MOVEM_L      = 2;\r
+                       CYC_SHIFT        = 0;\r
+                       CYC_RESET        = 518;\r
+                       return;\r
+               case M68K_CPU_TYPE_68040:               // TODO: these values are not correct\r
+                       CPU_TYPE         = CPU_TYPE_040;\r
+                       CPU_ADDRESS_MASK = 0xffffffff;\r
+                       CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */\r
+                       CYC_INSTRUCTION  = m68ki_cycles[2];\r
+                       CYC_EXCEPTION    = m68ki_exception_cycle_table[2];\r
+                       CYC_BCC_NOTAKE_B = -2;\r
+                       CYC_BCC_NOTAKE_W = 0;\r
+                       CYC_DBCC_F_NOEXP = 0;\r
+                       CYC_DBCC_F_EXP   = 4;\r
+                       CYC_SCC_R_TRUE   = 0;\r
+                       CYC_MOVEM_W      = 2;\r
+                       CYC_MOVEM_L      = 2;\r
+                       CYC_SHIFT        = 0;\r
+                       CYC_RESET        = 518;\r
+                       return;\r
+       }\r
+}\r
+\r
+/* Execute some instructions until we use up num_cycles clock cycles */\r
+/* ASG: removed per-instruction interrupt checks */\r
+int m68k_execute(int num_cycles)\r
+{\r
+       /* Make sure we're not stopped */\r
+       if(!CPU_STOPPED)\r
+       {\r
+               /* Set our pool of clock cycles available */\r
+               SET_CYCLES(num_cycles);\r
+               m68ki_initial_cycles = num_cycles;\r
+\r
+               /* ASG: update cycles */\r
+               USE_CYCLES(CPU_INT_CYCLES);\r
+               CPU_INT_CYCLES = 0;\r
+\r
+               /* Return point if we had an address error */\r
+               m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */\r
+\r
+               /* Main loop.  Keep going until we run out of clock cycles */\r
+               while(GET_CYCLES() > 0)\r
+               {\r
+                       /* Set tracing accodring to T1. (T0 is done inside instruction) */\r
+                       m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */\r
+\r
+                       /* Set the address space for reads */\r
+                       m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */\r
+\r
+                       /* Call external hook to peek at CPU */\r
+                       m68ki_instr_hook(); /* auto-disable (see m68kcpu.h) */\r
+\r
+                       /* Record previous program counter */\r
+                       REG_PPC = REG_PC;\r
+\r
+                       /* Read an instruction and call its handler */\r
+                       REG_IR = m68ki_read_imm_16();\r
+                       m68ki_instruction_jump_table[REG_IR]();\r
+                       USE_CYCLES(CYC_INSTRUCTION[REG_IR]);\r
+\r
+                       /* Trace m68k_exception, if necessary */\r
+                       m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */\r
+               }\r
+\r
+               /* set previous PC to current PC for the next entry into the loop */\r
+               REG_PPC = REG_PC;\r
+\r
+               /* ASG: update cycles */\r
+               USE_CYCLES(CPU_INT_CYCLES);\r
+               CPU_INT_CYCLES = 0;\r
+\r
+               /* return how many clocks we used */\r
+               return m68ki_initial_cycles - GET_CYCLES();\r
+       }\r
+\r
+       /* We get here if the CPU is stopped or halted */\r
+       SET_CYCLES(0);\r
+       CPU_INT_CYCLES = 0;\r
+\r
+       return num_cycles;\r
+}\r
+\r
+\r
+int m68k_cycles_run(void)\r
+{\r
+       return m68ki_initial_cycles - GET_CYCLES();\r
+}\r
+\r
+int m68k_cycles_remaining(void)\r
+{\r
+       return GET_CYCLES();\r
+}\r
+\r
+/* Change the timeslice */\r
+void m68k_modify_timeslice(int cycles)\r
+{\r
+       m68ki_initial_cycles += cycles;\r
+       ADD_CYCLES(cycles);\r
+}\r
+\r
+\r
+void m68k_end_timeslice(void)\r
+{\r
+       m68ki_initial_cycles = GET_CYCLES();\r
+       SET_CYCLES(0);\r
+}\r
+\r
+\r
+/* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */\r
+/* KS: Modified so that IPL* bits match with mask positions in the SR\r
+ *     and cleaned out remenants of the interrupt controller.\r
+ */\r
+void m68k_set_irq(unsigned int int_level)\r
+{\r
+       uint old_level = CPU_INT_LEVEL;\r
+       CPU_INT_LEVEL = int_level << 8;\r
+\r
+       /* A transition from < 7 to 7 always interrupts (NMI) */\r
+       /* Note: Level 7 can also level trigger like a normal IRQ */\r
+       if(old_level != 0x0700 && CPU_INT_LEVEL == 0x0700)\r
+               m68ki_exception_interrupt(7); /* Edge triggered level 7 (NMI) */\r
+       else\r
+               m68ki_check_interrupts(); /* Level triggered (IRQ) */\r
+}\r
+\r
+void m68k_init(void)\r
+{\r
+       static uint emulation_initialized = 0;\r
+\r
+       /* The first call to this function initializes the opcode handler jump table */\r
+       if(!emulation_initialized)\r
+               {\r
+               m68ki_build_opcode_table();\r
+               emulation_initialized = 1;\r
+       }\r
+\r
+       m68k_set_int_ack_callback(NULL);\r
+       m68k_set_bkpt_ack_callback(NULL);\r
+       m68k_set_reset_instr_callback(NULL);\r
+       m68k_set_cmpild_instr_callback(NULL);\r
+       m68k_set_rte_instr_callback(NULL);\r
+       m68k_set_pc_changed_callback(NULL);\r
+       m68k_set_fc_callback(NULL);\r
+       m68k_set_instr_hook_callback(NULL);\r
+}\r
+\r
+/* Pulse the RESET line on the CPU */\r
+void m68k_pulse_reset(void)\r
+{\r
+       /* Clear all stop levels and eat up all remaining cycles */\r
+       CPU_STOPPED = 0;\r
+       SET_CYCLES(0);\r
+\r
+       CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET;\r
+\r
+       /* Turn off tracing */\r
+       FLAG_T1 = FLAG_T0 = 0;\r
+       m68ki_clear_trace();\r
+       /* Interrupt mask to level 7 */\r
+       FLAG_INT_MASK = 0x0700;\r
+       /* Reset VBR */\r
+       REG_VBR = 0;\r
+       /* Go to supervisor mode */\r
+       m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR);\r
+\r
+       /* Invalidate the prefetch queue */\r
+#if M68K_EMULATE_PREFETCH\r
+       /* Set to arbitrary number since our first fetch is from 0 */\r
+       CPU_PREF_ADDR = 0x1000;\r
+#endif /* M68K_EMULATE_PREFETCH */\r
+\r
+       /* Read the initial stack pointer and program counter */\r
+       m68ki_jump(0);\r
+       REG_SP = m68ki_read_imm_32();\r
+       REG_PC = m68ki_read_imm_32();\r
+       m68ki_jump(REG_PC);\r
+\r
+       CPU_RUN_MODE = RUN_MODE_NORMAL;\r
+}\r
+\r
+/* Pulse the HALT line on the CPU */\r
+void m68k_pulse_halt(void)\r
+{\r
+       CPU_STOPPED |= STOP_LEVEL_HALT;\r
+}\r
+\r
+\r
+/* Get and set the current CPU context */\r
+/* This is to allow for multiple CPUs */\r
+unsigned int m68k_context_size()\r
+{\r
+       return sizeof(m68ki_cpu_core);\r
+}\r
+\r
+/*\r
+unsigned int m68k_get_context(void* dst)\r
+{\r
+       if(dst) *(m68ki_cpu_core*)dst = m68ki_cpu;\r
+       return sizeof(m68ki_cpu_core);\r
+}\r
+*/\r
+\r
+void m68k_set_context(void* src)\r
+{\r
+       if(src) m68ki_cpu_p = src;\r
+}\r
+\r
+\r
+\r
+/* ======================================================================== */\r
+/* ============================== MAME STUFF ============================== */\r
+/* ======================================================================== */\r
+\r
+#if M68K_COMPILE_FOR_MAME == OPT_ON\r
+\r
+#include "state.h"\r
+\r
+static struct {\r
+       UINT16 sr;\r
+       UINT8 stopped;\r
+       UINT8 halted;\r
+} m68k_substate;\r
+\r
+static void m68k_prepare_substate(void)\r
+{\r
+       m68k_substate.sr = m68ki_get_sr();\r
+       m68k_substate.stopped = (CPU_STOPPED & STOP_LEVEL_STOP) != 0;\r
+       m68k_substate.halted  = (CPU_STOPPED & STOP_LEVEL_HALT) != 0;\r
+}\r
+\r
+static void m68k_post_load(void)\r
+{\r
+       m68ki_set_sr_noint_nosp(m68k_substate.sr);\r
+       CPU_STOPPED = m68k_substate.stopped ? STOP_LEVEL_STOP : 0\r
+                       | m68k_substate.halted  ? STOP_LEVEL_HALT : 0;\r
+       m68ki_jump(REG_PC);\r
+}\r
+\r
+void m68k_state_register(const char *type, int index)\r
+{\r
+       state_save_register_item_array(type, index, REG_D);\r
+       state_save_register_item_array(type, index, REG_A);\r
+       state_save_register_item(type, index, REG_PPC);\r
+       state_save_register_item(type, index, REG_PC);\r
+       state_save_register_item(type, index, REG_USP);\r
+       state_save_register_item(type, index, REG_ISP);\r
+       state_save_register_item(type, index, REG_MSP);\r
+       state_save_register_item(type, index, REG_VBR);\r
+       state_save_register_item(type, index, REG_SFC);\r
+       state_save_register_item(type, index, REG_DFC);\r
+       state_save_register_item(type, index, REG_CACR);\r
+       state_save_register_item(type, index, REG_CAAR);\r
+       state_save_register_item(type, index, m68k_substate.sr);\r
+       state_save_register_item(type, index, CPU_INT_LEVEL);\r
+       state_save_register_item(type, index, CPU_INT_CYCLES);\r
+       state_save_register_item(type, index, m68k_substate.stopped);\r
+       state_save_register_item(type, index, m68k_substate.halted);\r
+       state_save_register_item(type, index, CPU_PREF_ADDR);\r
+       state_save_register_item(type, index, CPU_PREF_DATA);\r
+       state_save_register_func_presave(m68k_prepare_substate);\r
+       state_save_register_func_postload(m68k_post_load);\r
+}\r
+\r
+#endif /* M68K_COMPILE_FOR_MAME */\r
+\r
+/* ======================================================================== */\r
+/* ============================== END OF FILE ============================= */\r
+/* ======================================================================== */\r