Commit | Line | Data |
---|---|---|
cf76e892 JPM |
1 | // |
2 | // Inline functions used by cpuemu.c | |
3 | // | |
4 | // by Bernd Schmidt, Thomas Huth, and James Hammons | |
5 | // | |
6 | // Since inline functions have to be in a header, we have them all defined | |
7 | // here, in one place to make finding them easy. | |
8 | // | |
9 | ||
10 | #ifndef __INLINES_H__ | |
11 | #define __INLINES_H__ | |
12 | ||
13 | #include "cpudefs.h" | |
14 | ||
15 | STATIC_INLINE int cctrue(const int cc) | |
16 | { | |
17 | switch (cc) | |
18 | { | |
19 | case 0: return 1; /* T */ | |
20 | case 1: return 0; /* F */ | |
21 | case 2: return !CFLG && !ZFLG; /* HI */ | |
22 | case 3: return CFLG || ZFLG; /* LS */ | |
23 | case 4: return !CFLG; /* CC */ | |
24 | case 5: return CFLG; /* CS */ | |
25 | case 6: return !ZFLG; /* NE */ | |
26 | case 7: return ZFLG; /* EQ */ | |
27 | case 8: return !VFLG; /* VC */ | |
28 | case 9: return VFLG; /* VS */ | |
29 | case 10: return !NFLG; /* PL */ | |
30 | case 11: return NFLG; /* MI */ | |
31 | case 12: return NFLG == VFLG; /* GE */ | |
32 | case 13: return NFLG != VFLG; /* LT */ | |
33 | case 14: return !ZFLG && (NFLG == VFLG); /* GT */ | |
34 | case 15: return ZFLG || (NFLG != VFLG); /* LE */ | |
35 | } | |
36 | ||
37 | abort(); | |
38 | return 0; | |
39 | } | |
40 | ||
41 | //no #define m68k_incpc(o) (regs.pc_p += (o)) | |
42 | #define m68k_incpc(o) (regs.pc += (o)) | |
43 | ||
44 | STATIC_INLINE void m68k_setpc(uint32_t newpc) | |
45 | { | |
46 | //This is only done here... (get_real_address()) | |
47 | // regs.pc_p = regs.pc_oldp = get_real_address(newpc); | |
48 | regs.pc = newpc; | |
49 | } | |
50 | ||
51 | #define m68k_setpc_rte m68k_setpc | |
52 | ||
53 | STATIC_INLINE uint32_t m68k_getpc(void) | |
54 | { | |
55 | // return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp); | |
56 | return regs.pc; | |
57 | } | |
58 | ||
59 | #if 0 | |
60 | STATIC_INLINE uint32_t m68k_getpc_p(uint8_t * p) | |
61 | { | |
62 | return regs.pc + ((char *)p - (char *)regs.pc_oldp); | |
63 | } | |
64 | #endif | |
65 | ||
66 | STATIC_INLINE void m68k_setstopped(int stop) | |
67 | { | |
68 | regs.stopped = stop; | |
69 | regs.remainingCycles = 0; | |
70 | ||
71 | //But trace instructions are only on >68000 cpus, so this is bogus. | |
72 | #if 0 | |
73 | /* A traced STOP instruction drops through immediately without | |
74 | actually stopping. */ | |
75 | if (stop && (regs.spcflags & SPCFLAG_DOTRACE) == 0) | |
76 | regs.spcflags |= SPCFLAG_STOP; | |
77 | #endif | |
78 | } | |
79 | ||
80 | STATIC_INLINE void m68k_do_rts(void) | |
81 | { | |
82 | m68k_setpc(m68k_read_memory_32(m68k_areg(regs, 7))); | |
83 | m68k_areg(regs, 7) += 4; | |
84 | } | |
85 | ||
86 | STATIC_INLINE void m68k_do_bsr(uint32_t oldpc, int32_t offset) | |
87 | { | |
88 | m68k_areg(regs, 7) -= 4; | |
89 | m68k_write_memory_32(m68k_areg(regs, 7), oldpc); | |
90 | m68k_incpc(offset); | |
91 | } | |
92 | ||
93 | STATIC_INLINE void m68k_do_jsr(uint32_t oldpc, uint32_t dest) | |
94 | { | |
95 | m68k_areg(regs, 7) -= 4; | |
96 | m68k_write_memory_32(m68k_areg(regs, 7), oldpc); | |
97 | m68k_setpc(dest); | |
98 | } | |
99 | ||
100 | #if 0 | |
101 | //These do_get_mem_* functions are only used in newcpu... | |
102 | //What it does is use a pointer to make instruction fetching quicker, | |
103 | //though it probably leads to more problems than it solves. Something to | |
104 | //decide using a profiler... | |
105 | #define get_ibyte(o) do_get_mem_byte(regs.pc_p + (o) + 1) | |
106 | #define get_iword(o) do_get_mem_word(regs.pc_p + (o)) | |
107 | #define get_ilong(o) do_get_mem_long(regs.pc_p + (o)) | |
108 | #else | |
109 | // For now, we'll punt this crap... | |
110 | // (Also, notice that the byte read is at address + 1...) | |
111 | #define get_ibyte(o) m68k_read_memory_8(regs.pc + (o) + 1) | |
112 | #define get_iword(o) m68k_read_memory_16(regs.pc + (o)) | |
113 | #define get_ilong(o) m68k_read_memory_32(regs.pc + (o)) | |
114 | #endif | |
115 | ||
116 | // We don't use this crap, so let's comment out for now... | |
117 | STATIC_INLINE void refill_prefetch(uint32_t currpc, uint32_t offs) | |
118 | { | |
119 | #if 0 | |
120 | uint32_t t = (currpc + offs) & ~1; | |
121 | int32_t pc_p_offs = t - currpc; | |
122 | uint8_t * ptr = regs.pc_p + pc_p_offs; | |
123 | uint32_t r; | |
124 | ||
125 | #ifdef UNALIGNED_PROFITABLE | |
126 | r = *(uint32_t *)ptr; | |
127 | regs.prefetch = r; | |
128 | #else | |
129 | r = do_get_mem_long(ptr); | |
130 | do_put_mem_long(®s.prefetch, r); | |
131 | #endif | |
132 | /* printf ("PC %lx T %lx PCPOFFS %d R %lx\n", currpc, t, pc_p_offs, r); */ | |
133 | regs.prefetch_pc = t; | |
134 | #endif | |
135 | } | |
136 | ||
137 | STATIC_INLINE uint32_t get_ibyte_prefetch(int32_t o) | |
138 | { | |
139 | #if 0 | |
140 | uint32_t currpc = m68k_getpc(); | |
141 | uint32_t addr = currpc + o + 1; | |
142 | uint32_t offs = addr - regs.prefetch_pc; | |
143 | ||
144 | if (offs > 3) | |
145 | { | |
146 | refill_prefetch(currpc, o + 1); | |
147 | offs = addr - regs.prefetch_pc; | |
148 | } | |
149 | ||
150 | uint32_t v = do_get_mem_byte(((uint8_t *)®s.prefetch) + offs); | |
151 | ||
152 | if (offs >= 2) | |
153 | refill_prefetch(currpc, 2); | |
154 | ||
155 | /* printf ("get_ibyte PC %lx ADDR %lx OFFS %lx V %lx\n", currpc, addr, offs, v); */ | |
156 | return v; | |
157 | #else | |
158 | return get_ibyte(o); | |
159 | #endif | |
160 | } | |
161 | ||
162 | STATIC_INLINE uint32_t get_iword_prefetch(int32_t o) | |
163 | { | |
164 | #if 0 | |
165 | uint32_t currpc = m68k_getpc(); | |
166 | uint32_t addr = currpc + o; | |
167 | uint32_t offs = addr - regs.prefetch_pc; | |
168 | ||
169 | if (offs > 3) | |
170 | { | |
171 | refill_prefetch(currpc, o); | |
172 | offs = addr - regs.prefetch_pc; | |
173 | } | |
174 | ||
175 | uint32_t v = do_get_mem_word(((uint8_t *)®s.prefetch) + offs); | |
176 | ||
177 | if (offs >= 2) | |
178 | refill_prefetch(currpc, 2); | |
179 | ||
180 | /* printf ("get_iword PC %lx ADDR %lx OFFS %lx V %lx\n", currpc, addr, offs, v); */ | |
181 | return v; | |
182 | #else | |
183 | return get_iword(o); | |
184 | #endif | |
185 | } | |
186 | ||
187 | STATIC_INLINE uint32_t get_ilong_prefetch(int32_t o) | |
188 | { | |
189 | #if 0 | |
190 | uint32_t v = get_iword_prefetch(o); | |
191 | v <<= 16; | |
192 | v |= get_iword_prefetch(o + 2); | |
193 | return v; | |
194 | #else | |
195 | return get_ilong(o); | |
196 | #endif | |
197 | } | |
198 | ||
199 | STATIC_INLINE void fill_prefetch_0(void) | |
200 | { | |
201 | } | |
202 | ||
203 | #define fill_prefetch_2 fill_prefetch_0 | |
204 | ||
205 | #endif // __INLINES_H__ |