|
|
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); \
1.1.1.7 root 30: } while (0)
1.1.1.6 root 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.7 root 100: STATIC_INLINE uae_u32 get_ibyte_prefetch (uae_s32 o)
1.1 root 101: {
1.1.1.3 root 102: if (o > 3 || o < 0)
103: return do_get_mem_byte((uae_u8 *)(regs.pc_p + o + 1));
104:
105: return do_get_mem_byte((uae_u8 *)(((uae_u8 *)®s.prefetch) + o + 1));
1.1.1.2 root 106: }
1.1.1.7 root 107: STATIC_INLINE uae_u32 get_iword_prefetch (uae_s32 o)
1.1.1.3 root 108: {
109: if (o > 3 || o < 0)
110: return do_get_mem_word((uae_u16 *)(regs.pc_p + o));
1.1.1.2 root 111:
1.1.1.3 root 112: return do_get_mem_word((uae_u16 *)(((uae_u8 *)®s.prefetch) + o));
113: }
1.1.1.7 root 114: STATIC_INLINE uae_u32 get_ilong_prefetch (uae_s32 o)
1.1.1.2 root 115: {
1.1.1.3 root 116: if (o > 3 || o < 0)
117: return do_get_mem_long((uae_u32 *)(regs.pc_p + o));
118: if (o == 0)
119: return do_get_mem_long(®s.prefetch);
120: return (do_get_mem_word (((uae_u16 *)®s.prefetch) + 1) << 16) | do_get_mem_word ((uae_u16 *)(regs.pc_p + 4));
1.1 root 121: }
122:
1.1.1.3 root 123: #define m68k_incpc(o) (regs.pc_p += (o))
124:
1.1.1.7 root 125: STATIC_INLINE void fill_prefetch_0 (void)
1.1 root 126: {
1.1.1.3 root 127: uae_u32 r;
128: #ifdef UNALIGNED_PROFITABLE
129: r = *(uae_u32 *)regs.pc_p;
130: regs.prefetch = r;
131: #else
132: r = do_get_mem_long ((uae_u32 *)regs.pc_p);
133: do_put_mem_long (®s.prefetch, r);
134: #endif
135: }
136:
137: #if 0
1.1.1.7 root 138: STATIC_INLINE void fill_prefetch_2 (void)
1.1.1.3 root 139: {
140: uae_u32 r = do_get_mem_long (®s.prefetch) << 16;
141: uae_u32 r2 = do_get_mem_word (((uae_u16 *)regs.pc_p) + 1);
142: r |= r2;
143: do_put_mem_long (®s.prefetch, r);
1.1 root 144: }
145: #else
1.1.1.3 root 146: #define fill_prefetch_2 fill_prefetch_0
147: #endif
1.1 root 148:
1.1.1.3 root 149: /* These are only used by the 68020/68881 code, and therefore don't
150: * need to handle prefetch. */
1.1.1.7 root 151: STATIC_INLINE uae_u32 next_ibyte (void)
1.1 root 152: {
1.1.1.4 root 153: uae_u32 r = get_ibyte (0);
154: m68k_incpc (2);
1.1.1.2 root 155: return r;
156: }
157:
1.1.1.7 root 158: STATIC_INLINE uae_u32 next_iword (void)
1.1.1.2 root 159: {
1.1.1.4 root 160: uae_u32 r = get_iword (0);
161: m68k_incpc (2);
1.1 root 162: return r;
163: }
164:
1.1.1.7 root 165: STATIC_INLINE uae_u32 next_ilong (void)
1.1 root 166: {
1.1.1.4 root 167: uae_u32 r = get_ilong (0);
168: m68k_incpc (4);
1.1 root 169: return r;
170: }
171:
1.1.1.4 root 172: #if !defined USE_COMPILER
1.1.1.7 root 173: STATIC_INLINE void m68k_setpc (uaecptr newpc)
1.1 root 174: {
175: regs.pc_p = regs.pc_oldp = get_real_address(newpc);
1.1.1.2 root 176: regs.pc = newpc;
1.1 root 177: }
178: #else
1.1.1.4 root 179: extern void m68k_setpc (uaecptr newpc);
1.1 root 180: #endif
181:
1.1.1.7 root 182: STATIC_INLINE uaecptr m68k_getpc (void)
1.1 root 183: {
184: return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp);
185: }
186:
1.1.1.7 root 187: STATIC_INLINE uaecptr m68k_getpc_p (uae_u8 *p)
1.1.1.4 root 188: {
189: return regs.pc + ((char *)p - (char *)regs.pc_oldp);
190: }
191:
1.1 root 192: #ifdef USE_COMPILER
1.1.1.4 root 193: extern void m68k_setpc_fast (uaecptr newpc);
194: extern void m68k_setpc_bcc (uaecptr newpc);
195: extern void m68k_setpc_rte (uaecptr newpc);
1.1 root 196: #else
197: #define m68k_setpc_fast m68k_setpc
198: #define m68k_setpc_bcc m68k_setpc
199: #define m68k_setpc_rte m68k_setpc
200: #endif
201:
1.1.1.7 root 202: STATIC_INLINE void m68k_setstopped (int stop)
1.1 root 203: {
204: regs.stopped = stop;
205: if (stop)
206: regs.spcflags |= SPCFLAG_STOP;
207: }
208:
1.1.1.5 root 209: extern uae_u32 get_disp_ea_020 (uae_u32 base, uae_u32 dp);
210: extern uae_u32 get_disp_ea_000 (uae_u32 base, uae_u32 dp);
1.1 root 211:
1.1.1.9 ! root 212: extern uae_s32 ShowEA (FILE *, int reg, amodes mode, wordsizes size, char *buf);
1.1.1.2 root 213:
1.1.1.4 root 214: extern void MakeSR (void);
215: extern void MakeFromSR (void);
216: extern void Exception (int, uaecptr);
217: extern void dump_counts (void);
1.1.1.8 root 218: extern int m68k_move2c (int, uae_u32 *);
219: extern int m68k_movec2 (int, uae_u32 *);
1.1.1.3 root 220: extern void m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr);
221: extern void m68k_mull (uae_u32, uae_u32, uae_u16);
1.1 root 222: extern void init_m68k (void);
1.1.1.4 root 223: extern void m68k_go (int);
1.1.1.9 ! root 224: extern void m68k_dumpstate (FILE *, uaecptr *);
! 225: extern void m68k_disasm (FILE *, uaecptr, uaecptr *, int);
1.1.1.4 root 226: extern void m68k_reset (void);
1.1.1.2 root 227:
1.1.1.3 root 228: extern void mmu_op (uae_u32, uae_u16);
1.1.1.2 root 229:
1.1.1.3 root 230: extern void fpp_opp (uae_u32, uae_u16);
231: extern void fdbcc_opp (uae_u32, uae_u16);
232: extern void fscc_opp (uae_u32, uae_u16);
233: extern void ftrapcc_opp (uae_u32,uaecptr);
234: extern void fbcc_opp (uae_u32, uaecptr, uae_u32);
235: extern void fsave_opp (uae_u32);
236: extern void frestore_opp (uae_u32);
237:
238: /* Opcode of faulting instruction */
239: extern uae_u16 last_op_for_exception_3;
240: /* PC at fault time */
241: extern uaecptr last_addr_for_exception_3;
242: /* Address that generated the exception */
243: extern uaecptr last_fault_for_exception_3;
1.1 root 244:
1.1.1.2 root 245: #define CPU_OP_NAME(a) op ## a
246:
1.1.1.3 root 247: /* 68020 + 68881 */
248: extern struct cputbl op_smalltbl_0[];
249: /* 68020 */
250: extern struct cputbl op_smalltbl_1[];
251: /* 68010 */
252: extern struct cputbl op_smalltbl_2[];
253: /* 68000 */
254: extern struct cputbl op_smalltbl_3[];
255: /* 68000 slow but compatible. */
256: extern struct cputbl op_smalltbl_4[];
257:
258: extern cpuop_func *cpufunctbl[65536] ASM_SYM_FOR_FUNC ("cpufunctbl");
1.1.1.2 root 259:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.