|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * MC68000 emulation ! 5: * ! 6: * Copyright 1995 Bernd Schmidt ! 7: */ ! 8: ! 9: #ifndef NEWCPU_H ! 10: #define NEWCPU_H ! 11: ! 12: #include "readcpu.h" ! 13: //#include "machdep/m68k.h" ! 14: #include "m68k.h" ! 15: #include "compat.h" ! 16: #include "maccess.h" ! 17: #include "events.h" ! 18: #include "memory.h" ! 19: #include "custom.h" ! 20: ! 21: /* Possible exceptions sources for M68000_Exception() and Exception() */ ! 22: #define M68000_EXC_SRC_CPU 1 /* Direct CPU exception */ ! 23: #define M68000_EXC_SRC_AUTOVEC 2 /* Auto-vector exception (e.g. VBL) */ ! 24: #define M68000_EXC_SRC_INT_MFP 3 /* MFP interrupt exception */ ! 25: #define M68000_EXC_SRC_INT_DSP 4 /* DSP interrupt exception */ ! 26: ! 27: ! 28: /* Special flags */ ! 29: #define SPCFLAG_DEBUGGER 1 ! 30: #define SPCFLAG_STOP 2 ! 31: #define SPCFLAG_BUSERROR 4 ! 32: #define SPCFLAG_INT 8 ! 33: #define SPCFLAG_BRK 0x10 ! 34: #define SPCFLAG_EXTRA_CYCLES 0x20 ! 35: #define SPCFLAG_TRACE 0x40 ! 36: #define SPCFLAG_DOTRACE 0x80 ! 37: #define SPCFLAG_DOINT 0x100 ! 38: #define SPCFLAG_MFP 0x200 ! 39: #define SPCFLAG_EXEC 0x400 ! 40: #define SPCFLAG_MODE_CHANGE 0x800 ! 41: ! 42: ! 43: #ifndef SET_CFLG ! 44: ! 45: #define SET_CFLG(x) (CFLG() = (x)) ! 46: #define SET_NFLG(x) (NFLG() = (x)) ! 47: #define SET_VFLG(x) (VFLG() = (x)) ! 48: #define SET_ZFLG(x) (ZFLG() = (x)) ! 49: #define SET_XFLG(x) (XFLG() = (x)) ! 50: ! 51: #define GET_CFLG() CFLG() ! 52: #define GET_NFLG() NFLG() ! 53: #define GET_VFLG() VFLG() ! 54: #define GET_ZFLG() ZFLG() ! 55: #define GET_XFLG() XFLG() ! 56: ! 57: #define CLEAR_CZNV() do { \ ! 58: SET_CFLG (0); \ ! 59: SET_ZFLG (0); \ ! 60: SET_NFLG (0); \ ! 61: SET_VFLG (0); \ ! 62: } while (0) ! 63: ! 64: #define COPY_CARRY() (SET_XFLG (GET_CFLG ())) ! 65: #endif ! 66: ! 67: extern const int areg_byteinc[]; ! 68: extern const int imm8_table[]; ! 69: ! 70: extern int movem_index1[256]; ! 71: extern int movem_index2[256]; ! 72: extern int movem_next[256]; ! 73: ! 74: #ifdef FPUEMU ! 75: extern int fpp_movem_index1[256]; ! 76: extern int fpp_movem_index2[256]; ! 77: extern int fpp_movem_next[256]; ! 78: #endif ! 79: ! 80: extern int OpcodeFamily; ! 81: ! 82: typedef unsigned long REGPARAM3 cpuop_func (uae_u32) REGPARAM; ! 83: typedef void REGPARAM3 cpuop_func_ce (uae_u32) REGPARAM; ! 84: ! 85: struct cputbl { ! 86: cpuop_func *handler; ! 87: uae_u16 opcode; ! 88: }; ! 89: ! 90: #ifdef JIT ! 91: typedef unsigned long REGPARAM3 compop_func (uae_u32) REGPARAM; ! 92: ! 93: struct comptbl { ! 94: compop_func *handler; ! 95: uae_u32 opcode; ! 96: int specific; ! 97: }; ! 98: #endif ! 99: ! 100: extern unsigned long REGPARAM3 op_illg (uae_u32) REGPARAM; ! 101: ! 102: typedef uae_u8 flagtype; ! 103: ! 104: #ifdef FPUEMU ! 105: /* You can set this to long double to be more accurate. However, the ! 106: resulting alignment issues will cost a lot of performance in some ! 107: apps */ ! 108: #define USE_LONG_DOUBLE 0 ! 109: ! 110: #if USE_LONG_DOUBLE ! 111: typedef long double fptype; ! 112: #define LDPTR tbyte ptr ! 113: #else ! 114: typedef double fptype; ! 115: #define LDPTR qword ptr ! 116: #endif ! 117: #endif ! 118: ! 119: #define CPU_PIPELINE_MAX 2 ! 120: #define CPU000_MEM_CYCLE 4 ! 121: #define CPU000_CLOCK_MULT 2 ! 122: #define CPU020_MEM_CYCLE 3 ! 123: #define CPU020_CLOCK_MULT 4 ! 124: ! 125: #define CACHELINES020 64 ! 126: struct cache020 ! 127: { ! 128: uae_u32 data; ! 129: uae_u32 tag; ! 130: bool valid; ! 131: }; ! 132: ! 133: #define CACHELINES030 16 ! 134: struct cache030 ! 135: { ! 136: uae_u32 data[4]; ! 137: bool valid[4]; ! 138: uae_u32 tag; ! 139: }; ! 140: ! 141: #define CACHESETS040 64 ! 142: #define CACHELINES040 4 ! 143: struct cache040 ! 144: { ! 145: uae_u32 data[CACHELINES040][4]; ! 146: bool valid[CACHELINES040]; ! 147: uae_u32 tag[CACHELINES040]; ! 148: }; ! 149: ! 150: ! 151: struct regstruct ! 152: { ! 153: uae_u32 regs[16]; ! 154: ! 155: uae_u32 pc; ! 156: uae_u8 *pc_p; ! 157: uae_u8 *pc_oldp; ! 158: ! 159: uae_u16 irc, ir; ! 160: uae_u32 spcflags; ! 161: ! 162: uaecptr usp, isp, msp; ! 163: uae_u16 sr; ! 164: flagtype t1; ! 165: flagtype t0; ! 166: flagtype s; ! 167: flagtype m; ! 168: flagtype x; ! 169: flagtype stopped; ! 170: int intmask; ! 171: int ipl, ipl_pin; ! 172: ! 173: uae_u32 vbr, sfc, dfc; ! 174: ! 175: #ifdef FPUEMU ! 176: fptype fp[8]; ! 177: fptype fp_result; ! 178: ! 179: uae_u32 fpcr, fpsr, fpiar; ! 180: uae_u32 fpsr_highbyte; ! 181: #endif ! 182: #ifndef CPUEMU_68000_ONLY ! 183: uae_u32 cacr, caar; ! 184: uae_u32 itt0, itt1, dtt0, dtt1; ! 185: uae_u32 tcr, mmusr, urp, srp, buscr; ! 186: uae_u32 mmu_fslw, mmu_fault_addr; ! 187: uae_u16 mmu_ssw; ! 188: uae_u32 wb3_data; ! 189: uae_u16 wb3_status; ! 190: int mmu_enabled; ! 191: int mmu_pagesize_8k; ! 192: uae_u32 fault_pc; ! 193: #endif ! 194: ! 195: uae_u32 pcr; ! 196: uae_u32 address_space_mask; ! 197: ! 198: uae_u8 panic; ! 199: uae_u32 panic_pc, panic_addr; ! 200: ! 201: uae_u32 prefetch020data[CPU_PIPELINE_MAX]; ! 202: uae_u32 prefetch020addr[CPU_PIPELINE_MAX]; ! 203: int ce020memcycles; ! 204: }; ! 205: ! 206: extern struct regstruct regs; ! 207: ! 208: STATIC_INLINE uae_u32 munge24 (uae_u32 x) ! 209: { ! 210: return x & regs.address_space_mask; ! 211: } ! 212: ! 213: extern int mmu_enabled, mmu_triggered; ! 214: extern int cpu_cycles; ! 215: extern int cpucycleunit; ! 216: STATIC_INLINE void set_special (uae_u32 x) ! 217: { ! 218: regs.spcflags |= x; ! 219: cycles_do_special (); ! 220: } ! 221: ! 222: STATIC_INLINE void unset_special (uae_u32 x) ! 223: { ! 224: regs.spcflags &= ~x; ! 225: } ! 226: ! 227: #define m68k_dreg(r,num) ((r).regs[(num)]) ! 228: #define m68k_areg(r,num) (((r).regs + 8)[(num)]) ! 229: ! 230: STATIC_INLINE void m68k_setpc (uaecptr newpc) ! 231: { ! 232: regs.pc_p = regs.pc_oldp = get_real_address (newpc); ! 233: regs.fault_pc = regs.pc = newpc; ! 234: } ! 235: ! 236: STATIC_INLINE uaecptr m68k_getpc (void) ! 237: { ! 238: return (uaecptr)(regs.pc + ((uae_u8*)regs.pc_p - (uae_u8*)regs.pc_oldp)); ! 239: } ! 240: #define M68K_GETPC m68k_getpc() ! 241: ! 242: STATIC_INLINE uaecptr m68k_getpc_p (uae_u8 *p) ! 243: { ! 244: return (uaecptr)(regs.pc + ((uae_u8*)p - (uae_u8*)regs.pc_oldp)); ! 245: } ! 246: ! 247: STATIC_INLINE void fill_prefetch_0 (void) ! 248: { ! 249: } ! 250: ! 251: #define fill_prefetch_2 fill_prefetch_0 ! 252: ! 253: STATIC_INLINE void m68k_incpc (int o) ! 254: { ! 255: regs.pc_p += o; ! 256: } ! 257: ! 258: STATIC_INLINE void m68k_setpc_mmu (uaecptr newpc) ! 259: { ! 260: regs.fault_pc = regs.pc = newpc; ! 261: regs.pc_p = regs.pc_oldp = 0; ! 262: } ! 263: STATIC_INLINE void m68k_setpci (uaecptr newpc) ! 264: { ! 265: regs.fault_pc = regs.pc = newpc; ! 266: } ! 267: STATIC_INLINE uaecptr m68k_getpci (void) ! 268: { ! 269: return regs.pc; ! 270: } ! 271: STATIC_INLINE void m68k_incpci (int o) ! 272: { ! 273: regs.pc += o; ! 274: } ! 275: ! 276: STATIC_INLINE void m68k_do_rts (void) ! 277: { ! 278: uae_u32 newpc = get_long (m68k_areg (regs, 7)); ! 279: m68k_setpc (newpc); ! 280: m68k_areg (regs, 7) += 4; ! 281: } ! 282: STATIC_INLINE void m68k_do_rtsi (void) ! 283: { ! 284: m68k_setpci (get_long (m68k_areg (regs, 7))); ! 285: m68k_areg (regs, 7) += 4; ! 286: } ! 287: ! 288: STATIC_INLINE void m68k_do_bsr (uaecptr oldpc, uae_s32 offset) ! 289: { ! 290: m68k_areg (regs, 7) -= 4; ! 291: put_long (m68k_areg (regs, 7), oldpc); ! 292: m68k_incpc (offset); ! 293: } ! 294: STATIC_INLINE void m68k_do_bsri (uaecptr oldpc, uae_s32 offset) ! 295: { ! 296: m68k_areg (regs, 7) -= 4; ! 297: put_long (m68k_areg (regs, 7), oldpc); ! 298: m68k_incpci (offset); ! 299: } ! 300: ! 301: STATIC_INLINE uae_u32 get_ibyte (int o) ! 302: { ! 303: return do_get_mem_byte((uae_u8 *)((regs).pc_p + (o) + 1)); ! 304: } ! 305: STATIC_INLINE uae_u32 get_iword (int o) ! 306: { ! 307: return do_get_mem_word((uae_u16 *)((regs).pc_p + (o))); ! 308: } ! 309: STATIC_INLINE uae_u32 get_ilong (int o) ! 310: { ! 311: return do_get_mem_long((uae_u32 *)((regs).pc_p + (o))); ! 312: } ! 313: ! 314: #define get_iwordi(o) get_wordi(o) ! 315: #define get_ilongi(o) get_longi(o) ! 316: ! 317: /* These are only used by the 68020/68881 code, and therefore don't ! 318: * need to handle prefetch. */ ! 319: STATIC_INLINE uae_u32 next_ibyte (void) ! 320: { ! 321: uae_u32 r = get_ibyte (0); ! 322: m68k_incpc (2); ! 323: return r; ! 324: } ! 325: STATIC_INLINE uae_u32 next_iword (void) ! 326: { ! 327: uae_u32 r = get_iword (0); ! 328: m68k_incpc (2); ! 329: return r; ! 330: } ! 331: STATIC_INLINE uae_u32 next_iwordi (void) ! 332: { ! 333: uae_u32 r = get_iwordi (m68k_getpci ()); ! 334: m68k_incpc (2); ! 335: return r; ! 336: } ! 337: STATIC_INLINE uae_u32 next_ilong (void) ! 338: { ! 339: uae_u32 r = get_ilong (0); ! 340: m68k_incpc (4); ! 341: return r; ! 342: } ! 343: STATIC_INLINE uae_u32 next_ilongi (void) ! 344: { ! 345: uae_u32 r = get_ilongi (m68k_getpci ()); ! 346: m68k_incpc (4); ! 347: return r; ! 348: } ! 349: ! 350: extern uae_u32 (*x_get_byte)(uaecptr addr); ! 351: extern uae_u32 (*x_get_word)(uaecptr addr); ! 352: extern uae_u32 (*x_get_long)(uaecptr addr); ! 353: extern void (*x_put_byte)(uaecptr addr, uae_u32 v); ! 354: extern void (*x_put_word)(uaecptr addr, uae_u32 v); ! 355: extern void (*x_put_long)(uaecptr addr, uae_u32 v); ! 356: extern uae_u32 (*x_next_iword)(void); ! 357: extern uae_u32 (*x_next_ilong)(void); ! 358: ! 359: extern uae_u32 REGPARAM3 x_get_disp_ea_020 (uae_u32 base, uae_u32 dp) REGPARAM; ! 360: extern uae_u32 REGPARAM3 x_get_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width) REGPARAM; ! 361: extern void REGPARAM3 x_put_bitfield (uae_u32 dst, uae_u32 bdata[2], uae_u32 val, uae_s32 offset, int width) REGPARAM; ! 362: ! 363: extern void m68k_setstopped (void); ! 364: extern void m68k_resumestopped (void); ! 365: ! 366: extern uae_u32 REGPARAM3 get_disp_ea_020 (uae_u32 base, uae_u32 dp) REGPARAM; ! 367: extern uae_u32 REGPARAM3 get_disp_ea_000 (uae_u32 base, uae_u32 dp) REGPARAM; ! 368: extern uae_u32 REGPARAM3 get_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width) REGPARAM; ! 369: extern void REGPARAM3 put_bitfield (uae_u32 dst, uae_u32 bdata[2], uae_u32 val, uae_s32 offset, int width) REGPARAM; ! 370: ! 371: extern void m68k_disasm_ea (FILE *f, uaecptr addr, uaecptr *nextpc, int cnt, uae_u32 *seaddr, uae_u32 *deaddr); ! 372: extern void m68k_disasm (FILE *f, uaecptr addr, uaecptr *nextpc, int cnt); ! 373: extern int get_cpu_model (void); ! 374: ! 375: extern void REGPARAM3 MakeSR (void) REGPARAM; ! 376: extern void REGPARAM3 MakeFromSR (void) REGPARAM; ! 377: extern void MakeSR (void); ! 378: extern void MakeFromSR (void); ! 379: extern void REGPARAM3 Exception (int, uaecptr, int) REGPARAM; ! 380: extern void NMI (void); ! 381: extern void NMI_delayed (void); ! 382: extern void prepare_interrupt (uae_u32); ! 383: extern void doint (void); ! 384: extern void dump_counts (void); ! 385: extern int m68k_move2c (int, uae_u32 *); ! 386: extern int m68k_movec2 (int, uae_u32 *); ! 387: extern void m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr); ! 388: extern void m68k_mull (uae_u32, uae_u32, uae_u16); ! 389: extern void init_m68k (void); ! 390: extern void init_m68k_full (void); ! 391: extern void m68k_go (int); ! 392: extern void m68k_dumpstate (FILE *, uaecptr *); ! 393: extern void m68k_disasm (FILE *, uaecptr, uaecptr *, int); ! 394: extern void sm68k_disasm (TCHAR*, TCHAR*, uaecptr addr, uaecptr *nextpc); ! 395: extern void m68k_reset (int); ! 396: extern int getDivu68kCycles (uae_u32 dividend, uae_u16 divisor); ! 397: extern int getDivs68kCycles (uae_s32 dividend, uae_s16 divisor); ! 398: extern void m68k_do_rte (void); ! 399: ! 400: extern void mmu_op (uae_u32, uae_u32); ! 401: extern void mmu_op30 (uaecptr, uae_u32, uae_u16, uaecptr); ! 402: ! 403: extern void fpuop_arithmetic(uae_u32, uae_u16); ! 404: extern void fpuop_dbcc(uae_u32, uae_u16); ! 405: extern void fpuop_scc(uae_u32, uae_u16); ! 406: extern void fpuop_trapcc(uae_u32, uaecptr, uae_u16); ! 407: extern void fpuop_bcc(uae_u32, uaecptr, uae_u32); ! 408: extern void fpuop_save(uae_u32); ! 409: extern void fpuop_restore(uae_u32); ! 410: extern uae_u32 fpp_get_fpsr (void); ! 411: extern void fpu_reset (void); ! 412: extern void fpux_save (int*); ! 413: extern void fpux_restore (int*); ! 414: ! 415: extern void exception3 (uae_u32 opcode, uaecptr addr, uaecptr fault); ! 416: extern void exception3i (uae_u32 opcode, uaecptr addr, uaecptr fault); ! 417: extern void exception2 (uaecptr addr, uaecptr fault); ! 418: extern void cpureset (void); ! 419: ! 420: extern void fill_prefetch_slow (void); ! 421: ! 422: #define CPU_OP_NAME(a) op ## a ! 423: ! 424: /* 68060 */ ! 425: extern const struct cputbl op_smalltbl_0_ff[]; ! 426: extern const struct cputbl op_smalltbl_20_ff[]; // CE ! 427: /* 68040 */ ! 428: extern const struct cputbl op_smalltbl_1_ff[]; ! 429: extern const struct cputbl op_smalltbl_21_ff[]; // CE ! 430: extern const struct cputbl op_smalltbl_31_ff[]; // MMU ! 431: /* 68030 */ ! 432: extern const struct cputbl op_smalltbl_2_ff[]; ! 433: extern const struct cputbl op_smalltbl_22_ff[]; // CE ! 434: /* 68020 */ ! 435: extern const struct cputbl op_smalltbl_3_ff[]; ! 436: extern const struct cputbl op_smalltbl_23_ff[]; // CE ! 437: /* 68010 */ ! 438: extern const struct cputbl op_smalltbl_4_ff[]; ! 439: /* 68000 */ ! 440: extern const struct cputbl op_smalltbl_5_ff[]; ! 441: /* 68000 slow but compatible. */ ! 442: extern const struct cputbl op_smalltbl_11_ff[]; ! 443: /* 68000 slow but compatible and cycle-exact. */ ! 444: extern const struct cputbl op_smalltbl_12_ff[]; ! 445: ! 446: extern cpuop_func *cpufunctbl[65536] ASM_SYM_FOR_FUNC ("cpufunctbl"); ! 447: ! 448: /* Added for hatari_glue.c */ ! 449: extern void build_cpufunctbl(void); ! 450: ! 451: #ifdef JIT ! 452: extern void flush_icache (uaecptr, int); ! 453: extern void compemu_reset (void); ! 454: extern bool check_prefs_changed_comp (void); ! 455: #else ! 456: #define flush_icache(uaecptr, int) do {} while (0) ! 457: #endif ! 458: extern void flush_dcache (uaecptr, int); ! 459: extern void flush_mmu (uaecptr, int); ! 460: ! 461: extern int movec_illg (int regno); ! 462: extern uae_u32 val_move2c (int regno); ! 463: extern void val_move2c2 (int regno, uae_u32 val); ! 464: struct cpum2c { ! 465: int regno; ! 466: const TCHAR *regname; ! 467: }; ! 468: extern struct cpum2c m2cregs[]; ! 469: ! 470: /* Family of the latest instruction executed (to check for pairing) */ ! 471: extern int OpcodeFamily; /* see instrmnem in readcpu.h */ ! 472: ! 473: /* How many cycles to add to the current instruction in case a "misaligned" bus acces is made */ ! 474: /* (used when addressing mode is d8(an,ix)) */ ! 475: extern int BusCyclePenalty; ! 476: ! 477: STATIC_INLINE uae_u32 get_iword_prefetch (uae_s32 o) ! 478: { ! 479: /* Laurent : let's see this later ! 480: uae_u32 currpc = m68k_getpc (); ! 481: uae_u32 addr = currpc + o; ! 482: uae_u32 offs = addr - prefetch_pc; ! 483: uae_u32 v; ! 484: if (offs > 3) { ! 485: refill_prefetch (currpc, o); ! 486: offs = addr - prefetch_pc; ! 487: } ! 488: v = do_get_mem_word (((uae_u8 *)&prefetch) + offs); ! 489: if (offs >= 2) ! 490: refill_prefetch (currpc, 2); ! 491: */ ! 492: /* printf ("get_iword PC %lx ADDR %lx OFFS %lx V %lx\n", currpc, addr, offs, v); */ ! 493: //return v; ! 494: return 0; ! 495: } ! 496: ! 497: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.