PCem

view src/x86_ops_jump.h @ 142:bd46c39a78e8

Implemented selector limits on some instructions - fixes LBA2. GPFs in real mode now work. Selectors correctly zeroed on far return to lower privilege.
author TomW
date Wed Aug 13 20:33:56 2014 +0100
parents 9c201151bb4b
children
line source
1 #define cond_O ( VF_SET())
2 #define cond_NO (!VF_SET())
3 #define cond_B ( CF_SET())
4 #define cond_NB (!CF_SET())
5 #define cond_E ( ZF_SET())
6 #define cond_NE (!ZF_SET())
7 #define cond_BE ( CF_SET() || ZF_SET())
8 #define cond_NBE (!CF_SET() && !ZF_SET())
9 #define cond_S ( NF_SET())
10 #define cond_NS (!NF_SET())
11 #define cond_P ( PF_SET())
12 #define cond_NP (!PF_SET())
13 #define cond_L (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0))
14 #define cond_NL (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0))
15 #define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET()))
16 #define cond_NLE (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0) && (!ZF_SET()))
18 #define opJ(condition) \
19 static int opJ ## condition(uint32_t fetchdat) \
20 { \
21 int8_t offset = (int8_t)getbytef(); \
22 if (cond_ ## condition) \
23 { \
24 pc += offset; \
25 cycles -= timing_bt; \
26 } \
27 cycles -= timing_bnt; \
28 return 0; \
29 } \
30 \
31 static int opJ ## condition ## _w(uint32_t fetchdat) \
32 { \
33 int16_t offset = (int16_t)getwordf(); \
34 if (cond_ ## condition) \
35 { \
36 pc += offset; \
37 cycles -= timing_bt; \
38 } \
39 cycles -= timing_bnt; \
40 return 0; \
41 } \
42 \
43 static int opJ ## condition ## _l(uint32_t fetchdat) \
44 { \
45 uint32_t offset = getlong(); \
46 if (cond_ ## condition) \
47 { \
48 pc += offset; \
49 cycles -= timing_bt; \
50 } \
51 cycles -= timing_bnt; \
52 return 0; \
53 } \
55 opJ(O)
56 opJ(NO)
57 opJ(B)
58 opJ(NB)
59 opJ(E)
60 opJ(NE)
61 opJ(BE)
62 opJ(NBE)
63 opJ(S)
64 opJ(NS)
65 opJ(P)
66 opJ(NP)
67 opJ(L)
68 opJ(NL)
69 opJ(LE)
70 opJ(NLE)
74 static int opLOOPNE_w(uint32_t fetchdat)
75 {
76 int8_t offset = (int8_t)getbytef();
77 CX--;
78 if (CX && !ZF_SET())
79 pc += offset;
80 cycles -= (is486) ? 7 : 11;
81 return 0;
82 }
83 static int opLOOPNE_l(uint32_t fetchdat)
84 {
85 int8_t offset = (int8_t)getbytef();
86 ECX--;
87 if (ECX && !ZF_SET())
88 pc += offset;
89 cycles -= (is486) ? 7 : 11;
90 return 0;
91 }
93 static int opLOOPE_w(uint32_t fetchdat)
94 {
95 int8_t offset = (int8_t)getbytef();
96 CX--;
97 if (CX && ZF_SET())
98 pc += offset;
99 cycles -= (is486) ? 7 : 11;
100 return 0;
101 }
102 static int opLOOPE_l(uint32_t fetchdat)
103 {
104 int8_t offset = (int8_t)getbytef();
105 ECX--;
106 if (ECX && ZF_SET())
107 pc += offset;
108 cycles -= (is486) ? 7 : 11;
109 return 0;
110 }
112 static int opLOOP_w(uint32_t fetchdat)
113 {
114 int8_t offset = (int8_t)getbytef();
115 CX--;
116 if (CX)
117 pc += offset;
118 cycles -= (is486) ? 7 : 11;
119 return 0;
120 }
121 static int opLOOP_l(uint32_t fetchdat)
122 {
123 int8_t offset = (int8_t)getbytef();
124 ECX--;
125 if (ECX)
126 pc += offset;
127 cycles -= (is486) ? 7 : 11;
128 return 0;
129 }
131 static int opJCXZ(uint32_t fetchdat)
132 {
133 int8_t offset = (int8_t)getbytef();
134 if (!CX)
135 {
136 pc += offset;
137 cycles -= 4;
138 }
139 cycles -= 5;
140 return 0;
141 }
142 static int opJECXZ(uint32_t fetchdat)
143 {
144 int8_t offset = (int8_t)getbytef();
145 if (!ECX)
146 {
147 pc += offset;
148 cycles -= 4;
149 }
150 cycles -= 5;
151 return 0;
152 }
155 static int opJMP_r8(uint32_t fetchdat)
156 {
157 int8_t offset = (int8_t)getbytef();
158 pc += offset;
159 cycles -= (is486) ? 3 : 7;
160 return 0;
161 }
162 static int opJMP_r16(uint32_t fetchdat)
163 {
164 int16_t offset = (int16_t)getwordf();
165 pc += offset;
166 cycles -= (is486) ? 3 : 7;
167 return 0;
168 }
169 static int opJMP_r32(uint32_t fetchdat)
170 {
171 int32_t offset = (int32_t)getlong(); if (abrt) return 0;
172 pc += offset;
173 cycles -= (is486) ? 3 : 7;
174 return 0;
175 }
177 static int opJMP_far_a16(uint32_t fetchdat)
178 {
179 uint16_t addr = getwordf();
180 uint16_t seg = getword(); if (abrt) return 0;
181 uint32_t oxpc = pc;
182 pc = addr;
183 loadcsjmp(seg, oxpc);
184 cycles -= (is486) ? 17 : 12;
185 return 0;
186 }
187 static int opJMP_far_a32(uint32_t fetchdat)
188 {
189 uint32_t addr = getlong();
190 uint16_t seg = getword(); if (abrt) return 0;
191 uint32_t oxpc = pc;
192 pc = addr;
193 loadcsjmp(seg, oxpc);
194 cycles -= (is486) ? 17 : 12;
195 return 0;
196 }
198 int opCALL_r16(uint32_t fetchdat)
199 {
200 int16_t addr = (int16_t)getwordf();
201 PUSH_W(pc);
202 pc += addr;
203 cycles -= (is486) ? 3 : 7;
204 return 0;
205 }
206 int opCALL_r32(uint32_t fetchdat)
207 {
208 int32_t addr = getlong(); if (abrt) return 0;
209 PUSH_L(pc);
210 pc += addr;
211 cycles -= (is486) ? 3 : 7;
212 return 0;
213 }
215 int opRET_w(uint32_t fetchdat)
216 {
217 uint16_t ret;
219 ret = POP_W(); if (abrt) return 0;
220 pc = ret;
222 cycles -= (is486) ? 5 : 10;
223 return 0;
224 }
225 int opRET_l(uint32_t fetchdat)
226 {
227 uint32_t ret;
229 ret = POP_L(); if (abrt) return 0;
230 pc = ret;
232 cycles -= (is486) ? 5 : 10;
233 return 0;
234 }
236 int opRET_w_imm(uint32_t fetchdat)
237 {
238 uint16_t offset = getwordf();
239 uint16_t ret;
241 ret = POP_W(); if (abrt) return 0;
242 if (stack32) ESP += offset;
243 else SP += offset;
244 pc = ret;
246 cycles -= (is486) ? 5 : 10;
247 return 0;
248 }
249 int opRET_l_imm(uint32_t fetchdat)
250 {
251 uint16_t offset = getwordf();
252 uint32_t ret;
254 ret = POP_L(); if (abrt) return 0;
255 if (stack32) ESP += offset;
256 else SP += offset;
257 pc = ret;
259 cycles -= (is486) ? 5 : 10;
260 return 0;
261 }