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