|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator - CPU core ! 3: * ! 4: * MC68000 emulation ! 5: * ! 6: * Copyright 1995 Bernd Schmidt ! 7: * ! 8: * Adaptation to Hatari by Thomas Huth ! 9: * ! 10: * This file is distributed under the GNU Public License, version 2 or at ! 11: * your option any later version. Read the file gpl.txt for details. ! 12: */ ! 13: ! 14: #ifndef UAE_NEWCPU_H ! 15: #define UAE_NEWCPU_H ! 16: ! 17: #include "readcpu.h" ! 18: #include "m68k.h" ! 19: ! 20: ! 21: /* custom chip support */ ! 22: #define SPCFLAG_STOP 2 ! 23: #define SPCFLAG_BUSERROR 4 ! 24: #define SPCFLAG_INT 8 ! 25: #define SPCFLAG_BRK 0x10 ! 26: #define SPCFLAG_EXTRA_CYCLES 0x20 ! 27: #define SPCFLAG_TRACE 0x40 ! 28: #define SPCFLAG_DOTRACE 0x80 ! 29: #define SPCFLAG_DOINT 0x100 ! 30: /*#define SPCFLAG_BLTNASTY 0x200 */ ! 31: #define SPCFLAG_EXEC 0x400 ! 32: #define SPCFLAG_MODE_CHANGE 0x800 ! 33: ! 34: #ifndef SET_CFLG ! 35: ! 36: #define SET_CFLG(x) (CFLG = (x)) ! 37: #define SET_NFLG(x) (NFLG = (x)) ! 38: #define SET_VFLG(x) (VFLG = (x)) ! 39: #define SET_ZFLG(x) (ZFLG = (x)) ! 40: #define SET_XFLG(x) (XFLG = (x)) ! 41: ! 42: #define GET_CFLG CFLG ! 43: #define GET_NFLG NFLG ! 44: #define GET_VFLG VFLG ! 45: #define GET_ZFLG ZFLG ! 46: #define GET_XFLG XFLG ! 47: ! 48: #define CLEAR_CZNV do { \ ! 49: SET_CFLG (0); \ ! 50: SET_ZFLG (0); \ ! 51: SET_NFLG (0); \ ! 52: SET_VFLG (0); \ ! 53: } while (0) ! 54: ! 55: #define COPY_CARRY (SET_XFLG (GET_CFLG)) ! 56: #endif ! 57: ! 58: extern int areg_byteinc[]; ! 59: extern int imm8_table[]; ! 60: ! 61: extern int movem_index1[256]; ! 62: extern int movem_index2[256]; ! 63: extern int movem_next[256]; ! 64: ! 65: extern int fpp_movem_index1[256]; ! 66: extern int fpp_movem_index2[256]; ! 67: extern int fpp_movem_next[256]; ! 68: ! 69: extern int broken_in; ! 70: ! 71: typedef unsigned long cpuop_func (uae_u32) REGPARAM; ! 72: ! 73: struct cputbl { ! 74: cpuop_func *handler; ! 75: int specific; ! 76: uae_u16 opcode; ! 77: }; ! 78: ! 79: extern unsigned long op_illg (uae_u32) REGPARAM; ! 80: ! 81: typedef char flagtype; ! 82: ! 83: /* You can set this to long double to be more accurate. However, the ! 84: resulting alignment issues will cost a lot of performance in some ! 85: apps */ ! 86: #define USE_LONG_DOUBLE 0 ! 87: ! 88: #if USE_LONG_DOUBLE ! 89: typedef long double fptype; ! 90: #else ! 91: typedef double fptype; ! 92: #endif ! 93: ! 94: extern struct regstruct ! 95: { ! 96: uae_u32 regs[16]; ! 97: uaecptr usp,isp,msp; ! 98: uae_u16 sr; ! 99: flagtype t1; ! 100: flagtype t0; ! 101: flagtype s; ! 102: flagtype m; ! 103: flagtype x; ! 104: flagtype stopped; ! 105: int intmask; ! 106: ! 107: uae_u32 pc; ! 108: uae_u8 *pc_p; ! 109: uae_u8 *pc_oldp; ! 110: ! 111: uae_u32 vbr,sfc,dfc; ! 112: ! 113: fptype fp[8]; ! 114: fptype fp_result; ! 115: ! 116: uae_u32 fpcr,fpsr,fpiar; ! 117: uae_u32 fpsr_highbyte; ! 118: ! 119: uae_u32 spcflags; ! 120: ! 121: uae_u32 prefetch_pc; ! 122: uae_u32 prefetch; ! 123: } regs, lastint_regs; ! 124: ! 125: STATIC_INLINE void set_special (uae_u32 x) ! 126: { ! 127: regs.spcflags |= x; ! 128: } ! 129: ! 130: STATIC_INLINE void unset_special (uae_u32 x) ! 131: { ! 132: regs.spcflags &= ~x; ! 133: } ! 134: ! 135: #define m68k_dreg(r,num) ((r).regs[(num)]) ! 136: #define m68k_areg(r,num) (((r).regs + 8)[(num)]) ! 137: ! 138: ! 139: STATIC_INLINE void m68k_setpc (uaecptr newpc) ! 140: { ! 141: regs.pc_p = regs.pc_oldp = get_real_address (newpc); ! 142: regs.pc = newpc; ! 143: } ! 144: ! 145: STATIC_INLINE uaecptr m68k_getpc (void) ! 146: { ! 147: return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp); ! 148: } ! 149: ! 150: STATIC_INLINE uaecptr m68k_getpc_p (uae_u8 *p) ! 151: { ! 152: return regs.pc + ((char *)p - (char *)regs.pc_oldp); ! 153: } ! 154: ! 155: #define get_ibyte(o) do_get_mem_byte((uae_u8 *)(regs.pc_p + (o) + 1)) ! 156: #define get_iword(o) do_get_mem_word((uae_u16 *)(regs.pc_p + (o))) ! 157: #define get_ilong(o) do_get_mem_long((uae_u32 *)(regs.pc_p + (o))) ! 158: ! 159: STATIC_INLINE void refill_prefetch (uae_u32 currpc, uae_u32 offs) ! 160: { ! 161: uae_u32 t = (currpc + offs) & ~1; ! 162: uae_s32 pc_p_offs = t - currpc; ! 163: uae_u8 *ptr = regs.pc_p + pc_p_offs; ! 164: uae_u32 r; ! 165: #ifdef UNALIGNED_PROFITABLE ! 166: r = *(uae_u32 *)ptr; ! 167: regs.prefetch = r; ! 168: #else ! 169: r = do_get_mem_long ((uae_u32 *)ptr); ! 170: do_put_mem_long (®s.prefetch, r); ! 171: #endif ! 172: /* printf ("PC %lx T %lx PCPOFFS %d R %lx\n", currpc, t, pc_p_offs, r); */ ! 173: regs.prefetch_pc = t; ! 174: } ! 175: ! 176: STATIC_INLINE uae_u32 get_ibyte_prefetch (uae_s32 o) ! 177: { ! 178: uae_u32 currpc = m68k_getpc (); ! 179: uae_u32 addr = currpc + o + 1; ! 180: uae_u32 offs = addr - regs.prefetch_pc; ! 181: uae_u32 v; ! 182: if (offs > 3) { ! 183: refill_prefetch (currpc, o + 1); ! 184: offs = addr - regs.prefetch_pc; ! 185: } ! 186: v = do_get_mem_byte (((uae_u8 *)®s.prefetch) + offs); ! 187: if (offs >= 2) ! 188: refill_prefetch (currpc, 2); ! 189: /* printf ("get_ibyte PC %lx ADDR %lx OFFS %lx V %lx\n", currpc, addr, offs, v); */ ! 190: return v; ! 191: } ! 192: STATIC_INLINE uae_u32 get_iword_prefetch (uae_s32 o) ! 193: { ! 194: uae_u32 currpc = m68k_getpc (); ! 195: uae_u32 addr = currpc + o; ! 196: uae_u32 offs = addr - regs.prefetch_pc; ! 197: uae_u32 v; ! 198: if (offs > 3) { ! 199: refill_prefetch (currpc, o); ! 200: offs = addr - regs.prefetch_pc; ! 201: } ! 202: v = do_get_mem_word ((uae_u16 *)(((uae_u8 *)®s.prefetch) + offs)); ! 203: if (offs >= 2) ! 204: refill_prefetch (currpc, 2); ! 205: /* printf ("get_iword PC %lx ADDR %lx OFFS %lx V %lx\n", currpc, addr, offs, v); */ ! 206: return v; ! 207: } ! 208: STATIC_INLINE uae_u32 get_ilong_prefetch (uae_s32 o) ! 209: { ! 210: uae_u32 v = get_iword_prefetch (o); ! 211: v <<= 16; ! 212: v |= get_iword_prefetch (o + 2); ! 213: return v; ! 214: } ! 215: ! 216: #define m68k_incpc(o) (regs.pc_p += (o)) ! 217: ! 218: STATIC_INLINE void fill_prefetch_0 (void) ! 219: { ! 220: } ! 221: ! 222: #define fill_prefetch_2 fill_prefetch_0 ! 223: ! 224: /* These are only used by the 68020/68881 code, and therefore don't ! 225: * need to handle prefetch. */ ! 226: STATIC_INLINE uae_u32 next_ibyte (void) ! 227: { ! 228: uae_u32 r = get_ibyte (0); ! 229: m68k_incpc (2); ! 230: return r; ! 231: } ! 232: ! 233: STATIC_INLINE uae_u32 next_iword (void) ! 234: { ! 235: uae_u32 r = get_iword (0); ! 236: m68k_incpc (2); ! 237: return r; ! 238: } ! 239: ! 240: STATIC_INLINE uae_u32 next_ilong (void) ! 241: { ! 242: uae_u32 r = get_ilong (0); ! 243: m68k_incpc (4); ! 244: return r; ! 245: } ! 246: ! 247: #define m68k_setpc_bcc m68k_setpc ! 248: #define m68k_setpc_rte m68k_setpc ! 249: ! 250: STATIC_INLINE void m68k_setstopped (int stop) ! 251: { ! 252: regs.stopped = stop; ! 253: /* A traced STOP instruction drops through immediately without ! 254: actually stopping. */ ! 255: if (stop && (regs.spcflags & SPCFLAG_DOTRACE) == 0) ! 256: regs.spcflags |= SPCFLAG_STOP; ! 257: } ! 258: ! 259: /* m68k_do_rts, m68k_do_bsr and m68k_do_jsr were originally defined in ! 260: * compiler.h, but since that header file has been removed from Hatari, ! 261: * they are now defined here: */ ! 262: STATIC_INLINE void m68k_do_rts(void) ! 263: { ! 264: m68k_setpc(get_long(m68k_areg(regs, 7))); ! 265: m68k_areg(regs, 7) += 4; ! 266: } ! 267: ! 268: STATIC_INLINE void m68k_do_bsr(uaecptr oldpc, uae_s32 offset) ! 269: { ! 270: m68k_areg(regs, 7) -= 4; ! 271: put_long(m68k_areg(regs, 7), oldpc); ! 272: m68k_incpc(offset); ! 273: } ! 274: ! 275: STATIC_INLINE void m68k_do_jsr(uaecptr oldpc, uaecptr dest) ! 276: { ! 277: m68k_areg(regs, 7) -= 4; ! 278: put_long(m68k_areg(regs, 7), oldpc); ! 279: m68k_setpc(dest); ! 280: } ! 281: ! 282: ! 283: extern uae_u32 get_disp_ea_020 (uae_u32 base, uae_u32 dp); ! 284: extern uae_u32 get_disp_ea_000 (uae_u32 base, uae_u32 dp); ! 285: ! 286: extern uae_s32 ShowEA (FILE *, int reg, amodes mode, wordsizes size, char *buf); ! 287: ! 288: extern void MakeSR (void); ! 289: extern void MakeFromSR (void); ! 290: extern void Exception (int, uaecptr); ! 291: extern void dump_counts (void); ! 292: extern int m68k_move2c (int, uae_u32 *); ! 293: extern int m68k_movec2 (int, uae_u32 *); ! 294: extern void m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr); ! 295: extern void m68k_mull (uae_u32, uae_u32, uae_u16); ! 296: extern void build_cpufunctbl(void); ! 297: extern void init_m68k (void); ! 298: extern void m68k_go (int); ! 299: extern void m68k_dumpstate (FILE *, uaecptr *); ! 300: extern void m68k_disasm (FILE *, uaecptr, uaecptr *, int); ! 301: extern void m68k_reset (void); ! 302: ! 303: extern void mmu_op (uae_u32, uae_u16); ! 304: ! 305: extern void fpp_opp (uae_u32, uae_u16); ! 306: extern void fdbcc_opp (uae_u32, uae_u16); ! 307: extern void fscc_opp (uae_u32, uae_u16); ! 308: extern void ftrapcc_opp (uae_u32,uaecptr); ! 309: extern void fbcc_opp (uae_u32, uaecptr, uae_u32); ! 310: extern void fsave_opp (uae_u32); ! 311: extern void frestore_opp (uae_u32); ! 312: ! 313: extern int lastInstructionCycles; ! 314: ! 315: /* Opcode of faulting instruction */ ! 316: extern uae_u16 last_op_for_exception_3; ! 317: /* PC at fault time */ ! 318: extern uaecptr last_addr_for_exception_3; ! 319: /* Address that generated the exception */ ! 320: extern uaecptr last_fault_for_exception_3; ! 321: ! 322: #define CPU_OP_NAME(a) op ## a ! 323: ! 324: /* 68040 */ ! 325: extern struct cputbl op_smalltbl_0_ff[]; ! 326: /* 68020 + 68881 */ ! 327: extern struct cputbl op_smalltbl_1_ff[]; ! 328: /* 68020 */ ! 329: extern struct cputbl op_smalltbl_2_ff[]; ! 330: /* 68010 */ ! 331: extern struct cputbl op_smalltbl_3_ff[]; ! 332: /* 68000 */ ! 333: extern struct cputbl op_smalltbl_4_ff[]; ! 334: /* 68000 slow but compatible. */ ! 335: extern struct cputbl op_smalltbl_5_ff[]; ! 336: ! 337: extern cpuop_func *cpufunctbl[65536]; ! 338: ! 339: #endif /* UAE_NEWCPU_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.