|
|
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:
1.1.1.7 root 21: /* Special flags */
1.1 root 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
1.1.1.7 root 30: #define SPCFLAG_MFP 0x200
1.1.1.6 root 31: #define SPCFLAG_EXEC 0x400
32: #define SPCFLAG_MODE_CHANGE 0x800
1.1 root 33:
1.1.1.7 root 34:
1.1 root 35: #ifndef SET_CFLG
36:
37: #define SET_CFLG(x) (CFLG = (x))
38: #define SET_NFLG(x) (NFLG = (x))
39: #define SET_VFLG(x) (VFLG = (x))
40: #define SET_ZFLG(x) (ZFLG = (x))
41: #define SET_XFLG(x) (XFLG = (x))
42:
43: #define GET_CFLG CFLG
44: #define GET_NFLG NFLG
45: #define GET_VFLG VFLG
46: #define GET_ZFLG ZFLG
47: #define GET_XFLG XFLG
48:
49: #define CLEAR_CZNV do { \
50: SET_CFLG (0); \
51: SET_ZFLG (0); \
52: SET_NFLG (0); \
53: SET_VFLG (0); \
54: } while (0)
55:
56: #define COPY_CARRY (SET_XFLG (GET_CFLG))
57: #endif
58:
59: extern int areg_byteinc[];
60: extern int imm8_table[];
61:
62: extern int movem_index1[256];
63: extern int movem_index2[256];
64: extern int movem_next[256];
65:
66: extern int fpp_movem_index1[256];
67: extern int fpp_movem_index2[256];
68: extern int fpp_movem_next[256];
69:
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.1.8 ! root 155: #define get_ibyte(o) do_get_mem_byte(regs.pc_p + (o) + 1)
! 156: #define get_iword(o) do_get_mem_word(regs.pc_p + (o))
! 157: #define get_ilong(o) do_get_mem_long(regs.pc_p + (o))
1.1 root 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
1.1.1.8 ! root 169: r = do_get_mem_long (ptr);
1.1.1.5 root 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: }
1.1.1.8 ! root 202: v = do_get_mem_word (((uae_u8 *)®s.prefetch) + offs);
1.1.1.5 root 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:
1.1 root 314: /* Opcode of faulting instruction */
315: extern uae_u16 last_op_for_exception_3;
316: /* PC at fault time */
317: extern uaecptr last_addr_for_exception_3;
318: /* Address that generated the exception */
319: extern uaecptr last_fault_for_exception_3;
320:
321: #define CPU_OP_NAME(a) op ## a
322:
323: /* 68040 */
324: extern struct cputbl op_smalltbl_0_ff[];
325: /* 68020 + 68881 */
326: extern struct cputbl op_smalltbl_1_ff[];
327: /* 68020 */
328: extern struct cputbl op_smalltbl_2_ff[];
329: /* 68010 */
330: extern struct cputbl op_smalltbl_3_ff[];
331: /* 68000 */
332: extern struct cputbl op_smalltbl_4_ff[];
333: /* 68000 slow but compatible. */
334: extern struct cputbl op_smalltbl_5_ff[];
335:
1.1.1.2 root 336: extern cpuop_func *cpufunctbl[65536];
1.1 root 337:
1.1.1.7 root 338: extern uae_u32 reg_caar, reg_cacr;
339:
1.1.1.4 root 340: #endif /* UAE_NEWCPU_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.