src/musashi/m68kcpu.c

Tue, 30 Nov 2010 01:51:22 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Tue, 30 Nov 2010 01:51:22 +0000
changeset 19
ea417ac1d83a
parent 0
8bf1bf91a36d
child 31
4fea89e86c5e
permissions
-rw-r--r--

[musashi] add preliminary bus error exception triggering

     1 /* ======================================================================== */
     2 /* ========================= LICENSING & COPYRIGHT ======================== */
     3 /* ======================================================================== */
     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
    25 /* ======================================================================== */
    26 /* ================================= NOTES ================================ */
    27 /* ======================================================================== */
    31 /* ======================================================================== */
    32 /* ================================ INCLUDES ============================== */
    33 /* ======================================================================== */
    35 #include "m68kops.h"
    36 #include "m68kcpu.h"
    38 /* ======================================================================== */
    39 /* ================================= DATA ================================= */
    40 /* ======================================================================== */
    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;
    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 */
    62 /* The CPU core */
    63 m68ki_cpu_core m68ki_cpu = {0};
    65 #if M68K_EMULATE_ADDRESS_ERROR
    66 jmp_buf m68ki_address_error_trap;
    67 #endif /* M68K_EMULATE_ADDRESS_ERROR */
    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 };
   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 };
   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 };
   354 /* ======================================================================== */
   355 /* =============================== CALLBACKS ============================== */
   356 /* ======================================================================== */
   358 /* Default callbacks used if the callback hasn't been set yet, or if the
   359  * callback is set to NULL
   360  */
   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 }
   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 }
   378 /* Called when a reset instruction is executed */
   379 static void default_reset_instr_callback(void)
   380 {
   381 }
   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 }
   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 }
   397 /* Called every instruction cycle prior to execution */
   398 static void default_instr_hook_callback(void)
   399 {
   400 }
   404 /* ======================================================================== */
   405 /* ================================= API ================================== */
   406 /* ======================================================================== */
   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;
   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 }
   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 }
   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 }
   525 void m68k_set_bkpt_ack_callback(void  (*callback)(unsigned int data))
   526 {
   527 	CALLBACK_BKPT_ACK = callback ? callback : default_bkpt_ack_callback;
   528 }
   530 void m68k_set_reset_instr_callback(void  (*callback)(void))
   531 {
   532 	CALLBACK_RESET_INSTR = callback ? callback : default_reset_instr_callback;
   533 }
   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 }
   540 void m68k_set_fc_callback(void  (*callback)(unsigned int new_fc))
   541 {
   542 	CALLBACK_SET_FC = callback ? callback : default_set_fc_callback;
   543 }
   545 void m68k_set_instr_hook_callback(void  (*callback)(void))
   546 {
   547 	CALLBACK_INSTR_HOOK = callback ? callback : default_instr_hook_callback;
   548 }
   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 }
   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;
   634 		/* ASG: update cycles */
   635 		USE_CYCLES(CPU_INT_CYCLES);
   636 		CPU_INT_CYCLES = 0;
   638 		/* Return point if we had an address error */
   639 		m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */
   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) */
   647 			/* Set the address space for reads */
   648 			m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */
   650 			/* Call external hook to peek at CPU */
   651 			m68ki_instr_hook(); /* auto-disable (see m68kcpu.h) */
   653 			/* Record previous program counter */
   654 			REG_PPC = REG_PC;
   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]);
   661 			/* Trace m68k_exception, if necessary */
   662 			m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */
   663 		} while(GET_CYCLES() > 0);
   665 		/* set previous PC to current PC for the next entry into the loop */
   666 		REG_PPC = REG_PC;
   668 		/* ASG: update cycles */
   669 		USE_CYCLES(CPU_INT_CYCLES);
   670 		CPU_INT_CYCLES = 0;
   672 		/* return how many clocks we used */
   673 		return m68ki_initial_cycles - GET_CYCLES();
   674 	}
   676 	/* We get here if the CPU is stopped or halted */
   677 	SET_CYCLES(0);
   678 	CPU_INT_CYCLES = 0;
   680 	return num_cycles;
   681 }
   684 int m68k_cycles_run(void)
   685 {
   686 	return m68ki_initial_cycles - GET_CYCLES();
   687 }
   689 int m68k_cycles_remaining(void)
   690 {
   691 	return GET_CYCLES();
   692 }
   694 /* Change the timeslice */
   695 void m68k_modify_timeslice(int cycles)
   696 {
   697 	m68ki_initial_cycles += cycles;
   698 	ADD_CYCLES(cycles);
   699 }
   702 void m68k_end_timeslice(void)
   703 {
   704 	m68ki_initial_cycles = GET_CYCLES();
   705 	SET_CYCLES(0);
   706 }
   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;
   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 }
   727 /* Trigger a Bus Error exception */
   728 void m68k_pulse_buserr(void)
   729 {
   730 	m68ki_exception_bus_error();
   731 }
   734 /* Pulse the RESET line on the CPU */
   735 void m68k_pulse_reset(void)
   736 {
   737 	static uint emulation_initialized = 0;
   739 	/* The first call to this function initializes the opcode handler jump table */
   740 	if(!emulation_initialized)
   741 	{
   742 		m68ki_build_opcode_table();
   743 		m68k_set_int_ack_callback(NULL);
   744 		m68k_set_bkpt_ack_callback(NULL);
   745 		m68k_set_reset_instr_callback(NULL);
   746 		m68k_set_pc_changed_callback(NULL);
   747 		m68k_set_fc_callback(NULL);
   748 		m68k_set_instr_hook_callback(NULL);
   750 		emulation_initialized = 1;
   751 	}
   754 	if(CPU_TYPE == 0)	/* KW 990319 */
   755 		m68k_set_cpu_type(M68K_CPU_TYPE_68000);
   757 	/* Clear all stop levels and eat up all remaining cycles */
   758 	CPU_STOPPED = 0;
   759 	SET_CYCLES(0);
   761 	/* Turn off tracing */
   762 	FLAG_T1 = FLAG_T0 = 0;
   763 	m68ki_clear_trace();
   764 	/* Interrupt mask to level 7 */
   765 	FLAG_INT_MASK = 0x0700;
   766 	/* Reset VBR */
   767 	REG_VBR = 0;
   768 	/* Go to supervisor mode */
   769 	m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR);
   771 	/* Invalidate the prefetch queue */
   772 #if M68K_EMULATE_PREFETCH
   773 	/* Set to arbitrary number since our first fetch is from 0 */
   774 	CPU_PREF_ADDR = 0x1000;
   775 #endif /* M68K_EMULATE_PREFETCH */
   777 	/* Read the initial stack pointer and program counter */
   778 	m68ki_jump(0);
   779 	REG_SP = m68ki_read_imm_32();
   780 	REG_PC = m68ki_read_imm_32();
   781 	m68ki_jump(REG_PC);
   782 }
   784 /* Pulse the HALT line on the CPU */
   785 void m68k_pulse_halt(void)
   786 {
   787 	CPU_STOPPED |= STOP_LEVEL_HALT;
   788 }
   791 /* Get and set the current CPU context */
   792 /* This is to allow for multiple CPUs */
   793 unsigned int m68k_context_size()
   794 {
   795 	return sizeof(m68ki_cpu_core);
   796 }
   798 unsigned int m68k_get_context(void* dst)
   799 {
   800 	if(dst) *(m68ki_cpu_core*)dst = m68ki_cpu;
   801 	return sizeof(m68ki_cpu_core);
   802 }
   804 void m68k_set_context(void* src)
   805 {
   806 	if(src) m68ki_cpu = *(m68ki_cpu_core*)src;
   807 }
   809 void m68k_save_context(	void (*save_value)(char*, unsigned int))
   810 {
   811 	if(!save_value)
   812 		return;
   814 	save_value("CPU_TYPE"  , m68k_get_reg(NULL, M68K_REG_CPU_TYPE));
   815 	save_value("D0"        , REG_D[0]);
   816 	save_value("D1"        , REG_D[1]);
   817 	save_value("D2"        , REG_D[2]);
   818 	save_value("D3"        , REG_D[3]);
   819 	save_value("D4"        , REG_D[4]);
   820 	save_value("D5"        , REG_D[5]);
   821 	save_value("D6"        , REG_D[6]);
   822 	save_value("D7"        , REG_D[7]);
   823 	save_value("A0"        , REG_A[0]);
   824 	save_value("A1"        , REG_A[1]);
   825 	save_value("A2"        , REG_A[2]);
   826 	save_value("A3"        , REG_A[3]);
   827 	save_value("A4"        , REG_A[4]);
   828 	save_value("A5"        , REG_A[5]);
   829 	save_value("A6"        , REG_A[6]);
   830 	save_value("A7"        , REG_A[7]);
   831 	save_value("PPC"       , REG_PPC);
   832 	save_value("PC"        , REG_PC);
   833 	save_value("USP"       , REG_USP);
   834 	save_value("ISP"       , REG_ISP);
   835 	save_value("MSP"       , REG_MSP);
   836 	save_value("VBR"       , REG_VBR);
   837 	save_value("SFC"       , REG_SFC);
   838 	save_value("DFC"       , REG_DFC);
   839 	save_value("CACR"      , REG_CACR);
   840 	save_value("CAAR"      , REG_CAAR);
   841 	save_value("SR"        , m68ki_get_sr());
   842 	save_value("INT_LEVEL" , CPU_INT_LEVEL);
   843 	save_value("INT_CYCLES", CPU_INT_CYCLES);
   844 	save_value("STOPPED"   , (CPU_STOPPED & STOP_LEVEL_STOP) != 0);
   845 	save_value("HALTED"    , (CPU_STOPPED & STOP_LEVEL_HALT) != 0);
   846 	save_value("PREF_ADDR" , CPU_PREF_ADDR);
   847 	save_value("PREF_DATA" , CPU_PREF_DATA);
   848 }
   850 void m68k_load_context(unsigned int (*load_value)(char*))
   851 {
   852 	unsigned int temp;
   854 	m68k_set_cpu_type(load_value("CPU_TYPE"));
   855 	REG_PPC = load_value("PPC");
   856 	REG_PC = load_value("PC");
   857 	m68ki_jump(REG_PC);
   858 	CPU_INT_LEVEL = 0;
   859 	m68ki_set_sr_noint(load_value("SR"));
   860 	REG_D[0]       = load_value("D0");
   861 	REG_D[1]       = load_value("D1");
   862 	REG_D[2]       = load_value("D2");
   863 	REG_D[3]       = load_value("D3");
   864 	REG_D[4]       = load_value("D4");
   865 	REG_D[5]       = load_value("D5");
   866 	REG_D[6]       = load_value("D6");
   867 	REG_D[7]       = load_value("D7");
   868 	REG_A[0]       = load_value("A0");
   869 	REG_A[1]       = load_value("A1");
   870 	REG_A[2]       = load_value("A2");
   871 	REG_A[3]       = load_value("A3");
   872 	REG_A[4]       = load_value("A4");
   873 	REG_A[5]       = load_value("A5");
   874 	REG_A[6]       = load_value("A6");
   875 	REG_A[7]       = load_value("A7");
   876 	REG_USP        = load_value("USP");
   877 	REG_ISP        = load_value("ISP");
   878 	REG_MSP        = load_value("MSP");
   879 	REG_VBR        = load_value("VBR");
   880 	REG_SFC        = load_value("SFC");
   881 	REG_DFC        = load_value("DFC");
   882 	REG_CACR       = load_value("CACR");
   883 	REG_CAAR       = load_value("CAAR");
   884 	CPU_INT_LEVEL  = load_value("INT_LEVEL");
   885 	CPU_INT_CYCLES = load_value("INT_CYCLES");
   887 	CPU_STOPPED = 0;
   888 	temp           = load_value("STOPPED");
   889 	if(temp) CPU_STOPPED |= STOP_LEVEL_STOP;
   890 	temp           = load_value("HALTED");
   891 	if(temp) CPU_STOPPED |= STOP_LEVEL_HALT;
   893 	CPU_PREF_ADDR  = load_value("PREF_ADDR");
   894 	CPU_PREF_DATA  = load_value("PREF_DATA");
   895 }
   899 /* ======================================================================== */
   900 /* ============================== END OF FILE ============================= */
   901 /* ======================================================================== */