|
|
1.1.1.3 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * MC68000 emulation
5: *
6: * Copyright 1995 Bernd Schmidt
7: */
8:
9: #ifndef NEWCPU_H
10: #define NEWCPU_H
11:
12: #include "readcpu.h"
13: //#include "machdep/m68k.h"
14: #include "m68k.h"
15: #include "compat.h"
16: #include "maccess.h"
17: #include "events.h"
18: #include "memory.h"
19: #include "custom.h"
20: #include "falcon_cycle030.h"
21:
22: /* Possible exceptions sources for M68000_Exception() and Exception() */
23: #define M68000_EXC_SRC_CPU 1 /* Direct CPU exception */
24: #define M68000_EXC_SRC_AUTOVEC 2 /* Auto-vector exception (e.g. VBL) */
25: #define M68000_EXC_SRC_INT_MFP 3 /* MFP interrupt exception */
26: #define M68000_EXC_SRC_INT_DSP 4 /* DSP interrupt exception */
27:
28:
29: /* Special flags */
30: #define SPCFLAG_DEBUGGER 1
31: #define SPCFLAG_STOP 2
32: #define SPCFLAG_BUSERROR 4
33: #define SPCFLAG_INT 8
34: #define SPCFLAG_BRK 0x10
35: #define SPCFLAG_EXTRA_CYCLES 0x20
36: #define SPCFLAG_TRACE 0x40
37: #define SPCFLAG_DOTRACE 0x80
38: #define SPCFLAG_DOINT 0x100
39: #define SPCFLAG_MFP 0x200
40: #define SPCFLAG_EXEC 0x400
41: #define SPCFLAG_MODE_CHANGE 0x800
1.1.1.4 ! root 42: #define SPCFLAG_DSP 0x1000
1.1.1.3 root 43:
44:
45: #ifndef SET_CFLG
46:
47: #define SET_CFLG(x) (CFLG() = (x))
48: #define SET_NFLG(x) (NFLG() = (x))
49: #define SET_VFLG(x) (VFLG() = (x))
50: #define SET_ZFLG(x) (ZFLG() = (x))
51: #define SET_XFLG(x) (XFLG() = (x))
52:
53: #define GET_CFLG() CFLG()
54: #define GET_NFLG() NFLG()
55: #define GET_VFLG() VFLG()
56: #define GET_ZFLG() ZFLG()
57: #define GET_XFLG() XFLG()
58:
59: #define CLEAR_CZNV() do { \
60: SET_CFLG (0); \
61: SET_ZFLG (0); \
62: SET_NFLG (0); \
63: SET_VFLG (0); \
64: } while (0)
65:
66: #define COPY_CARRY() (SET_XFLG (GET_CFLG ()))
67: #endif
68:
69: extern const int areg_byteinc[];
70: extern const int imm8_table[];
71:
72: extern int movem_index1[256];
73: extern int movem_index2[256];
74: extern int movem_next[256];
75:
76: #ifdef FPUEMU
77: extern int fpp_movem_index1[256];
78: extern int fpp_movem_index2[256];
79: extern int fpp_movem_next[256];
80: #endif
81:
82: extern int OpcodeFamily;
83:
84: typedef struct falcon_cycles_t falcon_cycles;
85:
86: typedef unsigned long REGPARAM3 cpuop_func (uae_u32) REGPARAM;
87: typedef void REGPARAM3 cpuop_func_ce (uae_u32) REGPARAM;
88:
89: struct cputbl {
90: cpuop_func *handler;
91: uae_u16 opcode;
92: };
93:
94: #ifdef JIT
95: typedef unsigned long REGPARAM3 compop_func (uae_u32) REGPARAM;
96:
97: struct comptbl {
98: compop_func *handler;
99: uae_u32 opcode;
100: int specific;
101: };
102: #endif
103:
104: extern unsigned long REGPARAM3 op_illg (uae_u32) REGPARAM;
105:
106: typedef uae_u8 flagtype;
107:
108: #ifdef FPUEMU
109: /* You can set this to long double to be more accurate. However, the
110: resulting alignment issues will cost a lot of performance in some
111: apps */
112: #define USE_LONG_DOUBLE 0
113:
114: #if USE_LONG_DOUBLE
115: typedef long double fptype;
116: #define LDPTR tbyte ptr
117: #else
118: typedef double fptype;
119: #define LDPTR qword ptr
120: #endif
121: #endif
122:
123: #define CPU_PIPELINE_MAX 2
124: #define CPU000_MEM_CYCLE 4
125: #define CPU000_CLOCK_MULT 2
126: #define CPU020_MEM_CYCLE 3
127: #define CPU020_CLOCK_MULT 4
128:
129: #define CACHELINES020 64
130: struct cache020
131: {
132: uae_u32 data;
133: uae_u32 tag;
134: bool valid;
135: };
136:
137: #define CACHELINES030 16
138: struct cache030
139: {
140: uae_u32 data[4];
141: bool valid[4];
142: uae_u32 tag;
143: };
144:
145: #define CACHESETS040 64
146: #define CACHELINES040 4
147: struct cache040
148: {
149: uae_u32 data[CACHELINES040][4];
150: bool valid[CACHELINES040];
151: uae_u32 tag[CACHELINES040];
152: };
153:
1.1.1.4 ! root 154: extern uae_u64 srp_030, crp_030;
! 155: extern uae_u32 tt0_030, tt1_030, tc_030;
! 156: extern uae_u16 mmusr_030;
! 157:
! 158: struct mmufixup
! 159: {
! 160: int reg;
! 161: uae_u32 value;
! 162: };
! 163: extern struct mmufixup mmufixup[2];
1.1.1.3 root 164:
165: struct regstruct
166: {
167: uae_u32 regs[16];
168:
169: uae_u32 pc;
170: uae_u8 *pc_p;
171: uae_u8 *pc_oldp;
172:
173: uae_u16 irc, ir;
174: uae_u32 spcflags;
175:
176: uaecptr usp, isp, msp;
177: uae_u16 sr;
178: flagtype t1;
179: flagtype t0;
180: flagtype s;
181: flagtype m;
182: flagtype x;
183: flagtype stopped;
184: int intmask;
185: int ipl, ipl_pin;
186:
187: uae_u32 vbr, sfc, dfc;
188:
189: #ifdef FPUEMU
190: fptype fp[8];
191: fptype fp_result;
192:
193: uae_u32 fpcr, fpsr, fpiar;
194: uae_u32 fpsr_highbyte;
195: #endif
196: #ifndef CPUEMU_68000_ONLY
197: uae_u32 cacr, caar;
198: uae_u32 itt0, itt1, dtt0, dtt1;
199: uae_u32 tcr, mmusr, urp, srp, buscr;
200: uae_u32 mmu_fslw, mmu_fault_addr;
201: uae_u16 mmu_ssw;
202: uae_u32 wb3_data;
203: uae_u16 wb3_status;
204: int mmu_enabled;
205: int mmu_pagesize_8k;
206: uae_u32 fault_pc;
207: #endif
208:
209: uae_u32 pcr;
210: uae_u32 address_space_mask;
211:
212: uae_u8 panic;
213: uae_u32 panic_pc, panic_addr;
214:
215: uae_u32 prefetch020data[CPU_PIPELINE_MAX];
216: uae_u32 prefetch020addr[CPU_PIPELINE_MAX];
217: int ce020memcycles;
218: struct falcon_cycles_t ce030_instr_cycles;
219: int ce030_instr_addcycles;
220: };
221:
222: extern struct regstruct regs;
223:
224: STATIC_INLINE uae_u32 munge24 (uae_u32 x)
225: {
226: return x & regs.address_space_mask;
227: }
228:
229: extern int mmu_enabled, mmu_triggered;
230: extern int cpu_cycles;
231: extern int cpucycleunit;
232: STATIC_INLINE void set_special (uae_u32 x)
233: {
234: regs.spcflags |= x;
235: cycles_do_special ();
236: }
237:
238: STATIC_INLINE void unset_special (uae_u32 x)
239: {
240: regs.spcflags &= ~x;
241: }
242:
243: #define m68k_dreg(r,num) ((r).regs[(num)])
244: #define m68k_areg(r,num) (((r).regs + 8)[(num)])
245:
246: STATIC_INLINE void m68k_setpc (uaecptr newpc)
247: {
248: regs.pc_p = regs.pc_oldp = get_real_address (newpc);
249: regs.fault_pc = regs.pc = newpc;
250: }
251:
252: STATIC_INLINE uaecptr m68k_getpc (void)
253: {
254: return (uaecptr)(regs.pc + ((uae_u8*)regs.pc_p - (uae_u8*)regs.pc_oldp));
255: }
256: #define M68K_GETPC m68k_getpc()
257:
258: STATIC_INLINE uaecptr m68k_getpc_p (uae_u8 *p)
259: {
260: return (uaecptr)(regs.pc + ((uae_u8*)p - (uae_u8*)regs.pc_oldp));
261: }
262:
263: STATIC_INLINE void m68k_incpc (int o)
264: {
265: regs.pc_p += o;
266: }
267:
268: STATIC_INLINE void m68k_setpc_mmu (uaecptr newpc)
269: {
270: regs.fault_pc = regs.pc = newpc;
271: regs.pc_p = regs.pc_oldp = 0;
272: }
273: STATIC_INLINE void m68k_setpci (uaecptr newpc)
274: {
275: regs.fault_pc = regs.pc = newpc;
276: }
277: STATIC_INLINE uaecptr m68k_getpci (void)
278: {
279: return regs.pc;
280: }
281: STATIC_INLINE void m68k_incpci (int o)
282: {
283: regs.pc += o;
284: }
285:
286: STATIC_INLINE void m68k_do_rts (void)
287: {
288: uae_u32 newpc = get_long (m68k_areg (regs, 7));
289: m68k_setpc (newpc);
290: m68k_areg (regs, 7) += 4;
291: }
292: STATIC_INLINE void m68k_do_rtsi (void)
293: {
294: m68k_setpci (get_long (m68k_areg (regs, 7)));
295: m68k_areg (regs, 7) += 4;
296: }
297:
298: STATIC_INLINE void m68k_do_bsr (uaecptr oldpc, uae_s32 offset)
299: {
300: m68k_areg (regs, 7) -= 4;
301: put_long (m68k_areg (regs, 7), oldpc);
302: m68k_incpc (offset);
303: }
304: STATIC_INLINE void m68k_do_bsri (uaecptr oldpc, uae_s32 offset)
305: {
306: m68k_areg (regs, 7) -= 4;
307: put_long (m68k_areg (regs, 7), oldpc);
308: m68k_incpci (offset);
309: }
310:
311: STATIC_INLINE uae_u32 get_ibyte (int o)
312: {
313: return do_get_mem_byte((uae_u8 *)((regs).pc_p + (o) + 1));
314: }
315: STATIC_INLINE uae_u32 get_iword (int o)
316: {
317: return do_get_mem_word((uae_u16 *)((regs).pc_p + (o)));
318: }
319: STATIC_INLINE uae_u32 get_ilong (int o)
320: {
321: return do_get_mem_long((uae_u32 *)((regs).pc_p + (o)));
322: }
323:
324: #define get_iwordi(o) get_wordi(o)
325: #define get_ilongi(o) get_longi(o)
326:
327: /* These are only used by the 68020/68881 code, and therefore don't
328: * need to handle prefetch. */
329: STATIC_INLINE uae_u32 next_ibyte (void)
330: {
331: uae_u32 r = get_ibyte (0);
332: m68k_incpc (2);
333: return r;
334: }
335: STATIC_INLINE uae_u32 next_iword (void)
336: {
337: uae_u32 r = get_iword (0);
338: m68k_incpc (2);
339: return r;
340: }
341: STATIC_INLINE uae_u32 next_iwordi (void)
342: {
343: uae_u32 r = get_iwordi (m68k_getpci ());
344: m68k_incpc (2);
345: return r;
346: }
347: STATIC_INLINE uae_u32 next_ilong (void)
348: {
349: uae_u32 r = get_ilong (0);
350: m68k_incpc (4);
351: return r;
352: }
353: STATIC_INLINE uae_u32 next_ilongi (void)
354: {
355: uae_u32 r = get_ilongi (m68k_getpci ());
356: m68k_incpc (4);
357: return r;
358: }
359:
360: extern uae_u32 (*x_get_byte)(uaecptr addr);
361: extern uae_u32 (*x_get_word)(uaecptr addr);
362: extern uae_u32 (*x_get_long)(uaecptr addr);
363: extern void (*x_put_byte)(uaecptr addr, uae_u32 v);
364: extern void (*x_put_word)(uaecptr addr, uae_u32 v);
365: extern void (*x_put_long)(uaecptr addr, uae_u32 v);
366: extern uae_u32 (*x_next_iword)(void);
367: extern uae_u32 (*x_next_ilong)(void);
368:
369: extern uae_u32 REGPARAM3 x_get_disp_ea_020 (uae_u32 base, uae_u32 dp) REGPARAM;
370: extern uae_u32 REGPARAM3 x_get_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width) REGPARAM;
371: extern void REGPARAM3 x_put_bitfield (uae_u32 dst, uae_u32 bdata[2], uae_u32 val, uae_s32 offset, int width) REGPARAM;
372:
373: extern void m68k_setstopped (void);
374: extern void m68k_resumestopped (void);
375:
376: extern uae_u32 REGPARAM3 get_disp_ea_020 (uae_u32 base, uae_u32 dp) REGPARAM;
377: extern uae_u32 REGPARAM3 get_disp_ea_000 (uae_u32 base, uae_u32 dp) REGPARAM;
378: extern uae_u32 REGPARAM3 get_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width) REGPARAM;
379: extern void REGPARAM3 put_bitfield (uae_u32 dst, uae_u32 bdata[2], uae_u32 val, uae_s32 offset, int width) REGPARAM;
380:
381: extern void m68k_disasm_ea (FILE *f, uaecptr addr, uaecptr *nextpc, int cnt, uae_u32 *seaddr, uae_u32 *deaddr);
382: extern void m68k_disasm (FILE *f, uaecptr addr, uaecptr *nextpc, int cnt);
383: extern int get_cpu_model (void);
384:
385: extern void REGPARAM3 MakeSR (void) REGPARAM;
386: extern void REGPARAM3 MakeFromSR (void) REGPARAM;
387: extern void MakeSR (void);
388: extern void MakeFromSR (void);
389: extern void REGPARAM3 Exception (int, uaecptr, int) REGPARAM;
390: extern void NMI (void);
391: extern void NMI_delayed (void);
392: extern void prepare_interrupt (uae_u32);
393: extern void doint (void);
394: extern void dump_counts (void);
395: extern int m68k_move2c (int, uae_u32 *);
396: extern int m68k_movec2 (int, uae_u32 *);
397: extern void m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr);
398: extern void m68k_mull (uae_u32, uae_u32, uae_u16);
399: extern void init_m68k (void);
400: extern void init_m68k_full (void);
401: extern void m68k_go (int);
402: extern void m68k_dumpstate (FILE *, uaecptr *);
403: extern void m68k_disasm (FILE *, uaecptr, uaecptr *, int);
404: extern void sm68k_disasm (TCHAR*, TCHAR*, uaecptr addr, uaecptr *nextpc);
405: extern void m68k_reset (int);
406: extern int getDivu68kCycles (uae_u32 dividend, uae_u16 divisor);
407: extern int getDivs68kCycles (uae_s32 dividend, uae_s16 divisor);
408: extern void m68k_do_rte (void);
409:
410: extern void mmu_op (uae_u32, uae_u32);
411: extern void mmu_op30 (uaecptr, uae_u32, uae_u16, uaecptr);
412:
413: extern void fpuop_arithmetic(uae_u32, uae_u16);
414: extern void fpuop_dbcc(uae_u32, uae_u16);
415: extern void fpuop_scc(uae_u32, uae_u16);
416: extern void fpuop_trapcc(uae_u32, uaecptr, uae_u16);
417: extern void fpuop_bcc(uae_u32, uaecptr, uae_u32);
418: extern void fpuop_save(uae_u32);
419: extern void fpuop_restore(uae_u32);
420: extern uae_u32 fpp_get_fpsr (void);
421: extern void fpu_reset (void);
422: extern void fpux_save (int*);
423: extern void fpux_restore (int*);
424:
425: extern void exception3 (uae_u32 opcode, uaecptr addr, uaecptr fault);
426: extern void exception3i (uae_u32 opcode, uaecptr addr, uaecptr fault);
427: extern void exception2 (uaecptr addr, uaecptr fault);
428: extern void cpureset (void);
429:
430: extern void fill_prefetch_slow (void);
431:
432: #define CPU_OP_NAME(a) op ## a
433:
434: /* 68060 */
435: extern const struct cputbl op_smalltbl_0_ff[];
436: extern const struct cputbl op_smalltbl_20_ff[]; // CE
437: /* 68040 */
438: extern const struct cputbl op_smalltbl_1_ff[];
439: extern const struct cputbl op_smalltbl_21_ff[]; // CE
440: extern const struct cputbl op_smalltbl_31_ff[]; // MMU
441: /* 68030 */
442: extern const struct cputbl op_smalltbl_2_ff[];
443: extern const struct cputbl op_smalltbl_22_ff[]; // CE
1.1.1.4 ! root 444: extern const struct cputbl op_smalltbl_32_ff[]; // MMU
1.1.1.3 root 445: /* 68020 */
446: extern const struct cputbl op_smalltbl_3_ff[];
447: extern const struct cputbl op_smalltbl_23_ff[]; // CE
448: /* 68010 */
449: extern const struct cputbl op_smalltbl_4_ff[];
450: /* 68000 */
451: extern const struct cputbl op_smalltbl_5_ff[];
452: /* 68000 slow but compatible. */
453: extern const struct cputbl op_smalltbl_11_ff[];
454: /* 68000 slow but compatible and cycle-exact. */
455: extern const struct cputbl op_smalltbl_12_ff[];
456:
457: extern cpuop_func *cpufunctbl[65536] ASM_SYM_FOR_FUNC ("cpufunctbl");
458:
459: /* Added for hatari_glue.c */
460: extern void build_cpufunctbl(void);
461:
462: #ifdef JIT
463: extern void flush_icache (uaecptr, int);
464: extern void compemu_reset (void);
465: extern bool check_prefs_changed_comp (void);
466: #else
467: #define flush_icache(uaecptr, int) do {} while (0)
468: #endif
469: extern void flush_dcache (uaecptr, int);
470: extern void flush_mmu (uaecptr, int);
471:
472: extern int movec_illg (int regno);
473: extern uae_u32 val_move2c (int regno);
474: extern void val_move2c2 (int regno, uae_u32 val);
475: struct cpum2c {
476: int regno;
477: const TCHAR *regname;
478: };
479: extern struct cpum2c m2cregs[];
480:
481: /* Family of the latest instruction executed (to check for pairing) */
482: extern int OpcodeFamily; /* see instrmnem in readcpu.h */
483:
484: /* How many cycles to add to the current instruction in case a "misaligned" bus acces is made */
485: /* (used when addressing mode is d8(an,ix)) */
486: extern int BusCyclePenalty;
487:
488: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.