|
|
1.1.1.3 ! root 1: /* 1.1 root 2: * UAE - The Un*x Amiga Emulator 1.1.1.3 ! root 3: * 1.1 root 4: * MC68000 emulation 5: * 6: * Copyright 1995 Bernd Schmidt 7: */ 8: 9: extern int areg_byteinc[]; 10: extern int imm8_table[]; 11: 12: extern int movem_index1[256]; 13: extern int movem_index2[256]; 14: extern int movem_next[256]; 15: 16: extern int fpp_movem_index1[256]; 17: extern int fpp_movem_index2[256]; 18: extern int fpp_movem_next[256]; 19: 20: extern int broken_in; 21: 1.1.1.3 ! root 22: typedef void cpuop_func(uae_u32) REGPARAM; 1.1 root 23: 24: struct cputbl { 25: cpuop_func *handler; 26: int specific; 1.1.1.3 ! root 27: uae_u16 opcode; 1.1 root 28: }; 29: 1.1.1.3 ! root 30: extern void op_illg(uae_u32) REGPARAM; 1.1 root 31: 1.1.1.2 root 32: typedef char flagtype; 1.1 root 33: 1.1.1.3 ! root 34: extern struct regstruct 1.1 root 35: { 1.1.1.3 ! root 36: uae_u32 regs[16]; ! 37: uaecptr usp,isp,msp; ! 38: uae_u16 sr; 1.1 root 39: flagtype t1; 40: flagtype t0; 41: flagtype s; 42: flagtype m; 43: flagtype x; 44: flagtype stopped; 45: int intmask; 1.1.1.3 ! root 46: ! 47: uae_u32 pc; ! 48: uae_u8 *pc_p; ! 49: uae_u8 *pc_oldp; ! 50: ! 51: uae_u32 vbr,sfc,dfc; 1.1 root 52: 53: double fp[8]; 1.1.1.3 ! root 54: uae_u32 fpcr,fpsr,fpiar; ! 55: ! 56: uae_u32 spcflags; ! 57: uae_u32 kick_mask; ! 58: ! 59: /* Fellow sources say this is 4 longwords. That's impossible. It needs ! 60: * to be at least a longword. The HRM has some cryptic comment about two ! 61: * instructions being on the same longword boundary. ! 62: * The way this is implemented now seems like a good compromise. ! 63: */ ! 64: uae_u32 prefetch; 1.1 root 65: } regs, lastint_regs; 66: 1.1.1.2 root 67: #define m68k_dreg(r,num) ((r).regs[(num)]) 68: #define m68k_areg(r,num) ((r).regs[(num)+8]) 1.1 root 69: 1.1.1.3 ! root 70: #define get_ibyte(o) do_get_mem_byte((uae_u8 *)(regs.pc_p + (o) + 1)) ! 71: #define get_iword(o) do_get_mem_word((uae_u16 *)(regs.pc_p + (o))) ! 72: #define get_ilong(o) do_get_mem_long((uae_u32 *)(regs.pc_p + (o))) ! 73: ! 74: static __inline__ uae_u32 get_ibyte_prefetch(uae_s32 o) 1.1 root 75: { 1.1.1.3 ! root 76: if (o > 3 || o < 0) ! 77: return do_get_mem_byte((uae_u8 *)(regs.pc_p + o + 1)); ! 78: ! 79: return do_get_mem_byte((uae_u8 *)(((uae_u8 *)®s.prefetch) + o + 1)); 1.1.1.2 root 80: } 1.1.1.3 ! root 81: static __inline__ uae_u32 get_iword_prefetch(uae_s32 o) ! 82: { ! 83: if (o > 3 || o < 0) ! 84: return do_get_mem_word((uae_u16 *)(regs.pc_p + o)); 1.1.1.2 root 85: 1.1.1.3 ! root 86: return do_get_mem_word((uae_u16 *)(((uae_u8 *)®s.prefetch) + o)); ! 87: } ! 88: static __inline__ uae_u32 get_ilong_prefetch(uae_s32 o) 1.1.1.2 root 89: { 1.1.1.3 ! root 90: if (o > 3 || o < 0) ! 91: return do_get_mem_long((uae_u32 *)(regs.pc_p + o)); ! 92: if (o == 0) ! 93: return do_get_mem_long(®s.prefetch); ! 94: return (do_get_mem_word (((uae_u16 *)®s.prefetch) + 1) << 16) | do_get_mem_word ((uae_u16 *)(regs.pc_p + 4)); 1.1 root 95: } 96: 1.1.1.3 ! root 97: #define m68k_incpc(o) (regs.pc_p += (o)) ! 98: ! 99: static __inline__ void fill_prefetch_0(void) 1.1 root 100: { 1.1.1.3 ! root 101: uae_u32 r; ! 102: #ifdef UNALIGNED_PROFITABLE ! 103: r = *(uae_u32 *)regs.pc_p; ! 104: regs.prefetch = r; ! 105: #else ! 106: r = do_get_mem_long ((uae_u32 *)regs.pc_p); ! 107: do_put_mem_long (®s.prefetch, r); ! 108: #endif ! 109: } ! 110: ! 111: #if 0 ! 112: static __inline__ void fill_prefetch_2(void) ! 113: { ! 114: uae_u32 r = do_get_mem_long (®s.prefetch) << 16; ! 115: uae_u32 r2 = do_get_mem_word (((uae_u16 *)regs.pc_p) + 1); ! 116: r |= r2; ! 117: do_put_mem_long (®s.prefetch, r); 1.1 root 118: } 119: #else 1.1.1.3 ! root 120: #define fill_prefetch_2 fill_prefetch_0 ! 121: #endif 1.1 root 122: 1.1.1.3 ! root 123: /* These are only used by the 68020/68881 code, and therefore don't ! 124: * need to handle prefetch. */ ! 125: static __inline__ uae_u32 next_ibyte(void) 1.1 root 126: { 1.1.1.3 ! root 127: uae_u32 r = get_ibyte(0); ! 128: m68k_incpc(2); 1.1.1.2 root 129: return r; 130: } 131: 1.1.1.3 ! root 132: static __inline__ uae_u32 next_iword(void) 1.1.1.2 root 133: { 1.1.1.3 ! root 134: uae_u32 r = get_iword(0); ! 135: m68k_incpc(2); 1.1 root 136: return r; 137: } 138: 1.1.1.3 ! root 139: static __inline__ uae_u32 next_ilong(void) 1.1 root 140: { 1.1.1.3 ! root 141: uae_u32 r = get_ilong(0); ! 142: m68k_incpc(4); 1.1 root 143: return r; 144: } 145: 1.1.1.3 ! root 146: #if !defined(USE_COMPILER) ! 147: static __inline__ void m68k_setpc(uaecptr newpc) 1.1 root 148: { 149: regs.pc_p = regs.pc_oldp = get_real_address(newpc); 1.1.1.2 root 150: regs.pc = newpc; 1.1 root 151: } 152: #else 1.1.1.3 ! root 153: extern void m68k_setpc(uaecptr newpc); 1.1 root 154: #endif 155: 1.1.1.3 ! root 156: static __inline__ uaecptr m68k_getpc(void) 1.1 root 157: { 158: return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp); 159: } 160: 161: #ifdef USE_COMPILER 1.1.1.3 ! root 162: extern void m68k_setpc_fast(uaecptr newpc); ! 163: extern void m68k_setpc_bcc(uaecptr newpc); ! 164: extern void m68k_setpc_rte(uaecptr newpc); 1.1 root 165: #else 166: #define m68k_setpc_fast m68k_setpc 167: #define m68k_setpc_bcc m68k_setpc 168: #define m68k_setpc_rte m68k_setpc 169: #endif 170: 171: static __inline__ void m68k_setstopped(int stop) 172: { 173: regs.stopped = stop; 174: if (stop) 175: regs.spcflags |= SPCFLAG_STOP; 176: } 177: 1.1.1.3 ! root 178: static __inline__ uae_u32 get_disp_ea_020 (uae_u32 base, uae_u32 dp) 1.1 root 179: { 1.1.1.2 root 180: int reg = (dp >> 12) & 15; 1.1.1.3 ! root 181: uae_s32 regd = regs.regs[reg]; 1.1 root 182: if ((dp & 0x800) == 0) 1.1.1.3 ! root 183: regd = (uae_s32)(uae_s16)regd; 1.1 root 184: regd <<= (dp >> 9) & 3; 185: if (dp & 0x100) { 1.1.1.3 ! root 186: uae_s32 outer = 0; 1.1 root 187: if (dp & 0x80) base = 0; 188: if (dp & 0x40) regd = 0; 189: 1.1.1.3 ! root 190: if ((dp & 0x30) == 0x20) base += (uae_s32)(uae_s16)next_iword(); ! 191: if ((dp & 0x30) == 0x30) base += next_ilong(); ! 192: ! 193: if ((dp & 0x3) == 0x2) outer = (uae_s32)(uae_s16)next_iword(); ! 194: if ((dp & 0x3) == 0x3) outer = next_ilong(); ! 195: 1.1 root 196: if ((dp & 0x4) == 0) base += regd; 197: if (dp & 0x3) base = get_long (base); 198: if (dp & 0x4) base += regd; 1.1.1.3 ! root 199: 1.1 root 200: return base + outer; 201: } else { 1.1.1.3 ! root 202: return base + (uae_s32)((uae_s8)dp) + regd; 1.1 root 203: } 204: } 1.1.1.3 ! root 205: static __inline__ uae_u32 get_disp_ea_000 (uae_u32 base, uae_u32 dp) 1.1 root 206: { 1.1.1.2 root 207: int reg = (dp >> 12) & 15; 1.1.1.3 ! root 208: uae_s32 regd = regs.regs[reg]; ! 209: 1.1 root 210: if ((dp & 0x800) == 0) 1.1.1.3 ! root 211: regd = (uae_s32)(uae_s16)regd; ! 212: return base + (uae_s8)dp + regd; 1.1 root 213: } 214: 1.1.1.3 ! root 215: extern uae_s32 ShowEA(int reg, amodes mode, wordsizes size, char *buf); 1.1.1.2 root 216: 1.1 root 217: extern void MakeSR(void); 218: extern void MakeFromSR(void); 1.1.1.3 ! root 219: extern void Exception(int, uaecptr); 1.1 root 220: extern void dump_counts(void); 1.1.1.3 ! root 221: extern void m68k_move2c(int, uae_u32 *); ! 222: extern void m68k_movec2(int, uae_u32 *); ! 223: extern void m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr); ! 224: extern void m68k_mull (uae_u32, uae_u32, uae_u16); 1.1 root 225: extern void init_m68k (void); 226: extern void m68k_go(int); 1.1.1.3 ! root 227: extern void m68k_dumpstate(uaecptr *); ! 228: extern void m68k_disasm(uaecptr,uaecptr *,int); 1.1 root 229: extern void m68k_reset(void); 1.1.1.2 root 230: 1.1.1.3 ! root 231: extern void mmu_op (uae_u32, uae_u16); 1.1.1.2 root 232: 1.1.1.3 ! root 233: extern void fpp_opp (uae_u32, uae_u16); ! 234: extern void fdbcc_opp (uae_u32, uae_u16); ! 235: extern void fscc_opp (uae_u32, uae_u16); ! 236: extern void ftrapcc_opp (uae_u32,uaecptr); ! 237: extern void fbcc_opp (uae_u32, uaecptr, uae_u32); ! 238: extern void fsave_opp (uae_u32); ! 239: extern void frestore_opp (uae_u32); ! 240: ! 241: /* Opcode of faulting instruction */ ! 242: extern uae_u16 last_op_for_exception_3; ! 243: /* PC at fault time */ ! 244: extern uaecptr last_addr_for_exception_3; ! 245: /* Address that generated the exception */ ! 246: extern uaecptr last_fault_for_exception_3; 1.1 root 247: 1.1.1.2 root 248: #define CPU_OP_NAME(a) op ## a 249: 1.1.1.3 ! root 250: /* 68020 + 68881 */ ! 251: extern struct cputbl op_smalltbl_0[]; ! 252: /* 68020 */ ! 253: extern struct cputbl op_smalltbl_1[]; ! 254: /* 68010 */ ! 255: extern struct cputbl op_smalltbl_2[]; ! 256: /* 68000 */ ! 257: extern struct cputbl op_smalltbl_3[]; ! 258: /* 68000 slow but compatible. */ ! 259: extern struct cputbl op_smalltbl_4[]; ! 260: ! 261: extern cpuop_func *cpufunctbl[65536] ASM_SYM_FOR_FUNC ("cpufunctbl"); 1.1.1.2 root 262:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.