1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/musashi/m68kcpu.c Sat Nov 27 01:13:12 2010 +0000 1.3 @@ -0,0 +1,894 @@ 1.4 +/* ======================================================================== */ 1.5 +/* ========================= LICENSING & COPYRIGHT ======================== */ 1.6 +/* ======================================================================== */ 1.7 + 1.8 +#if 0 1.9 +static const char* copyright_notice = 1.10 +"MUSASHI\n" 1.11 +"Version 3.3 (2001-01-29)\n" 1.12 +"A portable Motorola M680x0 processor emulation engine.\n" 1.13 +"Copyright 1998-2001 Karl Stenerud. All rights reserved.\n" 1.14 +"\n" 1.15 +"This code may be freely used for non-commercial purpooses as long as this\n" 1.16 +"copyright notice remains unaltered in the source code and any binary files\n" 1.17 +"containing this code in compiled form.\n" 1.18 +"\n" 1.19 +"All other lisencing terms must be negotiated with the author\n" 1.20 +"(Karl Stenerud).\n" 1.21 +"\n" 1.22 +"The latest version of this code can be obtained at:\n" 1.23 +"http://kstenerud.cjb.net\n" 1.24 +; 1.25 +#endif 1.26 + 1.27 + 1.28 +/* ======================================================================== */ 1.29 +/* ================================= NOTES ================================ */ 1.30 +/* ======================================================================== */ 1.31 + 1.32 + 1.33 + 1.34 +/* ======================================================================== */ 1.35 +/* ================================ INCLUDES ============================== */ 1.36 +/* ======================================================================== */ 1.37 + 1.38 +#include "m68kops.h" 1.39 +#include "m68kcpu.h" 1.40 + 1.41 +/* ======================================================================== */ 1.42 +/* ================================= DATA ================================= */ 1.43 +/* ======================================================================== */ 1.44 + 1.45 +int m68ki_initial_cycles; 1.46 +int m68ki_remaining_cycles = 0; /* Number of clocks remaining */ 1.47 +uint m68ki_tracing = 0; 1.48 +uint m68ki_address_space; 1.49 + 1.50 +#ifdef M68K_LOG_ENABLE 1.51 +char* m68ki_cpu_names[9] = 1.52 +{ 1.53 + "Invalid CPU", 1.54 + "M68000", 1.55 + "M68010", 1.56 + "Invalid CPU", 1.57 + "M68EC020" 1.58 + "Invalid CPU", 1.59 + "Invalid CPU", 1.60 + "Invalid CPU", 1.61 + "M68020" 1.62 +}; 1.63 +#endif /* M68K_LOG_ENABLE */ 1.64 + 1.65 +/* The CPU core */ 1.66 +m68ki_cpu_core m68ki_cpu = {0}; 1.67 + 1.68 +#if M68K_EMULATE_ADDRESS_ERROR 1.69 +jmp_buf m68ki_address_error_trap; 1.70 +#endif /* M68K_EMULATE_ADDRESS_ERROR */ 1.71 + 1.72 +/* Used by shift & rotate instructions */ 1.73 +uint8 m68ki_shift_8_table[65] = 1.74 +{ 1.75 + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 1.76 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1.77 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1.78 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1.79 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1.80 + 0xff, 0xff, 0xff, 0xff, 0xff 1.81 +}; 1.82 +uint16 m68ki_shift_16_table[65] = 1.83 +{ 1.84 + 0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 1.85 + 0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, 1.86 + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 1.87 + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 1.88 + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 1.89 + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 1.90 + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 1.91 + 0xffff, 0xffff 1.92 +}; 1.93 +uint m68ki_shift_32_table[65] = 1.94 +{ 1.95 + 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000, 1.96 + 0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, 1.97 + 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000, 1.98 + 0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, 1.99 + 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8, 1.100 + 0xfffffffc, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 1.101 + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 1.102 + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 1.103 + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 1.104 + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 1.105 + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff 1.106 +}; 1.107 + 1.108 + 1.109 +/* Number of clock cycles to use for exception processing. 1.110 + * I used 4 for any vectors that are undocumented for processing times. 1.111 + */ 1.112 +uint8 m68ki_exception_cycle_table[3][256] = 1.113 +{ 1.114 + { /* 000 */ 1.115 + 4, /* 0: Reset - Initial Stack Pointer */ 1.116 + 4, /* 1: Reset - Initial Program Counter */ 1.117 + 50, /* 2: Bus Error (unemulated) */ 1.118 + 50, /* 3: Address Error (unemulated) */ 1.119 + 34, /* 4: Illegal Instruction */ 1.120 + 38, /* 5: Divide by Zero -- ASG: changed from 42 */ 1.121 + 40, /* 6: CHK -- ASG: chanaged from 44 */ 1.122 + 34, /* 7: TRAPV */ 1.123 + 34, /* 8: Privilege Violation */ 1.124 + 34, /* 9: Trace */ 1.125 + 4, /* 10: 1010 */ 1.126 + 4, /* 11: 1111 */ 1.127 + 4, /* 12: RESERVED */ 1.128 + 4, /* 13: Coprocessor Protocol Violation (unemulated) */ 1.129 + 4, /* 14: Format Error */ 1.130 + 44, /* 15: Uninitialized Interrupt */ 1.131 + 4, /* 16: RESERVED */ 1.132 + 4, /* 17: RESERVED */ 1.133 + 4, /* 18: RESERVED */ 1.134 + 4, /* 19: RESERVED */ 1.135 + 4, /* 20: RESERVED */ 1.136 + 4, /* 21: RESERVED */ 1.137 + 4, /* 22: RESERVED */ 1.138 + 4, /* 23: RESERVED */ 1.139 + 44, /* 24: Spurious Interrupt */ 1.140 + 44, /* 25: Level 1 Interrupt Autovector */ 1.141 + 44, /* 26: Level 2 Interrupt Autovector */ 1.142 + 44, /* 27: Level 3 Interrupt Autovector */ 1.143 + 44, /* 28: Level 4 Interrupt Autovector */ 1.144 + 44, /* 29: Level 5 Interrupt Autovector */ 1.145 + 44, /* 30: Level 6 Interrupt Autovector */ 1.146 + 44, /* 31: Level 7 Interrupt Autovector */ 1.147 + 34, /* 32: TRAP #0 -- ASG: chanaged from 38 */ 1.148 + 34, /* 33: TRAP #1 */ 1.149 + 34, /* 34: TRAP #2 */ 1.150 + 34, /* 35: TRAP #3 */ 1.151 + 34, /* 36: TRAP #4 */ 1.152 + 34, /* 37: TRAP #5 */ 1.153 + 34, /* 38: TRAP #6 */ 1.154 + 34, /* 39: TRAP #7 */ 1.155 + 34, /* 40: TRAP #8 */ 1.156 + 34, /* 41: TRAP #9 */ 1.157 + 34, /* 42: TRAP #10 */ 1.158 + 34, /* 43: TRAP #11 */ 1.159 + 34, /* 44: TRAP #12 */ 1.160 + 34, /* 45: TRAP #13 */ 1.161 + 34, /* 46: TRAP #14 */ 1.162 + 34, /* 47: TRAP #15 */ 1.163 + 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */ 1.164 + 4, /* 49: FP Inexact Result (unemulated) */ 1.165 + 4, /* 50: FP Divide by Zero (unemulated) */ 1.166 + 4, /* 51: FP Underflow (unemulated) */ 1.167 + 4, /* 52: FP Operand Error (unemulated) */ 1.168 + 4, /* 53: FP Overflow (unemulated) */ 1.169 + 4, /* 54: FP Signaling NAN (unemulated) */ 1.170 + 4, /* 55: FP Unimplemented Data Type (unemulated) */ 1.171 + 4, /* 56: MMU Configuration Error (unemulated) */ 1.172 + 4, /* 57: MMU Illegal Operation Error (unemulated) */ 1.173 + 4, /* 58: MMU Access Level Violation Error (unemulated) */ 1.174 + 4, /* 59: RESERVED */ 1.175 + 4, /* 60: RESERVED */ 1.176 + 4, /* 61: RESERVED */ 1.177 + 4, /* 62: RESERVED */ 1.178 + 4, /* 63: RESERVED */ 1.179 + /* 64-255: User Defined */ 1.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, 1.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, 1.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, 1.183 + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 1.184 + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 1.185 + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 1.186 + }, 1.187 + { /* 010 */ 1.188 + 4, /* 0: Reset - Initial Stack Pointer */ 1.189 + 4, /* 1: Reset - Initial Program Counter */ 1.190 + 126, /* 2: Bus Error (unemulated) */ 1.191 + 126, /* 3: Address Error (unemulated) */ 1.192 + 38, /* 4: Illegal Instruction */ 1.193 + 44, /* 5: Divide by Zero */ 1.194 + 44, /* 6: CHK */ 1.195 + 34, /* 7: TRAPV */ 1.196 + 38, /* 8: Privilege Violation */ 1.197 + 38, /* 9: Trace */ 1.198 + 4, /* 10: 1010 */ 1.199 + 4, /* 11: 1111 */ 1.200 + 4, /* 12: RESERVED */ 1.201 + 4, /* 13: Coprocessor Protocol Violation (unemulated) */ 1.202 + 4, /* 14: Format Error */ 1.203 + 44, /* 15: Uninitialized Interrupt */ 1.204 + 4, /* 16: RESERVED */ 1.205 + 4, /* 17: RESERVED */ 1.206 + 4, /* 18: RESERVED */ 1.207 + 4, /* 19: RESERVED */ 1.208 + 4, /* 20: RESERVED */ 1.209 + 4, /* 21: RESERVED */ 1.210 + 4, /* 22: RESERVED */ 1.211 + 4, /* 23: RESERVED */ 1.212 + 46, /* 24: Spurious Interrupt */ 1.213 + 46, /* 25: Level 1 Interrupt Autovector */ 1.214 + 46, /* 26: Level 2 Interrupt Autovector */ 1.215 + 46, /* 27: Level 3 Interrupt Autovector */ 1.216 + 46, /* 28: Level 4 Interrupt Autovector */ 1.217 + 46, /* 29: Level 5 Interrupt Autovector */ 1.218 + 46, /* 30: Level 6 Interrupt Autovector */ 1.219 + 46, /* 31: Level 7 Interrupt Autovector */ 1.220 + 38, /* 32: TRAP #0 */ 1.221 + 38, /* 33: TRAP #1 */ 1.222 + 38, /* 34: TRAP #2 */ 1.223 + 38, /* 35: TRAP #3 */ 1.224 + 38, /* 36: TRAP #4 */ 1.225 + 38, /* 37: TRAP #5 */ 1.226 + 38, /* 38: TRAP #6 */ 1.227 + 38, /* 39: TRAP #7 */ 1.228 + 38, /* 40: TRAP #8 */ 1.229 + 38, /* 41: TRAP #9 */ 1.230 + 38, /* 42: TRAP #10 */ 1.231 + 38, /* 43: TRAP #11 */ 1.232 + 38, /* 44: TRAP #12 */ 1.233 + 38, /* 45: TRAP #13 */ 1.234 + 38, /* 46: TRAP #14 */ 1.235 + 38, /* 47: TRAP #15 */ 1.236 + 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */ 1.237 + 4, /* 49: FP Inexact Result (unemulated) */ 1.238 + 4, /* 50: FP Divide by Zero (unemulated) */ 1.239 + 4, /* 51: FP Underflow (unemulated) */ 1.240 + 4, /* 52: FP Operand Error (unemulated) */ 1.241 + 4, /* 53: FP Overflow (unemulated) */ 1.242 + 4, /* 54: FP Signaling NAN (unemulated) */ 1.243 + 4, /* 55: FP Unimplemented Data Type (unemulated) */ 1.244 + 4, /* 56: MMU Configuration Error (unemulated) */ 1.245 + 4, /* 57: MMU Illegal Operation Error (unemulated) */ 1.246 + 4, /* 58: MMU Access Level Violation Error (unemulated) */ 1.247 + 4, /* 59: RESERVED */ 1.248 + 4, /* 60: RESERVED */ 1.249 + 4, /* 61: RESERVED */ 1.250 + 4, /* 62: RESERVED */ 1.251 + 4, /* 63: RESERVED */ 1.252 + /* 64-255: User Defined */ 1.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, 1.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, 1.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, 1.256 + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 1.257 + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 1.258 + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 1.259 + }, 1.260 + { /* 020 */ 1.261 + 4, /* 0: Reset - Initial Stack Pointer */ 1.262 + 4, /* 1: Reset - Initial Program Counter */ 1.263 + 50, /* 2: Bus Error (unemulated) */ 1.264 + 50, /* 3: Address Error (unemulated) */ 1.265 + 20, /* 4: Illegal Instruction */ 1.266 + 38, /* 5: Divide by Zero */ 1.267 + 40, /* 6: CHK */ 1.268 + 20, /* 7: TRAPV */ 1.269 + 34, /* 8: Privilege Violation */ 1.270 + 25, /* 9: Trace */ 1.271 + 20, /* 10: 1010 */ 1.272 + 20, /* 11: 1111 */ 1.273 + 4, /* 12: RESERVED */ 1.274 + 4, /* 13: Coprocessor Protocol Violation (unemulated) */ 1.275 + 4, /* 14: Format Error */ 1.276 + 30, /* 15: Uninitialized Interrupt */ 1.277 + 4, /* 16: RESERVED */ 1.278 + 4, /* 17: RESERVED */ 1.279 + 4, /* 18: RESERVED */ 1.280 + 4, /* 19: RESERVED */ 1.281 + 4, /* 20: RESERVED */ 1.282 + 4, /* 21: RESERVED */ 1.283 + 4, /* 22: RESERVED */ 1.284 + 4, /* 23: RESERVED */ 1.285 + 30, /* 24: Spurious Interrupt */ 1.286 + 30, /* 25: Level 1 Interrupt Autovector */ 1.287 + 30, /* 26: Level 2 Interrupt Autovector */ 1.288 + 30, /* 27: Level 3 Interrupt Autovector */ 1.289 + 30, /* 28: Level 4 Interrupt Autovector */ 1.290 + 30, /* 29: Level 5 Interrupt Autovector */ 1.291 + 30, /* 30: Level 6 Interrupt Autovector */ 1.292 + 30, /* 31: Level 7 Interrupt Autovector */ 1.293 + 20, /* 32: TRAP #0 */ 1.294 + 20, /* 33: TRAP #1 */ 1.295 + 20, /* 34: TRAP #2 */ 1.296 + 20, /* 35: TRAP #3 */ 1.297 + 20, /* 36: TRAP #4 */ 1.298 + 20, /* 37: TRAP #5 */ 1.299 + 20, /* 38: TRAP #6 */ 1.300 + 20, /* 39: TRAP #7 */ 1.301 + 20, /* 40: TRAP #8 */ 1.302 + 20, /* 41: TRAP #9 */ 1.303 + 20, /* 42: TRAP #10 */ 1.304 + 20, /* 43: TRAP #11 */ 1.305 + 20, /* 44: TRAP #12 */ 1.306 + 20, /* 45: TRAP #13 */ 1.307 + 20, /* 46: TRAP #14 */ 1.308 + 20, /* 47: TRAP #15 */ 1.309 + 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */ 1.310 + 4, /* 49: FP Inexact Result (unemulated) */ 1.311 + 4, /* 50: FP Divide by Zero (unemulated) */ 1.312 + 4, /* 51: FP Underflow (unemulated) */ 1.313 + 4, /* 52: FP Operand Error (unemulated) */ 1.314 + 4, /* 53: FP Overflow (unemulated) */ 1.315 + 4, /* 54: FP Signaling NAN (unemulated) */ 1.316 + 4, /* 55: FP Unimplemented Data Type (unemulated) */ 1.317 + 4, /* 56: MMU Configuration Error (unemulated) */ 1.318 + 4, /* 57: MMU Illegal Operation Error (unemulated) */ 1.319 + 4, /* 58: MMU Access Level Violation Error (unemulated) */ 1.320 + 4, /* 59: RESERVED */ 1.321 + 4, /* 60: RESERVED */ 1.322 + 4, /* 61: RESERVED */ 1.323 + 4, /* 62: RESERVED */ 1.324 + 4, /* 63: RESERVED */ 1.325 + /* 64-255: User Defined */ 1.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, 1.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, 1.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, 1.329 + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 1.330 + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 1.331 + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 1.332 + } 1.333 +}; 1.334 + 1.335 +uint8 m68ki_ea_idx_cycle_table[64] = 1.336 +{ 1.337 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.338 + 0, /* ..01.000 no memory indirect, base NULL */ 1.339 + 5, /* ..01..01 memory indirect, base NULL, outer NULL */ 1.340 + 7, /* ..01..10 memory indirect, base NULL, outer 16 */ 1.341 + 7, /* ..01..11 memory indirect, base NULL, outer 32 */ 1.342 + 0, 5, 7, 7, 0, 5, 7, 7, 0, 5, 7, 7, 1.343 + 2, /* ..10.000 no memory indirect, base 16 */ 1.344 + 7, /* ..10..01 memory indirect, base 16, outer NULL */ 1.345 + 9, /* ..10..10 memory indirect, base 16, outer 16 */ 1.346 + 9, /* ..10..11 memory indirect, base 16, outer 32 */ 1.347 + 0, 7, 9, 9, 0, 7, 9, 9, 0, 7, 9, 9, 1.348 + 6, /* ..11.000 no memory indirect, base 32 */ 1.349 + 11, /* ..11..01 memory indirect, base 32, outer NULL */ 1.350 + 13, /* ..11..10 memory indirect, base 32, outer 16 */ 1.351 + 13, /* ..11..11 memory indirect, base 32, outer 32 */ 1.352 + 0, 11, 13, 13, 0, 11, 13, 13, 0, 11, 13, 13 1.353 +}; 1.354 + 1.355 + 1.356 + 1.357 +/* ======================================================================== */ 1.358 +/* =============================== CALLBACKS ============================== */ 1.359 +/* ======================================================================== */ 1.360 + 1.361 +/* Default callbacks used if the callback hasn't been set yet, or if the 1.362 + * callback is set to NULL 1.363 + */ 1.364 + 1.365 +/* Interrupt acknowledge */ 1.366 +static int default_int_ack_callback_data; 1.367 +static int default_int_ack_callback(int int_level) 1.368 +{ 1.369 + default_int_ack_callback_data = int_level; 1.370 + CPU_INT_LEVEL = 0; 1.371 + return M68K_INT_ACK_AUTOVECTOR; 1.372 +} 1.373 + 1.374 +/* Breakpoint acknowledge */ 1.375 +static unsigned int default_bkpt_ack_callback_data; 1.376 +static void default_bkpt_ack_callback(unsigned int data) 1.377 +{ 1.378 + default_bkpt_ack_callback_data = data; 1.379 +} 1.380 + 1.381 +/* Called when a reset instruction is executed */ 1.382 +static void default_reset_instr_callback(void) 1.383 +{ 1.384 +} 1.385 + 1.386 +/* Called when the program counter changed by a large value */ 1.387 +static unsigned int default_pc_changed_callback_data; 1.388 +static void default_pc_changed_callback(unsigned int new_pc) 1.389 +{ 1.390 + default_pc_changed_callback_data = new_pc; 1.391 +} 1.392 + 1.393 +/* Called every time there's bus activity (read/write to/from memory */ 1.394 +static unsigned int default_set_fc_callback_data; 1.395 +static void default_set_fc_callback(unsigned int new_fc) 1.396 +{ 1.397 + default_set_fc_callback_data = new_fc; 1.398 +} 1.399 + 1.400 +/* Called every instruction cycle prior to execution */ 1.401 +static void default_instr_hook_callback(void) 1.402 +{ 1.403 +} 1.404 + 1.405 + 1.406 + 1.407 +/* ======================================================================== */ 1.408 +/* ================================= API ================================== */ 1.409 +/* ======================================================================== */ 1.410 + 1.411 +/* Access the internals of the CPU */ 1.412 +unsigned int m68k_get_reg(void* context, m68k_register_t regnum) 1.413 +{ 1.414 + m68ki_cpu_core* cpu = context != NULL ?(m68ki_cpu_core*)context : &m68ki_cpu; 1.415 + 1.416 + switch(regnum) 1.417 + { 1.418 + case M68K_REG_D0: return cpu->dar[0]; 1.419 + case M68K_REG_D1: return cpu->dar[1]; 1.420 + case M68K_REG_D2: return cpu->dar[2]; 1.421 + case M68K_REG_D3: return cpu->dar[3]; 1.422 + case M68K_REG_D4: return cpu->dar[4]; 1.423 + case M68K_REG_D5: return cpu->dar[5]; 1.424 + case M68K_REG_D6: return cpu->dar[6]; 1.425 + case M68K_REG_D7: return cpu->dar[7]; 1.426 + case M68K_REG_A0: return cpu->dar[8]; 1.427 + case M68K_REG_A1: return cpu->dar[9]; 1.428 + case M68K_REG_A2: return cpu->dar[10]; 1.429 + case M68K_REG_A3: return cpu->dar[11]; 1.430 + case M68K_REG_A4: return cpu->dar[12]; 1.431 + case M68K_REG_A5: return cpu->dar[13]; 1.432 + case M68K_REG_A6: return cpu->dar[14]; 1.433 + case M68K_REG_A7: return cpu->dar[15]; 1.434 + case M68K_REG_PC: return MASK_OUT_ABOVE_32(cpu->pc); 1.435 + case M68K_REG_SR: return cpu->t1_flag | 1.436 + cpu->t0_flag | 1.437 + (cpu->s_flag << 11) | 1.438 + (cpu->m_flag << 11) | 1.439 + cpu->int_mask | 1.440 + ((cpu->x_flag & XFLAG_SET) >> 4) | 1.441 + ((cpu->n_flag & NFLAG_SET) >> 4) | 1.442 + ((!cpu->not_z_flag) << 2) | 1.443 + ((cpu->v_flag & VFLAG_SET) >> 6) | 1.444 + ((cpu->c_flag & CFLAG_SET) >> 8); 1.445 + case M68K_REG_SP: return cpu->dar[15]; 1.446 + case M68K_REG_USP: return cpu->s_flag ? cpu->sp[0] : cpu->dar[15]; 1.447 + case M68K_REG_ISP: return cpu->s_flag && !cpu->m_flag ? cpu->dar[15] : cpu->sp[4]; 1.448 + case M68K_REG_MSP: return cpu->s_flag && cpu->m_flag ? cpu->dar[15] : cpu->sp[6]; 1.449 + case M68K_REG_SFC: return cpu->sfc; 1.450 + case M68K_REG_DFC: return cpu->dfc; 1.451 + case M68K_REG_VBR: return cpu->vbr; 1.452 + case M68K_REG_CACR: return cpu->cacr; 1.453 + case M68K_REG_CAAR: return cpu->caar; 1.454 + case M68K_REG_PREF_ADDR: return cpu->pref_addr; 1.455 + case M68K_REG_PREF_DATA: return cpu->pref_data; 1.456 + case M68K_REG_PPC: return MASK_OUT_ABOVE_32(cpu->ppc); 1.457 + case M68K_REG_IR: return cpu->ir; 1.458 + case M68K_REG_CPU_TYPE: 1.459 + switch(cpu->cpu_type) 1.460 + { 1.461 + case CPU_TYPE_000: return (unsigned int)M68K_CPU_TYPE_68000; 1.462 + case CPU_TYPE_010: return (unsigned int)M68K_CPU_TYPE_68010; 1.463 + case CPU_TYPE_EC020: return (unsigned int)M68K_CPU_TYPE_68EC020; 1.464 + case CPU_TYPE_020: return (unsigned int)M68K_CPU_TYPE_68020; 1.465 + } 1.466 + return M68K_CPU_TYPE_INVALID; 1.467 + default: return 0; 1.468 + } 1.469 + return 0; 1.470 +} 1.471 + 1.472 +void m68k_set_reg(m68k_register_t regnum, unsigned int value) 1.473 +{ 1.474 + switch(regnum) 1.475 + { 1.476 + case M68K_REG_D0: REG_D[0] = MASK_OUT_ABOVE_32(value); return; 1.477 + case M68K_REG_D1: REG_D[1] = MASK_OUT_ABOVE_32(value); return; 1.478 + case M68K_REG_D2: REG_D[2] = MASK_OUT_ABOVE_32(value); return; 1.479 + case M68K_REG_D3: REG_D[3] = MASK_OUT_ABOVE_32(value); return; 1.480 + case M68K_REG_D4: REG_D[4] = MASK_OUT_ABOVE_32(value); return; 1.481 + case M68K_REG_D5: REG_D[5] = MASK_OUT_ABOVE_32(value); return; 1.482 + case M68K_REG_D6: REG_D[6] = MASK_OUT_ABOVE_32(value); return; 1.483 + case M68K_REG_D7: REG_D[7] = MASK_OUT_ABOVE_32(value); return; 1.484 + case M68K_REG_A0: REG_A[0] = MASK_OUT_ABOVE_32(value); return; 1.485 + case M68K_REG_A1: REG_A[1] = MASK_OUT_ABOVE_32(value); return; 1.486 + case M68K_REG_A2: REG_A[2] = MASK_OUT_ABOVE_32(value); return; 1.487 + case M68K_REG_A3: REG_A[3] = MASK_OUT_ABOVE_32(value); return; 1.488 + case M68K_REG_A4: REG_A[4] = MASK_OUT_ABOVE_32(value); return; 1.489 + case M68K_REG_A5: REG_A[5] = MASK_OUT_ABOVE_32(value); return; 1.490 + case M68K_REG_A6: REG_A[6] = MASK_OUT_ABOVE_32(value); return; 1.491 + case M68K_REG_A7: REG_A[7] = MASK_OUT_ABOVE_32(value); return; 1.492 + case M68K_REG_PC: m68ki_jump(MASK_OUT_ABOVE_32(value)); return; 1.493 + case M68K_REG_SR: m68ki_set_sr(value); return; 1.494 + case M68K_REG_SP: REG_SP = MASK_OUT_ABOVE_32(value); return; 1.495 + case M68K_REG_USP: if(FLAG_S) 1.496 + REG_USP = MASK_OUT_ABOVE_32(value); 1.497 + else 1.498 + REG_SP = MASK_OUT_ABOVE_32(value); 1.499 + return; 1.500 + case M68K_REG_ISP: if(FLAG_S && !FLAG_M) 1.501 + REG_SP = MASK_OUT_ABOVE_32(value); 1.502 + else 1.503 + REG_ISP = MASK_OUT_ABOVE_32(value); 1.504 + return; 1.505 + case M68K_REG_MSP: if(FLAG_S && FLAG_M) 1.506 + REG_SP = MASK_OUT_ABOVE_32(value); 1.507 + else 1.508 + REG_MSP = MASK_OUT_ABOVE_32(value); 1.509 + return; 1.510 + case M68K_REG_VBR: REG_VBR = MASK_OUT_ABOVE_32(value); return; 1.511 + case M68K_REG_SFC: REG_SFC = value & 7; return; 1.512 + case M68K_REG_DFC: REG_DFC = value & 7; return; 1.513 + case M68K_REG_CACR: REG_CACR = MASK_OUT_ABOVE_32(value); return; 1.514 + case M68K_REG_CAAR: REG_CAAR = MASK_OUT_ABOVE_32(value); return; 1.515 + case M68K_REG_PPC: REG_PPC = MASK_OUT_ABOVE_32(value); return; 1.516 + case M68K_REG_IR: REG_IR = MASK_OUT_ABOVE_16(value); return; 1.517 + case M68K_REG_CPU_TYPE: m68k_set_cpu_type(value); return; 1.518 + default: return; 1.519 + } 1.520 +} 1.521 + 1.522 +/* Set the callbacks */ 1.523 +void m68k_set_int_ack_callback(int (*callback)(int int_level)) 1.524 +{ 1.525 + CALLBACK_INT_ACK = callback ? callback : default_int_ack_callback; 1.526 +} 1.527 + 1.528 +void m68k_set_bkpt_ack_callback(void (*callback)(unsigned int data)) 1.529 +{ 1.530 + CALLBACK_BKPT_ACK = callback ? callback : default_bkpt_ack_callback; 1.531 +} 1.532 + 1.533 +void m68k_set_reset_instr_callback(void (*callback)(void)) 1.534 +{ 1.535 + CALLBACK_RESET_INSTR = callback ? callback : default_reset_instr_callback; 1.536 +} 1.537 + 1.538 +void m68k_set_pc_changed_callback(void (*callback)(unsigned int new_pc)) 1.539 +{ 1.540 + CALLBACK_PC_CHANGED = callback ? callback : default_pc_changed_callback; 1.541 +} 1.542 + 1.543 +void m68k_set_fc_callback(void (*callback)(unsigned int new_fc)) 1.544 +{ 1.545 + CALLBACK_SET_FC = callback ? callback : default_set_fc_callback; 1.546 +} 1.547 + 1.548 +void m68k_set_instr_hook_callback(void (*callback)(void)) 1.549 +{ 1.550 + CALLBACK_INSTR_HOOK = callback ? callback : default_instr_hook_callback; 1.551 +} 1.552 + 1.553 +#include <stdio.h> 1.554 +/* Set the CPU type. */ 1.555 +void m68k_set_cpu_type(unsigned int cpu_type) 1.556 +{ 1.557 + switch(cpu_type) 1.558 + { 1.559 + case M68K_CPU_TYPE_68000: 1.560 + CPU_TYPE = CPU_TYPE_000; 1.561 + CPU_ADDRESS_MASK = 0x00ffffff; 1.562 + CPU_SR_MASK = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */ 1.563 + CYC_INSTRUCTION = m68ki_cycles[0]; 1.564 + CYC_EXCEPTION = m68ki_exception_cycle_table[0]; 1.565 + CYC_BCC_NOTAKE_B = -2; 1.566 + CYC_BCC_NOTAKE_W = 2; 1.567 + CYC_DBCC_F_NOEXP = -2; 1.568 + CYC_DBCC_F_EXP = 2; 1.569 + CYC_SCC_R_FALSE = 2; 1.570 + CYC_MOVEM_W = 2; 1.571 + CYC_MOVEM_L = 3; 1.572 + CYC_SHIFT = 1; 1.573 + CYC_RESET = 132; 1.574 + return; 1.575 + case M68K_CPU_TYPE_68010: 1.576 + CPU_TYPE = CPU_TYPE_010; 1.577 + CPU_ADDRESS_MASK = 0x00ffffff; 1.578 + CPU_SR_MASK = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */ 1.579 + CYC_INSTRUCTION = m68ki_cycles[1]; 1.580 + CYC_EXCEPTION = m68ki_exception_cycle_table[1]; 1.581 + CYC_BCC_NOTAKE_B = -4; 1.582 + CYC_BCC_NOTAKE_W = 0; 1.583 + CYC_DBCC_F_NOEXP = 0; 1.584 + CYC_DBCC_F_EXP = 6; 1.585 + CYC_SCC_R_FALSE = 0; 1.586 + CYC_MOVEM_W = 2; 1.587 + CYC_MOVEM_L = 3; 1.588 + CYC_SHIFT = 1; 1.589 + CYC_RESET = 130; 1.590 + return; 1.591 + case M68K_CPU_TYPE_68EC020: 1.592 + CPU_TYPE = CPU_TYPE_EC020; 1.593 + CPU_ADDRESS_MASK = 0x00ffffff; 1.594 + CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ 1.595 + CYC_INSTRUCTION = m68ki_cycles[2]; 1.596 + CYC_EXCEPTION = m68ki_exception_cycle_table[2]; 1.597 + CYC_BCC_NOTAKE_B = -2; 1.598 + CYC_BCC_NOTAKE_W = 0; 1.599 + CYC_DBCC_F_NOEXP = 0; 1.600 + CYC_DBCC_F_EXP = 4; 1.601 + CYC_SCC_R_FALSE = 0; 1.602 + CYC_MOVEM_W = 2; 1.603 + CYC_MOVEM_L = 2; 1.604 + CYC_SHIFT = 0; 1.605 + CYC_RESET = 518; 1.606 + return; 1.607 + case M68K_CPU_TYPE_68020: 1.608 + CPU_TYPE = CPU_TYPE_020; 1.609 + CPU_ADDRESS_MASK = 0xffffffff; 1.610 + CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ 1.611 + CYC_INSTRUCTION = m68ki_cycles[2]; 1.612 + CYC_EXCEPTION = m68ki_exception_cycle_table[2]; 1.613 + CYC_BCC_NOTAKE_B = -2; 1.614 + CYC_BCC_NOTAKE_W = 0; 1.615 + CYC_DBCC_F_NOEXP = 0; 1.616 + CYC_DBCC_F_EXP = 4; 1.617 + CYC_SCC_R_FALSE = 0; 1.618 + CYC_MOVEM_W = 2; 1.619 + CYC_MOVEM_L = 2; 1.620 + CYC_SHIFT = 0; 1.621 + CYC_RESET = 518; 1.622 + return; 1.623 + } 1.624 +} 1.625 + 1.626 +/* Execute some instructions until we use up num_cycles clock cycles */ 1.627 +/* ASG: removed per-instruction interrupt checks */ 1.628 +int m68k_execute(int num_cycles) 1.629 +{ 1.630 + /* Make sure we're not stopped */ 1.631 + if(!CPU_STOPPED) 1.632 + { 1.633 + /* Set our pool of clock cycles available */ 1.634 + SET_CYCLES(num_cycles); 1.635 + m68ki_initial_cycles = num_cycles; 1.636 + 1.637 + /* ASG: update cycles */ 1.638 + USE_CYCLES(CPU_INT_CYCLES); 1.639 + CPU_INT_CYCLES = 0; 1.640 + 1.641 + /* Return point if we had an address error */ 1.642 + m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */ 1.643 + 1.644 + /* Main loop. Keep going until we run out of clock cycles */ 1.645 + do 1.646 + { 1.647 + /* Set tracing accodring to T1. (T0 is done inside instruction) */ 1.648 + m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */ 1.649 + 1.650 + /* Set the address space for reads */ 1.651 + m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */ 1.652 + 1.653 + /* Call external hook to peek at CPU */ 1.654 + m68ki_instr_hook(); /* auto-disable (see m68kcpu.h) */ 1.655 + 1.656 + /* Record previous program counter */ 1.657 + REG_PPC = REG_PC; 1.658 + 1.659 + /* Read an instruction and call its handler */ 1.660 + REG_IR = m68ki_read_imm_16(); 1.661 + m68ki_instruction_jump_table[REG_IR](); 1.662 + USE_CYCLES(CYC_INSTRUCTION[REG_IR]); 1.663 + 1.664 + /* Trace m68k_exception, if necessary */ 1.665 + m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */ 1.666 + } while(GET_CYCLES() > 0); 1.667 + 1.668 + /* set previous PC to current PC for the next entry into the loop */ 1.669 + REG_PPC = REG_PC; 1.670 + 1.671 + /* ASG: update cycles */ 1.672 + USE_CYCLES(CPU_INT_CYCLES); 1.673 + CPU_INT_CYCLES = 0; 1.674 + 1.675 + /* return how many clocks we used */ 1.676 + return m68ki_initial_cycles - GET_CYCLES(); 1.677 + } 1.678 + 1.679 + /* We get here if the CPU is stopped or halted */ 1.680 + SET_CYCLES(0); 1.681 + CPU_INT_CYCLES = 0; 1.682 + 1.683 + return num_cycles; 1.684 +} 1.685 + 1.686 + 1.687 +int m68k_cycles_run(void) 1.688 +{ 1.689 + return m68ki_initial_cycles - GET_CYCLES(); 1.690 +} 1.691 + 1.692 +int m68k_cycles_remaining(void) 1.693 +{ 1.694 + return GET_CYCLES(); 1.695 +} 1.696 + 1.697 +/* Change the timeslice */ 1.698 +void m68k_modify_timeslice(int cycles) 1.699 +{ 1.700 + m68ki_initial_cycles += cycles; 1.701 + ADD_CYCLES(cycles); 1.702 +} 1.703 + 1.704 + 1.705 +void m68k_end_timeslice(void) 1.706 +{ 1.707 + m68ki_initial_cycles = GET_CYCLES(); 1.708 + SET_CYCLES(0); 1.709 +} 1.710 + 1.711 + 1.712 +/* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */ 1.713 +/* KS: Modified so that IPL* bits match with mask positions in the SR 1.714 + * and cleaned out remenants of the interrupt controller. 1.715 + */ 1.716 +void m68k_set_irq(unsigned int int_level) 1.717 +{ 1.718 + uint old_level = CPU_INT_LEVEL; 1.719 + CPU_INT_LEVEL = int_level << 8; 1.720 + 1.721 + /* A transition from < 7 to 7 always interrupts (NMI) */ 1.722 + /* Note: Level 7 can also level trigger like a normal IRQ */ 1.723 + if(old_level != 0x0700 && CPU_INT_LEVEL == 0x0700) 1.724 + m68ki_exception_interrupt(7); /* Edge triggered level 7 (NMI) */ 1.725 + else 1.726 + m68ki_check_interrupts(); /* Level triggered (IRQ) */ 1.727 +} 1.728 + 1.729 + 1.730 +/* Pulse the RESET line on the CPU */ 1.731 +void m68k_pulse_reset(void) 1.732 +{ 1.733 + static uint emulation_initialized = 0; 1.734 + 1.735 + /* The first call to this function initializes the opcode handler jump table */ 1.736 + if(!emulation_initialized) 1.737 + { 1.738 + m68ki_build_opcode_table(); 1.739 + m68k_set_int_ack_callback(NULL); 1.740 + m68k_set_bkpt_ack_callback(NULL); 1.741 + m68k_set_reset_instr_callback(NULL); 1.742 + m68k_set_pc_changed_callback(NULL); 1.743 + m68k_set_fc_callback(NULL); 1.744 + m68k_set_instr_hook_callback(NULL); 1.745 + 1.746 + emulation_initialized = 1; 1.747 + } 1.748 + 1.749 + 1.750 + if(CPU_TYPE == 0) /* KW 990319 */ 1.751 + m68k_set_cpu_type(M68K_CPU_TYPE_68000); 1.752 + 1.753 + /* Clear all stop levels and eat up all remaining cycles */ 1.754 + CPU_STOPPED = 0; 1.755 + SET_CYCLES(0); 1.756 + 1.757 + /* Turn off tracing */ 1.758 + FLAG_T1 = FLAG_T0 = 0; 1.759 + m68ki_clear_trace(); 1.760 + /* Interrupt mask to level 7 */ 1.761 + FLAG_INT_MASK = 0x0700; 1.762 + /* Reset VBR */ 1.763 + REG_VBR = 0; 1.764 + /* Go to supervisor mode */ 1.765 + m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR); 1.766 + 1.767 + /* Invalidate the prefetch queue */ 1.768 +#if M68K_EMULATE_PREFETCH 1.769 + /* Set to arbitrary number since our first fetch is from 0 */ 1.770 + CPU_PREF_ADDR = 0x1000; 1.771 +#endif /* M68K_EMULATE_PREFETCH */ 1.772 + 1.773 + /* Read the initial stack pointer and program counter */ 1.774 + m68ki_jump(0); 1.775 + REG_SP = m68ki_read_imm_32(); 1.776 + REG_PC = m68ki_read_imm_32(); 1.777 + m68ki_jump(REG_PC); 1.778 +} 1.779 + 1.780 +/* Pulse the HALT line on the CPU */ 1.781 +void m68k_pulse_halt(void) 1.782 +{ 1.783 + CPU_STOPPED |= STOP_LEVEL_HALT; 1.784 +} 1.785 + 1.786 + 1.787 +/* Get and set the current CPU context */ 1.788 +/* This is to allow for multiple CPUs */ 1.789 +unsigned int m68k_context_size() 1.790 +{ 1.791 + return sizeof(m68ki_cpu_core); 1.792 +} 1.793 + 1.794 +unsigned int m68k_get_context(void* dst) 1.795 +{ 1.796 + if(dst) *(m68ki_cpu_core*)dst = m68ki_cpu; 1.797 + return sizeof(m68ki_cpu_core); 1.798 +} 1.799 + 1.800 +void m68k_set_context(void* src) 1.801 +{ 1.802 + if(src) m68ki_cpu = *(m68ki_cpu_core*)src; 1.803 +} 1.804 + 1.805 +void m68k_save_context( void (*save_value)(char*, unsigned int)) 1.806 +{ 1.807 + if(!save_value) 1.808 + return; 1.809 + 1.810 + save_value("CPU_TYPE" , m68k_get_reg(NULL, M68K_REG_CPU_TYPE)); 1.811 + save_value("D0" , REG_D[0]); 1.812 + save_value("D1" , REG_D[1]); 1.813 + save_value("D2" , REG_D[2]); 1.814 + save_value("D3" , REG_D[3]); 1.815 + save_value("D4" , REG_D[4]); 1.816 + save_value("D5" , REG_D[5]); 1.817 + save_value("D6" , REG_D[6]); 1.818 + save_value("D7" , REG_D[7]); 1.819 + save_value("A0" , REG_A[0]); 1.820 + save_value("A1" , REG_A[1]); 1.821 + save_value("A2" , REG_A[2]); 1.822 + save_value("A3" , REG_A[3]); 1.823 + save_value("A4" , REG_A[4]); 1.824 + save_value("A5" , REG_A[5]); 1.825 + save_value("A6" , REG_A[6]); 1.826 + save_value("A7" , REG_A[7]); 1.827 + save_value("PPC" , REG_PPC); 1.828 + save_value("PC" , REG_PC); 1.829 + save_value("USP" , REG_USP); 1.830 + save_value("ISP" , REG_ISP); 1.831 + save_value("MSP" , REG_MSP); 1.832 + save_value("VBR" , REG_VBR); 1.833 + save_value("SFC" , REG_SFC); 1.834 + save_value("DFC" , REG_DFC); 1.835 + save_value("CACR" , REG_CACR); 1.836 + save_value("CAAR" , REG_CAAR); 1.837 + save_value("SR" , m68ki_get_sr()); 1.838 + save_value("INT_LEVEL" , CPU_INT_LEVEL); 1.839 + save_value("INT_CYCLES", CPU_INT_CYCLES); 1.840 + save_value("STOPPED" , (CPU_STOPPED & STOP_LEVEL_STOP) != 0); 1.841 + save_value("HALTED" , (CPU_STOPPED & STOP_LEVEL_HALT) != 0); 1.842 + save_value("PREF_ADDR" , CPU_PREF_ADDR); 1.843 + save_value("PREF_DATA" , CPU_PREF_DATA); 1.844 +} 1.845 + 1.846 +void m68k_load_context(unsigned int (*load_value)(char*)) 1.847 +{ 1.848 + unsigned int temp; 1.849 + 1.850 + m68k_set_cpu_type(load_value("CPU_TYPE")); 1.851 + REG_PPC = load_value("PPC"); 1.852 + REG_PC = load_value("PC"); 1.853 + m68ki_jump(REG_PC); 1.854 + CPU_INT_LEVEL = 0; 1.855 + m68ki_set_sr_noint(load_value("SR")); 1.856 + REG_D[0] = load_value("D0"); 1.857 + REG_D[1] = load_value("D1"); 1.858 + REG_D[2] = load_value("D2"); 1.859 + REG_D[3] = load_value("D3"); 1.860 + REG_D[4] = load_value("D4"); 1.861 + REG_D[5] = load_value("D5"); 1.862 + REG_D[6] = load_value("D6"); 1.863 + REG_D[7] = load_value("D7"); 1.864 + REG_A[0] = load_value("A0"); 1.865 + REG_A[1] = load_value("A1"); 1.866 + REG_A[2] = load_value("A2"); 1.867 + REG_A[3] = load_value("A3"); 1.868 + REG_A[4] = load_value("A4"); 1.869 + REG_A[5] = load_value("A5"); 1.870 + REG_A[6] = load_value("A6"); 1.871 + REG_A[7] = load_value("A7"); 1.872 + REG_USP = load_value("USP"); 1.873 + REG_ISP = load_value("ISP"); 1.874 + REG_MSP = load_value("MSP"); 1.875 + REG_VBR = load_value("VBR"); 1.876 + REG_SFC = load_value("SFC"); 1.877 + REG_DFC = load_value("DFC"); 1.878 + REG_CACR = load_value("CACR"); 1.879 + REG_CAAR = load_value("CAAR"); 1.880 + CPU_INT_LEVEL = load_value("INT_LEVEL"); 1.881 + CPU_INT_CYCLES = load_value("INT_CYCLES"); 1.882 + 1.883 + CPU_STOPPED = 0; 1.884 + temp = load_value("STOPPED"); 1.885 + if(temp) CPU_STOPPED |= STOP_LEVEL_STOP; 1.886 + temp = load_value("HALTED"); 1.887 + if(temp) CPU_STOPPED |= STOP_LEVEL_HALT; 1.888 + 1.889 + CPU_PREF_ADDR = load_value("PREF_ADDR"); 1.890 + CPU_PREF_DATA = load_value("PREF_DATA"); 1.891 +} 1.892 + 1.893 + 1.894 + 1.895 +/* ======================================================================== */ 1.896 +/* ============================== END OF FILE ============================= */ 1.897 +/* ======================================================================== */