|
|
1.1 root 1: /* 1.1.1.2 root 2: * UAE - The Un*x Amiga Emulator - CPU core 1.1.1.6 ! root 3: * 1.1 root 4: * MC68000 emulation 5: * 6: * Copyright 1995 Bernd Schmidt 1.1.1.2 root 7: * 8: * Adaptation to Hatari by Thomas Huth 9: * 1.1.1.5 root 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. 1.1 root 12: */ 13: 1.1.1.4 root 14: #ifndef UAE_NEWCPU_H 15: #define UAE_NEWCPU_H 1.1 root 16: 17: #include "readcpu.h" 18: #include "m68k.h" 19: 20: 21: /* custom chip support */ 22: #define SPCFLAG_STOP 2 1.1.1.6 ! root 23: #define SPCFLAG_BUSERROR 4 1.1 root 24: #define SPCFLAG_INT 8 1.1.1.6 ! root 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 1.1 root 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: 1.1.1.5 root 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: 1.1 root 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: 1.1.1.5 root 113: fptype fp[8]; 114: fptype fp_result; 115: 1.1 root 116: uae_u32 fpcr,fpsr,fpiar; 1.1.1.5 root 117: uae_u32 fpsr_highbyte; 1.1 root 118: 119: uae_u32 spcflags; 120: 1.1.1.5 root 121: uae_u32 prefetch_pc; 1.1 root 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: 1.1.1.6 ! root 138: 1.1.1.5 root 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: 1.1 root 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: 1.1.1.5 root 159: STATIC_INLINE void refill_prefetch (uae_u32 currpc, uae_u32 offs) 1.1 root 160: { 1.1.1.6 ! root 161: uae_u32 t = (currpc + offs) & ~1; 1.1.1.5 root 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: } 1.1 root 175: 1.1.1.5 root 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) 1.1.1.6 ! root 188: refill_prefetch (currpc, 2); 1.1.1.5 root 189: /* printf ("get_ibyte PC %lx ADDR %lx OFFS %lx V %lx\n", currpc, addr, offs, v); */ 190: return v; 1.1 root 191: } 192: STATIC_INLINE uae_u32 get_iword_prefetch (uae_s32 o) 193: { 1.1.1.5 root 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) 1.1.1.6 ! root 204: refill_prefetch (currpc, 2); 1.1.1.5 root 205: /* printf ("get_iword PC %lx ADDR %lx OFFS %lx V %lx\n", currpc, addr, offs, v); */ 206: return v; 1.1 root 207: } 208: STATIC_INLINE uae_u32 get_ilong_prefetch (uae_s32 o) 209: { 1.1.1.5 root 210: uae_u32 v = get_iword_prefetch (o); 211: v <<= 16; 212: v |= get_iword_prefetch (o + 2); 213: return v; 1.1 root 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; 1.1.1.5 root 253: /* A traced STOP instruction drops through immediately without 254: actually stopping. */ 255: if (stop && (regs.spcflags & SPCFLAG_DOTRACE) == 0) 1.1 root 256: regs.spcflags |= SPCFLAG_STOP; 257: } 258: 1.1.1.6 ! root 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: 1.1 root 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); 1.1.1.4 root 296: extern void build_cpufunctbl(void); 1.1 root 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: 1.1.1.2 root 313: extern int lastInstructionCycles; 314: 1.1 root 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: 1.1.1.2 root 337: extern cpuop_func *cpufunctbl[65536]; 1.1 root 338: 1.1.1.4 root 339: #endif /* UAE_NEWCPU_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.