ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/newcpu.h
Revision: 1.9
Committed: 2002-09-13T12:50:56Z (21 years, 9 months ago) by gbeauche
Content type: text/plain
Branch: MAIN
Changes since 1.8: +0 -20 lines
Log Message:
Updates for new FPU core architecture

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * UAE - The Un*x Amiga Emulator
3     *
4     * MC68000 emulation
5     *
6     * Copyright 1995 Bernd Schmidt
7     */
8    
9 gbeauche 1.4 #ifndef NEWCPU_H
10     #define NEWCPU_H
11    
12 gbeauche 1.8 #include "m68k.h"
13     #include "readcpu.h"
14     #include "spcflags.h"
15    
16 cebix 1.1 extern int areg_byteinc[];
17     extern int imm8_table[];
18    
19     extern int movem_index1[256];
20     extern int movem_index2[256];
21     extern int movem_next[256];
22    
23     extern int broken_in;
24    
25 gbeauche 1.8 /* Control flow information */
26     #define CFLOW_NORMAL 0
27     #define CFLOW_BRANCH 1
28     #define CFLOW_JUMP 2
29     #define CFLOW_TRAP CFLOW_JUMP
30     #define CFLOW_RETURN 3
31     #define CFLOW_SPCFLAGS 32 /* some spcflags are set */
32     #define CFLOW_EXEC_RETURN 64 /* must exit from the execution loop */
33    
34     #define cpuop_rettype void
35     #define cpuop_return(v) do { (v); return; } while (0)
36    
37     #ifdef X86_ASSEMBLY
38     /* This hack seems to force all register saves (pushl %reg) to be moved to the
39     begining of the function, thus making it possible to cpuopti to remove them
40     since m68k_run_1 will save those registers before calling the instruction
41     handler */
42     # define cpuop_tag(tag) __asm__ __volatile__ ( "#cpuop_" tag )
43     #else
44     # define cpuop_tag(tag) ;
45     #endif
46    
47     #define cpuop_begin() do { cpuop_tag("begin"); } while (0)
48     #define cpuop_end(cflow) do { cpuop_tag("end"); cpuop_return(cflow); } while (0)
49 cebix 1.1
50 gbeauche 1.8 typedef cpuop_rettype REGPARAM2 cpuop_func (uae_u32) REGPARAM;
51    
52 cebix 1.1 struct cputbl {
53     cpuop_func *handler;
54 gbeauche 1.8 uae_u16 specific;
55 cebix 1.1 uae_u16 opcode;
56     };
57    
58 gbeauche 1.8 extern cpuop_rettype REGPARAM2 op_illg (uae_u32) REGPARAM;
59 cebix 1.1
60     typedef char flagtype;
61    
62 gbeauche 1.8 struct regstruct {
63     uae_u32 regs[16];
64 cebix 1.1
65 gbeauche 1.8 uae_u32 pc;
66     uae_u8 * pc_p;
67     uae_u8 * pc_oldp;
68    
69     spcflags_t spcflags;
70     int intmask;
71    
72     uae_u32 vbr, sfc, dfc;
73     uaecptr usp, isp, msp;
74     uae_u16 sr;
75     flagtype t1;
76     flagtype t0;
77     flagtype s;
78     flagtype m;
79     flagtype x;
80     flagtype stopped;
81 cebix 1.1
82 gbeauche 1.8 #if USE_PREFETCH_BUFFER
83 cebix 1.1 /* Fellow sources say this is 4 longwords. That's impossible. It needs
84     * to be at least a longword. The HRM has some cryptic comment about two
85     * instructions being on the same longword boundary.
86     * The way this is implemented now seems like a good compromise.
87     */
88     uae_u32 prefetch;
89 gbeauche 1.8 #endif
90     };
91    
92     extern regstruct regs, lastint_regs;
93 cebix 1.1
94     #define m68k_dreg(r,num) ((r).regs[(num)])
95     #define m68k_areg(r,num) (((r).regs + 8)[(num)])
96    
97     #define get_ibyte(o) do_get_mem_byte((uae_u8 *)(regs.pc_p + (o) + 1))
98     #define get_iword(o) do_get_mem_word((uae_u16 *)(regs.pc_p + (o)))
99     #define get_ilong(o) do_get_mem_long((uae_u32 *)(regs.pc_p + (o)))
100    
101     #ifdef HAVE_GET_WORD_UNSWAPPED
102     #define GET_OPCODE (do_get_mem_word_unswapped (regs.pc_p))
103     #else
104     #define GET_OPCODE (get_iword (0))
105     #endif
106    
107 gbeauche 1.8 #if USE_PREFETCH_BUFFER
108 cebix 1.1 static __inline__ uae_u32 get_ibyte_prefetch (uae_s32 o)
109     {
110     if (o > 3 || o < 0)
111     return do_get_mem_byte((uae_u8 *)(regs.pc_p + o + 1));
112    
113     return do_get_mem_byte((uae_u8 *)(((uae_u8 *)&regs.prefetch) + o + 1));
114     }
115     static __inline__ uae_u32 get_iword_prefetch (uae_s32 o)
116     {
117     if (o > 3 || o < 0)
118     return do_get_mem_word((uae_u16 *)(regs.pc_p + o));
119    
120     return do_get_mem_word((uae_u16 *)(((uae_u8 *)&regs.prefetch) + o));
121     }
122     static __inline__ uae_u32 get_ilong_prefetch (uae_s32 o)
123     {
124     if (o > 3 || o < 0)
125     return do_get_mem_long((uae_u32 *)(regs.pc_p + o));
126     if (o == 0)
127     return do_get_mem_long(&regs.prefetch);
128     return (do_get_mem_word (((uae_u16 *)&regs.prefetch) + 1) << 16) | do_get_mem_word ((uae_u16 *)(regs.pc_p + 4));
129     }
130 gbeauche 1.8 #endif
131 cebix 1.1
132     #define m68k_incpc(o) (regs.pc_p += (o))
133    
134     static __inline__ void fill_prefetch_0 (void)
135     {
136 gbeauche 1.4 #if USE_PREFETCH_BUFFER
137 cebix 1.1 uae_u32 r;
138     #ifdef UNALIGNED_PROFITABLE
139     r = *(uae_u32 *)regs.pc_p;
140     regs.prefetch = r;
141     #else
142     r = do_get_mem_long ((uae_u32 *)regs.pc_p);
143     do_put_mem_long (&regs.prefetch, r);
144     #endif
145 gbeauche 1.4 #endif
146 cebix 1.1 }
147    
148     #if 0
149     static __inline__ void fill_prefetch_2 (void)
150     {
151     uae_u32 r = do_get_mem_long (&regs.prefetch) << 16;
152     uae_u32 r2 = do_get_mem_word (((uae_u16 *)regs.pc_p) + 1);
153     r |= r2;
154     do_put_mem_long (&regs.prefetch, r);
155     }
156     #else
157     #define fill_prefetch_2 fill_prefetch_0
158     #endif
159    
160     /* These are only used by the 68020/68881 code, and therefore don't
161     * need to handle prefetch. */
162     static __inline__ uae_u32 next_ibyte (void)
163     {
164     uae_u32 r = get_ibyte (0);
165     m68k_incpc (2);
166     return r;
167     }
168    
169     static __inline__ uae_u32 next_iword (void)
170     {
171     uae_u32 r = get_iword (0);
172     m68k_incpc (2);
173     return r;
174     }
175    
176     static __inline__ uae_u32 next_ilong (void)
177     {
178     uae_u32 r = get_ilong (0);
179     m68k_incpc (4);
180     return r;
181     }
182    
183     static __inline__ void m68k_setpc (uaecptr newpc)
184     {
185 gbeauche 1.4 #if REAL_ADDRESSING || DIRECT_ADDRESSING
186     regs.pc_p = get_real_address(newpc);
187     #else
188 cebix 1.1 regs.pc_p = regs.pc_oldp = get_real_address(newpc);
189     regs.pc = newpc;
190 gbeauche 1.4 #endif
191 cebix 1.1 }
192    
193     static __inline__ uaecptr m68k_getpc (void)
194     {
195 gbeauche 1.4 #if REAL_ADDRESSING || DIRECT_ADDRESSING
196     return get_virtual_address(regs.pc_p);
197     #else
198 cebix 1.1 return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp);
199 gbeauche 1.4 #endif
200 cebix 1.1 }
201    
202     #define m68k_setpc_fast m68k_setpc
203     #define m68k_setpc_bcc m68k_setpc
204     #define m68k_setpc_rte m68k_setpc
205    
206 gbeauche 1.5 static __inline__ void m68k_do_rts(void)
207     {
208     m68k_setpc(get_long(m68k_areg(regs, 7)));
209     m68k_areg(regs, 7) += 4;
210     }
211    
212     static __inline__ void m68k_do_bsr(uaecptr oldpc, uae_s32 offset)
213     {
214     m68k_areg(regs, 7) -= 4;
215     put_long(m68k_areg(regs, 7), oldpc);
216     m68k_incpc(offset);
217     }
218    
219     static __inline__ void m68k_do_jsr(uaecptr oldpc, uaecptr dest)
220     {
221     m68k_areg(regs, 7) -= 4;
222     put_long(m68k_areg(regs, 7), oldpc);
223     m68k_setpc(dest);
224     }
225    
226 cebix 1.1 static __inline__ void m68k_setstopped (int stop)
227     {
228     regs.stopped = stop;
229 gbeauche 1.7 /* A traced STOP instruction drops through immediately without
230     actually stopping. */
231     if (stop && (regs.spcflags & SPCFLAG_DOTRACE) == 0)
232 gbeauche 1.8 SPCFLAGS_SET( SPCFLAG_STOP );
233 cebix 1.1 }
234    
235     extern uae_u32 get_disp_ea_020 (uae_u32 base, uae_u32 dp);
236     extern uae_u32 get_disp_ea_000 (uae_u32 base, uae_u32 dp);
237    
238     extern uae_s32 ShowEA (int reg, amodes mode, wordsizes size, char *buf);
239    
240     extern void MakeSR (void);
241     extern void MakeFromSR (void);
242     extern void Exception (int, uaecptr);
243     extern void dump_counts (void);
244 gbeauche 1.6 extern int m68k_move2c (int, uae_u32 *);
245     extern int m68k_movec2 (int, uae_u32 *);
246 cebix 1.1 extern void m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr);
247     extern void m68k_mull (uae_u32, uae_u32, uae_u16);
248 gbeauche 1.8 extern void m68k_emulop (uae_u32);
249     extern void m68k_emulop_return (void);
250 cebix 1.1 extern void init_m68k (void);
251 gbeauche 1.3 extern void exit_m68k (void);
252 cebix 1.1 extern void m68k_dumpstate (uaecptr *);
253     extern void m68k_disasm (uaecptr, uaecptr *, int);
254     extern void m68k_reset (void);
255     extern void m68k_enter_debugger(void);
256 gbeauche 1.8 extern int m68k_do_specialties(void);
257 cebix 1.1
258     extern void mmu_op (uae_u32, uae_u16);
259    
260     /* Opcode of faulting instruction */
261     extern uae_u16 last_op_for_exception_3;
262     /* PC at fault time */
263     extern uaecptr last_addr_for_exception_3;
264     /* Address that generated the exception */
265     extern uaecptr last_fault_for_exception_3;
266    
267     #define CPU_OP_NAME(a) op ## a
268    
269     /* 68020 + 68881 */
270 gbeauche 1.8 extern struct cputbl op_smalltbl_0_ff[];
271 cebix 1.1 /* 68020 */
272 gbeauche 1.8 extern struct cputbl op_smalltbl_1_ff[];
273 cebix 1.1 /* 68010 */
274 gbeauche 1.8 extern struct cputbl op_smalltbl_2_ff[];
275 cebix 1.1 /* 68000 */
276 gbeauche 1.8 extern struct cputbl op_smalltbl_3_ff[];
277 cebix 1.1 /* 68000 slow but compatible. */
278 gbeauche 1.8 extern struct cputbl op_smalltbl_4_ff[];
279 cebix 1.1
280 gbeauche 1.8 extern void m68k_do_execute(void);
281     extern void m68k_execute(void);
282    
283 gbeauche 1.4 #endif /* NEWCPU_H */