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