|
|
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 UAENEWCPU ! 10: #define UAENEWCPU ! 11: ! 12: #include "readcpu.h" ! 13: #include "m68k.h" ! 14: ! 15: ! 16: /* custom chip support */ ! 17: #define SPCFLAG_STOP 2 ! 18: /*#define SPCFLAG_COPPER 4*/ ! 19: #define SPCFLAG_INT 8 ! 20: #define SPCFLAG_BRK 16 ! 21: #define SPCFLAG_EXTRA_CYCLES 32 ! 22: #define SPCFLAG_TRACE 64 ! 23: #define SPCFLAG_DOTRACE 128 ! 24: #define SPCFLAG_DOINT 256 ! 25: /*#define SPCFLAG_BLTNASTY 512*/ ! 26: #define SPCFLAG_EXEC 1024 ! 27: #define SPCFLAG_MODE_CHANGE 8192 ! 28: ! 29: ! 30: #ifndef SET_CFLG ! 31: ! 32: #define SET_CFLG(x) (CFLG = (x)) ! 33: #define SET_NFLG(x) (NFLG = (x)) ! 34: #define SET_VFLG(x) (VFLG = (x)) ! 35: #define SET_ZFLG(x) (ZFLG = (x)) ! 36: #define SET_XFLG(x) (XFLG = (x)) ! 37: ! 38: #define GET_CFLG CFLG ! 39: #define GET_NFLG NFLG ! 40: #define GET_VFLG VFLG ! 41: #define GET_ZFLG ZFLG ! 42: #define GET_XFLG XFLG ! 43: ! 44: #define CLEAR_CZNV do { \ ! 45: SET_CFLG (0); \ ! 46: SET_ZFLG (0); \ ! 47: SET_NFLG (0); \ ! 48: SET_VFLG (0); \ ! 49: } while (0) ! 50: ! 51: #define COPY_CARRY (SET_XFLG (GET_CFLG)) ! 52: #endif ! 53: ! 54: extern int areg_byteinc[]; ! 55: extern int imm8_table[]; ! 56: ! 57: extern int movem_index1[256]; ! 58: extern int movem_index2[256]; ! 59: extern int movem_next[256]; ! 60: ! 61: extern int fpp_movem_index1[256]; ! 62: extern int fpp_movem_index2[256]; ! 63: extern int fpp_movem_next[256]; ! 64: ! 65: extern int broken_in; ! 66: ! 67: typedef unsigned long cpuop_func (uae_u32) REGPARAM; ! 68: ! 69: struct cputbl { ! 70: cpuop_func *handler; ! 71: int specific; ! 72: uae_u16 opcode; ! 73: }; ! 74: ! 75: extern unsigned long op_illg (uae_u32) REGPARAM; ! 76: ! 77: typedef char flagtype; ! 78: ! 79: extern struct regstruct ! 80: { ! 81: uae_u32 regs[16]; ! 82: uaecptr usp,isp,msp; ! 83: uae_u16 sr; ! 84: flagtype t1; ! 85: flagtype t0; ! 86: flagtype s; ! 87: flagtype m; ! 88: flagtype x; ! 89: flagtype stopped; ! 90: int intmask; ! 91: ! 92: uae_u32 pc; ! 93: uae_u8 *pc_p; ! 94: uae_u8 *pc_oldp; ! 95: ! 96: uae_u32 vbr,sfc,dfc; ! 97: ! 98: double fp[8]; ! 99: uae_u32 fpcr,fpsr,fpiar; ! 100: ! 101: uae_u32 spcflags; ! 102: uae_u32 kick_mask; ! 103: ! 104: /* Fellow sources say this is 4 longwords. That's impossible. It needs ! 105: * to be at least a longword. The HRM has some cryptic comment about two ! 106: * instructions being on the same longword boundary. ! 107: * The way this is implemented now seems like a good compromise. ! 108: */ ! 109: uae_u32 prefetch; ! 110: } regs, lastint_regs; ! 111: ! 112: STATIC_INLINE void set_special (uae_u32 x) ! 113: { ! 114: regs.spcflags |= x; ! 115: } ! 116: ! 117: STATIC_INLINE void unset_special (uae_u32 x) ! 118: { ! 119: regs.spcflags &= ~x; ! 120: } ! 121: ! 122: #define m68k_dreg(r,num) ((r).regs[(num)]) ! 123: #define m68k_areg(r,num) (((r).regs + 8)[(num)]) ! 124: ! 125: #define get_ibyte(o) do_get_mem_byte((uae_u8 *)(regs.pc_p + (o) + 1)) ! 126: #define get_iword(o) do_get_mem_word((uae_u16 *)(regs.pc_p + (o))) ! 127: #define get_ilong(o) do_get_mem_long((uae_u32 *)(regs.pc_p + (o))) ! 128: ! 129: STATIC_INLINE uae_u32 get_ibyte_prefetch (uae_s32 o) ! 130: { ! 131: if (o > 3 || o < 0) ! 132: return do_get_mem_byte((uae_u8 *)(regs.pc_p + o + 1)); ! 133: ! 134: return do_get_mem_byte((uae_u8 *)(((uae_u8 *)®s.prefetch) + o + 1)); ! 135: } ! 136: STATIC_INLINE uae_u32 get_iword_prefetch (uae_s32 o) ! 137: { ! 138: if (o > 3 || o < 0) ! 139: return do_get_mem_word((uae_u16 *)(regs.pc_p + o)); ! 140: ! 141: return do_get_mem_word((uae_u16 *)(((uae_u8 *)®s.prefetch) + o)); ! 142: } ! 143: STATIC_INLINE uae_u32 get_ilong_prefetch (uae_s32 o) ! 144: { ! 145: if (o > 3 || o < 0) ! 146: return do_get_mem_long((uae_u32 *)(regs.pc_p + o)); ! 147: if (o == 0) ! 148: return do_get_mem_long(®s.prefetch); ! 149: return (do_get_mem_word (((uae_u16 *)®s.prefetch) + 1) << 16) | do_get_mem_word ((uae_u16 *)(regs.pc_p + 4)); ! 150: } ! 151: ! 152: #define m68k_incpc(o) (regs.pc_p += (o)) ! 153: ! 154: STATIC_INLINE void fill_prefetch_0 (void) ! 155: { ! 156: uae_u32 r; ! 157: #ifdef UNALIGNED_PROFITABLE ! 158: r = *(uae_u32 *)regs.pc_p; ! 159: regs.prefetch = r; ! 160: #else ! 161: r = do_get_mem_long ((uae_u32 *)regs.pc_p); ! 162: do_put_mem_long (®s.prefetch, r); ! 163: #endif ! 164: } ! 165: ! 166: #if 0 ! 167: STATIC_INLINE void fill_prefetch_2 (void) ! 168: { ! 169: uae_u32 r = do_get_mem_long (®s.prefetch) << 16; ! 170: uae_u32 r2 = do_get_mem_word (((uae_u16 *)regs.pc_p) + 1); ! 171: r |= r2; ! 172: do_put_mem_long (®s.prefetch, r); ! 173: } ! 174: #else ! 175: #define fill_prefetch_2 fill_prefetch_0 ! 176: #endif ! 177: ! 178: /* These are only used by the 68020/68881 code, and therefore don't ! 179: * need to handle prefetch. */ ! 180: STATIC_INLINE uae_u32 next_ibyte (void) ! 181: { ! 182: uae_u32 r = get_ibyte (0); ! 183: m68k_incpc (2); ! 184: return r; ! 185: } ! 186: ! 187: STATIC_INLINE uae_u32 next_iword (void) ! 188: { ! 189: uae_u32 r = get_iword (0); ! 190: m68k_incpc (2); ! 191: return r; ! 192: } ! 193: ! 194: STATIC_INLINE uae_u32 next_ilong (void) ! 195: { ! 196: uae_u32 r = get_ilong (0); ! 197: m68k_incpc (4); ! 198: return r; ! 199: } ! 200: ! 201: #if !defined USE_COMPILER ! 202: STATIC_INLINE void m68k_setpc (uaecptr newpc) ! 203: { ! 204: regs.pc_p = regs.pc_oldp = (uae_u8 *)get_real_address(newpc); ! 205: regs.pc = newpc; ! 206: } ! 207: #else ! 208: extern void m68k_setpc (uaecptr newpc); ! 209: #endif ! 210: ! 211: STATIC_INLINE uaecptr m68k_getpc (void) ! 212: { ! 213: return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp); ! 214: } ! 215: ! 216: STATIC_INLINE uaecptr m68k_getpc_p (uae_u8 *p) ! 217: { ! 218: return regs.pc + ((char *)p - (char *)regs.pc_oldp); ! 219: } ! 220: ! 221: #ifdef USE_COMPILER ! 222: extern void m68k_setpc_fast (uaecptr newpc); ! 223: extern void m68k_setpc_bcc (uaecptr newpc); ! 224: extern void m68k_setpc_rte (uaecptr newpc); ! 225: #else ! 226: #define m68k_setpc_fast m68k_setpc ! 227: #define m68k_setpc_bcc m68k_setpc ! 228: #define m68k_setpc_rte m68k_setpc ! 229: #endif ! 230: ! 231: STATIC_INLINE void m68k_setstopped (int stop) ! 232: { ! 233: regs.stopped = stop; ! 234: if (stop) ! 235: regs.spcflags |= SPCFLAG_STOP; ! 236: } ! 237: ! 238: extern uae_u32 get_disp_ea_020 (uae_u32 base, uae_u32 dp); ! 239: extern uae_u32 get_disp_ea_000 (uae_u32 base, uae_u32 dp); ! 240: ! 241: extern uae_s32 ShowEA (FILE *, int reg, amodes mode, wordsizes size, char *buf); ! 242: ! 243: extern void MakeSR (void); ! 244: extern void MakeFromSR (void); ! 245: extern void Exception (int, uaecptr); ! 246: extern void dump_counts (void); ! 247: extern int m68k_move2c (int, uae_u32 *); ! 248: extern int m68k_movec2 (int, uae_u32 *); ! 249: extern void m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr); ! 250: extern void m68k_mull (uae_u32, uae_u32, uae_u16); ! 251: extern void init_m68k (void); ! 252: extern void m68k_go (int); ! 253: extern void m68k_dumpstate (FILE *, uaecptr *); ! 254: extern void m68k_disasm (FILE *, uaecptr, uaecptr *, int); ! 255: extern void m68k_reset (void); ! 256: ! 257: extern void mmu_op (uae_u32, uae_u16); ! 258: ! 259: extern void fpp_opp (uae_u32, uae_u16); ! 260: extern void fdbcc_opp (uae_u32, uae_u16); ! 261: extern void fscc_opp (uae_u32, uae_u16); ! 262: extern void ftrapcc_opp (uae_u32,uaecptr); ! 263: extern void fbcc_opp (uae_u32, uaecptr, uae_u32); ! 264: extern void fsave_opp (uae_u32); ! 265: extern void frestore_opp (uae_u32); ! 266: ! 267: /* Opcode of faulting instruction */ ! 268: extern uae_u16 last_op_for_exception_3; ! 269: /* PC at fault time */ ! 270: extern uaecptr last_addr_for_exception_3; ! 271: /* Address that generated the exception */ ! 272: extern uaecptr last_fault_for_exception_3; ! 273: ! 274: #define CPU_OP_NAME(a) op ## a ! 275: ! 276: /* 68040 */ ! 277: extern struct cputbl op_smalltbl_0_ff[]; ! 278: /* 68020 + 68881 */ ! 279: extern struct cputbl op_smalltbl_1_ff[]; ! 280: /* 68020 */ ! 281: extern struct cputbl op_smalltbl_2_ff[]; ! 282: /* 68010 */ ! 283: extern struct cputbl op_smalltbl_3_ff[]; ! 284: /* 68000 */ ! 285: extern struct cputbl op_smalltbl_4_ff[]; ! 286: /* 68000 slow but compatible. */ ! 287: extern struct cputbl op_smalltbl_5_ff[]; ! 288: ! 289: extern cpuop_func *cpufunctbl[65536] ASM_SYM_FOR_FUNC ("cpufunctbl"); ! 290: ! 291: #endif /* ifndef UAENEWCPU */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.