|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * MC68000 emulation
5: *
6: * (c) 1995 Bernd Schmidt
7: *
8: */
9:
10: /* Kludge! */
11: #define INLINE static __inline__
12:
13: extern bool broken_in;
14:
15: typedef void cpuop_func(UWORD) REGPARAM;
16:
17: extern cpuop_func *cpufunctbl[65536];
18: extern void op_illg(UWORD) REGPARAM;
19:
20: typedef char flagtype;
21:
22: extern struct regstruct
23: {
24: ULONG d[8];
25: CPTR a[8],usp;
26: UWORD sr;
27: flagtype t,s,x,n,z,v,c,stopped;
28: int intmask;
29: ULONG pc;
30: UWORD *pc_p;
31: UWORD *pc_oldp;
32: } regs;
33:
34: extern void MC68000_oldstep(UWORD opcode);
35:
36: INLINE UWORD nextiword(void)
37: {
38: UWORD r = *regs.pc_p++;
39: return r;
40: }
41:
42: INLINE ULONG nextilong(void)
43: {
44: ULONG r = *regs.pc_p++;
45: r = (r << 16) + *regs.pc_p++;
46: return r;
47: }
48:
49: INLINE void m68k_setpc(CPTR newpc)
50: {
51: regs.pc = newpc;
52: regs.pc_p = regs.pc_oldp = get_real_address(newpc);
53: }
54:
55: INLINE CPTR m68k_getpc(void)
56: {
57: return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp);
58: }
59:
60: INLINE void m68k_setstopped(int stop)
61: {
62: regs.stopped = stop;
63: if (stop)
64: specialflags |= SPCFLAG_STOP;
65: }
66:
67: INLINE void setflags_add(const ULONG src, const ULONG oldv,
68: const ULONG newv, const ULONG mask)
69: {
70: int n=0, o=0, s=0;
71: switch(mask) {
72: case 0xff:
73: s = (BYTE)src < 0;
74: o = (BYTE)oldv < 0;
75: n = (BYTE)newv < 0;
76: regs.z = (BYTE)newv == 0;
77: break;
78: case 0xffff:
79: s = (WORD)src < 0;
80: o = (WORD)oldv < 0;
81: n = (WORD)newv < 0;
82: regs.z = (WORD)newv == 0;
83: break;
84: case 0xffffffff:
85: s = (LONG)src < 0;
86: o = (LONG)oldv < 0;
87: n = (LONG)newv < 0;
88: regs.z = (LONG)newv == 0;
89: break;
90: }
91: regs.c = regs.x = (s && o) || (!n && (o || s));
92: regs.n = n;
93: regs.v = ((s && o && !n) || (!s && !o && n));
94: }
95:
96: INLINE void setflags_sub(const ULONG src, const ULONG oldv,
97: const ULONG newv, const ULONG mask)
98: {
99: int n=0, o=0, s=0;
100: switch(mask) {
101: case 0xff:
102: s = (BYTE)src < 0;
103: o = (BYTE)oldv < 0;
104: n = (BYTE)newv < 0;
105: regs.z = (BYTE)newv == 0;
106: break;
107: case 0xffff:
108: s = (WORD)src < 0;
109: o = (WORD)oldv < 0;
110: n = (WORD)newv < 0;
111: regs.z = (WORD)newv == 0;
112: break;
113: case 0xffffffff:
114: s = (LONG)src < 0;
115: o = (LONG)oldv < 0;
116: n = (LONG)newv < 0;
117: regs.z = (LONG)newv == 0;
118: break;
119: }
120:
121: regs.z = newv == 0;
122: regs.c = regs.x = (s && !o) || (n && (!o || s));
123: regs.n = n;
124: regs.v = ((!s && o && !n) || (s && !o && n));
125: }
126:
127: INLINE void setflags_addx(const ULONG src, const ULONG oldv,
128: const ULONG newv, const ULONG mask)
129: {
130: int n=0, o=0, s=0;
131: switch(mask) {
132: case 0xff:
133: s = (BYTE)src < 0;
134: o = (BYTE)oldv < 0;
135: n = (BYTE)newv < 0;
136: if ((BYTE)newv != 0) regs.z = 0;
137: break;
138: case 0xffff:
139: s = (WORD)src < 0;
140: o = (WORD)oldv < 0;
141: n = (WORD)newv < 0;
142: if ((WORD)newv != 0) regs.z = 0;
143: break;
144: case 0xffffffff:
145: s = (LONG)src < 0;
146: o = (LONG)oldv < 0;
147: n = (LONG)newv < 0;
148: if ((LONG)newv != 0) regs.z = 0;
149: break;
150: }
151:
152: regs.c = regs.x = (s && o) || (!n && (o || s));
153: regs.n = n;
154: regs.v = ((s && o && !n) || (!s && !o && n));
155: }
156:
157: INLINE void setflags_subx(const ULONG src, const ULONG oldv,
158: const ULONG newv, const ULONG mask)
159: {
160: int n=0, o=0, s=0;
161: switch(mask) {
162: case 0xff:
163: s = (BYTE)src < 0;
164: o = (BYTE)oldv < 0;
165: n = (BYTE)newv < 0;
166: if ((BYTE)newv != 0) regs.z = 0;
167: break;
168: case 0xffff:
169: s = (WORD)src < 0;
170: o = (WORD)oldv < 0;
171: n = (WORD)newv < 0;
172: if ((WORD)newv != 0) regs.z = 0;
173: break;
174: case 0xffffffff:
175: s = (LONG)src < 0;
176: o = (LONG)oldv < 0;
177: n = (LONG)newv < 0;
178: if ((LONG)newv != 0) regs.z = 0;
179: break;
180: }
181:
182: if (newv != 0) regs.z = 0;
183: regs.c = regs.x = (s && !o) || (n && (!o || s));
184: regs.n = n;
185: regs.v = ((!s && o && !n) || (s && !o && n));
186: }
187:
188: INLINE void setflags_cmp(const ULONG src, const ULONG oldv,
189: const ULONG newv, const ULONG mask)
190: {
191: int n=0, o=0, s=0;
192: switch(mask) {
193: case 0xff:
194: s = (BYTE)src < 0;
195: o = (BYTE)oldv < 0;
196: n = (BYTE)newv < 0;
197: regs.z = (BYTE)newv == 0;
198: break;
199: case 0xffff:
200: s = (WORD)src < 0;
201: o = (WORD)oldv < 0;
202: n = (WORD)newv < 0;
203: regs.z = (WORD)newv == 0;
204: break;
205: case 0xffffffff:
206: s = (LONG)src < 0;
207: o = (LONG)oldv < 0;
208: n = (LONG)newv < 0;
209: regs.z = (LONG)newv == 0;
210: break;
211: }
212:
213: regs.z = newv == 0;
214: regs.c = (s && !o) || (n && (!o || s));
215: regs.n = n;
216: regs.v = ((!s && o && !n) || (s && !o && n));
217: }
218:
219: INLINE void setflags_logical(ULONG newv, const ULONG mask)
220: {
221: switch(mask) {
222: case 0xff:
223: regs.z = (BYTE)(newv) == 0;
224: regs.n = (BYTE)(newv) < 0;
225: break;
226: case 0xffff:
227: regs.z = (WORD)(newv) == 0;
228: regs.n = (WORD)(newv) < 0;
229: break;
230: case 0xffffffff:
231: regs.z = (LONG)(newv) == 0;
232: regs.n = (LONG)(newv) < 0;
233: break;
234: }
235: regs.v = regs.c = 0;
236: }
237:
238:
239: static __inline__ bool cctrue(const int cc)
240: {
241: switch(cc){
242: case 0: return true; /* T */
243: case 1: return false; /* F */
244: case 2: return !regs.c && !regs.z; /* HI */
245: case 3: return regs.c || regs.z; /* LS */
246: case 4: return !regs.c; /* CC */
247: case 5: return regs.c; /* CS */
248: case 6: return !regs.z; /* NE */
249: case 7: return regs.z; /* EQ */
250: case 8: return !regs.v; /* VC */
251: case 9: return regs.v; /* VS */
252: case 10:return !regs.n; /* PL */
253: case 11:return regs.n; /* MI */
254: #if 0
255: case 12:return (regs.n && regs.v) || (!regs.n && !regs.v); /* GE */
256: case 13:return (regs.n && !regs.v) || (!regs.n && regs.v); /* LT */
257: case 14:return !regs.z && ((regs.n && regs.v) || (!regs.n && !regs.v)); /* GT */
258: case 15:return regs.z || ((regs.n && !regs.v) || (!regs.n && regs.v)); /* LE */
259: #endif
260: case 12:return regs.n == regs.v; /* GE */
261: case 13:return regs.n != regs.v; /* LT */
262: case 14:return !regs.z && (regs.n == regs.v);/* GT */
263: case 15:return regs.z || (regs.n != regs.v); /* LE */
264: }
265: abort();
266: return 0;
267: }
268:
269: extern void MakeSR(void);
270: extern void MakeFromSR(void);
271: extern void Exception(int);
272:
273: extern void MC68000_init(void);
274: extern void MC68000_step(void);
275: extern void MC68000_run(void);
276: extern void MC68000_skip(CPTR);
277: extern void MC68000_dumpstate(CPTR *);
278: extern void MC68000_disasm(CPTR,CPTR *,int);
279: extern void MC68000_reset(void);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.