|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
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:
22: typedef void cpuop_func(ULONG) REGPARAM;
23:
24: struct cputbl {
25: cpuop_func *handler;
26: int specific;
27: UWORD opcode;
28: };
29:
30: extern struct cputbl smallcputbl[];
31:
32: extern cpuop_func *cpufunctbl[65536];
33: extern void op_illg(ULONG) REGPARAM;
34:
35: typedef char flagtype;
36:
37: /* Arrrghh.. */
38:
39: #if defined(USE_COMPILER) && !defined(USE_POINTER)
40: #define USE_POINTER
41: #undef NEED_TO_DEBUG_BADLY
42: #endif
43: #if defined(NEED_TO_DEBUG_BADLY) && !defined(USE_POINTER)
44: #define USE_POINTER
45: #endif
46:
47: struct flag_struct {
48: unsigned int c:1; /* first byte */
49: int :5;
50: unsigned int z:1;
51: unsigned int n:1;
52: int :3;
53: unsigned int v:1; /* second byte */
54: int :4;
55: unsigned int x:1; /* third & fourth */
56: int :15;
57: };
58:
59: extern struct regstruct
60: {
61: ULONG d[8];
62: CPTR a[8],usp,isp,msp;
63: UWORD sr;
64: flagtype t1;
65: flagtype t0;
66: flagtype s;
67: flagtype m;
68: flagtype x;
69: flagtype stopped;
70: int intmask;
71: ULONG pc;
72: #ifdef USE_POINTER
73: UBYTE *pc_p;
74: UBYTE *pc_oldp;
75: #endif
76:
77: ULONG vbr,sfc,dfc;
78:
79: double fp[8];
80: ULONG fpcr,fpsr,fpiar;
81: ULONG spcflags;
82: } regs, lastint_regs;
83:
84: #ifdef INTEL_FLAG_OPT
85: extern struct flag_struct regflags __asm__ ("regflags");
86: #else
87: extern struct flag_struct regflags;
88: #endif
89:
90: #define ZFLG (regflags.z)
91: #define NFLG (regflags.n)
92: #define CFLG (regflags.c)
93: #define VFLG (regflags.v)
94: #define XFLG (regflags.x)
95:
96: #ifdef USE_POINTER
97: static __inline__ UWORD nextiword(void)
98: {
99: UWORD r = (*(regs.pc_p) << 8) | (*(regs.pc_p + 1) << 0);
100: regs.pc_p += 2;
101: return r;
102: }
103:
104: static __inline__ ULONG nextilong(void)
105: {
106: ULONG r = (*regs.pc_p << 24) | (*(regs.pc_p + 1) << 16) | (*(regs.pc_p + 2) << 8) | (*(regs.pc_p + 3) << 0);
107: regs.pc_p += 4;
108: return r;
109: }
110: #else
111:
112: static __inline__ UWORD nextiword(void)
113: {
114: UWORD r = get_aword(regs.pc);
115: regs.pc += 2;
116: return r;
117: }
118:
119: static __inline__ ULONG nextilong(void)
120: {
121: ULONG r = get_along(regs.pc);
122: regs.pc += 4;
123: return r;
124: }
125:
126: #endif
127:
128: #ifdef USE_POINTER
129:
130: #if !defined(NEED_TO_DEBUG_BADLY) && !defined(USE_COMPILER)
131: static __inline__ void m68k_setpc(CPTR newpc)
132: {
133: regs.pc = newpc;
134: regs.pc_p = regs.pc_oldp = get_real_address(newpc);
135: }
136: #else
137: extern void m68k_setpc(CPTR newpc);
138: #endif
139:
140: static __inline__ CPTR m68k_getpc(void)
141: {
142: return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp);
143: }
144:
145: #else
146:
147: static __inline__ void m68k_setpc(CPTR newpc)
148: {
149: regs.pc = newpc;
150: }
151:
152: static __inline__ CPTR m68k_getpc(void)
153: {
154: return regs.pc;
155: }
156: #endif
157:
158: #ifdef USE_COMPILER
159: extern void m68k_setpc_fast(CPTR newpc);
160: extern void m68k_setpc_bcc(CPTR newpc);
161: extern void m68k_setpc_rte(CPTR newpc);
162: #else
163: #define m68k_setpc_fast m68k_setpc
164: #define m68k_setpc_bcc m68k_setpc
165: #define m68k_setpc_rte m68k_setpc
166: #endif
167:
168: static __inline__ void m68k_setstopped(int stop)
169: {
170: regs.stopped = stop;
171: if (stop)
172: regs.spcflags |= SPCFLAG_STOP;
173: }
174:
175: static __inline__ int cctrue(const int cc)
176: {
177: switch(cc){
178: case 0: return 1; /* T */
179: case 1: return 0; /* F */
180: case 2: return !CFLG && !ZFLG; /* HI */
181: case 3: return CFLG || ZFLG; /* LS */
182: case 4: return !CFLG; /* CC */
183: case 5: return CFLG; /* CS */
184: case 6: return !ZFLG; /* NE */
185: case 7: return ZFLG; /* EQ */
186: case 8: return !VFLG; /* VC */
187: case 9: return VFLG; /* VS */
188: case 10:return !NFLG; /* PL */
189: case 11:return NFLG; /* MI */
190: case 12:return NFLG == VFLG; /* GE */
191: case 13:return NFLG != VFLG; /* LT */
192: case 14:return !ZFLG && (NFLG == VFLG); /* GT */
193: case 15:return ZFLG || (NFLG != VFLG); /* LE */
194: }
195: abort();
196: return 0;
197: }
198:
199: #if CPU_LEVEL > 1
200: static __inline__ ULONG get_disp_ea (ULONG base)
201: {
202: UWORD dp = nextiword();
203: int reg = (dp >> 12) & 7;
204: LONG regd = dp & 0x8000 ? regs.a[reg] : regs.d[reg];
205: if ((dp & 0x800) == 0)
206: regd = (LONG)(WORD)regd;
207: regd <<= (dp >> 9) & 3;
208: if (dp & 0x100) {
209: LONG outer = 0;
210: if (dp & 0x80) base = 0;
211: if (dp & 0x40) regd = 0;
212:
213: if ((dp & 0x30) == 0x20) base += (LONG)(WORD)nextiword();
214: if ((dp & 0x30) == 0x30) base += nextilong();
215:
216: if ((dp & 0x3) == 0x2) outer = (LONG)(WORD)nextiword();
217: if ((dp & 0x3) == 0x3) outer = nextilong();
218:
219: if ((dp & 0x4) == 0) base += regd;
220: if (dp & 0x3) base = get_long (base);
221: if (dp & 0x4) base += regd;
222:
223: return base + outer;
224: } else {
225: return base + (LONG)((BYTE)dp) + regd;
226: }
227: }
228: #else
229: static __inline__ ULONG get_disp_ea (ULONG base)
230: {
231: UWORD dp = nextiword();
232: int reg = (dp >> 12) & 7;
233: LONG regd = dp & 0x8000 ? regs.a[reg] : regs.d[reg];
234: if ((dp & 0x800) == 0)
235: regd = (LONG)(WORD)regd;
236: return base + (BYTE)(dp) + regd;
237: }
238: #endif
239:
240: extern void MakeSR(void);
241: extern void MakeFromSR(void);
242: extern void Exception(int, CPTR);
243: extern void dump_counts(void);
244: extern void m68k_move2c(int, ULONG *);
245: extern void m68k_movec2(int, ULONG *);
246: extern void m68k_divl (ULONG, ULONG, UWORD, CPTR);
247: extern void m68k_mull (ULONG, ULONG, UWORD);
248: extern void init_m68k (void);
249: extern void m68k_run(void);
250: extern void m68k_go(int);
251: extern void m68k_run_2(void);
252: extern void m68k_dumpstate(CPTR *);
253: extern void m68k_disasm(CPTR,CPTR *,int);
254: extern void m68k_reset(void);
255: extern void mmu_op (ULONG, UWORD);
256: extern void fpp_opp (ULONG, UWORD);
257: extern void fdbcc_opp (ULONG, UWORD);
258: extern void fscc_opp (ULONG, UWORD);
259: extern void ftrapcc_opp (ULONG,CPTR);
260: extern void fbcc_opp (ULONG, CPTR, ULONG);
261: extern void fsave_opp (ULONG);
262: extern void frestore_opp (ULONG);
263:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.