2 JPC-RR: A x86 PC Hardware Emulator
5 Copyright (C) 2007-2009 Isis Innovation Limited
6 Copyright (C) 2009-2010 H. Ilari Liusvaara
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as published by
10 the Free Software Foundation.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 Based on JPC x86 PC Hardware emulator,
22 A project from the Physics Dept, The University of Oxford
24 Details about original JPC can be found at:
26 www-jpc.physics.ox.ac.uk
30 package org
.jpc
.emulator
.memory
.codeblock
.optimised
;
32 import org
.jpc
.emulator
.processor
.*;
33 import org
.jpc
.emulator
.processor
.fpu64
.*;
34 import org
.jpc
.emulator
.memory
.codeblock
.*;
36 import java
.util
.HashMap
;
38 import static org
.jpc
.emulator
.memory
.codeblock
.optimised
.MicrocodeSet
.*;
42 * @author Chris Dennis
44 public class ProtectedModeUBlock
implements ProtectedModeCodeBlock
46 private static final boolean[] parityMap
;
50 parityMap
= new boolean[256];
51 for(int i
= 0; i
< parityMap
.length
; i
++)
52 parityMap
[i
] = ((Integer
.bitCount(i
) & 0x1) == 0);
55 private Processor cpu
;
60 protected int[] microcodes
;
61 protected int[] cumulativeX86Length
;
62 private int executeCount
;
63 private HashMap
<Integer
, Integer
> haltComplained
;
64 public static OpcodeLogger opcodeCounter
= null;//new OpcodeLogger("PM Stats:");
66 public ProtectedModeUBlock()
68 haltComplained
= new HashMap
<Integer
, Integer
>();
71 public ProtectedModeUBlock(int[] microcodes
, int[] x86lengths
)
74 this.microcodes
= microcodes
;
75 cumulativeX86Length
= x86lengths
;
76 if(cumulativeX86Length
.length
== 0)
80 for(int i
= 1; i
< cumulativeX86Length
.length
; i
++)
81 if(cumulativeX86Length
[i
] > cumulativeX86Length
[i
-1]) count
++;
86 public int getX86Length()
88 if(microcodes
.length
== 0)
90 return cumulativeX86Length
[microcodes
.length
-1];
93 public int getX86Count()
98 public boolean handleMemoryRegionChange(int startAddress
, int endAddress
)
103 public String
getDisplayString()
105 StringBuilder buf
= new StringBuilder();
106 buf
.append(this.toString()).append('\n');
107 for(int i
=0; i
<microcodes
.length
; i
++)
108 buf
.append(i
).append(": ").append(microcodes
[i
]).append('\n');
109 return buf
.toString();
112 public String
toString()
114 return "Protected Mode Interpreted Block";
117 public InstructionSource
getAsInstructionSource()
119 int[] codes
= new int[microcodes
.length
];
120 int[] positions
= new int[microcodes
.length
];
121 System
.arraycopy(microcodes
, 0, codes
, 0, codes
.length
);
122 System
.arraycopy(cumulativeX86Length
, 0, positions
, 0, positions
.length
);
124 return new ArrayBackedInstructionSource(codes
, positions
);
127 public int[] getMicrocodes()
129 int[] result
= new int[microcodes
.length
];
130 System
.arraycopy(microcodes
, 0, result
, 0, result
.length
);
134 public int execute(Processor cpu
)
139 if(opcodeCounter
!= null)
140 opcodeCounter
.addBlock(getMicrocodes());
143 int addr0
= 0, reg0
= 0, reg1
= 0, reg2
= 0;
147 boolean eipUpdated
= false;
150 cpu
.eflagsLastAborted
= false;
152 fpu
.setProtectedMode(true);
155 while(position
< microcodes
.length
) {
156 switch(microcodes
[position
++]) {
160 cpu
.eip
+= cumulativeX86Length
[position
- 1];
165 System
.err
.println("Emulated: undefined opcode");
166 throw ProcessorException
.UNDEFINED
;
168 case MEM_RESET
: addr0
= 0; seg0
= null; break;
170 case LOAD0_EAX
: reg0
= cpu
.eax
; break;
171 case LOAD0_ECX
: reg0
= cpu
.ecx
; break;
172 case LOAD0_EDX
: reg0
= cpu
.edx
; break;
173 case LOAD0_EBX
: reg0
= cpu
.ebx
; break;
174 case LOAD0_ESP
: reg0
= cpu
.esp
; break;
175 case LOAD0_EBP
: reg0
= cpu
.ebp
; break;
176 case LOAD0_ESI
: reg0
= cpu
.esi
; break;
177 case LOAD0_EDI
: reg0
= cpu
.edi
; break;
179 case STORE0_EAX
: cpu
.eax
= reg0
; break;
180 case STORE0_ECX
: cpu
.ecx
= reg0
; break;
181 case STORE0_EDX
: cpu
.edx
= reg0
; break;
182 case STORE0_EBX
: cpu
.ebx
= reg0
; break;
183 case STORE0_ESP
: cpu
.esp
= reg0
; break;
184 case STORE0_EBP
: cpu
.ebp
= reg0
; break;
185 case STORE0_ESI
: cpu
.esi
= reg0
; break;
186 case STORE0_EDI
: cpu
.edi
= reg0
; break;
188 case LOAD1_EAX
: reg1
= cpu
.eax
; break;
189 case LOAD1_ECX
: reg1
= cpu
.ecx
; break;
190 case LOAD1_EDX
: reg1
= cpu
.edx
; break;
191 case LOAD1_EBX
: reg1
= cpu
.ebx
; break;
192 case LOAD1_ESP
: reg1
= cpu
.esp
; break;
193 case LOAD1_EBP
: reg1
= cpu
.ebp
; break;
194 case LOAD1_ESI
: reg1
= cpu
.esi
; break;
195 case LOAD1_EDI
: reg1
= cpu
.edi
; break;
197 case STORE1_EAX
: cpu
.eax
= reg1
; break;
198 case STORE1_ECX
: cpu
.ecx
= reg1
; break;
199 case STORE1_EDX
: cpu
.edx
= reg1
; break;
200 case STORE1_EBX
: cpu
.ebx
= reg1
; break;
201 case STORE1_ESP
: cpu
.esp
= reg1
; break;
202 case STORE1_EBP
: cpu
.ebp
= reg1
; break;
203 case STORE1_ESI
: cpu
.esi
= reg1
; break;
204 case STORE1_EDI
: cpu
.edi
= reg1
; break;
206 case LOAD0_AX
: reg0
= cpu
.eax
& 0xffff; break;
207 case LOAD0_CX
: reg0
= cpu
.ecx
& 0xffff; break;
208 case LOAD0_DX
: reg0
= cpu
.edx
& 0xffff; break;
209 case LOAD0_BX
: reg0
= cpu
.ebx
& 0xffff; break;
210 case LOAD0_SP
: reg0
= cpu
.esp
& 0xffff; break;
211 case LOAD0_BP
: reg0
= cpu
.ebp
& 0xffff; break;
212 case LOAD0_SI
: reg0
= cpu
.esi
& 0xffff; break;
213 case LOAD0_DI
: reg0
= cpu
.edi
& 0xffff; break;
215 case STORE0_AX
: cpu
.eax
= (cpu
.eax
& ~
0xffff) | (reg0
& 0xffff); break;
216 case STORE0_CX
: cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (reg0
& 0xffff); break;
217 case STORE0_DX
: cpu
.edx
= (cpu
.edx
& ~
0xffff) | (reg0
& 0xffff); break;
218 case STORE0_BX
: cpu
.ebx
= (cpu
.ebx
& ~
0xffff) | (reg0
& 0xffff); break;
219 case STORE0_SP
: cpu
.esp
= (cpu
.esp
& ~
0xffff) | (reg0
& 0xffff); break;
220 case STORE0_BP
: cpu
.ebp
= (cpu
.ebp
& ~
0xffff) | (reg0
& 0xffff); break;
221 case STORE0_SI
: cpu
.esi
= (cpu
.esi
& ~
0xffff) | (reg0
& 0xffff); break;
222 case STORE0_DI
: cpu
.edi
= (cpu
.edi
& ~
0xffff) | (reg0
& 0xffff); break;
224 case STORE1_AX
: cpu
.eax
= (cpu
.eax
& ~
0xffff) | (reg1
& 0xffff); break;
225 case STORE1_CX
: cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (reg1
& 0xffff); break;
226 case STORE1_DX
: cpu
.edx
= (cpu
.edx
& ~
0xffff) | (reg1
& 0xffff); break;
227 case STORE1_BX
: cpu
.ebx
= (cpu
.ebx
& ~
0xffff) | (reg1
& 0xffff); break;
228 case STORE1_SP
: cpu
.esp
= (cpu
.esp
& ~
0xffff) | (reg1
& 0xffff); break;
229 case STORE1_BP
: cpu
.ebp
= (cpu
.ebp
& ~
0xffff) | (reg1
& 0xffff); break;
230 case STORE1_SI
: cpu
.esi
= (cpu
.esi
& ~
0xffff) | (reg1
& 0xffff); break;
231 case STORE1_DI
: cpu
.edi
= (cpu
.edi
& ~
0xffff) | (reg1
& 0xffff); break;
233 case LOAD1_AX
: reg1
= cpu
.eax
& 0xffff; break;
234 case LOAD1_CX
: reg1
= cpu
.ecx
& 0xffff; break;
235 case LOAD1_DX
: reg1
= cpu
.edx
& 0xffff; break;
236 case LOAD1_BX
: reg1
= cpu
.ebx
& 0xffff; break;
237 case LOAD1_SP
: reg1
= cpu
.esp
& 0xffff; break;
238 case LOAD1_BP
: reg1
= cpu
.ebp
& 0xffff; break;
239 case LOAD1_SI
: reg1
= cpu
.esi
& 0xffff; break;
240 case LOAD1_DI
: reg1
= cpu
.edi
& 0xffff; break;
242 case LOAD0_AL
: reg0
= cpu
.eax
& 0xff; break;
243 case LOAD0_CL
: reg0
= cpu
.ecx
& 0xff; break;
244 case LOAD0_DL
: reg0
= cpu
.edx
& 0xff; break;
245 case LOAD0_BL
: reg0
= cpu
.ebx
& 0xff; break;
246 case LOAD0_AH
: reg0
= (cpu
.eax
>> 8) & 0xff; break;
247 case LOAD0_CH
: reg0
= (cpu
.ecx
>> 8) & 0xff; break;
248 case LOAD0_DH
: reg0
= (cpu
.edx
>> 8) & 0xff; break;
249 case LOAD0_BH
: reg0
= (cpu
.ebx
>> 8) & 0xff; break;
251 case STORE0_AL
: cpu
.eax
= (cpu
.eax
& ~
0xff) | (reg0
& 0xff); break;
252 case STORE0_CL
: cpu
.ecx
= (cpu
.ecx
& ~
0xff) | (reg0
& 0xff); break;
253 case STORE0_DL
: cpu
.edx
= (cpu
.edx
& ~
0xff) | (reg0
& 0xff); break;
254 case STORE0_BL
: cpu
.ebx
= (cpu
.ebx
& ~
0xff) | (reg0
& 0xff); break;
255 case STORE0_AH
: cpu
.eax
= (cpu
.eax
& ~
0xff00) | ((reg0
<< 8) & 0xff00); break;
256 case STORE0_CH
: cpu
.ecx
= (cpu
.ecx
& ~
0xff00) | ((reg0
<< 8) & 0xff00); break;
257 case STORE0_DH
: cpu
.edx
= (cpu
.edx
& ~
0xff00) | ((reg0
<< 8) & 0xff00); break;
258 case STORE0_BH
: cpu
.ebx
= (cpu
.ebx
& ~
0xff00) | ((reg0
<< 8) & 0xff00); break;
260 case LOAD1_AL
: reg1
= cpu
.eax
& 0xff; break;
261 case LOAD1_CL
: reg1
= cpu
.ecx
& 0xff; break;
262 case LOAD1_DL
: reg1
= cpu
.edx
& 0xff; break;
263 case LOAD1_BL
: reg1
= cpu
.ebx
& 0xff; break;
264 case LOAD1_AH
: reg1
= (cpu
.eax
>> 8) & 0xff; break;
265 case LOAD1_CH
: reg1
= (cpu
.ecx
>> 8) & 0xff; break;
266 case LOAD1_DH
: reg1
= (cpu
.edx
>> 8) & 0xff; break;
267 case LOAD1_BH
: reg1
= (cpu
.ebx
>> 8) & 0xff; break;
269 case STORE1_AL
: cpu
.eax
= (cpu
.eax
& ~
0xff) | (reg1
& 0xff); break;
270 case STORE1_CL
: cpu
.ecx
= (cpu
.ecx
& ~
0xff) | (reg1
& 0xff); break;
271 case STORE1_DL
: cpu
.edx
= (cpu
.edx
& ~
0xff) | (reg1
& 0xff); break;
272 case STORE1_BL
: cpu
.ebx
= (cpu
.ebx
& ~
0xff) | (reg1
& 0xff); break;
273 case STORE1_AH
: cpu
.eax
= (cpu
.eax
& ~
0xff00) | ((reg1
<< 8) & 0xff00); break;
274 case STORE1_CH
: cpu
.ecx
= (cpu
.ecx
& ~
0xff00) | ((reg1
<< 8) & 0xff00); break;
275 case STORE1_DH
: cpu
.edx
= (cpu
.edx
& ~
0xff00) | ((reg1
<< 8) & 0xff00); break;
276 case STORE1_BH
: cpu
.ebx
= (cpu
.ebx
& ~
0xff00) | ((reg1
<< 8) & 0xff00); break;
278 case LOAD0_CR0
: reg0
= cpu
.getCR0(); break;
279 case LOAD0_CR2
: reg0
= cpu
.getCR2(); break;
280 case LOAD0_CR3
: reg0
= cpu
.getCR3(); break;
281 case LOAD0_CR4
: reg0
= cpu
.getCR4(); break;
283 case STORE0_CR0
: cpu
.setCR0(reg0
); break;
284 case STORE0_CR2
: cpu
.setCR2(reg0
); break;
285 case STORE0_CR3
: cpu
.setCR3(reg0
); break;
286 case STORE0_CR4
: cpu
.setCR4(reg0
); break;
288 case LOAD0_DR0
: reg0
= cpu
.getDR0(); break;
289 case LOAD0_DR1
: reg0
= cpu
.getDR1(); break;
290 case LOAD0_DR2
: reg0
= cpu
.getDR2(); break;
291 case LOAD0_DR3
: reg0
= cpu
.getDR3(); break;
292 case LOAD0_DR6
: reg0
= cpu
.getDR6(); break;
293 case LOAD0_DR7
: reg0
= cpu
.getDR7(); break;
295 case STORE0_DR0
: cpu
.setDR0(reg0
); break;
296 case STORE0_DR1
: cpu
.setDR1(reg0
); break;
297 case STORE0_DR2
: cpu
.setDR2(reg0
); break;
298 case STORE0_DR3
: cpu
.setDR3(reg0
); break;
299 case STORE0_DR6
: cpu
.setDR6(reg0
); break;
300 case STORE0_DR7
: cpu
.setDR7(reg0
); break;
302 case LOAD0_ES
: reg0
= 0xffff & cpu
.es
.getSelector(); break;
303 case LOAD0_CS
: reg0
= 0xffff & cpu
.cs
.getSelector(); break;
304 case LOAD0_SS
: reg0
= 0xffff & cpu
.ss
.getSelector(); break;
305 case LOAD0_DS
: reg0
= 0xffff & cpu
.ds
.getSelector(); break;
306 case LOAD0_FS
: reg0
= 0xffff & cpu
.fs
.getSelector(); break;
307 case LOAD0_GS
: reg0
= 0xffff & cpu
.gs
.getSelector(); break;
309 case STORE0_ES
: cpu
.es
= loadSegment(reg0
); break;
312 Segment temp
= loadSegment(reg0
);
313 if(temp
== SegmentFactory
.NULL_SEGMENT
)
314 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
315 cpu
.ss
= temp
; cpu
.eflagsInterruptEnable
= false;
317 case STORE0_DS
: cpu
.ds
= loadSegment(reg0
); break;
318 case STORE0_FS
: cpu
.fs
= loadSegment(reg0
); break;
319 case STORE0_GS
: cpu
.gs
= loadSegment(reg0
); break;
321 case STORE1_ES
: cpu
.es
= loadSegment(reg1
); break;
324 Segment temp
= loadSegment(reg1
);
325 if(temp
== SegmentFactory
.NULL_SEGMENT
)
326 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
327 cpu
.ss
= temp
; cpu
.eflagsInterruptEnable
= false;
329 case STORE1_DS
: cpu
.ds
= loadSegment(reg1
); break;
330 case STORE1_FS
: cpu
.fs
= loadSegment(reg1
); break;
331 case STORE1_GS
: cpu
.gs
= loadSegment(reg1
); break;
333 case STORE0_FLAGS
: cpu
.setEFlags((cpu
.getEFlags() & ~
0xffff) | (reg0
& 0xffff)); break;
334 case STORE0_EFLAGS
: cpu
.setEFlags(reg0
); break;
336 case LOAD0_FLAGS
: reg0
= 0xffff & cpu
.getEFlags(); break;
337 case LOAD0_EFLAGS
: reg0
= cpu
.getEFlags(); break;
339 case LOAD0_IB
: reg0
= microcodes
[position
++] & 0xff; break;
340 case LOAD0_IW
: reg0
= microcodes
[position
++] & 0xffff; break;
341 case LOAD0_ID
: reg0
= microcodes
[position
++]; break;
343 case LOAD1_IB
: reg1
= microcodes
[position
++] & 0xff; break;
344 case LOAD1_IW
: reg1
= microcodes
[position
++] & 0xffff; break;
345 case LOAD1_ID
: reg1
= microcodes
[position
++]; break;
347 case LOAD2_EAX
: reg2
= cpu
.eax
; break;
348 case LOAD2_AX
: reg2
= cpu
.eax
& 0xffff; break;
349 case LOAD2_AL
: reg2
= cpu
.eax
& 0xff; break;
350 case LOAD2_CL
: reg2
= cpu
.ecx
& 0xffff; break;
351 case LOAD2_IB
: reg2
= microcodes
[position
++] & 0xff; break;
353 case LOAD_SEG_ES
: seg0
= cpu
.es
; break;
354 case LOAD_SEG_CS
: seg0
= cpu
.cs
; break;
355 case LOAD_SEG_SS
: seg0
= cpu
.ss
; break;
356 case LOAD_SEG_DS
: seg0
= cpu
.ds
; break;
357 case LOAD_SEG_FS
: seg0
= cpu
.fs
; break;
358 case LOAD_SEG_GS
: seg0
= cpu
.gs
; break;
360 case ADDR_REG1
: addr0
+= reg1
; break;
361 case ADDR_2REG1
: addr0
+= (reg1
<< 1); break;
362 case ADDR_4REG1
: addr0
+= (reg1
<< 2); break;
363 case ADDR_8REG1
: addr0
+= (reg1
<< 3); break;
365 case ADDR_EAX
: addr0
+= cpu
.eax
; break;
366 case ADDR_ECX
: addr0
+= cpu
.ecx
; break;
367 case ADDR_EDX
: addr0
+= cpu
.edx
; break;
368 case ADDR_EBX
: addr0
+= cpu
.ebx
; break;
369 case ADDR_ESP
: addr0
+= cpu
.esp
; break;
370 case ADDR_EBP
: addr0
+= cpu
.ebp
; break;
371 case ADDR_ESI
: addr0
+= cpu
.esi
; break;
372 case ADDR_EDI
: addr0
+= cpu
.edi
; break;
374 case ADDR_AX
: addr0
+= ((short)cpu
.eax
); break;
375 case ADDR_CX
: addr0
+= ((short)cpu
.ecx
); break;
376 case ADDR_DX
: addr0
+= ((short)cpu
.edx
); break;
377 case ADDR_BX
: addr0
+= ((short)cpu
.ebx
); break;
378 case ADDR_SP
: addr0
+= ((short)cpu
.esp
); break;
379 case ADDR_BP
: addr0
+= ((short)cpu
.ebp
); break;
380 case ADDR_SI
: addr0
+= ((short)cpu
.esi
); break;
381 case ADDR_DI
: addr0
+= ((short)cpu
.edi
); break;
383 case ADDR_2EAX
: addr0
+= (cpu
.eax
<< 1); break;
384 case ADDR_2ECX
: addr0
+= (cpu
.ecx
<< 1); break;
385 case ADDR_2EDX
: addr0
+= (cpu
.edx
<< 1); break;
386 case ADDR_2EBX
: addr0
+= (cpu
.ebx
<< 1); break;
387 case ADDR_2ESP
: addr0
+= (cpu
.esp
<< 1); break;
388 case ADDR_2EBP
: addr0
+= (cpu
.ebp
<< 1); break;
389 case ADDR_2ESI
: addr0
+= (cpu
.esi
<< 1); break;
390 case ADDR_2EDI
: addr0
+= (cpu
.edi
<< 1); break;
392 case ADDR_4EAX
: addr0
+= (cpu
.eax
<< 2); break;
393 case ADDR_4ECX
: addr0
+= (cpu
.ecx
<< 2); break;
394 case ADDR_4EDX
: addr0
+= (cpu
.edx
<< 2); break;
395 case ADDR_4EBX
: addr0
+= (cpu
.ebx
<< 2); break;
396 case ADDR_4ESP
: addr0
+= (cpu
.esp
<< 2); break;
397 case ADDR_4EBP
: addr0
+= (cpu
.ebp
<< 2); break;
398 case ADDR_4ESI
: addr0
+= (cpu
.esi
<< 2); break;
399 case ADDR_4EDI
: addr0
+= (cpu
.edi
<< 2); break;
401 case ADDR_8EAX
: addr0
+= (cpu
.eax
<< 3); break;
402 case ADDR_8ECX
: addr0
+= (cpu
.ecx
<< 3); break;
403 case ADDR_8EDX
: addr0
+= (cpu
.edx
<< 3); break;
404 case ADDR_8EBX
: addr0
+= (cpu
.ebx
<< 3); break;
405 case ADDR_8ESP
: addr0
+= (cpu
.esp
<< 3); break;
406 case ADDR_8EBP
: addr0
+= (cpu
.ebp
<< 3); break;
407 case ADDR_8ESI
: addr0
+= (cpu
.esi
<< 3); break;
408 case ADDR_8EDI
: addr0
+= (cpu
.edi
<< 3); break;
410 case ADDR_IB
: addr0
+= ((byte)microcodes
[position
++]); break;
411 case ADDR_IW
: addr0
+= ((short)microcodes
[position
++]); break;
412 case ADDR_ID
: addr0
+= microcodes
[position
++]; break;
414 case ADDR_MASK16
: addr0
&= 0xffff; break;
416 case ADDR_uAL
: addr0
+= 0xff & cpu
.eax
; break;
418 case LOAD0_ADDR
: reg0
= addr0
; break;
420 case LOAD0_MEM_BYTE
: reg0
= 0xff & seg0
.getByte(addr0
); break;
421 case LOAD0_MEM_WORD
: reg0
= 0xffff & seg0
.getWord(addr0
); break;
422 case LOAD0_MEM_DWORD
: reg0
= seg0
.getDoubleWord(addr0
); break;
423 case LOAD0_MEM_QWORD
: reg0l
= seg0
.getQuadWord(addr0
); break;
425 case LOAD1_MEM_BYTE
: reg1
= 0xff & seg0
.getByte(addr0
); break;
426 case LOAD1_MEM_WORD
: reg1
= 0xffff & seg0
.getWord(addr0
); break;
427 case LOAD1_MEM_DWORD
: reg1
= seg0
.getDoubleWord(addr0
); break;
429 case STORE0_MEM_BYTE
: seg0
.setByte(addr0
, (byte)reg0
); break;
430 case STORE0_MEM_WORD
: seg0
.setWord(addr0
, (short)reg0
); break;
431 case STORE0_MEM_DWORD
: seg0
.setDoubleWord(addr0
, reg0
); break;
432 case STORE0_MEM_QWORD
: seg0
.setQuadWord(addr0
, reg0l
); break;
434 case STORE1_MEM_BYTE
: seg0
.setByte(addr0
, (byte)reg1
); break;
435 case STORE1_MEM_WORD
: seg0
.setWord(addr0
, (short)reg1
); break;
436 case STORE1_MEM_DWORD
: seg0
.setDoubleWord(addr0
, reg1
); break;
438 case XOR
: reg0 ^
= reg1
; break;
439 case AND
: reg0
&= reg1
; break;
440 case OR
: reg0
|= reg1
; break;
441 case NOT
: reg0
= ~reg0
; break;
443 case SUB
: reg2
= reg0
; reg0
= reg2
- reg1
; break;
444 case SBB
: reg2
= reg0
; reg0
= reg2
- (reg1
+ (cpu
.getCarryFlag() ?
1 : 0)); break;
445 case ADD
: reg2
= reg0
; reg0
= reg2
+ reg1
; break;
446 case ADC
: reg2
= reg0
; reg0
= reg2
+ reg1
+ (cpu
.getCarryFlag() ?
1 : 0); break;
447 case NEG
: reg0
= -reg0
; break;
449 case MUL_O8
: mul_o8(reg0
); break;
450 case MUL_O16
: mul_o16(reg0
); break;
451 case MUL_O32
: mul_o32(reg0
); break;
453 case IMULA_O8
: imula_o8((byte)reg0
); break;
454 case IMULA_O16
: imula_o16((short)reg0
); break;
455 case IMULA_O32
: imula_o32(reg0
); break;
457 case IMUL_O16
: reg0
= imul_o16((short)reg0
, (short)reg1
); break;
458 case IMUL_O32
: reg0
= imul_o32(reg0
, reg1
); break;
460 case DIV_O8
: div_o8(reg0
); break;
461 case DIV_O16
: div_o16(reg0
); break;
462 case DIV_O32
: div_o32(reg0
); break;
464 case IDIV_O8
: idiv_o8((byte)reg0
); break;
465 case IDIV_O16
: idiv_o16((short)reg0
); break;
466 case IDIV_O32
: idiv_o32(reg0
); break;
468 case BSF
: reg0
= bsf(reg1
, reg0
); break;
469 case BSR
: reg0
= bsr(reg1
, reg0
); break;
471 case BT_MEM
: bt_mem(reg1
, seg0
, addr0
); break;
472 case BTS_MEM
: bts_mem(reg1
, seg0
, addr0
); break;
473 case BTR_MEM
: btr_mem(reg1
, seg0
, addr0
); break;
474 case BTC_MEM
: btc_mem(reg1
, seg0
, addr0
); break;
476 case BT_O32
: reg1
&= 0x1f; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); break;
477 case BT_O16
: reg1
&= 0xf; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); break;
478 case BTS_O32
: reg1
&= 0x1f; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); reg0
|= (1 << reg1
); break;
479 case BTS_O16
: reg1
&= 0xf; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); reg0
|= (1 << reg1
); break;
480 case BTR_O32
: reg1
&= 0x1f; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); reg0
&= ~
(1 << reg1
); break;
481 case BTR_O16
: reg1
&= 0xf; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); reg0
&= ~
(1 << reg1
); break;
482 case BTC_O32
: reg1
&= 0x1f; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); reg0 ^
= (1 << reg1
); break;
483 case BTC_O16
: reg1
&= 0xf; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); reg0 ^
= (1 << reg1
); break;
485 case ROL_O8
: reg2
= reg1
& 0x7; reg0
= (reg0
<< reg2
) | (reg0
>>> (8 - reg2
)); break;
486 case ROL_O16
: reg2
= reg1
& 0xf; reg0
= (reg0
<< reg2
) | (reg0
>>> (16 - reg2
)); break;
487 case ROL_O32
: reg1
&= 0x1f; reg0
= (reg0
<< reg1
) | (reg0
>>> (32 - reg1
)); break;
489 case ROR_O8
: reg1
&= 0x7; reg0
= (reg0
>>> reg1
) | (reg0
<< (8 - reg1
)); break;
490 case ROR_O16
: reg1
&= 0xf; reg0
= (reg0
>>> reg1
) | (reg0
<< (16 - reg1
)); break;
491 case ROR_O32
: reg1
&= 0x1f; reg0
= (reg0
>>> reg1
) | (reg0
<< (32 - reg1
)); break;
493 case RCL_O8
: reg1
&= 0x1f; reg1
%= 9; reg0
|= (cpu
.getCarryFlag() ?
0x100 : 0);
494 reg0
= (reg0
<< reg1
) | (reg0
>>> (9 - reg1
)); break;
495 case RCL_O16
: reg1
&= 0x1f; reg1
%= 17; reg0
|= (cpu
.getCarryFlag() ?
0x10000 : 0);
496 reg0
= (reg0
<< reg1
) | (reg0
>>> (17 - reg1
)); break;
497 case RCL_O32
: reg1
&= 0x1f; reg0l
= (0xffffffffl
& reg0
) | (cpu
.getCarryFlag() ?
0x100000000l
: 0);
498 reg0
= (int)(reg0l
= (reg0l
<< reg1
) | (reg0l
>>> (33 - reg1
))); break;
500 case RCR_O8
: reg1
&= 0x1f; reg1
%= 9; reg0
|= (cpu
.getCarryFlag() ?
0x100 : 0);
501 reg2
= (cpu
.getCarryFlag() ^
((reg0
& 0x80) != 0) ?
1:0);
502 reg0
= (reg0
>>> reg1
) | (reg0
<< (9 - reg1
));
504 case RCR_O16
: reg1
&= 0x1f; reg1
%= 17;
505 reg2
= (cpu
.getCarryFlag() ^
((reg0
& 0x8000) != 0) ?
1:0);
506 reg0
|= (cpu
.getCarryFlag() ?
0x10000 : 0);
507 reg0
= (reg0
>>> reg1
) | (reg0
<< (17 - reg1
));
509 case RCR_O32
: reg1
&= 0x1f; reg0l
= (0xffffffffl
& reg0
) | (cpu
.getCarryFlag() ?
0x100000000L
: 0);
510 reg2
= (cpu
.getCarryFlag() ^
((reg0
& 0x80000000) != 0) ?
1:0);
511 reg0
= (int)(reg0l
= (reg0l
>>> reg1
) | (reg0l
<< (33 - reg1
)));
514 case SHL
: reg2
= reg0
; reg0
<<= reg1
; break;
515 case SHR
: reg2
= reg0
; reg0
>>>= reg1
; break;
516 case SAR_O8
: reg2
= reg0
; reg0
= ((byte)reg0
) >> reg1
; break;
517 case SAR_O16
: reg2
= reg0
; reg0
= ((short)reg0
) >> reg1
; break;
518 case SAR_O32
: reg2
= reg0
; reg0
>>= reg1
; break;
521 int i
= reg0
; reg2
&= 0x1f;
523 reg0
= (reg0
<< reg2
) | (reg1
>>> (16 - reg2
));
527 i
= (reg1
& 0xFFFF) | (reg0
<< 16);
528 reg0
= (reg1
<< (reg2
- 16)) | ((reg0
& 0xFFFF) >>> (32 - reg2
));
534 int i
= reg0
; reg2
&= 0x1f;
536 reg0
= (reg0
<< reg2
) | (reg1
>>> (32 - reg2
));
537 reg1
= reg2
; reg2
= i
;
541 int i
= reg0
; reg2
&= 0x1f;
543 reg0
= (reg0
>>> reg2
) | (reg1
<< (16 - reg2
));
547 i
= (reg0
& 0xFFFF) | (reg1
<< 16);
548 reg0
= (reg1
>>> (reg2
-16)) | (reg0
<< (32 - reg2
));
554 int i
= reg0
; reg2
&= 0x1f;
556 reg0
= (reg0
>>> reg2
) | (reg1
<< (32 - reg2
));
557 reg1
= reg2
; reg2
= i
;
560 case CWD
: if((cpu
.eax
& 0x8000) == 0) cpu
.edx
&= 0xffff0000; else cpu
.edx
|= 0x0000ffff; break;
561 case CDQ
: if((cpu
.eax
& 0x80000000) == 0) cpu
.edx
= 0; else cpu
.edx
= -1; break;
563 case AAA
: aaa(); break;
564 case AAD
: aad(reg0
); break;
565 case AAM
: aam(reg0
); break;
566 case AAS
: aas(); break;
568 case DAA
: daa(); break;
569 case DAS
: das(); break;
571 case LAHF
: lahf(); break;
572 case SAHF
: sahf(); break;
574 case CLC
: cpu
.setCarryFlag(false); break;
575 case STC
: cpu
.setCarryFlag(true); break;
577 if(cpu
.getIOPrivilegeLevel() >= cpu
.getCPL()) {
578 cpu
.eflagsInterruptEnable
= false;
579 cpu
.eflagsInterruptEnableSoon
= false;
581 if((cpu
.getIOPrivilegeLevel() < cpu
.getCPL()) && (cpu
.getCPL() == 3) && ((cpu
.getCR4() & 1) != 0)) {
582 cpu
.eflagsInterruptEnableSoon
= false;
584 System
.err
.println("Emulated: IOPL=" + cpu
.getIOPrivilegeLevel() + ", CPL=" + cpu
.getCPL());
585 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);
589 if(cpu
.getIOPrivilegeLevel() >= cpu
.getCPL()) {
590 cpu
.eflagsInterruptEnable
= true;
591 cpu
.eflagsInterruptEnableSoon
= true;
593 if((cpu
.getIOPrivilegeLevel() < cpu
.getCPL()) && (cpu
.getCPL() == 3) && ((cpu
.getEFlags() & (1 << 20)) == 0))
594 cpu
.eflagsInterruptEnableSoon
= true;
596 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);
598 case CLD
: cpu
.eflagsDirection
= false; break;
599 case STD
: cpu
.eflagsDirection
= true; break;
600 case CMC
: cpu
.setCarryFlag(!cpu
.getCarryFlag()); break;
602 case SIGN_EXTEND_8_16
: reg0
= 0xffff & ((byte)reg0
); break;
603 case SIGN_EXTEND_8_32
: reg0
= (byte)reg0
; break;
604 case SIGN_EXTEND_16_32
: reg0
= (short)reg0
; break;
606 case INC
: reg0
++; break;
607 case DEC
: reg0
--; break;
610 if(cpu
.getCPL() != 0) {
611 if(haltComplained
.containsKey(position
- 1))
612 haltComplained
.put(position
- 1, haltComplained
.get(position
- 1) + 1);
614 haltComplained
.put(position
- 1, 1);
615 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);
617 cpu
.waitForInterrupt(); break;
619 case JO_O8
: jo_o8((byte)reg0
); break;
620 case JNO_O8
: jno_o8((byte)reg0
); break;
621 case JC_O8
: jc_o8((byte)reg0
); break;
622 case JNC_O8
: jnc_o8((byte)reg0
); break;
623 case JZ_O8
: jz_o8((byte)reg0
); break;
624 case JNZ_O8
: jnz_o8((byte)reg0
); break;
625 case JNA_O8
: jna_o8((byte)reg0
); break;
626 case JA_O8
: ja_o8((byte)reg0
); break;
627 case JS_O8
: js_o8((byte)reg0
); break;
628 case JNS_O8
: jns_o8((byte)reg0
); break;
629 case JP_O8
: jp_o8((byte)reg0
); break;
630 case JNP_O8
: jnp_o8((byte)reg0
); break;
631 case JL_O8
: jl_o8((byte)reg0
); break;
632 case JNL_O8
: jnl_o8((byte)reg0
); break;
633 case JNG_O8
: jng_o8((byte)reg0
); break;
634 case JG_O8
: jg_o8((byte)reg0
); break;
636 case JO_O16
: jo_o16((short)reg0
); break;
637 case JNO_O16
: jno_o16((short)reg0
); break;
638 case JC_O16
: jc_o16((short)reg0
); break;
639 case JNC_O16
: jnc_o16((short)reg0
); break;
640 case JZ_O16
: jz_o16((short)reg0
); break;
641 case JNZ_O16
: jnz_o16((short)reg0
); break;
642 case JNA_O16
: jna_o16((short)reg0
); break;
643 case JA_O16
: ja_o16((short)reg0
); break;
644 case JS_O16
: js_o16((short)reg0
); break;
645 case JNS_O16
: jns_o16((short)reg0
); break;
646 case JP_O16
: jp_o16((short)reg0
); break;
647 case JNP_O16
: jnp_o16((short)reg0
); break;
648 case JL_O16
: jl_o16((short)reg0
); break;
649 case JNL_O16
: jnl_o16((short)reg0
); break;
650 case JNG_O16
: jng_o16((short)reg0
); break;
651 case JG_O16
: jg_o16((short)reg0
); break;
653 case JO_O32
: jo_o32(reg0
); break;
654 case JNO_O32
: jno_o32(reg0
); break;
655 case JC_O32
: jc_o32(reg0
); break;
656 case JNC_O32
: jnc_o32(reg0
); break;
657 case JZ_O32
: jz_o32(reg0
); break;
658 case JNZ_O32
: jnz_o32(reg0
); break;
659 case JNA_O32
: jna_o32(reg0
); break;
660 case JA_O32
: ja_o32(reg0
); break;
661 case JS_O32
: js_o32(reg0
); break;
662 case JNS_O32
: jns_o32(reg0
); break;
663 case JP_O32
: jp_o32(reg0
); break;
664 case JNP_O32
: jnp_o32(reg0
); break;
665 case JL_O32
: jl_o32(reg0
); break;
666 case JNL_O32
: jnl_o32(reg0
); break;
667 case JNG_O32
: jng_o32(reg0
); break;
668 case JG_O32
: jg_o32(reg0
); break;
670 case JCXZ
: jcxz((byte)reg0
); break;
671 case JECXZ
: jecxz((byte)reg0
); break;
673 case LOOP_CX
: loop_cx((byte)reg0
); break;
674 case LOOP_ECX
: loop_ecx((byte)reg0
); break;
675 case LOOPZ_CX
: loopz_cx((byte)reg0
); break;
676 case LOOPZ_ECX
: loopz_ecx((byte)reg0
); break;
677 case LOOPNZ_CX
: loopnz_cx((byte)reg0
); break;
678 case LOOPNZ_ECX
: loopnz_ecx((byte)reg0
); break;
680 case JUMP_O8
: jump_o8((byte)reg0
); break;
681 case JUMP_O16
: jump_o16((short)reg0
); break;
682 case JUMP_O32
: jump_o32(reg0
); break;
684 case JUMP_ABS_O16
: jump_abs(reg0
); break;
685 case JUMP_ABS_O32
: jump_abs(reg0
); break;
687 case JUMP_FAR_O16
: jump_far(reg0
, reg1
); break;
688 case JUMP_FAR_O32
: jump_far(reg0
, reg1
); break;
692 if(cpu
.ss
.getDefaultSizeFlag())
699 if(cpu
.ss
.getDefaultSizeFlag())
706 if(cpu
.ss
.getDefaultSizeFlag())
707 call_abs_o16_a32(reg0
);
709 call_abs_o16_a16(reg0
);
713 if(cpu
.ss
.getDefaultSizeFlag())
714 call_abs_o32_a32(reg0
);
716 call_abs_o32_a16(reg0
);
720 if(cpu
.ss
.getDefaultSizeFlag())
721 call_far_o16_a32(reg0
, reg1
);
723 call_far_o16_a16(reg0
, reg1
);
727 if(cpu
.ss
.getDefaultSizeFlag())
728 call_far_o32_a32(reg0
, reg1
);
730 call_far_o32_a16(reg0
, reg1
);
734 if(cpu
.ss
.getDefaultSizeFlag())
741 if (cpu
.ss
.getDefaultSizeFlag())
748 if (cpu
.ss
.getDefaultSizeFlag())
749 ret_iw_o16_a32((short)reg0
);
751 ret_iw_o16_a16((short)reg0
);
755 if (cpu
.ss
.getDefaultSizeFlag())
756 ret_iw_o32_a32((short)reg0
);
758 ret_iw_o32_a16((short)reg0
);
762 if (cpu
.ss
.getDefaultSizeFlag())
770 if (cpu
.ss
.getDefaultSizeFlag())
776 case RET_FAR_IW_O16
: {
777 if (cpu
.ss
.getDefaultSizeFlag())
778 ret_far_o16_a32((short)reg0
);
780 ret_far_o16_a16((short)reg0
);
784 case RET_FAR_IW_O32
: {
785 if (cpu
.ss
.getDefaultSizeFlag())
786 ret_far_o32_a32((short)reg0
);
788 ret_far_o32_a16((short)reg0
);
793 cpu
.handleSoftProtectedModeInterrupt(reg0
, getInstructionLength(position
));
796 cpu
.handleSoftProtectedModeInterrupt(reg0
, getInstructionLength(position
));
800 cpu
.handleSoftProtectedModeInterrupt(3, getInstructionLength(position
));
804 if (cpu
.getOverflowFlag() == true)
805 cpu
.handleSoftProtectedModeInterrupt(4, getInstructionLength(position
));
809 if (cpu
.ss
.getDefaultSizeFlag())
810 reg0
= iret_o32_a32();
812 reg0
= iret_o32_a16();
816 if (cpu
.ss
.getDefaultSizeFlag())
817 reg0
= iret_o16_a32();
819 reg0
= iret_o16_a16();
822 case SYSENTER
: sysenter(); break;
823 case SYSEXIT
: sysexit(reg0
, reg1
); break;
825 case IN_O8
: reg0
= in_o8(reg0
); break;
826 case IN_O16
: reg0
= in_o16(reg0
); break;
827 case IN_O32
: reg0
= in_o32(reg0
); break;
829 case OUT_O8
: out_o8(reg0
, reg1
); break;
830 case OUT_O16
: out_o16(reg0
, reg1
); break;
831 case OUT_O32
: out_o32(reg0
, reg1
); break;
833 case CMOVO
: if (cpu
.getOverflowFlag()) reg0
= reg1
; break;
834 case CMOVNO
: if (!cpu
.getOverflowFlag()) reg0
= reg1
; break;
835 case CMOVC
: if (cpu
.getCarryFlag()) reg0
= reg1
; break;
836 case CMOVNC
: if (!cpu
.getCarryFlag()) reg0
= reg1
; break;
837 case CMOVZ
: if (cpu
.getZeroFlag()) reg0
= reg1
; break;
838 case CMOVNZ
: if (!cpu
.getZeroFlag()) reg0
= reg1
; break;
839 case CMOVNA
: if (cpu
.getCarryFlag() || cpu
.getZeroFlag()) reg0
= reg1
; break;
840 case CMOVA
: if ((!cpu
.getCarryFlag()) && (!cpu
.getZeroFlag())) reg0
= reg1
; break;
841 case CMOVS
: if (cpu
.getSignFlag()) reg0
= reg1
; break;
842 case CMOVNS
: if (!cpu
.getSignFlag()) reg0
= reg1
; break;
843 case CMOVP
: if (cpu
.getParityFlag()) reg0
= reg1
; break;
844 case CMOVNP
: if (!cpu
.getParityFlag()) reg0
= reg1
; break;
845 case CMOVL
: if (cpu
.getSignFlag() != cpu
.getOverflowFlag()) reg0
= reg1
; break;
846 case CMOVNL
: if (cpu
.getSignFlag() == cpu
.getOverflowFlag()) reg0
= reg1
; break;
847 case CMOVNG
: if (cpu
.getZeroFlag() || (cpu
.getSignFlag() != cpu
.getOverflowFlag())) reg0
= reg1
; break;
848 case CMOVG
: if ((!cpu
.getZeroFlag()) && (cpu
.getSignFlag() == cpu
.getOverflowFlag())) reg0
= reg1
; break;
850 case SETO
: reg0
= cpu
.getOverflowFlag() ?
1 : 0; break;
851 case SETNO
: reg0
= cpu
.getOverflowFlag() ?
0 : 1; break;
852 case SETC
: reg0
= cpu
.getCarryFlag() ?
1 : 0; break;
853 case SETNC
: reg0
= cpu
.getCarryFlag() ?
0 : 1; break;
854 case SETZ
: reg0
= cpu
.getZeroFlag() ?
1 : 0; break;
855 case SETNZ
: reg0
= cpu
.getZeroFlag() ?
0 : 1; break;
856 case SETNA
: reg0
= cpu
.getCarryFlag() || cpu
.getZeroFlag() ?
1 : 0; break;
857 case SETA
: reg0
= cpu
.getCarryFlag() || cpu
.getZeroFlag() ?
0 : 1; break;
858 case SETS
: reg0
= cpu
.getSignFlag() ?
1 : 0; break;
859 case SETNS
: reg0
= cpu
.getSignFlag() ?
0 : 1; break;
860 case SETP
: reg0
= cpu
.getParityFlag() ?
1 : 0; break;
861 case SETNP
: reg0
= cpu
.getParityFlag() ?
0 : 1; break;
862 case SETL
: reg0
= cpu
.getSignFlag() != cpu
.getOverflowFlag() ?
1 : 0; break;
863 case SETNL
: reg0
= cpu
.getSignFlag() != cpu
.getOverflowFlag() ?
0 : 1; break;
864 case SETNG
: reg0
= cpu
.getZeroFlag() || (cpu
.getSignFlag() != cpu
.getOverflowFlag()) ?
1 : 0; break;
865 case SETG
: reg0
= cpu
.getZeroFlag() || (cpu
.getSignFlag() != cpu
.getOverflowFlag()) ?
0 : 1; break;
867 case SALC
: reg0
= cpu
.getCarryFlag() ?
-1 : 0; break;
869 case SMSW
: reg0
= cpu
.getCR0() & 0xffff; break;
870 case LMSW
: if (cpu
.getCPL() != 0) throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
871 cpu
.setCR0((cpu
.getCR0() & ~
0xe) | (reg0
& 0xe)); break;
882 long edxeax
= ((cpu
.edx
& 0xffffffffL
) << 32) | (cpu
.eax
& 0xffffffffL
);
883 if (edxeax
== reg0l
) {
884 cpu
.setZeroFlag(true);
885 reg0l
= ((cpu
.ecx
& 0xffffffffL
) << 32) | (cpu
.ebx
& 0xffffffffL
);
887 cpu
.setZeroFlag(false);
888 cpu
.edx
= (int)(reg0l
>> 32);
889 cpu
.eax
= (int)reg0l
;
893 case BSWAP
: reg0
= reverseBytes(reg0
); break;
896 if (cpu
.ss
.getDefaultSizeFlag())
897 enter_o32_a32(reg0
, reg1
);
899 System
.err
.println("Critical error: need enter_o32_a16.");
900 throw new IllegalStateException("PMODE O32 A16 ENTER is unimplemented");
905 if (cpu
.ss
.getDefaultSizeFlag())
906 enter_o16_a32(reg0
, reg1
);
908 enter_o16_a16(reg0
, reg1
);
912 if (cpu
.ss
.getDefaultSizeFlag())
919 if (cpu
.ss
.getDefaultSizeFlag())
926 if (cpu
.ss
.getDefaultSizeFlag())
933 if (cpu
.ss
.getDefaultSizeFlag())
934 push_o16_a32((short)reg0
);
936 push_o16_a16((short)reg0
);
940 if (cpu
.ss
.getDefaultSizeFlag())
941 push_o32_a32(~
0x30000 & reg0
);
943 push_o32_a16(~
0x30000 & reg0
);
947 if (cpu
.ss
.getDefaultSizeFlag())
948 push_o16_a32((short)reg0
);
950 push_o16_a16((short)reg0
);
954 if (cpu
.ss
.getDefaultSizeFlag()) {
956 if (microcodes
[position
] == STORE0_SS
)
957 cpu
.eflagsInterruptEnable
= false;
958 reg0
= cpu
.ss
.getDoubleWord(cpu
.esp
);
960 reg1
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 4) & 0xffff);
961 if (microcodes
[position
] == STORE0_SS
)
962 cpu
.eflagsInterruptEnable
= false;
963 reg0
= cpu
.ss
.getDoubleWord(0xffff & cpu
.esp
);
968 if (cpu
.ss
.getDefaultSizeFlag()) {
970 if (microcodes
[position
] == STORE0_SS
)
971 cpu
.eflagsInterruptEnable
= false;
972 reg0
= 0xffff & cpu
.ss
.getWord(cpu
.esp
);
974 reg1
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 2) & 0xffff);
975 if (microcodes
[position
] == STORE0_SS
)
976 cpu
.eflagsInterruptEnable
= false;
977 reg0
= 0xffff & cpu
.ss
.getWord(0xffff & cpu
.esp
);
982 if (cpu
.ss
.getDefaultSizeFlag()) {
983 reg0
= cpu
.ss
.getDoubleWord(cpu
.esp
);
986 reg0
= cpu
.ss
.getDoubleWord(0xffff & cpu
.esp
);
987 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 4) & 0xffff);
989 if (cpu
.getCPL() == 0)
990 reg0
= ((cpu
.getEFlags() & 0x20000) | (reg0
& ~
(0x20000 | 0x180000)));
992 if (cpu
.getCPL() > cpu
.eflagsIOPrivilegeLevel
)
993 reg0
= ((cpu
.getEFlags() & 0x23200) | (reg0
& ~
(0x23200 | 0x180000)));
995 reg0
= ((cpu
.getEFlags() & 0x23000) | (reg0
& ~
(0x23000 | 0x180000)));
1000 if (cpu
.ss
.getDefaultSizeFlag()) {
1001 reg0
= 0xffff & cpu
.ss
.getWord(cpu
.esp
);
1004 reg0
= 0xffff & cpu
.ss
.getWord(0xffff & cpu
.esp
);
1005 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 2) & 0xffff);
1007 if (cpu
.getCPL() != 0)
1008 if (cpu
.getCPL() > cpu
.eflagsIOPrivilegeLevel
)
1009 reg0
= ((cpu
.getEFlags() & 0x3200) | (reg0
& ~
0x3200));
1011 reg0
= ((cpu
.getEFlags() & 0x3000) | (reg0
& ~
0x3000));
1015 if (cpu
.ss
.getDefaultSizeFlag())
1022 if (cpu
.ss
.getDefaultSizeFlag())
1029 if (cpu
.ss
.getDefaultSizeFlag())
1036 if (cpu
.ss
.getDefaultSizeFlag())
1042 case CMPSB_A32
: cmpsb_a32(seg0
); break;
1043 case CMPSW_A32
: cmpsw_a32(seg0
); break;
1044 case CMPSD_A32
: cmpsd_a32(seg0
); break;
1045 case REPE_CMPSB_A16
: repe_cmpsb_a16(seg0
); break;
1046 case REPE_CMPSB_A32
: repe_cmpsb_a32(seg0
); break;
1047 case REPE_CMPSW_A16
: repe_cmpsw_a16(seg0
); break;
1048 case REPE_CMPSW_A32
: repe_cmpsw_a32(seg0
); break;
1049 case REPE_CMPSD_A16
: repe_cmpsd_a16(seg0
); break;
1050 case REPE_CMPSD_A32
: repe_cmpsd_a32(seg0
); break;
1051 case REPNE_CMPSB_A16
: repne_cmpsb_a16(seg0
); break;
1052 case REPNE_CMPSW_A16
: repne_cmpsw_a16(seg0
); break;
1053 case REPNE_CMPSD_A16
: repne_cmpsd_a16(seg0
); break;
1054 case REPNE_CMPSB_A32
: repne_cmpsb_a32(seg0
); break;
1055 case REPNE_CMPSW_A32
: repne_cmpsw_a32(seg0
); break;
1056 case REPNE_CMPSD_A32
: repne_cmpsd_a32(seg0
); break;
1058 case INSB_A32
: insb_a32(reg0
); break;
1059 case INSW_A32
: insw_a32(reg0
); break;
1060 case INSD_A32
: insd_a32(reg0
); break;
1061 case REP_INSB_A32
: rep_insb_a32(reg0
); break;
1062 case REP_INSW_A32
: rep_insw_a32(reg0
); break;
1063 case REP_INSD_A32
: rep_insd_a32(reg0
); break;
1065 case LODSB_A16
: lodsb_a16(seg0
); break;
1066 case LODSB_A32
: lodsb_a32(seg0
); break;
1067 case LODSW_A16
: lodsw_a16(seg0
); break;
1068 case LODSW_A32
: lodsw_a32(seg0
); break;
1069 case LODSD_A32
: lodsd_a32(seg0
); break;
1070 case REP_LODSB_A32
: rep_lodsb_a32(seg0
); break;
1071 case REP_LODSW_A32
: rep_lodsw_a32(seg0
); break;
1072 case REP_LODSD_A32
: rep_lodsd_a32(seg0
); break;
1074 case MOVSB_A16
: movsb_a16(seg0
); break;
1075 case MOVSW_A16
: movsw_a16(seg0
); break;
1076 case MOVSD_A16
: movsd_a16(seg0
); break;
1077 case REP_MOVSB_A16
: rep_movsb_a16(seg0
); break;
1078 case REP_MOVSW_A16
: rep_movsw_a16(seg0
); break;
1079 case REP_MOVSD_A16
: rep_movsd_a16(seg0
); break;
1080 case MOVSB_A32
: movsb_a32(seg0
); break;
1081 case MOVSW_A32
: movsw_a32(seg0
); break;
1082 case MOVSD_A32
: movsd_a32(seg0
); break;
1083 case REP_MOVSB_A32
: rep_movsb_a32(seg0
); break;
1084 case REP_MOVSW_A32
: rep_movsw_a32(seg0
); break;
1085 case REP_MOVSD_A32
: rep_movsd_a32(seg0
); break;
1087 case OUTSB_A16
: outsb_a16(reg0
, seg0
); break;
1088 case OUTSW_A16
: outsw_a16(reg0
, seg0
); break;
1089 case OUTSD_A16
: outsd_a16(reg0
, seg0
); break;
1090 case REP_OUTSB_A16
: rep_outsb_a16(reg0
, seg0
); break;
1091 case REP_OUTSW_A16
: rep_outsw_a16(reg0
, seg0
); break;
1092 case REP_OUTSD_A16
: rep_outsd_a16(reg0
, seg0
); break;
1093 case OUTSB_A32
: outsb_a32(reg0
, seg0
); break;
1094 case OUTSW_A32
: outsw_a32(reg0
, seg0
); break;
1095 case OUTSD_A32
: outsd_a32(reg0
, seg0
); break;
1096 case REP_OUTSB_A32
: rep_outsb_a32(reg0
, seg0
); break;
1097 case REP_OUTSW_A32
: rep_outsw_a32(reg0
, seg0
); break;
1098 case REP_OUTSD_A32
: rep_outsd_a32(reg0
, seg0
); break;
1100 case SCASB_A16
: scasb_a16(reg0
); break;
1101 case SCASB_A32
: scasb_a32(reg0
); break;
1102 case SCASW_A32
: scasw_a32(reg0
); break;
1103 case SCASD_A32
: scasd_a32(reg0
); break;
1104 case REPE_SCASB_A16
: repe_scasb_a16(reg0
); break;
1105 case REPE_SCASB_A32
: repe_scasb_a32(reg0
); break;
1106 case REPE_SCASW_A16
: repe_scasw_a16(reg0
); break;
1107 case REPE_SCASW_A32
: repe_scasw_a32(reg0
); break;
1108 case REPE_SCASD_A16
: repe_scasd_a16(reg0
); break;
1109 case REPE_SCASD_A32
: repe_scasd_a32(reg0
); break;
1110 case REPNE_SCASB_A16
: repne_scasb_a16(reg0
); break;
1111 case REPNE_SCASB_A32
: repne_scasb_a32(reg0
); break;
1112 case REPNE_SCASW_A16
: repne_scasw_a16(reg0
); break;
1113 case REPNE_SCASW_A32
: repne_scasw_a32(reg0
); break;
1114 case REPNE_SCASD_A16
: repne_scasd_a16(reg0
); break;
1115 case REPNE_SCASD_A32
: repne_scasd_a32(reg0
); break;
1117 case STOSB_A16
: stosb_a16(reg0
); break;
1118 case STOSB_A32
: stosb_a32(reg0
); break;
1119 case STOSW_A16
: stosw_a16(reg0
); break;
1120 case STOSW_A32
: stosw_a32(reg0
); break;
1121 case STOSD_A16
: stosd_a16(reg0
); break;
1122 case STOSD_A32
: stosd_a32(reg0
); break;
1123 case REP_STOSB_A16
: rep_stosb_a16(reg0
); break;
1124 case REP_STOSB_A32
: rep_stosb_a32(reg0
); break;
1125 case REP_STOSW_A16
: rep_stosw_a16(reg0
); break;
1126 case REP_STOSW_A32
: rep_stosw_a32(reg0
); break;
1127 case REP_STOSD_A16
: rep_stosd_a16(reg0
); break;
1128 case REP_STOSD_A32
: rep_stosd_a32(reg0
); break;
1130 case LGDT_O16
: cpu
.gdtr
= cpu
.createDescriptorTableSegment(reg1
& 0x00ffffff, reg0
); break;
1131 case LGDT_O32
: cpu
.gdtr
= cpu
.createDescriptorTableSegment(reg1
, reg0
); break;
1132 case SGDT_O16
: reg1
= cpu
.gdtr
.getBase() & 0x00ffffff; reg0
= cpu
.gdtr
.getLimit(); break;
1133 case SGDT_O32
: reg1
= cpu
.gdtr
.getBase(); reg0
= cpu
.gdtr
.getLimit(); break;
1135 case LIDT_O16
: cpu
.idtr
= cpu
.createDescriptorTableSegment(reg1
& 0x00ffffff, reg0
); break;
1136 case LIDT_O32
: cpu
.idtr
= cpu
.createDescriptorTableSegment(reg1
, reg0
); break;
1137 case SIDT_O16
: reg1
= cpu
.idtr
.getBase() & 0x00ffffff; reg0
= cpu
.idtr
.getLimit(); break;
1138 case SIDT_O32
: reg1
= cpu
.idtr
.getBase(); reg0
= cpu
.idtr
.getLimit(); break;
1140 case LLDT
: cpu
.ldtr
= lldt(reg0
); break;
1141 case SLDT
: reg0
= 0xffff & cpu
.ldtr
.getSelector(); break;
1143 case LTR
: cpu
.tss
= ltr(reg0
); break;
1144 case STR
: reg0
= 0xffff & cpu
.tss
.getSelector(); break;
1148 Segment test
= cpu
.getSegment(reg0
& 0xffff);
1149 int type
= test
.getType();
1150 if (((type
& ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) == 0) || (((type
& ProtectedModeSegment
.TYPE_CODE_CONFORMING
) == 0) && ((cpu
.getCPL() > test
.getDPL()) || (test
.getRPL() > test
.getDPL()))))
1151 cpu
.setZeroFlag(false);
1153 cpu
.setZeroFlag(((type
& ProtectedModeSegment
.TYPE_CODE
) == 0) || ((type
& ProtectedModeSegment
.TYPE_CODE_READABLE
) != 0));
1154 } catch (ProcessorException e
) {
1155 cpu
.setZeroFlag(false);
1160 Segment test
= cpu
.getSegment(reg0
& 0xffff);
1161 int type
= test
.getType();
1162 if (((type
& ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) == 0) || (((type
& ProtectedModeSegment
.TYPE_CODE_CONFORMING
) == 0) && ((cpu
.getCPL() > test
.getDPL()) || (test
.getRPL() > test
.getDPL()))))
1163 cpu
.setZeroFlag(false);
1165 cpu
.setZeroFlag(((type
& ProtectedModeSegment
.TYPE_CODE
) == 0) && ((type
& ProtectedModeSegment
.TYPE_DATA_WRITABLE
) != 0));
1166 } catch (ProcessorException e
) {
1167 cpu
.setZeroFlag(false);
1170 case CLTS
: if (cpu
.getCPL() != 0) throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
1171 cpu
.setCR0(cpu
.getCR0() & ~
0x8); break;
1173 case INVLPG
: if (cpu
.getCPL() != 0) throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
1174 cpu
.linearMemory
.invalidateTLBEntry(seg0
.translateAddressRead(addr0
)); break;
1176 case CPUID
: cpuid(); break;
1178 case LAR
: reg0
= lar(reg0
, reg1
); break;
1179 case LSL
: reg0
= lsl(reg0
, reg1
); break;
1181 case WRMSR
: if (cpu
.getCPL() != 0) throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
1182 cpu
.setMSR(reg0
, (reg2
& 0xffffffffl
) | ((reg1
& 0xffffffffl
) << 32)); break;
1183 case RDMSR
: if (cpu
.getCPL() != 0) throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
1184 long msr
= cpu
.getMSR(reg0
); reg0
= (int)msr
; reg1
= (int)(msr
>>> 32); break;
1186 case RDTSC
: long tsc
= rdtsc(); reg0
= (int)tsc
; reg1
= (int)(tsc
>>> 32); break;
1188 case CMPXCHG_O8_FLAGS
: sub_o8_flags(reg2
- reg1
, reg2
, reg1
); break;
1189 case CMPXCHG_O16_FLAGS
: sub_o16_flags(reg2
- reg1
, reg2
, reg1
); break;
1190 case CMPXCHG_O32_FLAGS
: sub_o32_flags((0xffffffffl
& reg2
) - (0xffffffffl
& reg1
), reg2
, reg1
); break;
1192 case BITWISE_FLAGS_O8
: bitwise_flags((byte)reg0
); break;
1193 case BITWISE_FLAGS_O16
: bitwise_flags((short)reg0
); break;
1194 case BITWISE_FLAGS_O32
: bitwise_flags(reg0
); break;
1196 case SUB_O8_FLAGS
: sub_o8_flags(reg0
, reg2
, reg1
); break;
1197 case SUB_O16_FLAGS
: sub_o16_flags(reg0
, reg2
, reg1
); break;
1198 case SUB_O32_FLAGS
: sub_o32_flags(reg0l
, reg2
, reg1
); break;
1200 case ADD_O8_FLAGS
: add_o8_flags(reg0
, reg2
, reg1
); break;
1201 case ADD_O16_FLAGS
: add_o16_flags(reg0
, reg2
, reg1
); break;
1202 case ADD_O32_FLAGS
: add_o32_flags(reg0l
, reg2
, reg1
); break;
1204 case ADC_O8_FLAGS
: adc_o8_flags(reg0
, reg2
, reg1
); break;
1205 case ADC_O16_FLAGS
: adc_o16_flags(reg0
, reg2
, reg1
); break;
1206 case ADC_O32_FLAGS
: adc_o32_flags(reg0l
, reg2
, reg1
); break;
1208 case SBB_O8_FLAGS
: sbb_o8_flags(reg0
, reg2
, reg1
); break;
1209 case SBB_O16_FLAGS
: sbb_o16_flags(reg0
, reg2
, reg1
); break;
1210 case SBB_O32_FLAGS
: sbb_o32_flags(reg0l
, reg2
, reg1
); break;
1212 case INC_O8_FLAGS
: inc_flags((byte)reg0
); break;
1213 case INC_O16_FLAGS
: inc_flags((short)reg0
); break;
1214 case INC_O32_FLAGS
: inc_flags(reg0
); break;
1216 case DEC_O8_FLAGS
: dec_flags((byte)reg0
); break;
1217 case DEC_O16_FLAGS
: dec_flags((short)reg0
); break;
1218 case DEC_O32_FLAGS
: dec_flags(reg0
); break;
1220 case SHL_O8_FLAGS
: shl_flags((byte)reg0
, (byte)reg2
, reg1
); break;
1221 case SHL_O16_FLAGS
: shl_flags((short)reg0
, (short)reg2
, reg1
); break;
1222 case SHL_O32_FLAGS
: shl_flags(reg0
, reg2
, reg1
); break;
1224 case SHR_O8_FLAGS
: shr_flags((byte)reg0
, reg2
, reg1
); break;
1225 case SHR_O16_FLAGS
: shr_flags((short)reg0
, reg2
, reg1
); break;
1226 case SHR_O32_FLAGS
: shr_flags(reg0
, reg2
, reg1
); break;
1228 case SAR_O8_FLAGS
: sar_flags((byte)reg0
, (byte)reg2
, reg1
); break;
1229 case SAR_O16_FLAGS
: sar_flags((short)reg0
, (short)reg2
, reg1
); break;
1230 case SAR_O32_FLAGS
: sar_flags(reg0
, reg2
, reg1
); break;
1232 case RCL_O8_FLAGS
: rcl_o8_flags(reg0
, reg1
); break;
1233 case RCL_O16_FLAGS
: rcl_o16_flags(reg0
, reg1
); break;
1234 case RCL_O32_FLAGS
: rcl_o32_flags(reg0l
, reg1
); break;
1236 case RCR_O8_FLAGS
: rcr_o8_flags(reg0
, reg1
, reg2
); break;
1237 case RCR_O16_FLAGS
: rcr_o16_flags(reg0
, reg1
, reg2
); break;
1238 case RCR_O32_FLAGS
: rcr_o32_flags(reg0l
, reg1
, reg2
); break;
1240 case ROL_O8_FLAGS
: rol_flags((byte)reg0
, reg1
); break;
1241 case ROL_O16_FLAGS
: rol_flags((short)reg0
, reg1
); break;
1242 case ROL_O32_FLAGS
: rol_flags(reg0
, reg1
); break;
1244 case ROR_O8_FLAGS
: ror_flags((byte)reg0
, reg1
); break;
1245 case ROR_O16_FLAGS
: ror_flags((short)reg0
, reg1
); break;
1246 case ROR_O32_FLAGS
: ror_flags(reg0
, reg1
); break;
1248 case NEG_O8_FLAGS
: neg_flags((byte)reg0
); break;
1249 case NEG_O16_FLAGS
: neg_flags((short)reg0
); break;
1250 case NEG_O32_FLAGS
: neg_flags(reg0
); break;
1253 if(cpu
.getCPL() != 0)
1254 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);
1257 case INSTRUCTION_START
:
1259 if(cpu
.eflagsMachineHalt
) throw ProcessorException
.TRACESTOP
;
1260 //HALT being aborted is special.
1261 if(!cpu
.eflagsWaiting
)
1262 cpu
.instructionExecuted();
1265 if(!Misc
.isFPUOp(microcodes
[position
- 1])) {
1266 System
.err
.println("Critical error: Unknown uCode " + microcodes
[position
- 1] + ".");
1267 throw new IllegalStateException("Unknown uCode P" + microcodes
[position
- 1]);
1270 cpu
.useFPU(microcodes
[position
- 1] == FWAIT
);
1271 int x
= fpu
.doFPUOp(microcodes
[position
- 1], microcodes
[position
], seg0
, addr0
, reg0
, reg1
, reg2
,
1273 //Handle buffer updates.
1274 if((x
& 1) != 0) reg0
= fpu
.getReg0();
1275 if((x
& 2) != 0) reg1
= fpu
.getReg1();
1276 if((x
& 4) != 0) reg2
= fpu
.getReg2();
1277 if((x
& 8) != 0) reg0l
= fpu
.getReg0l();
1278 if((x
& 16) != 0) position
++;
1281 } catch (ProcessorException e
) {
1282 int nextPosition
= position
- 1; //this makes position point at the microcode that just barfed
1285 cpu
.eip
-= cumulativeX86Length
[nextPosition
]; // undo the eipUpdate
1287 if (!e
.pointsToSelf()) {
1288 cpu
.eip
+= cumulativeX86Length
[nextPosition
];
1290 for (int selfPosition
= nextPosition
; selfPosition
>= 0; selfPosition
--) {
1291 if (cumulativeX86Length
[selfPosition
] != cumulativeX86Length
[nextPosition
]) {
1292 cpu
.eip
+= cumulativeX86Length
[selfPosition
];
1298 if(e
.getType() == ProcessorException
.Type
.TASK_SWITCH
)
1299 e
.printStackTrace();
1301 if(e
.getType() != ProcessorException
.Type
.PAGE_FAULT
&& e
.getType() != ProcessorException
.Type
.TRACESTOP
&& e
.getType() != ProcessorException
.Type
.NO_FPU
) {
1302 boolean isGPF
= (e
.getType() == ProcessorException
.Type
.GENERAL_PROTECTION
);
1303 boolean isHalt
= isGPF
&& haltComplained
.containsKey(position
-1);
1304 boolean isFirstHalt
= isHalt
&& (haltComplained
.get(position
- 1) == 1);
1305 if(!isHalt
&& isGPF
)
1306 e
.printStackTrace();
1307 if(!isHalt
|| isFirstHalt
) {
1308 System
.err
.println("Emulated: cs selector = " + Integer
.toHexString(cpu
.cs
.getSelector())
1309 + ", cs base = " + Integer
.toHexString(cpu
.cs
.getBase()) + ", EIP = "
1310 + Integer
.toHexString(cpu
.eip
));
1311 System
.err
.println("Emulated: processor exception at 0x" +
1312 Integer
.toHexString(cpu
.cs
.translateAddressRead(cpu
.eip
)) + ": " + e
);
1316 if(e
.getType() != ProcessorException
.Type
.TRACESTOP
) //Swallow trace stops!
1317 cpu
.handleProtectedModeException(e
);
1320 cpu
.eflagsLastAborted
= true;
1322 } catch (IllegalStateException e
) {
1323 System
.err
.println("Critical error: Failed at index: " + (position
-1) + " with microcode: " +
1324 microcodes
[position
-1]);
1325 System
.err
.println("Informational: Microcodes for failed block:");
1326 System
.err
.println(this.getDisplayString());
1328 } catch (NullPointerException e
) {
1329 System
.err
.println("Critical error: Failed at index: " + (position
-1) + " with microcode: " +
1330 microcodes
[position
-1]);
1331 System
.err
.println("Informational: Microcodes for failed block:");
1332 System
.err
.println(this.getDisplayString());
1336 return Math
.max(executeCount
, 0);
1339 private int getInstructionLength(int position
)
1341 int nextPosition
= position
- 1; //this makes position point at the microcode that just barfed
1343 int ans
= -cumulativeX86Length
[nextPosition
]; // undo the eipUpdate
1345 for (int selfPosition
= nextPosition
; selfPosition
>= 0; selfPosition
--) {
1346 if (cumulativeX86Length
[selfPosition
] != cumulativeX86Length
[nextPosition
]) {
1347 ans
+= cumulativeX86Length
[selfPosition
];
1352 ans
= -ans
; // instruction was first instruction in block
1356 private final void cmpsb_a32(Segment seg0
)
1358 int addrOne
= cpu
.esi
;
1359 int addrTwo
= cpu
.edi
;
1361 int dataOne
= 0xff & seg0
.getByte(addrOne
);
1362 int dataTwo
= 0xff & cpu
.es
.getByte(addrTwo
);
1363 if (cpu
.eflagsDirection
) {
1374 sub_o8_flags(dataOne
- dataTwo
, dataOne
, dataTwo
);
1377 private final void cmpsw_a32(Segment seg0
)
1379 int addrOne
= cpu
.esi
;
1380 int addrTwo
= cpu
.edi
;
1382 int dataOne
= 0xffff & seg0
.getWord(addrOne
);
1383 int dataTwo
= 0xffff & cpu
.es
.getWord(addrTwo
);
1384 if (cpu
.eflagsDirection
) {
1395 sub_o16_flags(dataOne
- dataTwo
, dataOne
, dataTwo
);
1398 private final void cmpsd_a32(Segment seg0
)
1400 int addrOne
= cpu
.esi
;
1401 int addrTwo
= cpu
.edi
;
1403 int dataOne
= seg0
.getDoubleWord(addrOne
);
1404 int dataTwo
= cpu
.es
.getDoubleWord(addrTwo
);
1405 if (cpu
.eflagsDirection
) {
1416 sub_o32_flags((0xffffffffl
& dataOne
) - (0xffffffffl
& dataTwo
), dataOne
, dataTwo
);
1419 private final void repe_cmpsb_a16(Segment seg0
)
1421 int count
= 0xFFFF & cpu
.ecx
;
1422 int addrOne
= 0xFFFF & cpu
.esi
;
1423 int addrTwo
= 0xFFFF & cpu
.edi
;
1424 boolean used
= count
!= 0;
1429 if (cpu
.eflagsDirection
) {
1430 while (count
!= 0) {
1431 //check hardware interrupts
1432 dataOne
= 0xff & seg0
.getByte(addrOne
);
1433 dataTwo
= 0xff & cpu
.es
.getByte(addrTwo
);
1437 if (dataOne
!= dataTwo
) break;
1440 while (count
!= 0) {
1441 //check hardware interrupts
1442 dataOne
= 0xff & seg0
.getByte(addrOne
);
1443 dataTwo
= 0xff & cpu
.es
.getByte(addrTwo
);
1447 if (dataOne
!= dataTwo
) break;
1452 executeCount
+= ((cpu
.ecx
&0xFFFF) - count
);
1453 cpu
.ecx
= (cpu
.ecx
& ~
0xFFFF)|(count
& 0xFFFF);
1454 cpu
.esi
= (cpu
.esi
& ~
0xFFFF)|(addrOne
& 0xFFFF);
1455 cpu
.edi
= (cpu
.edi
& ~
0xFFFF)|(addrTwo
& 0xFFFF);
1458 sub_o8_flags(dataOne
- dataTwo
, dataOne
, dataTwo
);
1462 private final void repe_cmpsb_a32(Segment seg0
)
1464 int count
= cpu
.ecx
;
1465 int addrOne
= cpu
.esi
;
1466 int addrTwo
= cpu
.edi
;
1467 boolean used
= count
!= 0;
1472 if (cpu
.eflagsDirection
) {
1473 while (count
!= 0) {
1474 //check hardware interrupts
1475 dataOne
= 0xff & seg0
.getByte(addrOne
);
1476 dataTwo
= 0xff & cpu
.es
.getByte(addrTwo
);
1480 if (dataOne
!= dataTwo
) break;
1483 while (count
!= 0) {
1484 //check hardware interrupts
1485 dataOne
= 0xff & seg0
.getByte(addrOne
);
1486 dataTwo
= 0xff & cpu
.es
.getByte(addrTwo
);
1490 if (dataOne
!= dataTwo
) break;
1495 executeCount
+= (cpu
.ecx
- count
);
1501 sub_o8_flags(dataOne
- dataTwo
, dataOne
, dataTwo
);
1505 private final void repe_cmpsw_a16(Segment seg0
)
1507 int count
= 0xFFFF & cpu
.ecx
;
1508 int addrOne
= 0xFFFF & cpu
.esi
;
1509 int addrTwo
= 0xFFFF & cpu
.edi
;
1510 boolean used
= count
!= 0;
1515 if (cpu
.eflagsDirection
) {
1516 while (count
!= 0) {
1517 //check hardware interrupts
1518 dataOne
= 0xffff & seg0
.getWord(addrOne
);
1519 dataTwo
= 0xffff & cpu
.es
.getWord(addrTwo
);
1523 if (dataOne
!= dataTwo
) break;
1526 while (count
!= 0) {
1527 //check hardware interrupts
1528 dataOne
= 0xffff & seg0
.getWord(addrOne
);
1529 dataTwo
= 0xffff & cpu
.es
.getWord(addrTwo
);
1533 if (dataOne
!= dataTwo
) break;
1538 executeCount
+= ((cpu
.ecx
&0xFFFF) - count
);
1539 cpu
.ecx
= (cpu
.ecx
& ~
0xFFFF)|(count
& 0xFFFF);
1540 cpu
.esi
= (cpu
.esi
& ~
0xFFFF)|(addrOne
& 0xFFFF);
1541 cpu
.edi
= (cpu
.edi
& ~
0xFFFF)|(addrTwo
& 0xFFFF);
1544 sub_o16_flags(dataOne
- dataTwo
, dataOne
, dataTwo
);
1548 private final void repe_cmpsw_a32(Segment seg0
)
1550 int count
= cpu
.ecx
;
1551 int addrOne
= cpu
.esi
;
1552 int addrTwo
= cpu
.edi
;
1553 boolean used
= count
!= 0;
1558 if (cpu
.eflagsDirection
) {
1559 while (count
!= 0) {
1560 //check hardware interrupts
1561 dataOne
= 0xffff & seg0
.getWord(addrOne
);
1562 dataTwo
= 0xffff & cpu
.es
.getWord(addrTwo
);
1566 if (dataOne
!= dataTwo
) break;
1569 while (count
!= 0) {
1570 //check hardware interrupts
1571 dataOne
= 0xffff & seg0
.getWord(addrOne
);
1572 dataTwo
= 0xffff & cpu
.es
.getWord(addrTwo
);
1576 if (dataOne
!= dataTwo
) break;
1581 executeCount
+= (cpu
.ecx
- count
);
1587 sub_o16_flags(dataOne
- dataTwo
, dataOne
, dataTwo
);
1591 private final void repe_cmpsd_a16(Segment seg0
)
1593 int count
= 0xFFFF & cpu
.ecx
;
1594 int addrOne
= 0xFFFF & cpu
.esi
;
1595 int addrTwo
= 0xFFFF & cpu
.edi
;
1596 boolean used
= count
!= 0;
1601 if (cpu
.eflagsDirection
) {
1602 while (count
!= 0) {
1603 //check hardware interrupts
1604 dataOne
= seg0
.getDoubleWord(addrOne
);
1605 dataTwo
= cpu
.es
.getDoubleWord(addrTwo
);
1609 if (dataOne
!= dataTwo
) break;
1612 while (count
!= 0) {
1613 //check hardware interrupts
1614 dataOne
= seg0
.getDoubleWord(addrOne
);
1615 dataTwo
= cpu
.es
.getDoubleWord(addrTwo
);
1619 if (dataOne
!= dataTwo
) break;
1624 executeCount
+= ((cpu
.ecx
&0xFFFF) - count
);
1625 cpu
.ecx
= (cpu
.ecx
& ~
0xFFFF)|(count
& 0xFFFF);
1626 cpu
.esi
= (cpu
.esi
& ~
0xFFFF)|(addrOne
& 0xFFFF);
1627 cpu
.edi
= (cpu
.edi
& ~
0xFFFF)|(addrTwo
& 0xFFFF);
1630 sub_o32_flags((0xffffffffl
& dataOne
) - (0xffffffffl
& dataTwo
), dataOne
, dataTwo
);
1634 private final void repe_cmpsd_a32(Segment seg0
)
1636 int count
= cpu
.ecx
;
1637 int addrOne
= cpu
.esi
;
1638 int addrTwo
= cpu
.edi
;
1639 boolean used
= count
!= 0;
1644 if (cpu
.eflagsDirection
) {
1645 while (count
!= 0) {
1646 //check hardware interrupts
1647 dataOne
= seg0
.getDoubleWord(addrOne
);
1648 dataTwo
= cpu
.es
.getDoubleWord(addrTwo
);
1652 if (dataOne
!= dataTwo
) break;
1655 while (count
!= 0) {
1656 //check hardware interrupts
1657 dataOne
= seg0
.getDoubleWord(addrOne
);
1658 dataTwo
= cpu
.es
.getDoubleWord(addrTwo
);
1662 if (dataOne
!= dataTwo
) break;
1667 executeCount
+= (cpu
.ecx
- count
);
1673 sub_o32_flags((0xffffffffl
& dataOne
) - (0xffffffffl
& dataTwo
), dataOne
, dataTwo
);
1677 private final void repne_cmpsb_a16(Segment seg0
)
1679 int count
= 0xFFFF & cpu
.ecx
;
1680 int addrOne
= 0xFFFF & cpu
.esi
;
1681 int addrTwo
= 0xFFFF & cpu
.edi
;
1682 boolean used
= count
!= 0;
1687 if (cpu
.eflagsDirection
) {
1688 while (count
!= 0) {
1689 //check hardware interrupts
1690 dataOne
= 0xff & seg0
.getByte(addrOne
);
1691 dataTwo
= 0xff & cpu
.es
.getByte(addrTwo
);
1695 if (dataOne
== dataTwo
) break;
1698 while (count
!= 0) {
1699 //check hardware interrupts
1700 dataOne
= 0xff & seg0
.getByte(addrOne
);
1701 dataTwo
= 0xff & cpu
.es
.getByte(addrTwo
);
1705 if (dataOne
== dataTwo
) break;
1710 executeCount
+= ((cpu
.ecx
&0xFFFF) - count
);
1711 cpu
.ecx
= (cpu
.ecx
& ~
0xFFFF)|(count
& 0xFFFF);
1712 cpu
.esi
= (cpu
.esi
& ~
0xFFFF)|(addrOne
& 0xFFFF);
1713 cpu
.edi
= (cpu
.edi
& ~
0xFFFF)|(addrTwo
& 0xFFFF);
1716 sub_o8_flags(dataOne
- dataTwo
, dataOne
, dataTwo
);
1721 private final void repne_cmpsb_a32(Segment seg0
)
1723 int count
= cpu
.ecx
;
1724 int addrOne
= cpu
.esi
;
1725 int addrTwo
= cpu
.edi
;
1726 boolean used
= count
!= 0;
1731 if (cpu
.eflagsDirection
) {
1732 while (count
!= 0) {
1733 //check hardware interrupts
1734 dataOne
= 0xff & seg0
.getByte(addrOne
);
1735 dataTwo
= 0xff & cpu
.es
.getByte(addrTwo
);
1739 if (dataOne
== dataTwo
) break;
1742 while (count
!= 0) {
1743 //check hardware interrupts
1744 dataOne
= 0xff & seg0
.getByte(addrOne
);
1745 dataTwo
= 0xff & cpu
.es
.getByte(addrTwo
);
1749 if (dataOne
== dataTwo
) break;
1754 executeCount
+= (cpu
.ecx
- count
);
1760 sub_o8_flags(dataOne
- dataTwo
, dataOne
, dataTwo
);
1764 private final void repne_cmpsw_a16(Segment seg0
)
1766 int count
= 0xFFFF & cpu
.ecx
;
1767 int addrOne
= 0xFFFF & cpu
.esi
;
1768 int addrTwo
= 0xFFFF & cpu
.edi
;
1769 boolean used
= count
!= 0;
1774 if (cpu
.eflagsDirection
) {
1775 while (count
!= 0) {
1776 //check hardware interrupts
1777 dataOne
= 0xffff & seg0
.getWord(addrOne
);
1778 dataTwo
= 0xffff & cpu
.es
.getWord(addrTwo
);
1782 if (dataOne
== dataTwo
) break;
1785 while (count
!= 0) {
1786 //check hardware interrupts
1787 dataOne
= 0xffff & seg0
.getWord(addrOne
);
1788 dataTwo
= 0xffff & cpu
.es
.getWord(addrTwo
);
1792 if (dataOne
== dataTwo
) break;
1797 executeCount
+= ((cpu
.ecx
&0xFFFF) - count
);
1798 cpu
.ecx
= (cpu
.ecx
& ~
0xFFFF)|(count
& 0xFFFF);
1799 cpu
.esi
= (cpu
.esi
& ~
0xFFFF)|(addrOne
& 0xFFFF);
1800 cpu
.edi
= (cpu
.edi
& ~
0xFFFF)|(addrTwo
& 0xFFFF);
1803 sub_o16_flags(dataOne
- dataTwo
, dataOne
, dataTwo
);
1808 private final void repne_cmpsw_a32(Segment seg0
)
1810 int count
= cpu
.ecx
;
1811 int addrOne
= cpu
.esi
;
1812 int addrTwo
= cpu
.edi
;
1813 boolean used
= count
!= 0;
1818 if (cpu
.eflagsDirection
) {
1819 while (count
!= 0) {
1820 //check hardware interrupts
1821 dataOne
= 0xffff & seg0
.getWord(addrOne
);
1822 dataTwo
= 0xffff & cpu
.es
.getWord(addrTwo
);
1826 if (dataOne
== dataTwo
) break;
1829 while (count
!= 0) {
1830 //check hardware interrupts
1831 dataOne
= 0xffff & seg0
.getWord(addrOne
);
1832 dataTwo
= 0xffff & cpu
.es
.getWord(addrTwo
);
1836 if (dataOne
== dataTwo
) break;
1841 executeCount
+= (cpu
.ecx
- count
);
1847 sub_o16_flags(dataOne
- dataTwo
, dataOne
, dataTwo
);
1851 private final void repne_cmpsd_a16(Segment seg0
)
1853 int count
= 0xFFFF & cpu
.ecx
;
1854 int addrOne
= 0xFFFF & cpu
.esi
;
1855 int addrTwo
= 0xFFFF & cpu
.edi
;
1856 boolean used
= count
!= 0;
1861 if (cpu
.eflagsDirection
) {
1862 while (count
!= 0) {
1863 //check hardware interrupts
1864 dataOne
= seg0
.getDoubleWord(addrOne
);
1865 dataTwo
= cpu
.es
.getDoubleWord(addrTwo
);
1869 if (dataOne
== dataTwo
) break;
1872 while (count
!= 0) {
1873 //check hardware interrupts
1874 dataOne
= seg0
.getDoubleWord(addrOne
);
1875 dataTwo
= cpu
.es
.getDoubleWord(addrTwo
);
1879 if (dataOne
== dataTwo
) break;
1884 executeCount
+= ((cpu
.ecx
&0xFFFF) - count
);
1885 cpu
.ecx
= (cpu
.ecx
& ~
0xFFFF)|(count
& 0xFFFF);
1886 cpu
.esi
= (cpu
.esi
& ~
0xFFFF)|(addrOne
& 0xFFFF);
1887 cpu
.edi
= (cpu
.edi
& ~
0xFFFF)|(addrTwo
& 0xFFFF);
1890 sub_o32_flags((0xffffffffl
& dataOne
) - (0xffffffffl
& dataTwo
), dataOne
, dataTwo
);
1894 private final void repne_cmpsd_a32(Segment seg0
)
1896 int count
= cpu
.ecx
;
1897 int addrOne
= cpu
.esi
;
1898 int addrTwo
= cpu
.edi
;
1899 boolean used
= count
!= 0;
1904 if (cpu
.eflagsDirection
) {
1905 while (count
!= 0) {
1906 //check hardware interrupts
1907 dataOne
= seg0
.getDoubleWord(addrOne
);
1908 dataTwo
= cpu
.es
.getDoubleWord(addrTwo
);
1912 if (dataOne
== dataTwo
) break;
1915 while (count
!= 0) {
1916 //check hardware interrupts
1917 dataOne
= cpu
.es
.getDoubleWord(addrOne
);
1918 dataTwo
= seg0
.getDoubleWord(addrTwo
);
1922 if (dataOne
== dataTwo
) break;
1927 executeCount
+= (cpu
.ecx
- count
);
1933 sub_o32_flags((0xffffffffl
& dataOne
) - (0xffffffffl
& dataTwo
), dataOne
, dataTwo
);
1937 private final void insb_a32(int port
)
1939 if (!checkIOPermissionsByte(port
)) {
1940 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
1941 " at cpl " + cpu
.getCPL() + ".");
1942 throw ProcessorException
.GENERAL_PROTECTION_0
;
1946 cpu
.es
.setByte(addr
, (byte)cpu
.ioports
.ioPortReadByte(port
));
1947 if (cpu
.eflagsDirection
) {
1956 private final void insw_a32(int port
)
1958 if (!checkIOPermissionsShort(port
)) {
1959 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
1960 " at cpl " + cpu
.getCPL() + ".");
1961 throw ProcessorException
.GENERAL_PROTECTION_0
;
1965 cpu
.es
.setWord(addr
, (short)cpu
.ioports
.ioPortReadWord(port
));
1966 if (cpu
.eflagsDirection
) {
1975 private final void insd_a32(int port
)
1977 if (!checkIOPermissionsInt(port
)) {
1978 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
1979 " at cpl " + cpu
.getCPL() + ".");
1980 throw ProcessorException
.GENERAL_PROTECTION_0
;
1984 cpu
.es
.setDoubleWord(addr
, cpu
.ioports
.ioPortReadLong(port
));
1985 if (cpu
.eflagsDirection
) {
1994 private final void rep_insb_a32(int port
)
1996 if (!checkIOPermissionsByte(port
)) {
1997 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
1998 " at cpl " + cpu
.getCPL() + ".");
1999 throw ProcessorException
.GENERAL_PROTECTION_0
;
2002 int count
= cpu
.ecx
;
2004 executeCount
+= count
;
2007 if (cpu
.eflagsDirection
) {
2008 while (count
!= 0) {
2009 //check hardware interrupts
2010 cpu
.es
.setByte(addr
, (byte)cpu
.ioports
.ioPortReadByte(port
));
2015 while (count
!= 0) {
2016 //check hardware interrupts
2017 cpu
.es
.setByte(addr
, (byte)cpu
.ioports
.ioPortReadByte(port
));
2029 private final void rep_insw_a32(int port
)
2031 if (!checkIOPermissionsShort(port
)) {
2032 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
2033 " at cpl " + cpu
.getCPL() + ".");
2034 throw ProcessorException
.GENERAL_PROTECTION_0
;
2037 int count
= cpu
.ecx
;
2039 executeCount
+= count
;
2042 if (cpu
.eflagsDirection
) {
2043 while (count
!= 0) {
2044 //check hardware interrupts
2045 cpu
.es
.setWord(addr
, (short)cpu
.ioports
.ioPortReadWord(port
));
2050 while (count
!= 0) {
2051 //check hardware interrupts
2052 cpu
.es
.setWord(addr
, (short)cpu
.ioports
.ioPortReadWord(port
));
2064 private final void rep_insd_a32(int port
)
2066 if (!checkIOPermissionsShort(port
)) {
2067 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
2068 " at cpl " + cpu
.getCPL() + ".");
2069 throw ProcessorException
.GENERAL_PROTECTION_0
;
2072 int count
= cpu
.ecx
;
2074 executeCount
+= count
;
2077 if (cpu
.eflagsDirection
) {
2078 while (count
!= 0) {
2079 //check hardware interrupts
2080 cpu
.es
.setDoubleWord(addr
, cpu
.ioports
.ioPortReadLong(port
));
2085 while (count
!= 0) {
2086 //check hardware interrupts
2087 cpu
.es
.setDoubleWord(addr
, cpu
.ioports
.ioPortReadLong(port
));
2099 private final void lodsb_a16(Segment dataSegment
)
2101 int addr
= 0xFFFF & cpu
.esi
;
2102 cpu
.eax
= (cpu
.eax
& ~
0xff) | (0xff & dataSegment
.getByte(addr
));
2104 if (cpu
.eflagsDirection
)
2109 cpu
.esi
=(cpu
.esi
& ~
0xffff) | (0xffff & addr
);
2112 private final void lodsb_a32(Segment dataSegment
)
2115 cpu
.eax
= (cpu
.eax
& ~
0xff) | (0xff & dataSegment
.getByte(addr
));
2117 if (cpu
.eflagsDirection
)
2125 private final void lodsw_a16(Segment dataSegment
)
2127 int addr
= cpu
.esi
& 0xFFFF;
2128 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (0xffff & dataSegment
.getWord(addr
));
2130 if (cpu
.eflagsDirection
)
2135 cpu
.esi
=(cpu
.esi
& ~
0xffff) | (0xffff & addr
);
2138 private final void lodsw_a32(Segment dataSegment
)
2141 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (0xffff & dataSegment
.getWord(addr
));
2143 if (cpu
.eflagsDirection
)
2151 private final void lodsd_a32(Segment dataSegment
)
2154 cpu
.eax
= dataSegment
.getDoubleWord(addr
);
2156 if (cpu
.eflagsDirection
)
2164 private final void rep_lodsb_a32(Segment dataSegment
)
2166 int count
= cpu
.ecx
;
2168 int data
= cpu
.eax
& 0xff;
2169 executeCount
+= count
;
2172 if (cpu
.eflagsDirection
) {
2173 while (count
!= 0) {
2174 //check hardware interrupts
2175 data
= 0xff & dataSegment
.getByte(addr
);
2180 while (count
!= 0) {
2181 //check hardware interrupts
2182 data
= 0xff & dataSegment
.getByte(addr
);
2189 cpu
.eax
= (cpu
.eax
& ~
0xff) | data
;
2195 private final void rep_lodsw_a32(Segment dataSegment
)
2197 int count
= cpu
.ecx
;
2199 int data
= cpu
.eax
& 0xffff;
2200 executeCount
+= count
;
2203 if (cpu
.eflagsDirection
) {
2204 while (count
!= 0) {
2205 //check hardware interrupts
2206 data
= 0xffff & dataSegment
.getWord(addr
);
2211 while (count
!= 0) {
2212 //check hardware interrupts
2213 data
= 0xffff & dataSegment
.getWord(addr
);
2220 cpu
.eax
= (cpu
.eax
& ~
0xffff) | data
;
2226 private final void rep_lodsd_a32(Segment dataSegment
)
2228 int count
= cpu
.ecx
;
2231 executeCount
+= count
;
2234 if (cpu
.eflagsDirection
) {
2235 while (count
!= 0) {
2236 //check hardware interrupts
2237 data
= dataSegment
.getDoubleWord(addr
);
2242 while (count
!= 0) {
2243 //check hardware interrupts
2244 data
= dataSegment
.getDoubleWord(addr
);
2257 private final void movsb_a16(Segment outSegment
)
2259 int inAddr
= cpu
.edi
& 0xffff;
2260 int outAddr
= cpu
.esi
& 0xffff;
2262 cpu
.es
.setByte(inAddr
, outSegment
.getByte(outAddr
));
2263 if (cpu
.eflagsDirection
) {
2271 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (inAddr
& 0xffff);
2272 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (outAddr
& 0xffff);
2275 private final void movsw_a16(Segment outSegment
)
2277 int inAddr
= cpu
.edi
& 0xffff;
2278 int outAddr
= cpu
.esi
& 0xffff;
2280 cpu
.es
.setWord(inAddr
, outSegment
.getWord(outAddr
));
2281 if (cpu
.eflagsDirection
) {
2289 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (inAddr
& 0xffff);
2290 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (outAddr
& 0xffff);
2293 private final void movsd_a16(Segment outSegment
)
2295 int inAddr
= cpu
.edi
& 0xffff;
2296 int outAddr
= cpu
.esi
& 0xffff;
2298 cpu
.es
.setDoubleWord(inAddr
, outSegment
.getDoubleWord(outAddr
));
2299 if (cpu
.eflagsDirection
) {
2307 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (inAddr
& 0xffff);
2308 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (outAddr
& 0xffff);
2311 private final void rep_movsb_a16(Segment outSegment
)
2313 int count
= cpu
.ecx
& 0xffff;
2314 int inAddr
= cpu
.edi
& 0xffff;
2315 int outAddr
= cpu
.esi
& 0xffff;
2316 executeCount
+= count
;
2319 if (cpu
.eflagsDirection
) {
2320 while (count
!= 0) {
2321 //check hardware interrupts
2322 cpu
.es
.setByte(inAddr
& 0xffff, outSegment
.getByte(outAddr
& 0xffff));
2328 while (count
!= 0) {
2329 //check hardware interrupts
2330 cpu
.es
.setByte(inAddr
& 0xffff, outSegment
.getByte(outAddr
& 0xffff));
2338 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2339 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (inAddr
& 0xffff);
2340 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (outAddr
& 0xffff);
2344 private final void rep_movsw_a16(Segment outSegment
)
2346 int count
= cpu
.ecx
& 0xffff;
2347 int inAddr
= cpu
.edi
& 0xffff;
2348 int outAddr
= cpu
.esi
& 0xffff;
2349 executeCount
+= count
;
2352 if (cpu
.eflagsDirection
) {
2353 while (count
!= 0) {
2354 //check hardware interrupts
2355 cpu
.es
.setWord(inAddr
& 0xffff, outSegment
.getWord(outAddr
& 0xffff));
2361 while (count
!= 0) {
2362 //check hardware interrupts
2363 cpu
.es
.setWord(inAddr
& 0xffff, outSegment
.getWord(outAddr
& 0xffff));
2371 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2372 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (inAddr
& 0xffff);
2373 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (outAddr
& 0xffff);
2377 private final void rep_movsd_a16(Segment outSegment
)
2379 int count
= cpu
.ecx
& 0xffff;
2380 int inAddr
= cpu
.edi
& 0xffff;
2381 int outAddr
= cpu
.esi
& 0xffff;
2382 executeCount
+= count
;
2385 if (cpu
.eflagsDirection
) {
2386 while (count
!= 0) {
2387 //check hardware interrupts
2388 cpu
.es
.setDoubleWord(inAddr
& 0xffff, outSegment
.getDoubleWord(outAddr
& 0xffff));
2394 while (count
!= 0) {
2395 //check hardware interrupts
2396 cpu
.es
.setDoubleWord(inAddr
& 0xffff, outSegment
.getDoubleWord(outAddr
& 0xffff));
2404 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2405 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (inAddr
& 0xffff);
2406 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (outAddr
& 0xffff);
2410 private final void movsb_a32(Segment outSegment
)
2412 int inAddr
= cpu
.edi
;
2413 int outAddr
= cpu
.esi
;
2415 cpu
.es
.setByte(inAddr
, outSegment
.getByte(outAddr
));
2416 if (cpu
.eflagsDirection
) {
2428 private final void movsw_a32(Segment outSegment
)
2430 int inAddr
= cpu
.edi
;
2431 int outAddr
= cpu
.esi
;
2433 cpu
.es
.setWord(inAddr
, outSegment
.getWord(outAddr
));
2434 if (cpu
.eflagsDirection
) {
2446 private final void movsd_a32(Segment outSegment
)
2448 int inAddr
= cpu
.edi
;
2449 int outAddr
= cpu
.esi
;
2451 cpu
.es
.setDoubleWord(inAddr
, outSegment
.getDoubleWord(outAddr
));
2452 if (cpu
.eflagsDirection
) {
2464 private final void rep_movsb_a32(Segment outSegment
)
2466 int count
= cpu
.ecx
;
2467 int inAddr
= cpu
.edi
;
2468 int outAddr
= cpu
.esi
;
2469 executeCount
+= count
;
2472 if (cpu
.eflagsDirection
) {
2473 while (count
!= 0) {
2474 //check hardware interrupts
2475 cpu
.es
.setByte(inAddr
, outSegment
.getByte(outAddr
));
2481 while (count
!= 0) {
2482 //check hardware interrupts
2483 cpu
.es
.setByte(inAddr
, outSegment
.getByte(outAddr
));
2497 private final void rep_movsw_a32(Segment outSegment
)
2499 int count
= cpu
.ecx
;
2500 int inAddr
= cpu
.edi
;
2501 int outAddr
= cpu
.esi
;
2502 executeCount
+= count
;
2505 if (cpu
.eflagsDirection
) {
2506 while (count
!= 0) {
2507 //check hardware interrupts
2508 cpu
.es
.setWord(inAddr
, outSegment
.getWord(outAddr
));
2514 while (count
!= 0) {
2515 //check hardware interrupts
2516 cpu
.es
.setWord(inAddr
, outSegment
.getWord(outAddr
));
2530 private final void rep_movsd_a32(Segment outSegment
)
2532 int count
= cpu
.ecx
;
2533 int inAddr
= cpu
.edi
;
2534 int outAddr
= cpu
.esi
;
2535 executeCount
+= count
;
2538 if (cpu
.eflagsDirection
) {
2539 while (count
!= 0) {
2540 //check hardware interrupts
2541 cpu
.es
.setDoubleWord(inAddr
, outSegment
.getDoubleWord(outAddr
));
2547 while (count
!= 0) {
2548 //check hardware interrupts
2549 cpu
.es
.setDoubleWord(inAddr
, outSegment
.getDoubleWord(outAddr
));
2563 private final void outsb_a16(int port
, Segment storeSegment
)
2565 if (!checkIOPermissionsByte(port
)) {
2566 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
2567 " at cpl " + cpu
.getCPL() + ".");
2568 throw ProcessorException
.GENERAL_PROTECTION_0
;
2571 int addr
= cpu
.esi
& 0xffff;
2573 cpu
.ioports
.ioPortWriteByte(port
, 0xff & storeSegment
.getByte(addr
));
2575 if (cpu
.eflagsDirection
)
2580 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2583 private final void outsw_a16(int port
, Segment storeSegment
)
2585 if (!checkIOPermissionsShort(port
)) {
2586 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
2587 " at cpl " + cpu
.getCPL() + ".");
2588 throw ProcessorException
.GENERAL_PROTECTION_0
;
2591 int addr
= cpu
.esi
& 0xffff;
2593 cpu
.ioports
.ioPortWriteWord(port
, 0xffff & storeSegment
.getWord(addr
));
2595 if (cpu
.eflagsDirection
)
2600 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2603 private final void outsd_a16(int port
, Segment storeSegment
)
2605 if (!checkIOPermissionsInt(port
)) {
2606 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
2607 " at cpl " + cpu
.getCPL() + ".");
2608 throw ProcessorException
.GENERAL_PROTECTION_0
;
2611 int addr
= cpu
.esi
& 0xffff;
2613 cpu
.ioports
.ioPortWriteLong(port
, storeSegment
.getDoubleWord(addr
));
2615 if (cpu
.eflagsDirection
)
2620 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2623 private final void rep_outsb_a16(int port
, Segment storeSegment
)
2625 if (!checkIOPermissionsByte(port
)) {
2626 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
2627 " at cpl " + cpu
.getCPL() + ".");
2628 throw ProcessorException
.GENERAL_PROTECTION_0
;
2631 int count
= cpu
.ecx
& 0xffff;
2632 int addr
= cpu
.esi
& 0xffff;
2633 executeCount
+= count
;
2636 if (cpu
.eflagsDirection
) {
2637 while (count
!= 0) {
2638 //check hardware interrupts
2639 cpu
.ioports
.ioPortWriteByte(port
, 0xffff & storeSegment
.getByte(addr
& 0xffff));
2644 while (count
!= 0) {
2645 //check hardware interrupts
2646 cpu
.ioports
.ioPortWriteByte(port
, 0xffff & storeSegment
.getByte(addr
& 0xffff));
2653 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2654 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2658 private final void rep_outsw_a16(int port
, Segment storeSegment
)
2660 if (!checkIOPermissionsShort(port
)) {
2661 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
2662 " at cpl " + cpu
.getCPL() + ".");
2663 throw ProcessorException
.GENERAL_PROTECTION_0
;
2666 int count
= cpu
.ecx
& 0xffff;
2667 int addr
= cpu
.esi
& 0xffff;
2668 executeCount
+= count
;
2671 if (cpu
.eflagsDirection
) {
2672 while (count
!= 0) {
2673 //check hardware interrupts
2674 cpu
.ioports
.ioPortWriteWord(port
, 0xffff & storeSegment
.getWord(addr
& 0xffff));
2679 while (count
!= 0) {
2680 //check hardware interrupts
2681 cpu
.ioports
.ioPortWriteWord(port
, 0xffff & storeSegment
.getWord(addr
& 0xffff));
2688 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2689 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2693 private final void rep_outsd_a16(int port
, Segment storeSegment
)
2695 if (!checkIOPermissionsInt(port
)) {
2696 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
2697 " at cpl " + cpu
.getCPL() + ".");
2698 throw ProcessorException
.GENERAL_PROTECTION_0
;
2701 int count
= cpu
.ecx
& 0xffff;
2702 int addr
= cpu
.esi
& 0xffff;
2703 executeCount
+= count
;
2706 if (cpu
.eflagsDirection
) {
2707 while (count
!= 0) {
2708 //check hardware interrupts
2709 cpu
.ioports
.ioPortWriteLong(port
, storeSegment
.getDoubleWord(addr
& 0xffff));
2714 while (count
!= 0) {
2715 //check hardware interrupts
2716 cpu
.ioports
.ioPortWriteLong(port
, storeSegment
.getDoubleWord(addr
& 0xffff));
2723 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2724 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2728 private final void outsb_a32(int port
, Segment storeSegment
)
2730 if (!checkIOPermissionsByte(port
)) {
2731 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
2732 " at cpl " + cpu
.getCPL() + ".");
2733 throw ProcessorException
.GENERAL_PROTECTION_0
;
2738 cpu
.ioports
.ioPortWriteByte(port
, 0xff & storeSegment
.getByte(addr
));
2740 if (cpu
.eflagsDirection
)
2748 private final void outsw_a32(int port
, Segment storeSegment
)
2750 if (!checkIOPermissionsShort(port
)) {
2751 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
2752 " at cpl " + cpu
.getCPL() + ".");
2753 throw ProcessorException
.GENERAL_PROTECTION_0
;
2758 cpu
.ioports
.ioPortWriteWord(port
, 0xffff & storeSegment
.getWord(addr
));
2760 if (cpu
.eflagsDirection
)
2768 private final void outsd_a32(int port
, Segment storeSegment
)
2770 if (!checkIOPermissionsInt(port
)) {
2771 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
2772 " at cpl " + cpu
.getCPL() + ".");
2773 throw ProcessorException
.GENERAL_PROTECTION_0
;
2778 cpu
.ioports
.ioPortWriteLong(port
, storeSegment
.getDoubleWord(addr
));
2780 if (cpu
.eflagsDirection
)
2788 private final void rep_outsb_a32(int port
, Segment storeSegment
)
2790 if (!checkIOPermissionsByte(port
)) {
2791 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
2792 " at cpl " + cpu
.getCPL() + ".");
2793 throw ProcessorException
.GENERAL_PROTECTION_0
;
2796 int count
= cpu
.ecx
;
2798 executeCount
+= count
;
2801 if (cpu
.eflagsDirection
) {
2802 while (count
!= 0) {
2803 //check hardware interrupts
2804 cpu
.ioports
.ioPortWriteByte(port
, 0xffff & storeSegment
.getByte(addr
));
2809 while (count
!= 0) {
2810 //check hardware interrupts
2811 cpu
.ioports
.ioPortWriteByte(port
, 0xffff & storeSegment
.getByte(addr
));
2823 private final void rep_outsw_a32(int port
, Segment storeSegment
)
2825 if (!checkIOPermissionsShort(port
)) {
2826 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
2827 " at cpl " + cpu
.getCPL() + ".");
2828 throw ProcessorException
.GENERAL_PROTECTION_0
;
2831 int count
= cpu
.ecx
;
2833 executeCount
+= count
;
2836 if (cpu
.eflagsDirection
) {
2837 while (count
!= 0) {
2838 //check hardware interrupts
2839 cpu
.ioports
.ioPortWriteWord(port
, 0xffff & storeSegment
.getWord(addr
));
2844 while (count
!= 0) {
2845 //check hardware interrupts
2846 cpu
.ioports
.ioPortWriteWord(port
, 0xffff & storeSegment
.getWord(addr
));
2858 private final void rep_outsd_a32(int port
, Segment storeSegment
)
2860 if (!checkIOPermissionsInt(port
)) {
2861 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
2862 " at cpl " + cpu
.getCPL() + ".");
2863 throw ProcessorException
.GENERAL_PROTECTION_0
;
2866 int count
= cpu
.ecx
;
2868 executeCount
+= count
;
2871 if (cpu
.eflagsDirection
) {
2872 while (count
!= 0) {
2873 //check hardware interrupts
2874 cpu
.ioports
.ioPortWriteLong(port
, storeSegment
.getDoubleWord(addr
));
2879 while (count
!= 0) {
2880 //check hardware interrupts
2881 cpu
.ioports
.ioPortWriteLong(port
, storeSegment
.getDoubleWord(addr
));
2893 private final void scasb_a16(int data
)
2895 int addr
= 0xFFFF & cpu
.edi
;
2896 int input
= 0xff & cpu
.es
.getByte(addr
);
2898 if (cpu
.eflagsDirection
)
2903 cpu
.edi
= (cpu
.edi
& ~
0xFFFF) | (0xFFFF & addr
);
2904 sub_o8_flags(data
- input
, data
, input
);
2906 private final void scasb_a32(int data
)
2909 int input
= 0xff & cpu
.es
.getByte(addr
);
2911 if (cpu
.eflagsDirection
)
2917 sub_o8_flags(data
- input
, data
, input
);
2920 private final void scasw_a32(int data
)
2923 int input
= 0xffff & cpu
.es
.getWord(addr
);
2925 if (cpu
.eflagsDirection
)
2931 sub_o16_flags(data
- input
, data
, input
);
2934 private final void scasd_a32(int data
)
2937 int input
= cpu
.es
.getDoubleWord(addr
);
2939 if (cpu
.eflagsDirection
)
2945 sub_o32_flags((0xffffffffl
& data
) - (0xffffffffl
& input
), data
, input
);
2948 private final void repe_scasb_a16(int data
)
2950 int count
= 0xffff & cpu
.ecx
;
2951 int addr
= 0xffff & cpu
.edi
;
2952 boolean used
= count
!= 0;
2956 if (cpu
.eflagsDirection
) {
2957 while (count
!= 0) {
2958 input
= 0xff & cpu
.es
.getByte(addr
);
2961 if (data
!= input
) break;
2964 while (count
!= 0) {
2965 input
= 0xff & cpu
.es
.getByte(addr
);
2968 if (data
!= input
) break;
2972 executeCount
+= ((0xffff & cpu
.ecx
) - count
);
2973 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (0xffff & count
);
2974 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (0xffff & addr
);
2976 sub_o8_flags(data
- input
, data
, input
);
2980 private final void repe_scasb_a32(int data
)
2982 int count
= cpu
.ecx
;
2984 boolean used
= count
!= 0;
2988 if (cpu
.eflagsDirection
) {
2989 while (count
!= 0) {
2990 input
= 0xff & cpu
.es
.getByte(addr
);
2993 if (data
!= input
) break;
2996 while (count
!= 0) {
2997 input
= 0xff & cpu
.es
.getByte(addr
);
3000 if (data
!= input
) break;
3004 executeCount
+= (cpu
.ecx
- count
);
3008 sub_o8_flags(data
- input
, data
, input
);
3012 private final void repe_scasw_a16(int data
)
3014 int count
= 0xffff & cpu
.ecx
;
3015 int addr
= 0xffff & cpu
.edi
;
3016 boolean used
= count
!= 0;
3020 if (cpu
.eflagsDirection
) {
3021 while (count
!= 0) {
3022 input
= 0xffff & cpu
.es
.getWord(addr
);
3025 if (data
!= input
) break;
3028 while (count
!= 0) {
3029 input
= 0xffff & cpu
.es
.getWord(addr
);
3032 if (data
!= input
) break;
3036 executeCount
+= ((0xffff & cpu
.ecx
) - count
);
3037 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (0xffff & count
);
3038 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (0xffff & addr
);
3040 sub_o16_flags(data
- input
, data
, input
);
3044 private final void repe_scasw_a32(int data
)
3046 int count
= cpu
.ecx
;
3048 boolean used
= count
!= 0;
3052 if (cpu
.eflagsDirection
) {
3053 while (count
!= 0) {
3054 input
= 0xffff & cpu
.es
.getWord(addr
);
3057 if (data
!= input
) break;
3060 while (count
!= 0) {
3061 input
= 0xffff & cpu
.es
.getWord(addr
);
3064 if (data
!= input
) break;
3068 executeCount
+= (cpu
.ecx
- count
);
3072 sub_o16_flags(data
- input
, data
, input
);
3076 private final void repe_scasd_a16(int data
)
3078 int count
= 0xffff & cpu
.ecx
;
3079 int addr
= 0xffff & cpu
.edi
;
3080 boolean used
= count
!= 0;
3084 if (cpu
.eflagsDirection
) {
3085 while (count
!= 0) {
3086 input
= cpu
.es
.getDoubleWord(addr
);
3089 if (data
!= input
) break;
3092 while (count
!= 0) {
3093 input
= cpu
.es
.getDoubleWord(addr
);
3096 if (data
!= input
) break;
3100 executeCount
+= ((0xffff & cpu
.ecx
) - count
);
3101 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (0xffff & count
);
3102 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (0xffff & addr
);
3104 sub_o32_flags((0xffffffffl
& data
) - (0xffffffffl
& input
), data
, input
);
3108 private final void repe_scasd_a32(int data
)
3110 int count
= cpu
.ecx
;
3112 boolean used
= count
!= 0;
3116 if (cpu
.eflagsDirection
) {
3117 while (count
!= 0) {
3118 input
= cpu
.es
.getDoubleWord(addr
);
3121 if (data
!= input
) break;
3124 while (count
!= 0) {
3125 input
= cpu
.es
.getDoubleWord(addr
);
3128 if (data
!= input
) break;
3132 executeCount
+= (cpu
.ecx
- count
);
3137 sub_o32_flags((0xffffffffl
& data
) - (0xffffffffl
& input
), data
, input
);
3141 private final void repne_scasb_a16(int data
)
3143 int count
= 0xFFFF & cpu
.ecx
;
3144 int addr
= 0xFFFF & cpu
.edi
;
3145 boolean used
= count
!= 0;
3149 if (cpu
.eflagsDirection
) {
3150 while (count
!= 0) {
3151 input
= 0xff & cpu
.es
.getByte(addr
);
3154 if (data
== input
) break;
3157 while (count
!= 0) {
3158 input
= 0xff & cpu
.es
.getByte(addr
);
3161 if (data
== input
) break;
3165 executeCount
+= ((cpu
.ecx
& 0xFFFF) - count
);
3166 cpu
.ecx
= (cpu
.ecx
& ~
0xFFFF) | (0xFFFF & count
);
3167 cpu
.edi
= (cpu
.edi
& ~
0xFFFF) | (0xFFFF & addr
);
3169 sub_o8_flags(data
- input
, data
, input
);
3173 private final void repne_scasb_a32(int data
)
3175 int count
= cpu
.ecx
;
3177 boolean used
= count
!= 0;
3181 if (cpu
.eflagsDirection
) {
3182 while (count
!= 0) {
3183 input
= 0xff & cpu
.es
.getByte(addr
);
3186 if (data
== input
) break;
3189 while (count
!= 0) {
3190 input
= 0xff & cpu
.es
.getByte(addr
);
3193 if (data
== input
) break;
3197 executeCount
+= (cpu
.ecx
- count
);
3201 sub_o8_flags(data
- input
, data
, input
);
3205 private final void repne_scasw_a16(int data
)
3207 int count
= 0xffff & cpu
.ecx
;
3208 int addr
= 0xffff & cpu
.edi
;
3209 boolean used
= count
!= 0;
3213 if (cpu
.eflagsDirection
) {
3214 while (count
!= 0) {
3215 input
= 0xffff & cpu
.es
.getWord(addr
);
3218 if (data
== input
) break;
3221 while (count
!= 0) {
3222 input
= 0xffff & cpu
.es
.getWord(addr
);
3225 if (data
== input
) break;
3229 executeCount
+= ((0xffff & cpu
.ecx
) - count
);
3230 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (0xffff & count
);
3231 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (0xffff & addr
);
3233 sub_o16_flags(data
- input
, data
, input
);
3237 private final void repne_scasw_a32(int data
)
3239 int count
= cpu
.ecx
;
3241 boolean used
= count
!= 0;
3245 if (cpu
.eflagsDirection
) {
3246 while (count
!= 0) {
3247 input
= 0xffff & cpu
.es
.getWord(addr
);
3250 if (data
== input
) break;
3253 while (count
!= 0) {
3254 input
= 0xffff & cpu
.es
.getWord(addr
);
3257 if (data
== input
) break;
3261 executeCount
+= (cpu
.ecx
- count
);
3265 sub_o16_flags(data
- input
, data
, input
);
3269 private final void repne_scasd_a16(int data
)
3271 int count
= 0xffff & cpu
.ecx
;
3272 int addr
= 0xffff & cpu
.edi
;
3273 boolean used
= count
!= 0;
3277 if (cpu
.eflagsDirection
) {
3278 while (count
!= 0) {
3279 input
= cpu
.es
.getDoubleWord(addr
);
3282 if (data
== input
) break;
3285 while (count
!= 0) {
3286 input
= cpu
.es
.getDoubleWord(addr
);
3289 if (data
== input
) break;
3293 executeCount
+= ((0xffff & cpu
.ecx
) - count
);
3294 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (0xffff & count
);
3295 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (0xffff & addr
);
3297 sub_o32_flags((0xffffffffl
& data
) - (0xffffffffl
& input
), data
, input
);
3302 private final void repne_scasd_a32(int data
)
3304 int count
= cpu
.ecx
;
3306 boolean used
= count
!= 0;
3310 if (cpu
.eflagsDirection
) {
3311 while (count
!= 0) {
3312 input
= cpu
.es
.getDoubleWord(addr
);
3315 if (data
== input
) break;
3318 while (count
!= 0) {
3319 input
= cpu
.es
.getDoubleWord(addr
);
3322 if (data
== input
) break;
3326 executeCount
+= (cpu
.ecx
- count
);
3331 sub_o32_flags((0xffffffffl
& data
) - (0xffffffffl
& input
), data
, input
);
3335 private final void stosb_a16(int data
)
3337 int addr
= 0xFFFF & cpu
.edi
;
3338 cpu
.es
.setByte(addr
, (byte)data
);
3340 if (cpu
.eflagsDirection
)
3345 cpu
.edi
= (cpu
.edi
& ~
0xFFFF) | (0xFFFF & addr
);
3348 private final void stosb_a32(int data
)
3351 cpu
.es
.setByte(addr
, (byte)data
);
3353 if (cpu
.eflagsDirection
)
3361 private final void stosw_a16(int data
)
3363 int addr
= 0xFFFF & cpu
.edi
;
3364 cpu
.es
.setWord(addr
, (short) data
);
3366 if (cpu
.eflagsDirection
)
3371 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (0xFFFF & addr
);
3374 private final void stosw_a32(int data
)
3377 cpu
.es
.setWord(addr
, (short)data
);
3379 if (cpu
.eflagsDirection
)
3387 private final void stosd_a16(int data
)
3389 int addr
= 0xffff & cpu
.edi
;
3390 cpu
.es
.setDoubleWord(addr
, data
);
3392 if (cpu
.eflagsDirection
)
3397 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (0xFFFF & addr
);
3400 private final void stosd_a32(int data
)
3403 cpu
.es
.setDoubleWord(addr
, data
);
3405 if (cpu
.eflagsDirection
)
3413 private final void rep_stosb_a16(int data
)
3415 int count
= 0xFFFF & cpu
.ecx
;
3416 int addr
= 0xFFFF & cpu
.edi
;
3417 executeCount
+= count
;
3420 if (cpu
.eflagsDirection
) {
3421 while (count
!= 0) {
3422 //check hardware interrupts
3423 cpu
.es
.setByte(addr
, (byte)data
);
3425 addr
= (addr
- 1) & 0xFFFF;
3428 while (count
!= 0) {
3429 //check hardware interrupts
3430 cpu
.es
.setByte(addr
, (byte)data
);
3432 addr
= (addr
+ 1) & 0xFFFF;
3437 cpu
.ecx
= (cpu
.ecx
& ~
0xFFFF) | count
;
3438 cpu
.edi
= (cpu
.edi
& ~
0xFFFF) | addr
;
3442 private final void rep_stosb_a32(int data
)
3444 int count
= cpu
.ecx
;
3446 executeCount
+= count
;
3449 if (cpu
.eflagsDirection
) {
3450 while (count
!= 0) {
3451 //check hardware interrupts
3452 cpu
.es
.setByte(addr
, (byte)data
);
3457 while (count
!= 0) {
3458 //check hardware interrupts
3459 cpu
.es
.setByte(addr
, (byte)data
);
3471 private final void rep_stosw_a16(int data
)
3473 int count
= 0xFFFF & cpu
.ecx
;
3474 int addr
= 0xFFFF & cpu
.edi
;
3475 executeCount
+= count
;
3478 if (cpu
.eflagsDirection
) {
3479 while (count
!= 0) {
3480 //check hardware interrupts
3481 cpu
.es
.setWord(addr
, (short)data
);
3483 addr
= (addr
- 2) & 0xFFFF;
3486 while (count
!= 0) {
3487 //check hardware interrupts
3488 cpu
.es
.setWord(addr
, (short)data
);
3490 addr
= (addr
+ 2) & 0xFFFF;
3495 cpu
.ecx
= (cpu
.ecx
& ~
0xFFFF) | (0xFFFF & count
);
3496 cpu
.edi
= (cpu
.edi
& ~
0xFFFF) | (0xFFFF & addr
);
3500 private final void rep_stosw_a32(int data
)
3502 int count
= cpu
.ecx
;
3504 executeCount
+= count
;
3507 if (cpu
.eflagsDirection
) {
3508 while (count
!= 0) {
3509 //check hardware interrupts
3510 cpu
.es
.setWord(addr
, (short)data
);
3515 while (count
!= 0) {
3516 //check hardware interrupts
3517 cpu
.es
.setWord(addr
, (short)data
);
3529 private final void rep_stosd_a16(int data
)
3531 int count
= 0xFFFF & cpu
.ecx
;
3532 int addr
= 0xFFFF & cpu
.edi
;
3533 executeCount
+= count
;
3536 if (cpu
.eflagsDirection
) {
3537 while (count
!= 0) {
3538 //check hardware interrupts
3539 cpu
.es
.setDoubleWord(addr
, data
);
3541 addr
= (addr
- 4) & 0xFFFF;
3544 while (count
!= 0) {
3545 //check hardware interrupts
3546 cpu
.es
.setDoubleWord(addr
, data
);
3548 addr
= (addr
+ 4) & 0xFFFF;
3553 cpu
.ecx
= (cpu
.ecx
& ~
0xFFFF) | (0xFFFF & count
);
3554 cpu
.edi
= (cpu
.edi
& ~
0xFFFF) | (0xFFFF & addr
);
3558 private final void rep_stosd_a32(int data
)
3560 int count
= cpu
.ecx
;
3562 executeCount
+= count
;
3565 if (cpu
.eflagsDirection
) {
3566 while (count
!= 0) {
3567 //check hardware interrupts
3568 cpu
.es
.setDoubleWord(addr
, data
);
3573 while (count
!= 0) {
3574 //check hardware interrupts
3575 cpu
.es
.setDoubleWord(addr
, data
);
3587 private final void mul_o8(int data
)
3589 int x
= cpu
.eax
& 0xff;
3591 int result
= x
* data
;
3592 cpu
.eax
&= 0xffff0000;
3593 cpu
.eax
|= (result
& 0xffff);
3595 cpu
.setOverflowFlag(result
, Processor
.OF_HIGH_BYTE_NZ
);
3596 cpu
.setCarryFlag(result
, Processor
.CY_HIGH_BYTE_NZ
);
3599 private final void mul_o16(int data
)
3601 int x
= cpu
.eax
& 0xffff;
3603 int result
= x
* data
;
3604 cpu
.eax
= (cpu
.eax
& 0xffff0000) | (0xffff & result
);
3605 result
= result
>>> 16;
3606 cpu
.edx
= (cpu
.edx
& 0xffff0000) | result
;
3608 cpu
.setOverflowFlag(result
, Processor
.OF_NZ
);
3609 cpu
.setCarryFlag(result
, Processor
.CY_NZ
);
3612 private final void mul_o32(int data
)
3614 long x
= cpu
.eax
& 0xffffffffl
;
3615 long y
= 0xffffffffl
& data
;
3617 long result
= x
* y
;
3618 cpu
.eax
= (int)result
;
3619 result
= result
>>> 32;
3620 cpu
.edx
= (int)result
;
3622 cpu
.setOverflowFlag( cpu
.edx
, Processor
.OF_NZ
);
3623 cpu
.setCarryFlag( cpu
.edx
, Processor
.CY_NZ
);
3626 private final void imula_o8(byte data
)
3628 byte al
= (byte)cpu
.eax
;
3629 int result
= al
* data
;
3631 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (result
& 0xffff);
3633 cpu
.setOverflowFlag(result
, Processor
.OF_NOT_BYTE
);
3634 cpu
.setCarryFlag(result
, Processor
.CY_NOT_BYTE
);
3637 private final void imula_o16(short data
)
3639 short ax
= (short)cpu
.eax
;
3640 int result
= ax
* data
;
3642 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (result
& 0xffff);
3643 cpu
.edx
= (cpu
.edx
& ~
0xffff) | (result
>>> 16);
3645 //answer too wide for 16-bits?
3646 cpu
.setOverflowFlag(result
, Processor
.OF_NOT_SHORT
);
3647 cpu
.setCarryFlag(result
, Processor
.CY_NOT_SHORT
);
3650 private final void imula_o32(int data
)
3652 long eax
= (long)cpu
.eax
;
3653 long y
= (long)data
;
3654 long result
= eax
* y
;
3656 cpu
.eax
= (int)result
;
3657 cpu
.edx
= (int)(result
>>> 32);
3659 //answer too wide for 32-bits?
3660 cpu
.setOverflowFlag(result
, Processor
.OF_NOT_INT
);
3661 cpu
.setCarryFlag(result
, Processor
.CY_NOT_INT
);
3664 private final int imul_o16(short data0
, short data1
)
3666 int result
= data0
* data1
;
3667 cpu
.setOverflowFlag(result
, Processor
.OF_NOT_SHORT
);
3668 cpu
.setCarryFlag(result
, Processor
.CY_NOT_SHORT
);
3672 private final int imul_o32(int data0
, int data1
)
3674 long x
= (long)data0
;
3675 long y
= (long)data1
;
3677 long result
= x
* y
;
3678 cpu
.setOverflowFlag(result
, Processor
.OF_NOT_INT
);
3679 cpu
.setCarryFlag(result
, Processor
.CY_NOT_INT
);
3683 private final void div_o8(int data
)
3686 throw ProcessorException
.DIVIDE_ERROR
;
3688 int x
= (cpu
.eax
& 0xffff);
3690 int result
= x
/ data
;
3692 throw ProcessorException
.DIVIDE_ERROR
;
3694 int remainder
= (x
% data
) << 8;
3695 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (0xff & result
) | (0xff00 & remainder
);
3698 private final void div_o16(int data
)
3701 throw ProcessorException
.DIVIDE_ERROR
;
3703 long x
= (cpu
.edx
& 0xffffl
);
3705 x
|= (cpu
.eax
& 0xffffl
);
3707 long result
= x
/ data
;
3708 if (result
> 0xffffl
)
3709 throw ProcessorException
.DIVIDE_ERROR
;
3711 long remainder
= x
% data
;
3712 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (int)(result
& 0xffff);
3713 cpu
.edx
= (cpu
.edx
& ~
0xffff) | (int)(remainder
& 0xffff);
3716 private final void div_o32(int data
)
3718 long d
= 0xffffffffl
& data
;
3721 throw ProcessorException
.DIVIDE_ERROR
;
3723 long temp
= (long)cpu
.edx
;
3725 temp
|= (0xffffffffl
& cpu
.eax
);
3727 long r2
= (temp
& 1);
3728 long n2
= (temp
>>> 1);
3734 long r
= (m2
<< 1) + r2
;
3738 if (q
> 0xffffffffl
)
3739 throw ProcessorException
.DIVIDE_ERROR
;
3745 private final void idiv_o8(byte data
)
3748 throw ProcessorException
.DIVIDE_ERROR
;
3750 short temp
= (short)cpu
.eax
;
3751 int result
= temp
/ data
;
3752 int remainder
= temp
% data
;
3753 if ((result
> Byte
.MAX_VALUE
) || (result
< Byte
.MIN_VALUE
))
3754 throw ProcessorException
.DIVIDE_ERROR
;
3756 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (0xff & result
) | ((0xff & remainder
) << 8); //AH is remainder
3759 private final void idiv_o16(short data
)
3762 throw ProcessorException
.DIVIDE_ERROR
;
3764 int temp
= (cpu
.edx
<< 16) | (cpu
.eax
& 0xffff);
3765 int result
= temp
/ (int)data
;
3766 int remainder
= temp
% data
;
3768 if ((result
> Short
.MAX_VALUE
) || (result
< Short
.MIN_VALUE
))
3769 throw ProcessorException
.DIVIDE_ERROR
;
3771 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (0xffff & result
); //AX is result
3772 cpu
.edx
= (cpu
.edx
& ~
0xffff) | (0xffff & remainder
); //DX is remainder
3775 private final void idiv_o32(int data
)
3778 throw ProcessorException
.DIVIDE_ERROR
;
3780 long temp
= (0xffffffffl
& cpu
.edx
) << 32;
3781 temp
|= (0xffffffffl
& cpu
.eax
);
3782 long result
= temp
/ data
;
3783 if ((result
> Integer
.MAX_VALUE
) || (result
< Integer
.MIN_VALUE
))
3784 throw ProcessorException
.DIVIDE_ERROR
;
3786 long remainder
= temp
% data
;
3788 cpu
.eax
= (int)result
; //EAX is result
3789 cpu
.edx
= (int)remainder
; //EDX is remainder
3792 private final void btc_mem(int offset
, Segment segment
, int address
) throws ProcessorException
3794 address
+= (offset
>>> 3);
3797 byte data
= segment
.getByte(address
);
3798 segment
.setByte(address
, (byte)(data ^
(1 << offset
)));
3799 cpu
.setCarryFlag(data
, offset
, Processor
.CY_NTH_BIT_SET
);
3802 private final void bts_mem(int offset
, Segment segment
, int address
) throws ProcessorException
3804 address
+= (offset
>>> 3);
3807 byte data
= segment
.getByte(address
);
3808 segment
.setByte(address
, (byte)(data
| (1 << offset
)));
3809 cpu
.setCarryFlag(data
, offset
, Processor
.CY_NTH_BIT_SET
);
3812 private final void btr_mem(int offset
, Segment segment
, int address
) throws ProcessorException
3814 address
+= (offset
>>> 3);
3817 byte data
= segment
.getByte(address
);
3818 segment
.setByte(address
, (byte)(data
& ~
(1 << offset
)));
3819 cpu
.setCarryFlag(data
, offset
, Processor
.CY_NTH_BIT_SET
);
3822 private final void bt_mem(int offset
, Segment segment
, int address
) throws ProcessorException
3824 address
+= (offset
>>> 3);
3826 cpu
.setCarryFlag(segment
.getByte(address
), offset
, Processor
.CY_NTH_BIT_SET
);
3829 private final int bsf(int source
, int initial
) throws ProcessorException
3832 cpu
.setZeroFlag(true);
3835 cpu
.setZeroFlag(false);
3836 return numberOfTrailingZeros(source
);
3840 private final int bsr(int source
, int initial
) throws ProcessorException
3843 cpu
.setZeroFlag(true);
3846 cpu
.setZeroFlag(false);
3847 return 31 - numberOfLeadingZeros(source
);
3851 private final void aaa()
3853 if (((cpu
.eax
& 0xf) > 0x9) || cpu
.getAuxiliaryCarryFlag()) {
3854 int alCarry
= ((cpu
.eax
& 0xff) > 0xf9) ?
0x100 : 0x000;
3855 cpu
.eax
= (0xffff0000 & cpu
.eax
) | (0x0f & (cpu
.eax
+ 6)) | (0xff00 & (cpu
.eax
+ 0x100 + alCarry
));
3856 cpu
.setAuxiliaryCarryFlag(true);
3857 cpu
.setCarryFlag(true);
3859 cpu
.setAuxiliaryCarryFlag(false);
3860 cpu
.setCarryFlag(false);
3861 cpu
.eax
= cpu
.eax
& 0xffffff0f;
3865 private final void aad(int base
) throws ProcessorException
3867 int tl
= (cpu
.eax
& 0xff);
3868 int th
= ((cpu
.eax
>> 8) & 0xff);
3870 int ax1
= th
* base
;
3873 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (ax2
& 0xff);
3876 bitwise_flags((byte)ax2
);
3878 cpu
.setAuxiliaryCarryFlag(ax1
, ax2
, Processor
.AC_BIT4_NEQ
);
3879 cpu
.setCarryFlag(ax2
, Processor
.CY_GREATER_FF
);
3880 cpu
.setOverflowFlag(ax2
, tl
, Processor
.OF_BIT7_DIFFERENT
);
3883 private final void aam(int base
) throws ProcessorException
3885 int tl
= 0xff & cpu
.eax
;
3887 throw ProcessorException
.DIVIDE_ERROR
;
3888 int ah
= 0xff & (tl
/ base
);
3889 int al
= 0xff & (tl
% base
);
3891 cpu
.eax
|= (al
| (ah
<< 8));
3893 cpu
.setAuxiliaryCarryFlag(false);
3894 bitwise_flags((byte)al
);
3897 private final void aas()
3899 if (((cpu
.eax
& 0xf) > 0x9) || cpu
.getAuxiliaryCarryFlag()) {
3900 int alBorrow
= (cpu
.eax
& 0xff) < 6 ?
0x100 : 0x000;
3901 cpu
.eax
= (0xffff0000 & cpu
.eax
) | (0x0f & (cpu
.eax
- 6)) | (0xff00 & (cpu
.eax
- 0x100 - alBorrow
));
3902 cpu
.setAuxiliaryCarryFlag(true);
3903 cpu
.setCarryFlag(true);
3905 cpu
.setAuxiliaryCarryFlag(false);
3906 cpu
.setCarryFlag(false);
3907 cpu
.eax
= cpu
.eax
& 0xffffff0f;
3911 private final void daa()
3913 int al
= cpu
.eax
& 0xff;
3915 if (((cpu
.eax
& 0xf) > 0x9) || cpu
.getAuxiliaryCarryFlag()) {
3917 cpu
.setAuxiliaryCarryFlag(true);
3919 cpu
.setAuxiliaryCarryFlag(false);
3921 if (((al
& 0xff) > 0x9f) || cpu
.getCarryFlag()) {
3927 cpu
.eax
= (cpu
.eax
& ~
0xff) | (0xff & al
);
3928 bitwise_flags((byte)al
);
3929 cpu
.setCarryFlag(newCF
);
3932 private final void das()
3934 boolean tempCF
= false;
3935 int tempAL
= 0xff & cpu
.eax
;
3936 if (((tempAL
& 0xf) > 0x9) || cpu
.getAuxiliaryCarryFlag()) {
3937 cpu
.setAuxiliaryCarryFlag(true);
3938 cpu
.eax
= (cpu
.eax
& ~
0xff) | ((cpu
.eax
- 0x06) & 0xff);
3939 tempCF
= (tempAL
< 0x06) || cpu
.getCarryFlag();
3942 if ((tempAL
> 0x99) || cpu
.getCarryFlag()) {
3943 cpu
.eax
= (cpu
.eax
& ~
0xff) | ((cpu
.eax
- 0x60) & 0xff);
3947 bitwise_flags((byte)cpu
.eax
);
3948 cpu
.setCarryFlag(tempCF
);
3951 private final void lahf()
3953 int result
= 0x0200;
3954 if (cpu
.getSignFlag()) result
|= 0x8000;
3955 if (cpu
.getZeroFlag()) result
|= 0x4000;
3956 if (cpu
.getAuxiliaryCarryFlag()) result
|= 0x1000;
3957 if (cpu
.getParityFlag()) result
|= 0x0400;
3958 if (cpu
.getCarryFlag()) result
|= 0x0100;
3959 cpu
.eax
&= 0xffff00ff;
3963 private final void sahf()
3965 int ah
= (cpu
.eax
& 0xff00);
3966 cpu
.setCarryFlag(0 != (ah
& 0x0100));
3967 cpu
.setParityFlag(0 != (ah
& 0x0400));
3968 cpu
.setAuxiliaryCarryFlag(0 != (ah
& 0x1000));
3969 cpu
.setZeroFlag(0 != (ah
& 0x4000));
3970 cpu
.setSignFlag(0 != (ah
& 0x8000));
3973 private final void jo_o8(byte offset
)
3975 if (cpu
.getOverflowFlag()) jump_o8(offset
);
3978 private final void jno_o8(byte offset
)
3980 if (!cpu
.getOverflowFlag()) jump_o8(offset
);
3983 private final void jc_o8(byte offset
)
3985 if (cpu
.getCarryFlag()) jump_o8(offset
);
3988 private final void jnc_o8(byte offset
)
3990 if (!cpu
.getCarryFlag()) jump_o8(offset
);
3993 private final void jz_o8(byte offset
)
3995 if (cpu
.getZeroFlag()) jump_o8(offset
);
3998 private final void jnz_o8(byte offset
)
4000 if (!cpu
.getZeroFlag()) jump_o8(offset
);
4003 private final void jna_o8(byte offset
)
4005 if (cpu
.getCarryFlag() || cpu
.getZeroFlag()) jump_o8(offset
);
4008 private final void ja_o8(byte offset
)
4010 if ((!cpu
.getCarryFlag()) && (!cpu
.getZeroFlag())) jump_o8(offset
);
4013 private final void js_o8(byte offset
)
4015 if (cpu
.getSignFlag()) jump_o8(offset
);
4018 private final void jns_o8(byte offset
)
4020 if (!cpu
.getSignFlag()) jump_o8(offset
);
4023 private final void jp_o8(byte offset
)
4025 if (cpu
.getParityFlag()) jump_o8(offset
);
4028 private final void jnp_o8(byte offset
)
4030 if (!cpu
.getParityFlag()) jump_o8(offset
);
4033 private final void jl_o8(byte offset
)
4035 if (cpu
.getSignFlag() != cpu
.getOverflowFlag()) jump_o8(offset
);
4038 private final void jnl_o8(byte offset
)
4040 if (cpu
.getSignFlag() == cpu
.getOverflowFlag()) jump_o8(offset
);
4043 private final void jng_o8(byte offset
)
4045 if (cpu
.getZeroFlag() || (cpu
.getSignFlag() != cpu
.getOverflowFlag())) jump_o8(offset
);
4048 private final void jg_o8(byte offset
)
4050 if ((!cpu
.getZeroFlag()) && (cpu
.getSignFlag() == cpu
.getOverflowFlag())) jump_o8(offset
);
4053 private final void jo_o16(short offset
)
4055 if (cpu
.getOverflowFlag()) jump_o16(offset
);
4058 private final void jno_o16(short offset
)
4060 if (!cpu
.getOverflowFlag()) jump_o16(offset
);
4063 private final void jc_o16(short offset
)
4065 if (cpu
.getCarryFlag()) jump_o16(offset
);
4068 private final void jnc_o16(short offset
)
4070 if (!cpu
.getCarryFlag()) jump_o16(offset
);
4073 private final void jz_o16(short offset
)
4075 if (cpu
.getZeroFlag()) jump_o16(offset
);
4078 private final void jnz_o16(short offset
)
4080 if (!cpu
.getZeroFlag()) jump_o16(offset
);
4083 private final void jna_o16(short offset
)
4085 if (cpu
.getCarryFlag() || cpu
.getZeroFlag()) jump_o16(offset
);
4088 private final void ja_o16(short offset
)
4090 if ((!cpu
.getCarryFlag()) && (!cpu
.getZeroFlag())) jump_o16(offset
);
4093 private final void js_o16(short offset
)
4095 if (cpu
.getSignFlag()) jump_o16(offset
);
4098 private final void jns_o16(short offset
)
4100 if (!cpu
.getSignFlag()) jump_o16(offset
);
4103 private final void jp_o16(short offset
)
4105 if (cpu
.getParityFlag()) jump_o16(offset
);
4108 private final void jnp_o16(short offset
)
4110 if (!cpu
.getParityFlag()) jump_o16(offset
);
4113 private final void jl_o16(short offset
)
4115 if (cpu
.getSignFlag() != cpu
.getOverflowFlag()) jump_o16(offset
);
4118 private final void jnl_o16(short offset
)
4120 if (cpu
.getSignFlag() == cpu
.getOverflowFlag()) jump_o16(offset
);
4123 private final void jng_o16(short offset
)
4125 if (cpu
.getZeroFlag() || (cpu
.getSignFlag() != cpu
.getOverflowFlag())) jump_o16(offset
);
4128 private final void jg_o16(short offset
)
4130 if ((!cpu
.getZeroFlag()) && (cpu
.getSignFlag() == cpu
.getOverflowFlag())) jump_o16(offset
);
4133 private final void jo_o32(int offset
)
4135 if (cpu
.getOverflowFlag()) jump_o32(offset
);
4138 private final void jno_o32(int offset
)
4140 if (!cpu
.getOverflowFlag()) jump_o32(offset
);
4143 private final void jc_o32(int offset
)
4145 if (cpu
.getCarryFlag()) jump_o32(offset
);
4148 private final void jnc_o32(int offset
)
4150 if (!cpu
.getCarryFlag()) jump_o32(offset
);
4153 private final void jz_o32(int offset
)
4155 if (cpu
.getZeroFlag()) jump_o32(offset
);
4158 private final void jnz_o32(int offset
)
4160 if (!cpu
.getZeroFlag()) jump_o32(offset
);
4163 private final void jna_o32(int offset
)
4165 if (cpu
.getCarryFlag() || cpu
.getZeroFlag()) jump_o32(offset
);
4168 private final void ja_o32(int offset
)
4170 if ((!cpu
.getCarryFlag()) && (!cpu
.getZeroFlag())) jump_o32(offset
);
4173 private final void js_o32(int offset
)
4175 if (cpu
.getSignFlag()) jump_o32(offset
);
4178 private final void jns_o32(int offset
)
4180 if (!cpu
.getSignFlag()) jump_o32(offset
);
4183 private final void jp_o32(int offset
)
4185 if (cpu
.getParityFlag()) jump_o32(offset
);
4188 private final void jnp_o32(int offset
)
4190 if (!cpu
.getParityFlag()) jump_o32(offset
);
4193 private final void jl_o32(int offset
)
4195 if (cpu
.getSignFlag() != cpu
.getOverflowFlag()) jump_o32(offset
);
4198 private final void jnl_o32(int offset
)
4200 if (cpu
.getSignFlag() == cpu
.getOverflowFlag()) jump_o32(offset
);
4203 private final void jng_o32(int offset
)
4205 if (cpu
.getZeroFlag() || (cpu
.getSignFlag() != cpu
.getOverflowFlag())) jump_o32(offset
);
4208 private final void jg_o32(int offset
)
4210 if ((!cpu
.getZeroFlag()) && (cpu
.getSignFlag() == cpu
.getOverflowFlag())) jump_o32(offset
);
4213 private final void jcxz(byte offset
)
4215 if ((cpu
.ecx
& 0xffff) == 0) jump_o8(offset
);
4218 private final void jecxz(byte offset
)
4220 if (cpu
.ecx
== 0) jump_o8(offset
);
4223 private final void loop_cx(byte offset
)
4225 cpu
.ecx
= (cpu
.ecx
& ~
0xFFFF) | (((0xFFFF &cpu
.ecx
)-1) & 0xFFFF);
4226 if ((cpu
.ecx
& 0xFFFF) != 0)
4230 private final void loop_ecx(byte offset
)
4237 private final void loopz_cx(byte offset
)
4239 cpu
.ecx
= (cpu
.ecx
& ~
0xFFFF) | ((cpu
.ecx
- 1) & 0xFFFF);
4240 if (cpu
.getZeroFlag() && ((cpu
.ecx
& 0xFFFF) != 0))
4244 private final void loopz_ecx(byte offset
)
4247 if (cpu
.getZeroFlag() && (cpu
.ecx
!= 0))
4251 private final void loopnz_cx(byte offset
)
4253 cpu
.ecx
= (cpu
.ecx
& ~
0xFFFF) | ((cpu
.ecx
-1) & 0xFFFF);
4254 if (!cpu
.getZeroFlag() && ((cpu
.ecx
& 0xFFFF) != 0))
4258 private final void loopnz_ecx(byte offset
)
4261 if (!cpu
.getZeroFlag() && (cpu
.ecx
!= 0))
4265 private final void jump_o8(byte offset
)
4268 return; //first protected mode throws on a jump 0 (some segment problem?)
4270 int tempEIP
= cpu
.eip
+ offset
;
4271 cpu
.cs
.checkAddress(tempEIP
);// check whether eip is outside cs limit
4275 private final void jump_o16(short offset
)
4277 int tempEIP
= (cpu
.eip
+ offset
) & 0xffff;
4278 cpu
.cs
.checkAddress(tempEIP
);// check whether eip is outside cs limit
4282 private final void jump_o32(int offset
)
4284 int tempEIP
= cpu
.eip
+ offset
;
4285 cpu
.cs
.checkAddress(tempEIP
);// check whether eip is outside cs limit
4289 private final void jump_abs(int offset
)
4291 cpu
.cs
.checkAddress(offset
);// check whether eip is outside cs limit
4295 private final void jump_far(int targetEIP
, int targetSelector
)
4297 Segment newSegment
= cpu
.getSegment(targetSelector
);
4298 if (newSegment
== SegmentFactory
.NULL_SEGMENT
)
4299 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
4301 switch (newSegment
.getType()) { // segment type
4302 default: // not a valid segment descriptor for a jump
4303 System
.err
.println("Emulated: Invalid segment type " + newSegment
.getType() + ".");
4304 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
4305 case 0x05: // Task Gate
4306 System
.err
.println("Critical error: Task gate not implemented");
4307 throw new IllegalStateException("Far jump through task gate is not implemented");
4308 case 0x0b: // TSS (Busy)
4309 case 0x09: // TSS (Not Busy)
4311 if ((newSegment
.getDPL() < cpu
.getCPL()) || (newSegment
.getDPL() < newSegment
.getRPL()) )
4312 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
4313 if (!newSegment
.isPresent())
4314 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSelector
, true);
4315 if (newSegment
.getLimit() < 0x67) // large enough to read ?
4316 throw new ProcessorException(ProcessorException
.Type
.TASK_SWITCH
, targetSelector
, true);
4317 if ((newSegment
.getType() & 0x2) != 0) // busy ? if yes,error
4318 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
4320 newSegment
.getByte(0); // new TSS paged into memory ?
4321 cpu
.tss
.getByte(0);// old TSS paged into memory ?
4323 int esSelector
= 0xFFFF & newSegment
.getWord(72); // read new registers
4324 int csSelector
= 0xFFFF & newSegment
.getWord(76);
4325 int ssSelector
= 0xFFFF & newSegment
.getWord(80);
4326 int dsSelector
= 0xFFFF & newSegment
.getWord(84);
4327 int fsSelector
= 0xFFFF & newSegment
.getWord(88);
4328 int gsSelector
= 0xFFFF & newSegment
.getWord(92);
4329 int ldtSelector
= 0xFFFF & newSegment
.getWord(96);
4331 if((ldtSelector
& 0x4) !=0) // not in gdt
4332 throw new ProcessorException(ProcessorException
.Type
.TASK_SWITCH
, ldtSelector
, true);
4333 cpu
.gdtr
.checkAddress((ldtSelector
& ~
0x7) + 7 ) ;// check ldtr is valid
4334 if((cpu
.readSupervisorByte(cpu
.gdtr
, ((ldtSelector
& ~
0x7) + 5 )) & 0xE) != 2) { // not a ldt entry
4335 System
.err
.println("Accessed LDT selector global byte 5:" + cpu
.readSupervisorByte(cpu
.gdtr
, ((ldtSelector
& ~
0x7) + 5 )));
4336 throw new ProcessorException(ProcessorException
.Type
.TASK_SWITCH
, ldtSelector
, true);
4338 Segment newLdtr
=cpu
.getSegment(ldtSelector
); // get new ldt
4340 if ((esSelector
& 0x4) !=0) // check es descriptor is in memory
4341 newLdtr
.checkAddress((esSelector
& ~
0x7)+7);
4343 cpu
.gdtr
.checkAddress((esSelector
& ~
0x7)+7);
4345 if ((csSelector
& 0x4)!=0) // check cs descriptor is in memory
4346 newLdtr
.checkAddress((csSelector
& ~
0x7)+7);
4348 cpu
.gdtr
.checkAddress((csSelector
& ~
0x7)+7);
4350 if ((ssSelector
& 0x4)!=0) // check ss descriptor is in memory
4351 newLdtr
.checkAddress((ssSelector
& ~
0x7)+7);
4353 cpu
.gdtr
.checkAddress((ssSelector
& ~
0x7)+7);
4355 if ((dsSelector
& 0x4)!=0) // check ds descriptor is in memory
4356 newLdtr
.checkAddress((dsSelector
& ~
0x7)+7);
4358 cpu
.gdtr
.checkAddress((dsSelector
& ~
0x7)+7);
4360 if ((fsSelector
& 0x4)!=0) // check fs descriptor is in memory
4361 newLdtr
.checkAddress((fsSelector
& ~
0x7)+7);
4363 cpu
.gdtr
.checkAddress((fsSelector
& ~
0x7)+7);
4365 if ((gsSelector
& 0x4)!=0) // check gs descriptor is in memory
4366 newLdtr
.checkAddress((gsSelector
& ~
0x7)+7);
4368 cpu
.gdtr
.checkAddress((gsSelector
& ~
0x7)+7);
4370 cpu
.setSupervisorDoubleWord(cpu
.gdtr
, (cpu
.tss
.getSelector() & ~
0x7) + 4,
4371 ~
0x200 & cpu
.readSupervisorDoubleWord(cpu
.gdtr
, (cpu
.tss
.getSelector() & ~
0x7) + 4)); // clear busy bit of current tss
4372 ((ProtectedModeSegment
.AbstractTSS
) cpu
.tss
).saveCPUState(cpu
);
4374 cpu
.setSupervisorDoubleWord(cpu
.gdtr
, (targetSelector
& ~
0x7) + 4,
4375 0x200 | cpu
.readSupervisorDoubleWord(cpu
.gdtr
, (targetSelector
& ~
0x7) + 4)); // set busy bit of new tss
4378 cpu
.setCR0(cpu
.getCR0() | 0x8); // set TS flag in CR0;
4380 ((ProtectedModeSegment
.AbstractTSS
) cpu
.tss
).restoreCPUState(cpu
);
4381 cpu
.cs
.checkAddress(cpu
.eip
);
4385 case 0x0c: // Call Gate
4386 System
.err
.println("Critical error: Call gate not implemented");
4387 throw new IllegalStateException("Far jump through call gate not implemented");
4388 case 0x18: // Non-conforming Code Segment
4389 case 0x19: // Non-conforming Code Segment
4390 case 0x1a: // Non-conforming Code Segment
4391 case 0x1b: { // Non-conforming Code Segment
4392 if ((newSegment
.getRPL() != cpu
.getCPL()) || (newSegment
.getDPL() > cpu
.getCPL()))
4393 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
4394 if (!newSegment
.isPresent())
4395 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSelector
, true);
4397 newSegment
.checkAddress(targetEIP
);
4398 newSegment
.setRPL(cpu
.getCPL());
4399 cpu
.cs
= newSegment
;
4400 cpu
.eip
= targetEIP
;
4403 case 0x1c: // Conforming Code Segment (Not Readable & Not Accessed)
4404 case 0x1d: // Conforming Code Segment (Not Readable & Accessed)
4405 case 0x1e: // Conforming Code Segment (Readable & Not Accessed)
4406 case 0x1f: { // Conforming Code Segment (Readable & Accessed)
4407 if (newSegment
.getDPL() > cpu
.getCPL())
4408 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
4409 if (!newSegment
.isPresent())
4410 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSelector
, true);
4412 newSegment
.checkAddress(targetEIP
);
4413 newSegment
.setRPL(cpu
.getCPL());
4414 cpu
.cs
= newSegment
;
4415 cpu
.eip
= targetEIP
;
4421 private final void call_o32_a32(int target
)
4423 int tempEIP
= cpu
.eip
+ target
;
4425 cpu
.cs
.checkAddress(tempEIP
);
4427 if ((cpu
.esp
< 4) && (cpu
.esp
> 0))
4428 throw ProcessorException
.STACK_SEGMENT_0
;
4430 cpu
.ss
.setDoubleWord(cpu
.esp
- 4, cpu
.eip
);
4436 private final void call_o16_a16(int target
)
4438 int tempEIP
= 0xFFFF & (cpu
.eip
+ target
) ;
4440 cpu
.cs
.checkAddress(tempEIP
);
4442 if ((0xffff & cpu
.esp
) < 2)
4443 throw ProcessorException
.STACK_SEGMENT_0
;
4445 cpu
.ss
.setWord((cpu
.esp
- 2) & 0xffff, (short) (0xFFFF & cpu
.eip
));
4446 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
- 2) & 0xffff);
4451 private final void call_o16_a32(int target
)
4453 int tempEIP
= 0xFFFF & (cpu
.eip
+ target
) ;
4455 cpu
.cs
.checkAddress(tempEIP
);
4457 if ((cpu
.esp
< 2) && (cpu
.esp
> 0))
4458 throw ProcessorException
.STACK_SEGMENT_0
;
4460 cpu
.ss
.setWord(cpu
.esp
- 2, (short) (0xFFFF & cpu
.eip
));
4466 private final void call_o32_a16(int target
)
4468 int tempEIP
= cpu
.eip
+ target
;
4470 cpu
.cs
.checkAddress(tempEIP
);
4472 if ((0xffff & cpu
.esp
) < 4)
4473 throw ProcessorException
.STACK_SEGMENT_0
;
4475 cpu
.ss
.setDoubleWord((cpu
.esp
- 4) & 0xffff, cpu
.eip
);
4476 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
- 4) & 0xffff);
4481 private final void call_abs_o16_a16(int target
)
4483 cpu
.cs
.checkAddress(target
& 0xFFFF);
4485 if ((cpu
.esp
& 0xffff) < 2)
4486 throw ProcessorException
.STACK_SEGMENT_0
;
4488 cpu
.ss
.setWord((cpu
.esp
- 2) & 0xffff, (short) (0xFFFF & cpu
.eip
));
4489 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
- 2) & 0xffff);
4491 cpu
.eip
= target
& 0xFFFF;
4494 private final void call_abs_o16_a32(int target
)
4496 cpu
.cs
.checkAddress(target
& 0xFFFF);
4498 if ((cpu
.esp
< 2) && (cpu
.esp
> 0))
4499 throw ProcessorException
.STACK_SEGMENT_0
;
4501 cpu
.ss
.setWord(cpu
.esp
- 2, (short) (0xFFFF & cpu
.eip
));
4504 cpu
.eip
= target
& 0xFFFF;
4507 private final void call_abs_o32_a32(int target
)
4509 cpu
.cs
.checkAddress(target
);
4511 if ((cpu
.esp
< 4) && (cpu
.esp
> 0))
4512 throw ProcessorException
.STACK_SEGMENT_0
;
4514 cpu
.ss
.setDoubleWord(cpu
.esp
- 4, cpu
.eip
);
4520 private final void call_abs_o32_a16(int target
)
4522 cpu
.cs
.checkAddress(target
);
4524 if ((cpu
.esp
& 0xffff) < 4)
4525 throw ProcessorException
.STACK_SEGMENT_0
;
4527 cpu
.ss
.setDoubleWord((cpu
.esp
- 4) & 0xffff, cpu
.eip
);
4528 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
- 4) & 0xffff);
4533 private final void call_far_o16_a32(int targetEIP
, int targetSelector
)
4535 Segment newSegment
= cpu
.getSegment(targetSelector
);
4536 if (newSegment
== SegmentFactory
.NULL_SEGMENT
)
4537 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
4539 switch (newSegment
.getType())
4541 default: // not a valid segment descriptor for a jump
4542 System
.err
.println("Emulated: Invalid segment type " + newSegment
.getType() + ".");
4543 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
4544 case 0x01: // TSS 16-bit (Not Busy)
4545 case 0x03: // TSS 16-bit (Busy)
4546 System
.err
.println("Critical error: 16-bit TSS not implemented");
4547 throw new IllegalStateException("O16 A32 CALL FAR to 16-bit TSS not implemented");
4548 case 0x04: // Call Gate 16-bit
4550 if ((newSegment
.getRPL() > cpu
.getCPL()) || (newSegment
.getDPL() < cpu
.getCPL()))
4551 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
4552 if (!newSegment
.isPresent())
4553 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSelector
, true);
4555 ProtectedModeSegment
.GateSegment gate
= (ProtectedModeSegment
.GateSegment
) newSegment
;
4557 int targetSegmentSelector
= gate
.getTargetSegment();
4559 Segment targetSegment
;
4561 targetSegment
= cpu
.getSegment(targetSegmentSelector
);
4562 } catch (ProcessorException e
) {
4563 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSegmentSelector
, true);
4565 if (targetSegment
== SegmentFactory
.NULL_SEGMENT
)
4566 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
4568 if (targetSegment
.getDPL() > cpu
.getCPL())
4569 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
4571 switch (targetSegment
.getType()) {
4573 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSegmentSelector
, true);
4575 case 0x18: //Code, Execute-Only
4576 case 0x19: //Code, Execute-Only, Accessed
4577 case 0x1a: //Code, Execute/Read
4578 case 0x1b: //Code, Execute/Read, Accessed
4580 if (!targetSegment
.isPresent())
4581 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSegmentSelector
, true);
4583 if (targetSegment
.getDPL() < cpu
.getCPL()) {
4584 System
.err
.println("Critical error: 16-bit call gate: jump to more privileged " +
4585 "segment not implemented");
4586 throw new IllegalStateException("O16 A32 CALL FAR to 16-bit call gate to more priviledged segment not implmented");
4588 } else if (targetSegment
.getDPL() == cpu
.getCPL()) {
4589 System
.err
.println("O16 A32 CALL FAR: 16-bit call gate to same priviledge segment not implemented");
4590 throw new IllegalStateException("O16 A32 CALL FARÂ to 16-bit call gate to same priviledge segment not implemented");
4593 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSegmentSelector
, true);
4596 case 0x1c: //Code: Execute-Only, Conforming
4597 case 0x1d: //Code: Execute-Only, Conforming, Accessed
4598 case 0x1e: //Code: Execute/Read, Conforming
4599 case 0x1f: //Code: Execute/Read, Conforming, Accessed
4601 if (!targetSegment
.isPresent())
4602 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSegmentSelector
, true);
4604 System
.err
.println("Critical error: 16-bit call gate: jump to same privilege " +
4605 "conforming segment not implemented");
4606 throw new IllegalStateException("O16 A32 CALL FAR to 16-bit call gate: Jump to " +
4607 "same privieledge conforming segment not implemented");
4614 case 0x05: // Task Gate
4615 System
.err
.println("Critical error: Task gate not implemented");
4616 throw new IllegalStateException("O16 A32 CALL FAR to task gate not implemented");
4617 case 0x09: // TSS (Not Busy)
4618 case 0x0b: // TSS (Busy)
4619 System
.err
.println("Critical error: TSS not implemented");
4620 throw new IllegalStateException("O16 A32 CALL FAR to TSS not implemented");
4621 case 0x0c: // Call Gate
4622 System
.err
.println("Critical error: Call gate not implemented");
4623 throw new IllegalStateException("O16 A32 CALL FAR TO call gate not supported");
4624 case 0x18: // Non-conforming Code Segment
4625 case 0x19: // Non-conforming Code Segment
4626 case 0x1a: // Non-conforming Code Segment
4627 case 0x1b: // Non-conforming Code Segment
4629 if ((newSegment
.getRPL() > cpu
.getCPL()) || (newSegment
.getDPL() != cpu
.getCPL()))
4630 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
4631 if (!newSegment
.isPresent())
4632 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSelector
, true);
4634 if ((cpu
.esp
< 4) && (cpu
.esp
> 0))
4635 throw ProcessorException
.STACK_SEGMENT_0
;
4637 newSegment
.checkAddress(targetEIP
&0xFFFF);
4639 cpu
.ss
.setWord(cpu
.esp
- 2, (short) (0xFFFF & cpu
.cs
.getSelector()));
4640 cpu
.ss
.setWord(cpu
.esp
- 4, (short) (0xFFFF & cpu
.eip
));
4643 cpu
.cs
= newSegment
;
4644 cpu
.cs
.setRPL(cpu
.getCPL());
4645 cpu
.eip
= targetEIP
& 0xFFFF;
4648 case 0x1c: // Conforming Code Segment (Not Readable & Not Accessed)
4649 case 0x1d: // Conforming Code Segment (Not Readable & Accessed)
4650 case 0x1e: // Conforming Code Segment (Readable & Not Accessed)
4651 case 0x1f: // Conforming Code Segment (Readable & Accessed)
4652 System
.err
.println("Critical error: Conforming code segment not implemented");
4653 throw new IllegalStateException("O16 A32 CALL FAR to conforming code segment not implemented");
4657 private final void call_far_o16_a16(int targetEIP
, int targetSelector
)
4659 if ((targetSelector
& 0xfffc) == 0)
4660 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
4662 Segment newSegment
= cpu
.getSegment(targetSelector
);
4663 if (newSegment
== SegmentFactory
.NULL_SEGMENT
)
4664 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
4666 switch (newSegment
.getType())
4668 default: // not a valid segment descriptor for a jump
4669 System
.err
.println("Emulated: Invalid segment type " + newSegment
.getType() + ".");
4670 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
4671 case 0x01: // TSS 16-bit (Not Busy)
4672 case 0x03: // TSS 16-bit (Busy)
4673 System
.err
.println("Critical error: 16-bit TSS not implemented");
4674 throw new IllegalStateException("O16 A16 CALL FAR to 16-bit TSS not implemented");
4675 case 0x04: // Call Gate 16-bit
4677 if ((newSegment
.getDPL() < newSegment
.getRPL()) || (newSegment
.getDPL() < cpu
.getCPL()))
4678 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
& 0xfffc, true);
4679 if (!newSegment
.isPresent())
4680 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSelector
& 0xfffc, true);
4682 ProtectedModeSegment
.CallGate16Bit gate
= (ProtectedModeSegment
.CallGate16Bit
) newSegment
;
4684 int targetSegmentSelector
= gate
.getTargetSegment();
4686 if ((targetSegmentSelector
& 0xfffc) == 0)
4687 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, 0, true);
4689 Segment targetSegment
;
4691 targetSegment
= cpu
.getSegment(targetSegmentSelector
);
4692 } catch (ProcessorException e
) {
4693 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSegmentSelector
& 0xfffc, true);
4695 if (targetSegment
== SegmentFactory
.NULL_SEGMENT
)
4696 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSegmentSelector
& 0xfffc, true);
4698 if ((targetSegment
.getDPL() > cpu
.getCPL()) || (targetSegment
.isSystem()) || ((targetSegment
.getType() & 0x18) == 0x10))
4699 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSegmentSelector
& 0xfffc, true);
4701 if (!targetSegment
.isPresent())
4702 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSegmentSelector
& 0xfffc, true);
4704 switch (targetSegment
.getType()) {
4706 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSegmentSelector
, true);
4708 case 0x18: //Code, Execute-Only
4709 case 0x19: //Code, Execute-Only, Accessed
4710 case 0x1a: //Code, Execute/Read
4711 case 0x1b: //Code, Execute/Read, Accessed
4714 if (targetSegment
.getDPL() < cpu
.getCPL()) {
4716 int newStackSelector
= 0;
4718 if ((cpu
.tss
.getType() & 0x8) != 0) {
4719 int tssStackAddress
= (targetSegment
.getDPL() * 8) + 4;
4720 if ((tssStackAddress
+ 7) > cpu
.tss
.getLimit())
4721 throw new ProcessorException(ProcessorException
.Type
.TASK_SWITCH
, cpu
.tss
.getSelector(), true);
4723 boolean isSup
= cpu
.linearMemory
.isSupervisor();
4725 cpu
.linearMemory
.setSupervisor(true);
4726 newStackSelector
= 0xffff & cpu
.tss
.getWord(tssStackAddress
+ 4);
4727 newESP
= cpu
.tss
.getDoubleWord(tssStackAddress
);
4729 cpu
.linearMemory
.setSupervisor(isSup
);
4732 int tssStackAddress
= (targetSegment
.getDPL() * 4) + 2;
4733 if ((tssStackAddress
+ 4) > cpu
.tss
.getLimit())
4734 throw new ProcessorException(ProcessorException
.Type
.TASK_SWITCH
, cpu
.tss
.getSelector(), true);
4735 newStackSelector
= 0xffff & cpu
.tss
.getWord(tssStackAddress
+ 2);
4736 newESP
= 0xffff & cpu
.tss
.getWord(tssStackAddress
);
4739 if ((newStackSelector
& 0xfffc) == 0)
4740 throw new ProcessorException(ProcessorException
.Type
.TASK_SWITCH
, 0, true);
4742 Segment newStackSegment
= null;
4744 newStackSegment
= cpu
.getSegment(newStackSelector
);
4745 } catch (ProcessorException e
) {
4746 throw new ProcessorException(ProcessorException
.Type
.TASK_SWITCH
, newStackSelector
, true);
4749 if (newStackSegment
.getRPL() != targetSegment
.getDPL())
4750 throw new ProcessorException(ProcessorException
.Type
.TASK_SWITCH
, newStackSelector
& 0xfffc, true);
4752 if ((newStackSegment
.getDPL() != targetSegment
.getDPL()) || ((newStackSegment
.getType() & 0x1a) != 0x12))
4753 throw new ProcessorException(ProcessorException
.Type
.TASK_SWITCH
, newStackSelector
& 0xfffc, true);
4755 if (!(newStackSegment
.isPresent()))
4756 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, newStackSelector
& 0xfffc, true);
4758 int parameters
= gate
.getParameterCount() & 0x1f;
4759 if ((newStackSegment
.getDefaultSizeFlag() && (cpu
.esp
< 8 + 2 * parameters
) && (cpu
.esp
> 0)) ||
4760 !newStackSegment
.getDefaultSizeFlag() && ((cpu
.esp
& 0xffff) < 8 + 2 * parameters
))
4761 throw ProcessorException
.STACK_SEGMENT_0
;
4763 int targetOffset
= 0xffff & gate
.getTargetOffset();
4765 int returnSS
= cpu
.ss
.getSelector();
4766 Segment oldStack
= cpu
.ss
;
4768 if (cpu
.ss
.getDefaultSizeFlag())
4769 returnESP
= cpu
.esp
;
4771 returnESP
= cpu
.esp
& 0xffff;
4772 int oldCS
= cpu
.cs
.getSelector();
4774 if (cpu
.cs
.getDefaultSizeFlag())
4777 oldEIP
= cpu
.eip
& 0xffff;
4778 cpu
.ss
= newStackSegment
;
4780 cpu
.ss
.setRPL(targetSegment
.getDPL());
4782 if (cpu
.ss
.getDefaultSizeFlag()) {
4784 cpu
.ss
.setWord(cpu
.esp
, (short)returnSS
);
4786 cpu
.ss
.setWord(cpu
.esp
, (short)returnESP
);
4787 for (int i
= 0; i
< parameters
; i
++) {
4789 cpu
.ss
.setWord(cpu
.esp
, oldStack
.getWord(returnESP
+ 2*parameters
- 2*i
-2));
4792 cpu
.ss
.setWord(cpu
.esp
, (short)oldCS
);
4794 cpu
.ss
.setWord(cpu
.esp
, (short)oldEIP
);
4796 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
- 2) & 0xffff);
4797 cpu
.ss
.setWord(cpu
.esp
& 0xffff, (short)returnSS
);
4798 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
- 2) & 0xffff);
4799 cpu
.ss
.setWord(cpu
.esp
& 0xffff, (short)returnESP
);
4800 for (int i
= 0; i
< parameters
; i
++) {
4801 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
- 2) & 0xffff);
4802 cpu
.ss
.setWord(cpu
.esp
& 0xffff, oldStack
.getWord((returnESP
+ 2*parameters
- 2*i
-2) & 0xffff));
4804 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
- 2) & 0xffff);
4805 cpu
.ss
.setWord(cpu
.esp
& 0xffff, (short)oldCS
);
4806 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
- 2) & 0xffff);
4807 cpu
.ss
.setWord(cpu
.esp
& 0xffff, (short)oldEIP
);
4809 targetSegment
.checkAddress(targetOffset
);
4810 cpu
.cs
= targetSegment
;
4811 cpu
.eip
= targetOffset
;
4812 cpu
.setCPL(cpu
.ss
.getDPL());
4813 cpu
.cs
.setRPL(cpu
.getCPL());
4815 } else if (targetSegment
.getDPL() == cpu
.getCPL()) {
4816 System
.err
.println("Critical error: 16-bit call gate: jump to same privilege " +
4817 "segment not implemented");
4818 throw new IllegalStateException("O16 A16 CALL FAR to 16-bit call gate same priviledge segment not implemented");
4821 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSegmentSelector
, true);
4824 case 0x1c: //Code: Execute-Only, Conforming
4825 case 0x1d: //Code: Execute-Only, Conforming, Accessed
4826 case 0x1e: //Code: Execute/Read, Conforming
4827 case 0x1f: //Code: Execute/Read, Conforming, Accessed
4829 System
.err
.println("Critical error: 16-bit call gate: jump to same privilege " +
4830 "conforming segment not implemented");
4831 throw new IllegalStateException("O16 A16 CALL FAR call gate to same priviledge conforming segment not implemented");
4838 case 0x05: // Task Gate
4839 System
.err
.println("Critical error: Task gate not implemented");
4840 throw new IllegalStateException("O16 A16 CALL FAR to task gate not implemented");
4841 case 0x09: // TSS (Not Busy)
4842 case 0x0b: // TSS (Busy)
4843 System
.err
.println("Critical error: TSS not implemented");
4844 throw new IllegalStateException("O16 A16 CALL FAR to TSS not implemented");
4845 case 0x0c: // Call Gate
4846 System
.err
.println("Critical error: Call gate not implemented");
4847 throw new IllegalStateException("O16 A16 CALL FAR to call gate not implemented");
4848 case 0x18: // Non-conforming Code Segment
4849 case 0x19: // Non-conforming Code Segment
4850 case 0x1a: // Non-conforming Code Segment
4851 case 0x1b: // Non-conforming Code Segment
4853 if(!newSegment
.isPresent())
4854 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, newSegment
.getSelector(), true);
4856 if ((cpu
.esp
< 4) && (cpu
.esp
> 0))
4857 throw ProcessorException
.STACK_SEGMENT_0
;
4859 newSegment
.checkAddress(targetEIP
&0xFFFF);
4862 if (cpu
.ss
.getDefaultSizeFlag())
4865 tempESP
= cpu
.esp
& 0xffff;
4867 cpu
.ss
.setWord((tempESP
- 2), (short) (0xFFFF & cpu
.cs
.getSelector()));
4868 cpu
.ss
.setWord((tempESP
- 4), (short) (0xFFFF & cpu
.eip
));
4869 cpu
.esp
= (cpu
.esp
& ~
0xFFFF) | ((cpu
.esp
-4) & 0xFFFF);
4871 cpu
.cs
= newSegment
;
4872 cpu
.cs
.setRPL(cpu
.getCPL());
4873 cpu
.eip
= targetEIP
& 0xFFFF;
4876 case 0x1c: // Conforming Code Segment (Not Readable & Not Accessed)
4877 case 0x1d: // Conforming Code Segment (Not Readable & Accessed)
4878 case 0x1e: // Conforming Code Segment (Readable & Not Accessed)
4879 case 0x1f: // Conforming Code Segment (Readable & Accessed)
4880 System
.err
.println("Critical error: Conforming code segment not implemented");
4881 throw new IllegalStateException("O16 A16 CALL FAR to conforming code segment not implemented");
4886 private final void call_far_o32_a32(int targetEIP
, int targetSelector
)
4888 Segment newSegment
= cpu
.getSegment(targetSelector
);
4889 if (newSegment
== SegmentFactory
.NULL_SEGMENT
)
4890 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
4892 switch (newSegment
.getType()) { // segment type
4893 default: // not a valid segment descriptor for a jump
4894 System
.err
.println("Emulated: Invalid segment type " + newSegment
.getType() + ".");
4895 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
4896 case 0x01: // TSS 16-bit (Not Busy)
4897 case 0x03: // TSS 16-bit (Busy)
4898 System
.err
.println("Critical error: 16-bit TSS not implemented");
4899 throw new IllegalStateException("O32 A32 CALL FAR to 16-bit TSS not implemented");
4900 case 0x04: // Call Gate 16-bit
4902 if ((newSegment
.getRPL() > cpu
.getCPL()) || (newSegment
.getDPL() < cpu
.getCPL()))
4903 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
4904 if (!newSegment
.isPresent())
4905 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSelector
, true);
4907 ProtectedModeSegment
.GateSegment gate
= (ProtectedModeSegment
.GateSegment
) newSegment
;
4909 int targetSegmentSelector
= gate
.getTargetSegment();
4911 Segment targetSegment
;
4913 targetSegment
= cpu
.getSegment(targetSegmentSelector
);
4914 } catch (ProcessorException e
) {
4915 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSegmentSelector
, true);
4917 if (targetSegment
== SegmentFactory
.NULL_SEGMENT
)
4918 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
4920 if (targetSegment
.getDPL() > cpu
.getCPL())
4921 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
4923 switch (targetSegment
.getType()) {
4925 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSegmentSelector
, true);
4927 case 0x18: //Code, Execute-Only
4928 case 0x19: //Code, Execute-Only, Accessed
4929 case 0x1a: //Code, Execute/Read
4930 case 0x1b: //Code, Execute/Read, Accessed
4932 if (!targetSegment
.isPresent())
4933 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSegmentSelector
, true);
4935 if (targetSegment
.getDPL() < cpu
.getCPL()) {
4936 System
.err
.println("Critical error: 16-bit call gate: jump to more privileged " +
4937 "segment not implemented");
4938 throw new IllegalStateException("O32 A32 CALL FAR to 16-bit call gate: Jump to more priviledged segment not implemented");
4940 } else if (targetSegment
.getDPL() == cpu
.getCPL()) {
4941 System
.err
.println("Critical error: 16-bit call gate: jump to same privilege " +
4942 "segment not implemented");
4943 throw new IllegalStateException("O32 A32 CALL FAR to 16-bit call gate: Jump to same-priviledge segment not implemented");
4946 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSegmentSelector
, true);
4949 case 0x1c: //Code: Execute-Only, Conforming
4950 case 0x1d: //Code: Execute-Only, Conforming, Accessed
4951 case 0x1e: //Code: Execute/Read, Conforming
4952 case 0x1f: //Code: Execute/Read, Conforming, Accessed
4954 if (!targetSegment
.isPresent())
4955 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSegmentSelector
, true);
4957 System
.err
.println("Critical error: 16-bit call gate: jump to same privilege " +
4958 "conforming segment not implemented");
4959 throw new IllegalStateException("O32 A32 CALL FAR to 16-bit call gate: Jump to same priviledge conforming segment not implemented");
4966 case 0x05: // Task Gate
4967 System
.err
.println("Critical error: Task gate not implemented");
4968 throw new IllegalStateException("O32 A32 CALL FAR to task gate not implemented");
4969 case 0x09: // TSS (Not Busy)
4970 case 0x0b: // TSS (Busy)
4971 System
.err
.println("Critical error: TSS not implemented");
4972 throw new IllegalStateException("O32 A32 CALL FAR to TSS not implemented");
4973 case 0x0c: // Call Gate
4974 System
.err
.println("Critical error: Call gate not implemented");
4975 throw new IllegalStateException("O32 A32 CALL FAR to call gate not implemented");
4976 case 0x18: // Non-conforming Code Segment
4977 case 0x19: // Non-conforming Code Segment
4978 case 0x1a: // Non-conforming Code Segment
4979 case 0x1b: // Non-conforming Code Segment
4981 if ((newSegment
.getRPL() > cpu
.getCPL()) || (newSegment
.getDPL() != cpu
.getCPL()))
4982 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
4983 if (!newSegment
.isPresent())
4984 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSelector
, true);
4986 if ((cpu
.esp
< 8) && (cpu
.esp
> 0))
4987 throw ProcessorException
.STACK_SEGMENT_0
;
4989 newSegment
.checkAddress(targetEIP
);
4991 cpu
.ss
.setDoubleWord(cpu
.esp
- 4, cpu
.cs
.getSelector());
4992 cpu
.ss
.setDoubleWord(cpu
.esp
- 8, cpu
.eip
);
4995 cpu
.cs
= newSegment
;
4996 cpu
.cs
.setRPL(cpu
.getCPL());
4997 cpu
.eip
= targetEIP
;
5000 case 0x1c: // Conforming Code Segment (Not Readable & Not Accessed)
5001 case 0x1d: // Conforming Code Segment (Not Readable & Accessed)
5002 case 0x1e: // Conforming Code Segment (Readable & Not Accessed)
5003 case 0x1f: // Conforming Code Segment (Readable & Accessed)
5004 System
.err
.println("Critical error: Conforming code segment not implemented");
5005 throw new IllegalStateException("O32 A32 CALL FAR to conforming code segment not implemented");
5009 private final void call_far_o32_a16(int targetEIP
, int targetSelector
)
5011 Segment newSegment
= cpu
.getSegment(targetSelector
);
5012 if (newSegment
== SegmentFactory
.NULL_SEGMENT
)
5013 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
5015 switch (newSegment
.getType())
5017 default: // not a valid segment descriptor for a jump
5018 System
.err
.println("Emulated: Invalid segment type " + newSegment
.getType() + ".");
5019 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
5020 case 0x01: // TSS 16-bit (Not Busy)
5021 case 0x03: // TSS 16-bit (Busy)
5022 System
.err
.println("Critical error: 16-bit TSS not implemented");
5023 throw new IllegalStateException("O32 A16 CALL FAR to 16-bit TSS not implemented");
5024 case 0x04: // Call Gate 16-bit
5026 if ((newSegment
.getRPL() > cpu
.getCPL()) || (newSegment
.getDPL() < cpu
.getCPL()))
5027 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
5028 if (!newSegment
.isPresent())
5029 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSelector
, true);
5031 ProtectedModeSegment
.GateSegment gate
= (ProtectedModeSegment
.GateSegment
) newSegment
;
5033 int targetSegmentSelector
= gate
.getTargetSegment();
5035 Segment targetSegment
;
5037 targetSegment
= cpu
.getSegment(targetSegmentSelector
);
5038 } catch (ProcessorException e
) {
5039 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSegmentSelector
, true);
5041 if (targetSegment
== SegmentFactory
.NULL_SEGMENT
)
5042 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
5044 if (targetSegment
.getDPL() > cpu
.getCPL())
5045 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
5047 switch (targetSegment
.getType()) {
5049 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSegmentSelector
, true);
5051 case 0x18: //Code, Execute-Only
5052 case 0x19: //Code, Execute-Only, Accessed
5053 case 0x1a: //Code, Execute/Read
5054 case 0x1b: //Code, Execute/Read, Accessed
5056 if (!targetSegment
.isPresent())
5057 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSegmentSelector
, true);
5059 if (targetSegment
.getDPL() < cpu
.getCPL()) {
5060 System
.err
.println("Critical error: 16-bit call gate: jump to more privileged " +
5061 "segment not implemented");
5062 throw new IllegalStateException("O32 A16 CALL FAR to 16-bit call gate: Jump to more priviledged segmment not supported");
5064 } else if (targetSegment
.getDPL() == cpu
.getCPL()) {
5065 System
.err
.println("Critical error: 16-bit call gate: jump to same privilege " +
5066 "segment not implemented");
5067 throw new IllegalStateException("O32 A16 CALL FAR to 16-bit call gate: Jump to same priviledge segmment not supported");
5070 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSegmentSelector
, true);
5073 case 0x1c: //Code: Execute-Only, Conforming
5074 case 0x1d: //Code: Execute-Only, Conforming, Accessed
5075 case 0x1e: //Code: Execute/Read, Conforming
5076 case 0x1f: //Code: Execute/Read, Conforming, Accessed
5078 if (!targetSegment
.isPresent())
5079 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSegmentSelector
, true);
5081 System
.err
.println("Critical error: 16-bit call gate: jump to same privilege " +
5082 "conforming segment not implemented");
5083 throw new IllegalStateException("O32 A16 CALL FAR to 16-bit call gate: Jump to same priviledge conforming segment not implemented");
5090 case 0x05: // Task Gate
5091 System
.err
.println("Critical error: Task gate not implemented");
5092 throw new IllegalStateException("O32 A16 CALL FAR to task gate not implemented");
5093 case 0x09: // TSS (Not Busy)
5094 case 0x0b: // TSS (Busy)
5095 System
.err
.println("Critical error: TSS not implemented");
5096 throw new IllegalStateException("O32 A16 CALL FAR to TSS not implemented");
5097 case 0x0c: // Call Gate
5098 System
.err
.println("Critical error: Call gate not implemented");
5099 throw new IllegalStateException("O32 A16 CALL FAR to call gate not implemented");
5100 case 0x18: // Non-conforming Code Segment
5101 case 0x19: // Non-conforming Code Segment
5102 case 0x1a: // Non-conforming Code Segment
5103 case 0x1b: // Non-conforming Code Segment
5105 if ((newSegment
.getRPL() > cpu
.getCPL()) || (newSegment
.getDPL() != cpu
.getCPL()))
5106 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, targetSelector
, true);
5107 if (!newSegment
.isPresent())
5108 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, targetSelector
, true);
5110 if ((cpu
.esp
& 0xffff) < 8)
5111 throw ProcessorException
.STACK_SEGMENT_0
;
5113 newSegment
.checkAddress(targetEIP
);
5115 cpu
.ss
.setDoubleWord((cpu
.esp
- 4) & 0xffff, cpu
.cs
.getSelector());
5116 cpu
.ss
.setDoubleWord((cpu
.esp
- 8) & 0xffff, cpu
.eip
);
5117 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
- 8) & 0xffff);
5119 cpu
.cs
= newSegment
;
5120 cpu
.cs
.setRPL(cpu
.getCPL());
5121 cpu
.eip
= targetEIP
;
5124 case 0x1c: // Conforming Code Segment (Not Readable & Not Accessed)
5125 case 0x1d: // Conforming Code Segment (Not Readable & Accessed)
5126 case 0x1e: // Conforming Code Segment (Readable & Not Accessed)
5127 case 0x1f: // Conforming Code Segment (Readable & Accessed)
5128 System
.err
.println("Critical error: Conforming code segment not implemented");
5129 throw new IllegalStateException("O32 A16 CALL FAR to conforming segment not implemented");
5133 private final void ret_o16_a32()
5135 // TODO: supposed to throw SS exception
5136 // "if top 6 bytes of stack not within stack limits"
5137 cpu
.eip
= cpu
.ss
.getWord(cpu
.esp
) & 0xffff;
5138 cpu
.esp
= cpu
.esp
+ 2;
5141 private final void ret_o16_a16()
5143 // TODO: supposed to throw SS exception
5144 // "if top 6 bytes of stack not within stack limits"
5145 cpu
.eip
= cpu
.ss
.getWord(cpu
.esp
& 0xffff) & 0xffff;
5146 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 2) & 0xffff);
5149 private final void ret_o32_a32()
5151 // TODO: supposed to throw SS exception
5152 // "if top 6 bytes of stack not within stack limits"
5153 cpu
.eip
= cpu
.ss
.getDoubleWord(cpu
.esp
);
5154 cpu
.esp
= cpu
.esp
+ 4;
5157 private final void ret_o32_a16()
5159 // TODO: supposed to throw SS exception
5160 // "if top 6 bytes of stack not within stack limits"
5161 cpu
.eip
= cpu
.ss
.getDoubleWord(0xffff & cpu
.esp
);
5162 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 4) & 0xffff);
5165 private final void ret_iw_o16_a32(short offset
)
5171 private final void ret_iw_o16_a16(short offset
)
5174 cpu
.esp
= (cpu
.esp
& ~
0xffff) | (((cpu
.esp
& 0xFFFF) + offset
) & 0xffff);
5178 private final void ret_iw_o32_a32(short offset
)
5184 private final void ret_iw_o32_a16(short offset
)
5187 cpu
.esp
= (cpu
.esp
& ~
0xffff) | (((cpu
.esp
& 0xFFFF) + offset
) & 0xffff);
5190 private final void ret_far_o16_a16(int stackdelta
)
5193 cpu
.ss
.checkAddress((cpu
.esp
+ 3) & 0xFFFF);
5194 } catch (ProcessorException e
) {
5195 throw ProcessorException
.STACK_SEGMENT_0
;
5198 int tempEIP
= 0xFFFF & cpu
.ss
.getWord(cpu
.esp
& 0xFFFF);
5199 int tempCS
= 0xFFFF & cpu
.ss
.getWord((cpu
.esp
+ 2) & 0xFFFF);
5201 if ((tempCS
& 0xfffc) == 0)
5202 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);
5204 Segment returnSegment
= cpu
.getSegment(tempCS
);
5205 if (returnSegment
== SegmentFactory
.NULL_SEGMENT
)
5206 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
5208 if (returnSegment
.getRPL() < cpu
.getCPL())
5210 System
.err
.println("Emulated: RPL too small in far ret: RPL=" + returnSegment
.getRPL() +
5211 ", CPL=" + cpu
.getCPL() + ", new CS=" + Integer
.toHexString(tempCS
));
5212 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5215 switch (returnSegment
.getType()) {
5217 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5219 case 0x18: //Code, Execute-Only
5220 case 0x19: //Code, Execute-Only, Accessed
5221 case 0x1a: //Code, Execute/Read
5222 case 0x1b: //Code, Execute/Read, Accessed
5224 if (!(returnSegment
.isPresent()))
5225 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, tempCS
, true);
5227 if (returnSegment
.getRPL() > cpu
.getCPL()) {
5228 //OUTER PRIVILEGE-LEVEL
5230 cpu
.ss
.checkAddress((cpu
.esp
+ 7 + stackdelta
) & 0xFFFF);
5231 } catch (ProcessorException e
) {
5232 throw ProcessorException
.STACK_SEGMENT_0
;
5235 int returnESP
= 0xffff & cpu
.ss
.getWord((cpu
.esp
+ 4 + stackdelta
) & 0xFFFF);
5236 int newSS
= 0xffff & cpu
.ss
.getWord((cpu
.esp
+ 6 + stackdelta
) & 0xFFFF);
5238 if ((newSS
& 0xfffc) == 0)
5239 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);
5241 Segment returnStackSegment
= cpu
.getSegment(newSS
);
5243 if ((returnStackSegment
.getRPL() != returnSegment
.getRPL()) || ((returnStackSegment
.getType() & 0x12) != 0x12) ||
5244 (returnStackSegment
.getDPL() != returnSegment
.getRPL()))
5245 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newSS
& 0xfffc, true);
5247 if (!returnStackSegment
.isPresent())
5248 throw new ProcessorException(ProcessorException
.Type
.STACK_SEGMENT
, newSS
& 0xfffc, true);
5250 returnSegment
.checkAddress(tempEIP
);
5253 cpu
.cs
= returnSegment
;
5255 cpu
.ss
= returnStackSegment
;
5256 cpu
.esp
= returnESP
+ stackdelta
;
5258 cpu
.setCPL(cpu
.cs
.getRPL());
5261 if ((((cpu
.es
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.es
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.es
.getDPL()))
5262 // can't use lower dpl data segment at higher cpl
5263 System
.err
.println("Emulated: Setting ES to NULL in ret far");
5264 cpu
.es
= SegmentFactory
.NULL_SEGMENT
;
5265 } catch (ProcessorException e
) {
5266 } catch (Exception e
) {
5270 if ((((cpu
.ds
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.ds
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.ds
.getDPL()))
5271 // can't use lower dpl data segment at higher cpl
5272 System
.err
.println("Emulated: Setting DS to NULL in ret far");
5273 cpu
.ds
= SegmentFactory
.NULL_SEGMENT
;
5274 } catch (ProcessorException e
) {
5275 } catch (Exception e
) {
5279 if ((((cpu
.fs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.fs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.fs
.getDPL()))
5280 // can't use lower dpl data segment at higher cpl
5281 System
.err
.println("Emulated: Setting FS to NULL in ret far");
5282 cpu
.fs
= SegmentFactory
.NULL_SEGMENT
;
5283 } catch (ProcessorException e
) {
5284 } catch (Exception e
) {
5288 if ((((cpu
.gs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.gs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.gs
.getDPL()))
5289 // can't use lower dpl data segment at higher cpl
5290 System
.err
.println("Emulated: Setting GS to NULL in ret far");
5291 cpu
.gs
= SegmentFactory
.NULL_SEGMENT
;
5292 } catch (ProcessorException e
) {
5293 } catch (Exception e
) {
5296 //SAME PRIVILEGE-LEVEL
5297 returnSegment
.checkAddress(tempEIP
);
5299 cpu
.esp
= (cpu
.esp
& ~
0xFFFF)| ((cpu
.esp
+ 4 + stackdelta
) &0xFFFF);
5301 cpu
.cs
= returnSegment
;
5305 case 0x1c: //Code: Execute-Only, Conforming
5306 case 0x1d: //Code: Execute-Only, Conforming, Accessed
5307 case 0x1e: //Code: Execute/Read, Conforming
5308 case 0x1f: //Code: Execute/Read, Conforming, Accessed
5310 if (returnSegment
.getDPL() > returnSegment
.getRPL())
5311 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5313 if (!(returnSegment
.isPresent()))
5314 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, tempCS
, true);
5316 if (returnSegment
.getRPL() > cpu
.getCPL()) {
5317 //OUTER PRIVILEGE-LEVEL
5319 System
.err
.println("Critical error: Conforming outer privilege level not implemented");
5320 throw new IllegalStateException("O16 A16 RETF to conforiming outer priviledge level not implemented");
5322 //SAME PRIVILEGE-LEVEL
5323 returnSegment
.checkAddress(tempEIP
);
5325 cpu
.esp
= (cpu
.esp
& ~
0xFFFF)| ((cpu
.esp
+ 4 + stackdelta
) &0xFFFF);
5327 cpu
.cs
= returnSegment
;
5333 private final void ret_far_o16_a32(int stackdelta
)
5336 cpu
.ss
.checkAddress(cpu
.esp
+ 3);
5337 } catch (ProcessorException e
) {
5338 throw ProcessorException
.STACK_SEGMENT_0
;
5341 int tempEIP
= 0xFFFF & cpu
.ss
.getWord(cpu
.esp
);
5342 int tempCS
= 0xFFFF & cpu
.ss
.getWord(cpu
.esp
+ 2);
5344 Segment returnSegment
= cpu
.getSegment(tempCS
);
5346 if (returnSegment
== SegmentFactory
.NULL_SEGMENT
)
5347 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
5349 switch (returnSegment
.getType()) {
5351 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5353 case 0x18: //Code, Execute-Only
5354 case 0x19: //Code, Execute-Only, Accessed
5355 case 0x1a: //Code, Execute/Read
5356 case 0x1b: //Code, Execute/Read, Accessed
5358 if (returnSegment
.getRPL() < cpu
.getCPL())
5359 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5361 if (!(returnSegment
.isPresent()))
5362 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, tempCS
, true);
5364 if (returnSegment
.getRPL() > cpu
.getCPL()) {
5365 //OUTER PRIVILEGE-LEVEL
5367 System
.err
.println("Critical error: Non-conforming outer privilege level not implemented");
5368 throw new IllegalStateException("O16 A32 RETF to non-conforming outer priviledge level not implemented");
5370 //SAME PRIVILEGE-LEVEL
5371 returnSegment
.checkAddress(tempEIP
);
5373 cpu
.esp
= cpu
.esp
+ 4 + stackdelta
;
5375 cpu
.cs
= returnSegment
;
5379 case 0x1c: //Code: Execute-Only, Conforming
5380 case 0x1d: //Code: Execute-Only, Conforming, Accessed
5381 case 0x1e: //Code: Execute/Read, Conforming
5382 case 0x1f: //Code: Execute/Read, Conforming, Accessed
5384 if (returnSegment
.getRPL() < cpu
.getCPL())
5385 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5387 if (returnSegment
.getDPL() > returnSegment
.getRPL())
5388 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5390 if (!(returnSegment
.isPresent()))
5391 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, tempCS
, true);
5393 if (returnSegment
.getRPL() > cpu
.getCPL()) {
5394 //OUTER PRIVILEGE-LEVEL
5396 System
.err
.println("Critical error: Conforming outer privilege level not implemented");
5397 throw new IllegalStateException("O16 A32 RETF to conforming outer priviledge level not implemented");
5399 //SAME PRIVILEGE-LEVEL
5400 returnSegment
.checkAddress(tempEIP
& 0xFFFF);
5402 cpu
.esp
= cpu
.esp
+ 4 + stackdelta
;
5403 cpu
.eip
= (0xFFFF & tempEIP
);
5404 cpu
.cs
= returnSegment
;
5410 private final void ret_far_o32_a16(int stackdelta
)
5413 cpu
.ss
.checkAddress((cpu
.esp
+ 7) & 0xFFFF);
5414 } catch (ProcessorException e
) {
5415 throw ProcessorException
.STACK_SEGMENT_0
;
5418 int tempEIP
= cpu
.ss
.getDoubleWord(cpu
.esp
& 0xFFFF);
5419 int tempCS
= 0xffff & cpu
.ss
.getDoubleWord((cpu
.esp
+ 4) & 0xFFFF);
5421 Segment returnSegment
= cpu
.getSegment(tempCS
);
5423 if (returnSegment
== SegmentFactory
.NULL_SEGMENT
)
5424 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
5426 switch (returnSegment
.getType()) {
5428 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5430 case 0x18: //Code, Execute-Only
5431 case 0x19: //Code, Execute-Only, Accessed
5432 case 0x1a: //Code, Execute/Read
5433 case 0x1b: //Code, Execute/Read, Accessed
5435 if (returnSegment
.getRPL() < cpu
.getCPL())
5436 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5438 if (!(returnSegment
.isPresent()))
5439 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, tempCS
, true);
5441 if (returnSegment
.getRPL() > cpu
.getCPL()) {
5442 //OUTER PRIVILEGE-LEVEL
5444 System
.err
.println("Critical error: Non-conforming outer privilege level not implemented");
5445 throw new IllegalStateException("O32 A16 RETF to non-conforming outer privilege level not implemented");
5447 //SAME PRIVILEGE-LEVEL
5448 returnSegment
.checkAddress(tempEIP
);
5450 cpu
.esp
= (cpu
.esp
& ~
0xFFFF)| ((cpu
.esp
+ 8 + stackdelta
) &0xFFFF);
5452 cpu
.cs
= returnSegment
;
5456 case 0x1c: //Code: Execute-Only, Conforming
5457 case 0x1d: //Code: Execute-Only, Conforming, Accessed
5458 case 0x1e: //Code: Execute/Read, Conforming
5459 case 0x1f: //Code: Execute/Read, Conforming, Accessed
5461 if (returnSegment
.getRPL() < cpu
.getCPL())
5462 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5464 if (returnSegment
.getDPL() > returnSegment
.getRPL())
5465 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5467 if (!(returnSegment
.isPresent()))
5468 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, tempCS
, true);
5470 if (returnSegment
.getRPL() > cpu
.getCPL()) {
5471 //OUTER PRIVILEGE-LEVEL
5473 System
.err
.println("Critical error: Conforming outer privilege level not implemented");
5474 throw new IllegalStateException("O32 A16 RETF to conforming outer privilege level not implemented");
5476 //SAME PRIVILEGE-LEVEL
5477 returnSegment
.checkAddress(tempEIP
);
5479 cpu
.esp
= (cpu
.esp
& ~
0xFFFF)| ((cpu
.esp
+ 8 + stackdelta
) &0xFFFF);
5481 cpu
.cs
= returnSegment
;
5487 private final void ret_far_o32_a32(int stackdelta
)
5490 cpu
.ss
.checkAddress(cpu
.esp
+ 7);
5491 } catch (ProcessorException e
) {
5492 throw ProcessorException
.STACK_SEGMENT_0
;
5495 int tempEIP
= cpu
.ss
.getDoubleWord(cpu
.esp
);
5496 int tempCS
= 0xffff & cpu
.ss
.getDoubleWord(cpu
.esp
+ 4);
5498 Segment returnSegment
= cpu
.getSegment(tempCS
);
5500 if (returnSegment
== SegmentFactory
.NULL_SEGMENT
)
5501 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
5503 switch (returnSegment
.getType()) {
5505 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5507 case 0x18: //Code, Execute-Only
5508 case 0x19: //Code, Execute-Only, Accessed
5509 case 0x1a: //Code, Execute/Read
5510 case 0x1b: //Code, Execute/Read, Accessed
5512 if (returnSegment
.getRPL() < cpu
.getCPL())
5513 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5515 if (!(returnSegment
.isPresent()))
5516 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, tempCS
, true);
5518 if (returnSegment
.getRPL() > cpu
.getCPL()) {
5519 //OUTER PRIVILEGE-LEVEL
5521 cpu
.ss
.checkAddress(cpu
.esp
+ 15);
5522 } catch (ProcessorException e
) {
5523 throw ProcessorException
.STACK_SEGMENT_0
;
5526 int returnESP
= cpu
.ss
.getDoubleWord(cpu
.esp
+ 8 + stackdelta
);
5527 int tempSS
= 0xffff & cpu
.ss
.getDoubleWord(cpu
.esp
+ 12 + stackdelta
);
5529 Segment returnStackSegment
= cpu
.getSegment(tempSS
);
5531 if ((returnStackSegment
.getRPL() != returnSegment
.getRPL()) || ((returnStackSegment
.getType() & 0x12) != 0x12) ||
5532 (returnStackSegment
.getDPL() != returnSegment
.getRPL()))
5533 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempSS
, true);
5535 if (!returnStackSegment
.isPresent())
5536 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempSS
, true);
5538 returnSegment
.checkAddress(tempEIP
);
5540 //cpu.esp += 20; //includes the 12 from earlier
5542 cpu
.cs
= returnSegment
;
5544 cpu
.ss
= returnStackSegment
;
5545 cpu
.esp
= returnESP
;
5547 cpu
.setCPL(cpu
.cs
.getRPL());
5549 //SAME PRIVILEGE-LEVEL
5550 returnSegment
.checkAddress(tempEIP
);
5552 cpu
.esp
+= 8 + stackdelta
;
5554 cpu
.cs
= returnSegment
;
5558 case 0x1c: //Code: Execute-Only, Conforming
5559 case 0x1d: //Code: Execute-Only, Conforming, Accessed
5560 case 0x1e: //Code: Execute/Read, Conforming
5561 case 0x1f: //Code: Execute/Read, Conforming, Accessed
5563 if (returnSegment
.getRPL() < cpu
.getCPL())
5564 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5566 if (returnSegment
.getDPL() > returnSegment
.getRPL())
5567 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempCS
, true);
5569 if (!(returnSegment
.isPresent()))
5570 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, tempCS
, true);
5572 if (returnSegment
.getRPL() > cpu
.getCPL()) {
5573 //OUTER PRIVILEGE-LEVEL
5575 System
.err
.println("Critical error: Conforming outer privilege level not implemented");
5576 throw new IllegalStateException("O32 A32 RETF to conforming outer priviledge level not implemented");
5578 //SAME PRIVILEGE-LEVEL
5579 returnSegment
.checkAddress(tempEIP
);
5583 cpu
.cs
= returnSegment
;
5589 private final int iretToVirtual8086Mode16BitAddressing(int newCS
, int newEIP
, int newEFlags
)
5592 cpu
.ss
.checkAddress((cpu
.esp
+ 23) & 0xffff);
5593 } catch (ProcessorException e
) {
5594 throw ProcessorException
.STACK_SEGMENT_0
;
5596 cpu
.cs
= SegmentFactory
.createVirtual8086ModeSegment(cpu
.linearMemory
, newCS
, true);
5597 cpu
.eip
= newEIP
& 0xffff;
5598 int newESP
= cpu
.ss
.getDoubleWord(cpu
.esp
& 0xffff);
5599 int newSS
= 0xffff & cpu
.ss
.getDoubleWord((cpu
.esp
+ 4) & 0xffff);
5600 cpu
.es
= SegmentFactory
.createVirtual8086ModeSegment(cpu
.linearMemory
, 0xffff & cpu
.ss
.getDoubleWord((cpu
.esp
+ 8) & 0xffff), false);
5601 cpu
.ds
= SegmentFactory
.createVirtual8086ModeSegment(cpu
.linearMemory
, 0xffff & cpu
.ss
.getDoubleWord((cpu
.esp
+ 12) & 0xffff), false);
5602 cpu
.fs
= SegmentFactory
.createVirtual8086ModeSegment(cpu
.linearMemory
, 0xffff & cpu
.ss
.getDoubleWord((cpu
.esp
+ 16) & 0xffff), false);
5603 cpu
.gs
= SegmentFactory
.createVirtual8086ModeSegment(cpu
.linearMemory
, 0xffff & cpu
.ss
.getDoubleWord((cpu
.esp
+ 20) & 0xffff), false);
5604 cpu
.ss
= SegmentFactory
.createVirtual8086ModeSegment(cpu
.linearMemory
, newSS
, false);
5611 private final int iret32ProtectedMode16BitAddressing(int newCS
, int newEIP
, int newEFlags
)
5613 Segment returnSegment
= cpu
.getSegment(newCS
);
5615 if (returnSegment
== SegmentFactory
.NULL_SEGMENT
)
5616 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
5618 switch (returnSegment
.getType()) {
5620 System
.err
.println("Emulated: Invalid segment type " + returnSegment
.getType() + ".");
5621 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
5623 case 0x18: //Code, Execute-Only
5624 case 0x19: //Code, Execute-Only, Accessed
5625 case 0x1a: //Code, Execute/Read
5626 case 0x1b: //Code, Execute/Read, Accessed
5628 if (returnSegment
.getRPL() < cpu
.getCPL())
5629 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
5631 if (!(returnSegment
.isPresent()))
5632 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, newCS
, true);
5634 if (returnSegment
.getRPL() > cpu
.getCPL()) {
5635 //OUTER PRIVILEGE-LEVEL
5637 cpu
.ss
.checkAddress((cpu
.esp
+ 7) & 0xFFFF);
5638 } catch (ProcessorException e
) {
5639 throw ProcessorException
.STACK_SEGMENT_0
;
5642 int returnESP
= cpu
.ss
.getDoubleWord((cpu
.esp
)&0xFFFF);
5643 int newSS
= 0xffff & cpu
.ss
.getDoubleWord((cpu
.esp
+ 4)&0xFFFF);
5645 Segment returnStackSegment
= cpu
.getSegment(newSS
);
5647 if ((returnStackSegment
.getRPL() != returnSegment
.getRPL()) || ((returnStackSegment
.getType() & 0x12) != 0x12) ||
5648 (returnStackSegment
.getDPL() != returnSegment
.getRPL()))
5649 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newSS
, true);
5651 if (!returnStackSegment
.isPresent())
5652 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newSS
, true);
5654 returnSegment
.checkAddress(newEIP
);
5656 //cpu.esp += 20; //includes the 12 from earlier
5658 cpu
.cs
= returnSegment
;
5660 cpu
.ss
= returnStackSegment
;
5661 cpu
.esp
= returnESP
;
5663 int eflags
= cpu
.getEFlags();
5664 eflags
&= ~
0x254dd5;
5665 eflags
|= (0x254dd5 & newEFlags
);
5666 //overwrite: all; preserve: if, iopl, vm, vif, vip
5668 if (cpu
.getCPL() <= cpu
.eflagsIOPrivilegeLevel
) {
5670 eflags
|= (0x200 & newEFlags
);
5671 //overwrite: all; preserve: iopl, vm, vif, vip
5673 if (cpu
.getCPL() == 0) {
5674 eflags
&= ~
0x1a3000;
5675 eflags
|= (0x1a3000 & newEFlags
);
5678 // cpu.setEFlags(eflags);
5680 cpu
.setCPL(cpu
.cs
.getRPL());
5683 if ((((cpu
.es
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.es
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.es
.getDPL()))
5684 cpu
.es
= SegmentFactory
.NULL_SEGMENT
;
5685 } catch (ProcessorException e
) {
5686 } catch (Exception e
) {
5690 if ((((cpu
.ds
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.ds
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.ds
.getDPL()))
5691 cpu
.ds
= SegmentFactory
.NULL_SEGMENT
;
5692 } catch (ProcessorException e
) {
5693 } catch (Exception e
) {
5697 if ((((cpu
.fs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.fs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.fs
.getDPL()))
5698 cpu
.fs
= SegmentFactory
.NULL_SEGMENT
;
5699 } catch (ProcessorException e
) {
5700 } catch (Exception e
) {
5704 if ((((cpu
.gs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.gs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.gs
.getDPL()))
5705 cpu
.gs
= SegmentFactory
.NULL_SEGMENT
;
5706 } catch (ProcessorException e
) {
5707 } catch (Exception e
) {
5712 //SAME PRIVILEGE-LEVEL
5713 returnSegment
.checkAddress(newEIP
);
5715 // cpu.esp = (cpu.esp & ~0xFFFF) | ((cpu.esp+12)&0xFFFF);
5716 cpu
.cs
= returnSegment
;
5720 int eflags
= cpu
.getEFlags();
5722 eflags
&= ~
0x254dd5;
5723 eflags
|= (0x254dd5 & newEFlags
);
5725 if (cpu
.getCPL() <= cpu
.eflagsIOPrivilegeLevel
) {
5727 eflags
|= (0x200 & newEFlags
);
5730 if (cpu
.getCPL() == 0) {
5731 eflags
&= ~
0x1a3000;
5732 eflags
|= (0x1a3000 & newEFlags
);
5735 // cpu.setEFlags(eflags);
5739 case 0x1c: //Code: Execute-Only, Conforming
5740 case 0x1d: //Code: Execute-Only, Conforming, Accessed
5741 case 0x1e: //Code: Execute/Read, Conforming
5742 case 0x1f: //Code: Execute/Read, Conforming, Accessed
5744 if (returnSegment
.getRPL() < cpu
.getCPL())
5745 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
5747 if (returnSegment
.getDPL() > returnSegment
.getRPL())
5748 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
5750 if (!(returnSegment
.isPresent()))
5751 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, newCS
, true);
5753 if (returnSegment
.getRPL() > cpu
.getCPL()) {
5754 //OUTER PRIVILEGE-LEVEL
5755 System
.err
.println("Critical error: Conforming outer privilege level not implemented");
5756 throw new IllegalStateException("iret32ProtectedMode16BitAddressing to conforming outer priviledge level not implemented");
5758 //SAME PRIVILEGE-LEVEL
5759 System
.err
.println("Critical error: Conforming same privilege level not implemented");
5760 throw new IllegalStateException("iret32ProtectedMode16BitAddressing to conforming same priviledge level not implemented");
5766 private final int iret_o32_a16()
5768 if (cpu
.eflagsNestedTask
)
5769 return iretFromTask();
5772 cpu
.ss
.checkAddress((cpu
.esp
+ 11) & 0xffff);
5773 } catch (ProcessorException e
) {
5774 throw ProcessorException
.STACK_SEGMENT_0
;
5776 int tempEIP
= cpu
.ss
.getDoubleWord(cpu
.esp
& 0xFFFF);
5777 int tempCS
= 0xffff & cpu
.ss
.getDoubleWord((cpu
.esp
+ 4) & 0xFFFF);
5778 int tempEFlags
= cpu
.ss
.getDoubleWord((cpu
.esp
+ 8) & 0xFFFF);
5779 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 12) & 0xffff);
5781 if (((tempEFlags
& (1 << 17)) != 0) && (cpu
.getCPL() == 0)) {
5782 return iretToVirtual8086Mode16BitAddressing(tempCS
, tempEIP
, tempEFlags
);
5784 return iret32ProtectedMode16BitAddressing(tempCS
, tempEIP
, tempEFlags
);
5789 private final int iretFromTask()
5791 System
.err
.println("Critical error: iretFromTask().");
5792 throw new IllegalStateException("IRET with NT set not implemented");
5795 private final int iretToVirtual8086Mode32BitAddressing(int newCS
, int newEIP
, int newEFlags
)
5798 cpu
.ss
.checkAddress(cpu
.esp
+ 23);
5799 } catch (ProcessorException e
) {
5800 throw ProcessorException
.STACK_SEGMENT_0
;
5802 if (newEIP
> 0xfffff)
5803 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
,0,true);//ProcessorException.GENERAL_PROTECTION_0;
5805 cpu
.cs
= SegmentFactory
.createVirtual8086ModeSegment(cpu
.linearMemory
, newCS
, true);
5806 cpu
.eip
= newEIP
& 0xffff;
5807 int newESP
= cpu
.ss
.getDoubleWord(cpu
.esp
);
5808 int newSS
= 0xffff & cpu
.ss
.getDoubleWord(cpu
.esp
+ 4);
5809 cpu
.es
= SegmentFactory
.createVirtual8086ModeSegment(cpu
.linearMemory
, 0xffff & cpu
.ss
.getDoubleWord(cpu
.esp
+ 8), false);
5810 cpu
.ds
= SegmentFactory
.createVirtual8086ModeSegment(cpu
.linearMemory
, 0xffff & cpu
.ss
.getDoubleWord(cpu
.esp
+ 12), false);
5811 cpu
.fs
= SegmentFactory
.createVirtual8086ModeSegment(cpu
.linearMemory
, 0xffff & cpu
.ss
.getDoubleWord(cpu
.esp
+ 16), false);
5812 cpu
.gs
= SegmentFactory
.createVirtual8086ModeSegment(cpu
.linearMemory
, 0xffff & cpu
.ss
.getDoubleWord(cpu
.esp
+ 20), false);
5813 cpu
.ss
= SegmentFactory
.createVirtual8086ModeSegment(cpu
.linearMemory
, newSS
, false);
5820 private final int iret32ProtectedMode32BitAddressing(int newCS
, int newEIP
, int newEFlags
)
5822 Segment returnSegment
= cpu
.getSegment(newCS
);
5824 if (returnSegment
== SegmentFactory
.NULL_SEGMENT
)
5825 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
5827 switch (returnSegment
.getType()) {
5829 System
.err
.println("Emulated: Invalid segment type " + returnSegment
.getType() + ".");
5830 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
5832 case 0x18: //Code, Execute-Only
5833 case 0x19: //Code, Execute-Only, Accessed
5834 case 0x1a: //Code, Execute/Read
5835 case 0x1b: { //Code, Execute/Read, Accessed
5836 if (returnSegment
.getRPL() < cpu
.getCPL())
5837 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
5839 if (!(returnSegment
.isPresent()))
5840 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, newCS
, true);
5842 if (returnSegment
.getRPL() > cpu
.getCPL()) {
5843 //OUTER PRIVILEGE-LEVEL
5845 cpu
.ss
.checkAddress(cpu
.esp
+ 7);
5846 } catch (ProcessorException e
) {
5847 throw ProcessorException
.STACK_SEGMENT_0
;
5850 int returnESP
= cpu
.ss
.getDoubleWord(cpu
.esp
);
5851 int tempSS
= 0xffff & cpu
.ss
.getDoubleWord(cpu
.esp
+ 4);
5853 Segment returnStackSegment
= cpu
.getSegment(tempSS
);
5855 if ((returnStackSegment
.getRPL() != returnSegment
.getRPL()) || ((returnStackSegment
.getType() & 0x12) != 0x12) ||
5856 (returnStackSegment
.getDPL() != returnSegment
.getRPL()))
5857 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempSS
, true);
5859 if (!returnStackSegment
.isPresent())
5860 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempSS
, true);
5862 returnSegment
.checkAddress(newEIP
);
5864 //cpu.esp += 20; //includes the 12 from earlier
5866 cpu
.cs
= returnSegment
;
5868 cpu
.ss
= returnStackSegment
;
5869 cpu
.esp
= returnESP
;
5871 int eflags
= cpu
.getEFlags();
5872 eflags
&= ~
0x254dd5;
5873 eflags
|= (0x254dd5 & newEFlags
);
5874 //overwrite: all; preserve: if, iopl, vm, vif, vip
5876 if (cpu
.getCPL() <= cpu
.eflagsIOPrivilegeLevel
) {
5878 eflags
|= (0x200 & newEFlags
);
5879 //overwrite: all; preserve: iopl, vm, vif, vip
5881 if (cpu
.getCPL() == 0) {
5882 eflags
&= ~
0x1a3000;
5883 eflags
|= (0x1a3000 & newEFlags
);
5886 // cpu.setEFlags(eflags);
5888 cpu
.setCPL(cpu
.cs
.getRPL());
5891 if ((((cpu
.es
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.es
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.es
.getDPL()))
5892 cpu
.es
= SegmentFactory
.NULL_SEGMENT
;
5893 } catch (ProcessorException e
) {
5894 } catch (Exception e
) {
5898 if ((((cpu
.ds
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.ds
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.ds
.getDPL()))
5899 cpu
.ds
= SegmentFactory
.NULL_SEGMENT
;
5900 } catch (ProcessorException e
) {
5901 } catch (Exception e
) {
5905 if ((((cpu
.fs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.fs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.fs
.getDPL()))
5906 cpu
.fs
= SegmentFactory
.NULL_SEGMENT
;
5907 } catch (ProcessorException e
) {
5908 } catch (Exception e
) {
5912 if ((((cpu
.gs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.gs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.gs
.getDPL()))
5913 cpu
.gs
= SegmentFactory
.NULL_SEGMENT
;
5914 } catch (ProcessorException e
) {
5915 } catch (Exception e
) {
5920 //SAME PRIVILEGE-LEVEL
5921 returnSegment
.checkAddress(newEIP
);
5923 cpu
.cs
= returnSegment
;
5927 int eflags
= cpu
.getEFlags();
5929 eflags
&= ~
0x254dd5;
5930 eflags
|= (0x254dd5 & newEFlags
);
5932 if (cpu
.getCPL() <= cpu
.eflagsIOPrivilegeLevel
) {
5934 eflags
|= (0x200 & newEFlags
);
5937 if (cpu
.getCPL() == 0) {
5938 eflags
&= ~
0x1a3000;
5939 eflags
|= (0x1a3000 & newEFlags
);
5941 // cpu.setEFlags(eflags);
5945 case 0x1c: //Code: Execute-Only, Conforming
5946 case 0x1d: //Code: Execute-Only, Conforming, Accessed
5947 case 0x1e: //Code: Execute/Read, Conforming
5948 case 0x1f: { //Code: Execute/Read, Conforming, Accessed
5949 if (returnSegment
.getRPL() < cpu
.getCPL())
5950 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
5952 if (returnSegment
.getDPL() > returnSegment
.getRPL())
5953 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
5955 if (!(returnSegment
.isPresent()))
5956 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, newCS
, true);
5958 if (returnSegment
.getRPL() > cpu
.getCPL()) {
5959 //OUTER PRIVILEGE-LEVEL
5960 System
.err
.println("Critical error: Conforming outer privilege level not implemented");
5961 throw new IllegalStateException("iret32ProtectedMode32BitAddressing to conforming outer privilege level not implemented");
5963 //SAME PRIVILEGE-LEVEL
5964 returnSegment
.checkAddress(newEIP
);
5966 cpu
.cs
= returnSegment
; //do descriptor as well
5967 cpu
.setCarryFlag((newEFlags
& 1) != 0);
5968 cpu
.setParityFlag((newEFlags
& (1 << 2)) != 0);
5969 cpu
.setAuxiliaryCarryFlag((newEFlags
& (1 << 4)) != 0);
5970 cpu
.setZeroFlag((newEFlags
& (1 << 6)) != 0);
5971 cpu
.setSignFlag((newEFlags
& (1 << 7)) != 0);
5972 cpu
.eflagsTrap
= ((newEFlags
& (1 << 8)) != 0);
5973 cpu
.eflagsDirection
= ((newEFlags
& (1 << 10)) != 0);
5974 cpu
.setOverflowFlag((newEFlags
& (1 << 11)) != 0);
5975 cpu
.eflagsNestedTask
= ((newEFlags
& (1 << 14)) != 0);
5976 cpu
.eflagsResume
= ((newEFlags
& (1 << 16)) != 0);
5977 cpu
.eflagsAlignmentCheck
= ((newEFlags
& (1 << 18)) != 0); //do we need to call checkAlignmentChecking()?
5978 cpu
.eflagsID
= ((newEFlags
& (1 << 21)) != 0);
5979 if (cpu
.getCPL() <= cpu
.eflagsIOPrivilegeLevel
)
5980 cpu
.eflagsInterruptEnableSoon
5981 = cpu
.eflagsInterruptEnable
= ((newEFlags
& (1 << 9)) != 0);
5982 if (cpu
.getCPL() == 0) {
5983 cpu
.eflagsIOPrivilegeLevel
= ((newEFlags
>> 12) & 3);
5984 cpu
.eflagsVirtual8086Mode
= ((newEFlags
& (1 << 17)) != 0);
5985 cpu
.eflagsVirtualInterrupt
= ((newEFlags
& (1 << 19)) != 0);
5986 cpu
.eflagsVirtualInterruptPending
= ((newEFlags
& (1 << 20)) != 0);
5994 private final int iret_o32_a32()
5996 if (cpu
.eflagsNestedTask
)
5997 return iretFromTask();
6000 cpu
.ss
.checkAddress(cpu
.esp
+ 11);
6001 } catch (ProcessorException e
) {
6002 throw ProcessorException
.STACK_SEGMENT_0
;
6004 int tempEIP
= cpu
.ss
.getDoubleWord(cpu
.esp
);
6005 int tempCS
= 0xffff & cpu
.ss
.getDoubleWord(cpu
.esp
+ 4);
6006 int tempEFlags
= cpu
.ss
.getDoubleWord(cpu
.esp
+ 8);
6009 if (((tempEFlags
& (1 << 17)) != 0) && (cpu
.getCPL() == 0)) {
6010 return iretToVirtual8086Mode32BitAddressing(tempCS
, tempEIP
, tempEFlags
);
6012 return iret32ProtectedMode32BitAddressing(tempCS
, tempEIP
, tempEFlags
);
6017 private final int iret_o16_a16()
6019 if (cpu
.eflagsNestedTask
)
6020 return iretFromTask();
6023 cpu
.ss
.checkAddress((cpu
.esp
+ 5) & 0xffff);
6024 } catch (ProcessorException e
) {
6025 throw ProcessorException
.STACK_SEGMENT_0
;
6027 int tempEIP
= 0xffff & cpu
.ss
.getWord(cpu
.esp
& 0xFFFF);
6028 int tempCS
= 0xffff & cpu
.ss
.getWord((cpu
.esp
+ 2) & 0xFFFF);
6029 int tempEFlags
= 0xffff & cpu
.ss
.getWord((cpu
.esp
+ 4) & 0xFFFF);
6030 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 6) & 0xffff);
6032 return iret16ProtectedMode16BitAddressing(tempCS
, tempEIP
, tempEFlags
);
6036 private final int iret_o16_a32()
6038 if (cpu
.eflagsNestedTask
)
6039 return iretFromTask();
6042 cpu
.ss
.checkAddress(cpu
.esp
+ 5);
6043 } catch (ProcessorException e
) {
6044 throw ProcessorException
.STACK_SEGMENT_0
;
6046 int tempEIP
= 0xffff & cpu
.ss
.getWord(cpu
.esp
);
6047 int tempCS
= 0xffff & cpu
.ss
.getWord(cpu
.esp
+ 4);
6048 int tempEFlags
= 0xffff & cpu
.ss
.getWord(cpu
.esp
+ 8);
6051 return iret16ProtectedMode32BitAddressing(tempCS
, tempEIP
, tempEFlags
);
6055 private final int iret16ProtectedMode16BitAddressing(int newCS
, int newEIP
, int newEFlags
)
6057 Segment returnSegment
= cpu
.getSegment(newCS
);
6059 if (returnSegment
== SegmentFactory
.NULL_SEGMENT
)
6060 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
6062 switch (returnSegment
.getType()) {
6064 System
.err
.println("Emulated: Invalid segment type " + returnSegment
.getType() + ".");
6065 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
6067 case 0x18: //Code, Execute-Only
6068 case 0x19: //Code, Execute-Only, Accessed
6069 case 0x1a: //Code, Execute/Read
6070 case 0x1b: //Code, Execute/Read, Accessed
6072 if (returnSegment
.getRPL() < cpu
.getCPL())
6073 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
6075 if (!(returnSegment
.isPresent()))
6076 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, newCS
, true);
6078 if (returnSegment
.getRPL() > cpu
.getCPL()) {
6079 //OUTER PRIVILEGE-LEVEL
6081 cpu
.ss
.checkAddress((cpu
.esp
+ 3) & 0xFFFF);
6082 } catch (ProcessorException e
) {
6083 throw ProcessorException
.STACK_SEGMENT_0
;
6086 int returnESP
= 0xffff & cpu
.ss
.getWord(cpu
.esp
& 0xFFFF);
6087 int newSS
= 0xffff & cpu
.ss
.getWord((cpu
.esp
+ 2) & 0xFFFF);
6089 Segment returnStackSegment
= cpu
.getSegment(newSS
);
6091 if ((returnStackSegment
.getRPL() != returnSegment
.getRPL()) || ((returnStackSegment
.getType() & 0x12) != 0x12) ||
6092 (returnStackSegment
.getDPL() != returnSegment
.getRPL()))
6093 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newSS
, true);
6095 if (!returnStackSegment
.isPresent())
6096 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newSS
, true);
6098 returnSegment
.checkAddress(newEIP
);
6100 //cpu.esp += 20; //includes the 12 from earlier
6102 cpu
.cs
= returnSegment
;
6104 cpu
.ss
= returnStackSegment
;
6105 cpu
.esp
= returnESP
;
6107 int eflags
= cpu
.getEFlags();
6109 eflags
|= (0x4dd5 & newEFlags
);
6110 //overwrite: all; preserve: if, iopl, vm, vif, vip
6112 if (cpu
.getCPL() <= cpu
.eflagsIOPrivilegeLevel
) {
6114 eflags
|= (0x200 & newEFlags
);
6115 //overwrite: all; preserve: iopl, vm, vif, vip
6117 if (cpu
.getCPL() == 0) {
6119 eflags
|= (0x3000 & newEFlags
);
6122 // cpu.setEFlags(eflags);
6124 cpu
.setCPL(cpu
.cs
.getRPL());
6127 if ((((cpu
.es
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.es
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.es
.getDPL()))
6128 cpu
.es
= SegmentFactory
.NULL_SEGMENT
;
6129 } catch (ProcessorException e
) {
6130 } catch (Exception e
) {
6134 if ((((cpu
.ds
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.ds
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.ds
.getDPL()))
6135 cpu
.ds
= SegmentFactory
.NULL_SEGMENT
;
6136 } catch (ProcessorException e
) {
6137 } catch (Exception e
) {
6141 if ((((cpu
.fs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.fs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.fs
.getDPL()))
6142 cpu
.fs
= SegmentFactory
.NULL_SEGMENT
;
6143 } catch (ProcessorException e
) {
6144 } catch (Exception e
) {
6148 if ((((cpu
.gs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.gs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.gs
.getDPL()))
6149 cpu
.gs
= SegmentFactory
.NULL_SEGMENT
;
6150 } catch (ProcessorException e
) {
6151 } catch (Exception e
) {
6156 //SAME PRIVILEGE-LEVEL
6157 returnSegment
.checkAddress(newEIP
);
6159 cpu
.cs
= returnSegment
;
6163 int eflags
= cpu
.getEFlags();
6166 eflags
|= (0x4dd5 & newEFlags
);
6168 if (cpu
.getCPL() <= cpu
.eflagsIOPrivilegeLevel
) {
6170 eflags
|= (0x200 & newEFlags
);
6173 if (cpu
.getCPL() == 0) {
6175 eflags
|= (0x3000 & newEFlags
);
6178 // cpu.setEFlags(eflags);
6182 case 0x1c: //Code: Execute-Only, Conforming
6183 case 0x1d: //Code: Execute-Only, Conforming, Accessed
6184 case 0x1e: //Code: Execute/Read, Conforming
6185 case 0x1f: //Code: Execute/Read, Conforming, Accessed
6187 if (returnSegment
.getRPL() < cpu
.getCPL())
6188 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
6190 if (returnSegment
.getDPL() > returnSegment
.getRPL())
6191 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
6193 if (!(returnSegment
.isPresent()))
6194 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, newCS
, true);
6196 if (returnSegment
.getRPL() > cpu
.getCPL()) {
6197 //OUTER PRIVILEGE-LEVEL
6198 System
.err
.println("Critical error: Conforming outer privilege level not implemented");
6199 throw new IllegalStateException("iret16ProtectedMode16BitAddressing to conforming outer privilege level not implemented");
6201 //SAME PRIVILEGE-LEVEL
6202 System
.err
.println("Critical error: Conforming same privilege level not implemented");
6203 throw new IllegalStateException("iret16ProtectedMode16BitAddressing to conforming same privilege level not implemented");
6209 private final int iret16ProtectedMode32BitAddressing(int newCS
, int newEIP
, int newEFlags
)
6211 Segment returnSegment
= cpu
.getSegment(newCS
);
6213 if (returnSegment
== SegmentFactory
.NULL_SEGMENT
)
6214 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
6216 switch (returnSegment
.getType()) {
6218 System
.err
.println("Emulated: Invalid segment type " + returnSegment
.getType() + ".");
6219 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
6221 case 0x18: //Code, Execute-Only
6222 case 0x19: //Code, Execute-Only, Accessed
6223 case 0x1a: //Code, Execute/Read
6224 case 0x1b: { //Code, Execute/Read, Accessed
6225 if (returnSegment
.getRPL() < cpu
.getCPL())
6226 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
6228 if (!(returnSegment
.isPresent()))
6229 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, newCS
, true);
6231 if (returnSegment
.getRPL() > cpu
.getCPL()) {
6232 //OUTER PRIVILEGE-LEVEL
6234 cpu
.ss
.checkAddress(cpu
.esp
+ 3);
6235 } catch (ProcessorException e
) {
6236 throw ProcessorException
.STACK_SEGMENT_0
;
6239 int returnESP
= 0xffff & cpu
.ss
.getWord(cpu
.esp
);
6240 int tempSS
= 0xffff & cpu
.ss
.getWord(cpu
.esp
+ 2);
6242 Segment returnStackSegment
= cpu
.getSegment(tempSS
);
6244 if ((returnStackSegment
.getRPL() != returnSegment
.getRPL()) || ((returnStackSegment
.getType() & 0x12) != 0x12) ||
6245 (returnStackSegment
.getDPL() != returnSegment
.getRPL()))
6246 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempSS
, true);
6248 if (!returnStackSegment
.isPresent())
6249 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, tempSS
, true);
6251 returnSegment
.checkAddress(newEIP
);
6253 //cpu.esp += 20; //includes the 12 from earlier
6255 cpu
.cs
= returnSegment
;
6257 cpu
.ss
= returnStackSegment
;
6258 cpu
.esp
= returnESP
;
6260 int eflags
= cpu
.getEFlags();
6262 eflags
|= (0x4dd5 & newEFlags
);
6263 //overwrite: all; preserve: if, iopl, vm, vif, vip
6265 if (cpu
.getCPL() <= cpu
.eflagsIOPrivilegeLevel
) {
6267 eflags
|= (0x200 & newEFlags
);
6268 //overwrite: all; preserve: iopl, vm, vif, vip
6270 if (cpu
.getCPL() == 0) {
6272 eflags
|= (0x3000 & newEFlags
);
6275 // cpu.setEFlags(eflags);
6277 cpu
.setCPL(cpu
.cs
.getRPL());
6280 if ((((cpu
.es
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.es
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.es
.getDPL()))
6281 cpu
.es
= SegmentFactory
.NULL_SEGMENT
;
6282 } catch (ProcessorException e
) {
6283 } catch (Exception e
) {
6287 if ((((cpu
.ds
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.ds
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.ds
.getDPL()))
6288 cpu
.ds
= SegmentFactory
.NULL_SEGMENT
;
6289 } catch (ProcessorException e
) {
6290 } catch (Exception e
) {
6294 if ((((cpu
.fs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.fs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.fs
.getDPL()))
6295 cpu
.fs
= SegmentFactory
.NULL_SEGMENT
;
6296 } catch (ProcessorException e
) {
6297 } catch (Exception e
) {
6301 if ((((cpu
.gs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
)) == ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
) || ((cpu
.gs
.getType() & (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
)) == (ProtectedModeSegment
.DESCRIPTOR_TYPE_CODE_DATA
| ProtectedModeSegment
.TYPE_CODE
))) && (cpu
.getCPL() > cpu
.gs
.getDPL()))
6302 cpu
.gs
= SegmentFactory
.NULL_SEGMENT
;
6303 } catch (ProcessorException e
) {
6304 } catch (Exception e
) {
6309 //SAME PRIVILEGE-LEVEL
6310 returnSegment
.checkAddress(newEIP
);
6312 cpu
.cs
= returnSegment
;
6316 int eflags
= cpu
.getEFlags();
6319 eflags
|= (0x4dd5 & newEFlags
);
6321 if (cpu
.getCPL() <= cpu
.eflagsIOPrivilegeLevel
) {
6323 eflags
|= (0x200 & newEFlags
);
6326 if (cpu
.getCPL() == 0) {
6328 eflags
|= (0x3000 & newEFlags
);
6330 // cpu.setEFlags(eflags);
6334 case 0x1c: //Code: Execute-Only, Conforming
6335 case 0x1d: //Code: Execute-Only, Conforming, Accessed
6336 case 0x1e: //Code: Execute/Read, Conforming
6337 case 0x1f: { //Code: Execute/Read, Conforming, Accessed
6338 if (returnSegment
.getRPL() < cpu
.getCPL())
6339 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
6341 if (returnSegment
.getDPL() > returnSegment
.getRPL())
6342 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, newCS
, true);
6344 if (!(returnSegment
.isPresent()))
6345 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, newCS
, true);
6347 if (returnSegment
.getRPL() > cpu
.getCPL()) {
6348 //OUTER PRIVILEGE-LEVEL
6349 System
.err
.println("Critical error: Conforming outer privilege level not implemented");
6350 throw new IllegalStateException("iret16ProtectedMode32BitAddressing to conforming outer privilege level not implemented");
6352 //SAME PRIVILEGE-LEVEL
6353 System
.err
.println("Critical error: Conforming same privilege level not implemented");
6354 throw new IllegalStateException("iret16ProtectedMode32BitAddressing to conforming same privilege level not implemented");
6360 private final void sysenter()
6362 int csSelector
= (int) cpu
.getMSR(Processor
.SYSENTER_CS_MSR
);
6363 if (csSelector
== 0)
6364 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, 0, true);//ProcessorException.GENERAL_PROTECTION_0;
6365 cpu
.eflagsInterruptEnable
= cpu
.eflagsInterruptEnableSoon
= false;
6366 cpu
.eflagsResume
= false;
6368 cpu
.cs
= SegmentFactory
.createProtectedModeSegment(cpu
.linearMemory
, csSelector
& 0xfffc, 0x00cf9b000000ffffl
);
6370 cpu
.ss
= SegmentFactory
.createProtectedModeSegment(cpu
.linearMemory
, (csSelector
+ 8) & 0xfffc, 0x00cf93000000ffffl
);
6372 cpu
.esp
= (int) cpu
.getMSR(Processor
.SYSENTER_ESP_MSR
);
6373 cpu
.eip
= (int) cpu
.getMSR(Processor
.SYSENTER_EIP_MSR
);
6376 private final void sysexit(int esp
, int eip
)
6378 int csSelector
= (int)cpu
.getMSR(Processor
.SYSENTER_CS_MSR
);
6379 if (csSelector
== 0)
6380 throw ProcessorException
.GENERAL_PROTECTION_0
;
6381 if (cpu
.getCPL() != 0)
6382 throw ProcessorException
.GENERAL_PROTECTION_0
;
6384 cpu
.cs
= SegmentFactory
.createProtectedModeSegment(cpu
.linearMemory
, (csSelector
+ 16) | 0x3, 0x00cffb000000ffffl
);
6386 cpu
.ss
= SegmentFactory
.createProtectedModeSegment(cpu
.linearMemory
, (csSelector
+ 24) | 0x3, 0x00cff3000000ffffl
);
6387 cpu
.correctAlignmentChecking(cpu
.ss
);
6393 private final int in_o8(int port
)
6395 if (checkIOPermissionsByte(port
))
6396 return 0xff & cpu
.ioports
.ioPortReadByte(port
);
6398 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
6399 " at cpl " + cpu
.getCPL() + ".");
6400 throw ProcessorException
.GENERAL_PROTECTION_0
;
6404 private final int in_o16(int port
)
6406 if (checkIOPermissionsShort(port
))
6407 return 0xffff & cpu
.ioports
.ioPortReadWord(port
);
6409 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
6410 " at cpl " + cpu
.getCPL() + ".");
6411 throw ProcessorException
.GENERAL_PROTECTION_0
;
6415 private final int in_o32(int port
)
6417 if (checkIOPermissionsInt(port
))
6418 return cpu
.ioports
.ioPortReadLong(port
);
6420 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
6421 " at cpl " + cpu
.getCPL() + ".");
6422 throw ProcessorException
.GENERAL_PROTECTION_0
;
6426 private final void out_o8(int port
, int data
)
6428 if (checkIOPermissionsByte(port
))
6429 cpu
.ioports
.ioPortWriteByte(port
, 0xff & data
);
6431 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
6432 " at cpl " + cpu
.getCPL() + ".");
6433 throw ProcessorException
.GENERAL_PROTECTION_0
;
6437 private final void out_o16(int port
, int data
)
6439 if (checkIOPermissionsShort(port
))
6440 cpu
.ioports
.ioPortWriteWord(port
, 0xffff & data
);
6442 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
6443 " at cpl " + cpu
.getCPL() + ".");
6444 throw ProcessorException
.GENERAL_PROTECTION_0
;
6448 private final void out_o32(int port
, int data
)
6450 if (checkIOPermissionsInt(port
))
6451 cpu
.ioports
.ioPortWriteLong(port
, data
);
6453 System
.err
.println("Emulated: denied access to io port 0x" + Integer
.toHexString(port
) +
6454 " at cpl " + cpu
.getCPL() + ".");
6455 throw ProcessorException
.GENERAL_PROTECTION_0
;
6459 private final void enter_o16_a16(int frameSize
, int nestingLevel
)
6463 int tempESP
= 0xFFFF & cpu
.esp
;
6464 int tempEBP
= 0xFFFF & cpu
.ebp
;
6466 if (nestingLevel
== 0) {
6467 if ((tempESP
< (2 + frameSize
)) && (tempESP
> 0))
6468 throw ProcessorException
.STACK_SEGMENT_0
;
6470 if ((tempESP
< (2 + frameSize
+ 2 * nestingLevel
)) && (tempESP
> 0))
6471 throw ProcessorException
.STACK_SEGMENT_0
;
6475 cpu
.ss
.setWord(tempESP
, (short) tempEBP
);
6477 int frameTemp
= tempESP
;
6479 if (nestingLevel
> 0) {
6480 while (--nestingLevel
!= 0) {
6483 cpu
.ss
.setWord(tempESP
, (short) (0xFFFF & cpu
.ss
.getWord(tempEBP
)));
6487 cpu
.ss
.setWord(tempESP
, (short)frameTemp
);
6490 cpu
.ebp
= (cpu
.ebp
& ~
0xFFFF)| (0xFFFF & frameTemp
);
6491 cpu
.esp
= (cpu
.esp
& ~
0xFFFF)| (0xFFFF & (frameTemp
- frameSize
- 2*nestingLevel
));
6494 private final void enter_o16_a32(int frameSize
, int nestingLevel
)
6498 int tempESP
= cpu
.esp
;
6499 int tempEBP
= cpu
.ebp
;
6501 if (nestingLevel
== 0) {
6502 if ((tempESP
< (2 + frameSize
)) && (tempESP
> 0))
6503 throw ProcessorException
.STACK_SEGMENT_0
;
6505 if ((tempESP
< (2 + frameSize
+ 2 * nestingLevel
)) && (tempESP
> 0))
6506 throw ProcessorException
.STACK_SEGMENT_0
;
6510 cpu
.ss
.setWord(tempESP
, (short)tempEBP
);
6512 int frameTemp
= tempESP
;
6514 if (nestingLevel
> 0)
6516 int tmpLevel
= nestingLevel
;
6517 while (--tmpLevel
!= 0)
6521 cpu
.ss
.setWord(tempESP
, cpu
.ss
.getWord(tempEBP
));
6525 cpu
.ss
.setWord(tempESP
, (short)frameTemp
);
6528 cpu
.ebp
= frameTemp
;
6529 cpu
.esp
= frameTemp
- frameSize
-2*nestingLevel
;
6532 private final void enter_o32_a32(int frameSize
, int nestingLevel
)
6536 int tempESP
= cpu
.esp
;
6537 int tempEBP
= cpu
.ebp
;
6539 if (nestingLevel
== 0) {
6540 if ((tempESP
< (4 + frameSize
)) && (tempESP
> 0))
6541 throw ProcessorException
.STACK_SEGMENT_0
;
6543 if ((tempESP
< (4 + frameSize
+ 4 * nestingLevel
)) && (tempESP
> 0))
6544 throw ProcessorException
.STACK_SEGMENT_0
;
6548 cpu
.ss
.setDoubleWord(tempESP
, tempEBP
);
6550 int frameTemp
= tempESP
;
6552 int tmplevel
= nestingLevel
;
6553 if (nestingLevel
!= 0) {
6554 while (--tmplevel
!= 0) {
6557 cpu
.ss
.setDoubleWord(tempESP
, cpu
.ss
.getDoubleWord(tempEBP
));
6560 cpu
.ss
.setDoubleWord(tempESP
, frameTemp
);
6563 cpu
.ebp
= frameTemp
;
6564 cpu
.esp
= frameTemp
- frameSize
- 4*nestingLevel
;
6567 private final void leave_o32_a16()
6569 cpu
.ss
.checkAddress(cpu
.ebp
& 0xffff);
6570 int tempESP
= cpu
.ebp
& 0xffff;
6571 int tempEBP
= cpu
.ss
.getDoubleWord(tempESP
);
6572 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((tempESP
+ 4) & 0xffff);
6576 private final void leave_o32_a32()
6578 cpu
.ss
.checkAddress(cpu
.ebp
);
6579 int tempESP
= cpu
.ebp
;
6580 int tempEBP
= cpu
.ss
.getDoubleWord(tempESP
);
6581 cpu
.esp
= tempESP
+ 4;
6585 private final void leave_o16_a16()
6587 cpu
.ss
.checkAddress(cpu
.ebp
& 0xffff);
6588 int tempESP
= cpu
.ebp
& 0xffff;
6589 int tempEBP
= 0xffff & cpu
.ss
.getWord(tempESP
);
6590 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((tempESP
+ 2) & 0xffff);
6591 cpu
.ebp
= (cpu
.ebp
& ~
0xffff) | tempEBP
;
6594 private final void leave_o16_a32()
6596 cpu
.ss
.checkAddress(cpu
.ebp
);
6597 int tempESP
= cpu
.ebp
;
6598 int tempEBP
= 0xffff & cpu
.ss
.getWord(tempESP
);
6599 cpu
.esp
= tempESP
+ 2;
6600 cpu
.ebp
= (cpu
.ebp
& ~
0xffff) | tempEBP
;
6603 private final void push_o32_a32(int value
)
6605 if ((cpu
.esp
< 4) && (cpu
.esp
> 0))
6606 throw ProcessorException
.STACK_SEGMENT_0
;
6608 cpu
.ss
.setDoubleWord(cpu
.esp
- 4, value
);
6612 private final void push_o32_a16(int value
)
6614 if (((0xffff & cpu
.esp
) < 4) && ((0xffff & cpu
.esp
) > 0))
6615 throw ProcessorException
.STACK_SEGMENT_0
;
6617 cpu
.ss
.setDoubleWord((cpu
.esp
- 4) & 0xffff, value
);
6618 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
- 4) & 0xffff);
6621 private final void push_o16_a32(short value
)
6623 if ((cpu
.esp
< 2) && (cpu
.esp
> 0))
6624 throw ProcessorException
.STACK_SEGMENT_0
;
6626 cpu
.ss
.setWord(cpu
.esp
- 2, value
);
6630 private final void push_o16_a16(short value
)
6632 if (((0xffff & cpu
.esp
) < 2) && ((0xffff & cpu
.esp
) > 0))
6633 throw ProcessorException
.STACK_SEGMENT_0
;
6635 cpu
.ss
.setWord(((0xFFFF & cpu
.esp
) - 2) & 0xffff, value
);
6636 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
- 2) & 0xffff);
6639 private final void pushad_a32()
6641 int offset
= cpu
.esp
;
6643 if ((offset
< 32) && (offset
> 0))
6644 throw ProcessorException
.STACK_SEGMENT_0
;
6647 cpu
.ss
.setDoubleWord(offset
, cpu
.eax
);
6649 cpu
.ss
.setDoubleWord(offset
, cpu
.ecx
);
6651 cpu
.ss
.setDoubleWord(offset
, cpu
.edx
);
6653 cpu
.ss
.setDoubleWord(offset
, cpu
.ebx
);
6655 cpu
.ss
.setDoubleWord(offset
, temp
);
6657 cpu
.ss
.setDoubleWord(offset
, cpu
.ebp
);
6659 cpu
.ss
.setDoubleWord(offset
, cpu
.esi
);
6661 cpu
.ss
.setDoubleWord(offset
, cpu
.edi
);
6666 private final void pushad_a16()
6668 int offset
= 0xFFFF & cpu
.esp
;
6669 int temp
= 0xFFFF & cpu
.esp
;
6670 if ((offset
< 32) && (offset
> 0))
6671 throw ProcessorException
.STACK_SEGMENT_0
;
6674 cpu
.ss
.setDoubleWord(offset
, cpu
.eax
);
6676 cpu
.ss
.setDoubleWord(offset
, cpu
.ecx
);
6678 cpu
.ss
.setDoubleWord(offset
, cpu
.edx
);
6680 cpu
.ss
.setDoubleWord(offset
, cpu
.ebx
);
6682 cpu
.ss
.setDoubleWord(offset
, temp
);
6684 cpu
.ss
.setDoubleWord(offset
, cpu
.ebp
);
6686 cpu
.ss
.setDoubleWord(offset
, cpu
.esi
);
6688 cpu
.ss
.setDoubleWord(offset
, cpu
.edi
);
6690 cpu
.esp
= (cpu
.esp
& ~
0xFFFF) | (0xFFFF & offset
);
6693 private final void pusha_a32()
6695 int offset
= cpu
.esp
;
6697 if ((offset
< 16) && (offset
> 0))
6698 throw ProcessorException
.STACK_SEGMENT_0
;
6701 cpu
.ss
.setWord(offset
,(short)( 0xffff & cpu
.eax
));
6703 cpu
.ss
.setWord(offset
,(short)( 0xffff & cpu
.ecx
));
6705 cpu
.ss
.setWord(offset
,(short)( 0xffff & cpu
.edx
));
6707 cpu
.ss
.setWord(offset
,(short)( 0xffff & cpu
.ebx
));
6709 cpu
.ss
.setWord(offset
,(short)( 0xffff & temp
));
6711 cpu
.ss
.setWord(offset
,(short)( 0xffff & cpu
.ebp
));
6713 cpu
.ss
.setWord(offset
,(short)( 0xffff & cpu
.esi
));
6715 cpu
.ss
.setWord(offset
,(short)( 0xffff & cpu
.edi
));
6717 cpu
.esp
= (cpu
.esp
& ~
0xffff) | (offset
& 0xffff);
6719 private final void pusha_a16()
6721 int offset
= 0xFFFF & cpu
.esp
;
6722 int temp
= 0xFFFF & cpu
.esp
;
6723 if ((offset
< 16) && (offset
> 0))
6724 throw ProcessorException
.STACK_SEGMENT_0
;
6727 cpu
.ss
.setWord(offset
,(short)(cpu
.eax
));
6729 cpu
.ss
.setWord(offset
,(short)( cpu
.ecx
));
6731 cpu
.ss
.setWord(offset
,(short)( cpu
.edx
));
6733 cpu
.ss
.setWord(offset
,(short)( cpu
.ebx
));
6735 cpu
.ss
.setWord(offset
,(short)(temp
));
6737 cpu
.ss
.setWord(offset
,(short)(cpu
.ebp
));
6739 cpu
.ss
.setWord(offset
,(short)(cpu
.esi
));
6741 cpu
.ss
.setWord(offset
,(short)(cpu
.edi
));
6743 cpu
.esp
= (cpu
.esp
& ~
0xffff) | (0xFFFF & offset
);
6746 private final void popa_a16()
6748 int offset
= 0xFFFF & cpu
.esp
;
6750 //Bochs claims no checking need on POPs
6751 //if (offset + 16 >= cpu.ss.limit)
6752 // throw ProcessorException.STACK_SEGMENT_0;
6754 int newedi
= (cpu
.edi
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offset
));
6756 int newesi
= (cpu
.esi
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offset
));
6758 int newebp
= (cpu
.ebp
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offset
));
6759 offset
+= 4;// yes - skip an extra 2 bytes in order to skip ESP
6761 int newebx
= (cpu
.ebx
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offset
));
6763 int newedx
= (cpu
.edx
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offset
));
6765 int newecx
= (cpu
.ecx
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offset
));
6767 int neweax
= (cpu
.eax
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offset
));
6778 cpu
.esp
= (cpu
.esp
& ~
0xffff) | (offset
& 0xffff);
6781 private final void popad_a16()
6783 int offset
= 0xFFFF &cpu
.esp
;
6785 //Bochs claims no checking need on POPs
6786 //if (offset + 16 >= cpu.ss.limit)
6787 // throw ProcessorException.STACK_SEGMENT_0;
6789 int newedi
= cpu
.ss
.getDoubleWord(offset
);
6791 int newesi
= cpu
.ss
.getDoubleWord(offset
);
6793 int newebp
= cpu
.ss
.getDoubleWord(offset
);
6794 offset
+= 8;// yes - skip an extra 4 bytes in order to skip ESP
6796 int newebx
= cpu
.ss
.getDoubleWord(offset
);
6798 int newedx
= cpu
.ss
.getDoubleWord(offset
);
6800 int newecx
= cpu
.ss
.getDoubleWord(offset
);
6802 int neweax
= cpu
.ss
.getDoubleWord(offset
);
6813 cpu
.esp
= (cpu
.esp
& ~
0xffff) | (offset
& 0xffff);
6816 private final void popa_a32()
6818 int offset
= cpu
.esp
;
6820 //Bochs claims no checking need on POPs
6821 //if (offset + 16 >= cpu.ss.limit)
6822 // throw ProcessorException.STACK_SEGMENT_0;
6824 int newedi
= (cpu
.edi
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offset
));
6826 int newesi
= (cpu
.esi
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offset
));
6828 int newebp
= (cpu
.ebp
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offset
));
6829 offset
+= 4;// yes - skip an extra 2 bytes in order to skip ESP
6831 int newebx
= (cpu
.ebx
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offset
));
6833 int newedx
= (cpu
.edx
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offset
));
6835 int newecx
= (cpu
.ecx
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offset
));
6837 int neweax
= (cpu
.eax
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offset
));
6851 private final void popad_a32()
6853 int offset
= cpu
.esp
;
6855 //Bochs claims no checking need on POPs
6856 //if (offset + 16 >= cpu.ss.limit)
6857 // throw ProcessorException.STACK_SEGMENT_0;
6859 int newedi
= cpu
.ss
.getDoubleWord(offset
);
6861 int newesi
= cpu
.ss
.getDoubleWord(offset
);
6863 int newebp
= cpu
.ss
.getDoubleWord(offset
);
6864 offset
+= 8;// yes - skip an extra 4 bytes in order to skip ESP
6866 int newebx
= cpu
.ss
.getDoubleWord(offset
);
6868 int newedx
= cpu
.ss
.getDoubleWord(offset
);
6870 int newecx
= cpu
.ss
.getDoubleWord(offset
);
6872 int neweax
= cpu
.ss
.getDoubleWord(offset
);
6886 private final int lar(int selector
, int original
)
6888 if ((selector
& 0xFFC) == 0)
6890 cpu
.setZeroFlag(false);
6893 int offset
= selector
& 0xfff8;
6895 //allow all normal segments
6896 // and available and busy 32 bit and 16 bit TSS (9, b, 3, 1)
6897 // and ldt and tsk gate (2, 5)
6898 // and 32 bit and 16 bit call gates (c, 4)
6899 final boolean valid
[] = {
6900 false, true, true, true,
6901 true, true, false, false,
6902 false, true, false, true,
6903 true, false, false, false,
6904 true, true, true, true,
6905 true, true, true, true,
6906 true, true, true, true,
6907 true, true, true, true
6910 Segment descriptorTable
;
6911 if ((selector
& 0x4) != 0)
6912 descriptorTable
= cpu
.ldtr
;
6914 descriptorTable
= cpu
.gdtr
;
6916 if ((offset
+ 7) > descriptorTable
.getLimit()) {
6917 cpu
.setZeroFlag(false);
6921 int descriptor
= cpu
.readSupervisorDoubleWord(descriptorTable
, offset
+ 4);
6922 int type
= (descriptor
& 0x1f00) >> 8;
6923 int dpl
= (descriptor
& 0x6000) >> 13;
6924 int rpl
= (selector
& 0x3);
6926 int conformingCode
= ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
;
6927 if ((((type
& conformingCode
) != conformingCode
) && ((cpu
.getCPL() > dpl
) || (rpl
> dpl
))) || !valid
[type
])
6929 cpu
.setZeroFlag(false);
6933 cpu
.setZeroFlag(true);
6934 return descriptor
& 0x00FFFF00;
6938 private final int lsl(int selector
, int original
)
6940 int offset
= selector
& 0xfff8;
6942 final boolean valid
[] = {
6943 false, true, true, true,
6944 true, true, false, false,
6945 false, true, false, true,
6946 true, false, false, false,
6947 true, true, true, true,
6948 true, true, true, true,
6949 true, true, true, true,
6950 true, true, true, true
6953 Segment descriptorTable
;
6954 if ((selector
& 0x4) != 0)
6955 descriptorTable
= cpu
.ldtr
;
6957 descriptorTable
= cpu
.gdtr
;
6959 if ((offset
+ 8) > descriptorTable
.getLimit()) { //
6960 cpu
.setZeroFlag(false);
6964 int segmentDescriptor
= cpu
.readSupervisorDoubleWord(descriptorTable
, offset
+ 4);
6966 int type
= (segmentDescriptor
& 0x1f00) >> 8;
6967 int dpl
= (segmentDescriptor
& 0x6000) >> 13;
6968 int rpl
= (selector
& 0x3);
6969 int conformingCode
= ProtectedModeSegment
.TYPE_CODE
| ProtectedModeSegment
.TYPE_CODE_CONFORMING
;
6970 if ((((type
& conformingCode
) != conformingCode
) && ((cpu
.getCPL() > dpl
) || (rpl
> dpl
))) || !valid
[type
]) {
6971 cpu
.setZeroFlag(false);
6976 if ((selector
& 0x4) != 0) // ldtr or gtdr
6977 lowsize
= cpu
.readSupervisorWord(cpu
.ldtr
, offset
);
6979 lowsize
= cpu
.readSupervisorWord(cpu
.gdtr
, offset
);
6981 int size
= (segmentDescriptor
& 0xf0000) | (lowsize
& 0xFFFF);
6983 if ((segmentDescriptor
& 0x800000) != 0) // granularity ==1
6984 size
= (size
<< 12) | 0xFFF;
6986 cpu
.setZeroFlag(true);
6990 private final Segment
lldt(int selector
)
6995 return SegmentFactory
.NULL_SEGMENT
;
6997 Segment newSegment
= cpu
.getSegment(selector
& ~
0x4);
6998 if (newSegment
.getType() != 0x02)
6999 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, selector
, true);
7001 if (!(newSegment
.isPresent()))
7002 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, selector
, true);
7008 private final Segment
ltr(int selector
)
7010 if ((selector
& 0x4) != 0) //must be gdtr table
7011 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, selector
, true);
7013 Segment tempSegment
= cpu
.getSegment(selector
);
7015 if ((tempSegment
.getType() != 0x01) && (tempSegment
.getType() != 0x09))
7016 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, selector
, true);
7018 if (!(tempSegment
.isPresent()))
7019 throw new ProcessorException(ProcessorException
.Type
.GENERAL_PROTECTION
, selector
, true);
7021 long descriptor
= cpu
.readSupervisorQuadWord(cpu
.gdtr
, (selector
& 0xfff8)) | (0x1l
<< 41); // set busy flag in segment descriptor
7022 cpu
.setSupervisorQuadWord(cpu
.gdtr
, selector
& 0xfff8, descriptor
);
7025 return cpu
.getSegment(selector
);
7028 private final void cpuid()
7033 cpu
.ebx
= 0x756e6547; /* "Genu", with G in the low nibble of BL */
7034 cpu
.edx
= 0x49656e69; /* "ineI", with i in the low nibble of DL */
7035 cpu
.ecx
= 0x6c65746e; /* "ntel", with n in the low nibble of CL */
7038 cpu
.eax
= 0x00000633; // Pentium II Model 8 Stepping 3
7039 cpu
.ebx
= 8 << 8; //not implemented (should be brand index)
7043 features
|= 0x01; //Have an FPU;
7044 features
|= (1<< 8); // Support CMPXCHG8B instruction
7045 features
|= (1<< 4); // implement TSC
7046 features
|= (1<< 5); // support RDMSR/WRMSR
7047 //features |= (1<<23); // support MMX
7048 //features |= (1<<24); // Implement FSAVE/FXRSTOR instructions.
7049 features
|= (1<<15); // Implement CMOV instructions.
7050 //features |= (1<< 9); // APIC on chip
7051 //features |= (1<<25); // support SSE
7052 features
|= (1<< 3); // Support Page-Size Extension (4M pages)
7053 features
|= (1<<13); // Support Global pages.
7054 //features |= (1<< 6); // Support PAE.
7055 features
|= (1<<11); // SYSENTER/SYSEXIT
7068 private final long rdtsc()
7070 if ((cpu
.getCPL() == 0) || ((cpu
.getCR4() & 0x4) == 0)) {
7071 return cpu
.getClockCount();
7073 throw ProcessorException
.GENERAL_PROTECTION_0
;
7076 private final void bitwise_flags(byte result
)
7078 cpu
.setOverflowFlag(false);
7079 cpu
.setCarryFlag(false);
7080 cpu
.setZeroFlag(result
);
7081 cpu
.setParityFlag(result
);
7082 cpu
.setSignFlag(result
);
7085 private final void bitwise_flags(short result
)
7087 cpu
.setOverflowFlag(false);
7088 cpu
.setCarryFlag(false);
7089 cpu
.setZeroFlag(result
);
7090 cpu
.setParityFlag(result
);
7091 cpu
.setSignFlag(result
);
7094 private final void bitwise_flags(int result
)
7096 cpu
.setOverflowFlag(false);
7097 cpu
.setCarryFlag(false);
7098 cpu
.setZeroFlag(result
);
7099 cpu
.setParityFlag(result
);
7100 cpu
.setSignFlag(result
);
7103 private final void arithmetic_flags_o8(int result
, int operand1
, int operand2
)
7105 cpu
.setZeroFlag((byte)result
);
7106 cpu
.setParityFlag(result
);
7107 cpu
.setSignFlag((byte)result
);
7109 cpu
.setCarryFlag(result
, Processor
.CY_TWIDDLE_FF
);
7110 cpu
.setAuxiliaryCarryFlag(operand1
, operand2
, result
, Processor
.AC_XOR
);
7113 private final void arithmetic_flags_o16(int result
, int operand1
, int operand2
)
7115 cpu
.setZeroFlag((short)result
);
7116 cpu
.setParityFlag(result
);
7117 cpu
.setSignFlag((short)result
);
7119 cpu
.setCarryFlag(result
, Processor
.CY_TWIDDLE_FFFF
);
7120 cpu
.setAuxiliaryCarryFlag(operand1
, operand2
, result
, Processor
.AC_XOR
);
7123 private final void arithmetic_flags_o32(long result
, int operand1
, int operand2
)
7125 cpu
.setZeroFlag((int)result
);
7126 cpu
.setParityFlag((int)result
);
7127 cpu
.setSignFlag((int)result
);
7129 cpu
.setCarryFlag(result
, Processor
.CY_TWIDDLE_FFFFFFFF
);
7130 cpu
.setAuxiliaryCarryFlag(operand1
, operand2
, (int)result
, Processor
.AC_XOR
);
7133 private final void add_o32_flags(long result
, int operand1
, int operand2
)
7135 result
= (0xffffffffl
& operand1
) + (0xffffffffl
& operand2
);
7137 arithmetic_flags_o32(result
, operand1
, operand2
);
7138 cpu
.setOverflowFlag((int)result
, operand1
, operand2
, Processor
.OF_ADD_INT
);
7141 private final void add_o16_flags(int result
, int operand1
, int operand2
)
7143 arithmetic_flags_o16(result
, operand1
, operand2
);
7144 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_ADD_SHORT
);
7147 private final void add_o8_flags(int result
, int operand1
, int operand2
)
7149 arithmetic_flags_o8(result
, operand1
, operand2
);
7150 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_ADD_BYTE
);
7153 private final void adc_o32_flags(long result
, int operand1
, int operand2
)
7155 int carry
= (cpu
.getCarryFlag() ?
1 : 0);
7156 result
= (0xffffffffl
& operand1
) + (0xffffffffl
& operand2
) + carry
;
7158 if (cpu
.getCarryFlag() && (operand2
== 0xffffffff)) {
7159 arithmetic_flags_o32(result
, operand1
, operand2
);
7160 cpu
.setOverflowFlag(false);
7161 cpu
.setCarryFlag(true);
7163 cpu
.setOverflowFlag((int)result
, operand1
, operand2
, Processor
.OF_ADD_INT
);
7164 arithmetic_flags_o32(result
, operand1
, operand2
);
7168 private final void adc_o16_flags(int result
, int operand1
, int operand2
)
7170 if (cpu
.getCarryFlag() && (operand2
== 0xffff)) {
7171 arithmetic_flags_o16(result
, operand1
, operand2
);
7172 cpu
.setOverflowFlag(false);
7173 cpu
.setCarryFlag(true);
7175 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_ADD_SHORT
);
7176 arithmetic_flags_o16(result
, operand1
, operand2
);
7180 private final void adc_o8_flags(int result
, int operand1
, int operand2
)
7182 if (cpu
.getCarryFlag() && (operand2
== 0xff)) {
7183 arithmetic_flags_o8(result
, operand1
, operand2
);
7184 cpu
.setOverflowFlag(false);
7185 cpu
.setCarryFlag(true);
7187 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_ADD_BYTE
);
7188 arithmetic_flags_o8(result
, operand1
, operand2
);
7192 private final void sub_o32_flags(long result
, int operand1
, int operand2
)
7194 result
= (0xffffffffl
& operand1
) - (0xffffffffl
& operand2
);
7196 arithmetic_flags_o32(result
, operand1
, operand2
);
7197 cpu
.setOverflowFlag((int)result
, operand1
, operand2
, Processor
.OF_SUB_INT
);
7200 private final void sub_o16_flags(int result
, int operand1
, int operand2
)
7202 arithmetic_flags_o16(result
, operand1
, operand2
);
7203 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_SUB_SHORT
);
7206 private final void sub_o8_flags(int result
, int operand1
, int operand2
)
7208 arithmetic_flags_o8(result
, operand1
, operand2
);
7209 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_SUB_BYTE
);
7212 private final void sbb_o32_flags(long result
, int operand1
, int operand2
)
7214 int carry
= (cpu
.getCarryFlag() ?
1 : 0);
7215 result
= (0xffffffffl
& operand1
) - ((0xffffffffl
& operand2
) + carry
);
7217 cpu
.setOverflowFlag((int)result
, operand1
, operand2
, Processor
.OF_SUB_INT
);
7218 arithmetic_flags_o32(result
, operand1
, operand2
);
7221 private final void sbb_o16_flags(int result
, int operand1
, int operand2
)
7223 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_SUB_SHORT
);
7224 arithmetic_flags_o16(result
, operand1
, operand2
);
7227 private final void sbb_o8_flags(int result
, int operand1
, int operand2
)
7229 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_SUB_BYTE
);
7230 arithmetic_flags_o8(result
, operand1
, operand2
);
7233 private final void dec_flags(int result
)
7235 cpu
.setZeroFlag(result
);
7236 cpu
.setParityFlag(result
);
7237 cpu
.setSignFlag(result
);
7238 cpu
.setOverflowFlag(result
, Processor
.OF_MAX_INT
);
7239 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_MAX
);
7242 private final void dec_flags(short result
)
7244 cpu
.setZeroFlag(result
);
7245 cpu
.setParityFlag(result
);
7246 cpu
.setSignFlag(result
);
7247 cpu
.setOverflowFlag(result
, Processor
.OF_MAX_SHORT
);
7248 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_MAX
);
7251 private final void dec_flags(byte result
)
7253 cpu
.setZeroFlag(result
);
7254 cpu
.setParityFlag(result
);
7255 cpu
.setSignFlag(result
);
7256 cpu
.setOverflowFlag(result
, Processor
.OF_MAX_BYTE
);
7257 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_MAX
);
7260 private final void inc_flags(int result
)
7262 cpu
.setZeroFlag(result
);
7263 cpu
.setParityFlag(result
);
7264 cpu
.setSignFlag(result
);
7265 cpu
.setOverflowFlag(result
, Processor
.OF_MIN_INT
);
7266 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_ZERO
);
7269 private final void inc_flags(short result
)
7271 cpu
.setZeroFlag(result
);
7272 cpu
.setParityFlag(result
);
7273 cpu
.setSignFlag(result
);
7274 cpu
.setOverflowFlag(result
, Processor
.OF_MIN_SHORT
);
7275 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_ZERO
);
7278 private final void inc_flags(byte result
)
7280 cpu
.setZeroFlag(result
);
7281 cpu
.setParityFlag(result
);
7282 cpu
.setSignFlag(result
);
7283 cpu
.setOverflowFlag(result
, Processor
.OF_MIN_BYTE
);
7284 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_ZERO
);
7287 private final void shl_flags(byte result
, byte initial
, int count
)
7290 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHL_OUTBIT_BYTE
);
7293 cpu
.setOverflowFlag(result
, Processor
.OF_BIT7_XOR_CARRY
);
7295 cpu
.setZeroFlag(result
);
7296 cpu
.setParityFlag(result
);
7297 cpu
.setSignFlag(result
);
7301 private final void shl_flags(short result
, short initial
, int count
)
7304 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHL_OUTBIT_SHORT
);
7307 cpu
.setOverflowFlag(result
, Processor
.OF_BIT15_XOR_CARRY
);
7309 cpu
.setZeroFlag(result
);
7310 cpu
.setParityFlag(result
);
7311 cpu
.setSignFlag(result
);
7315 private final void shl_flags(int result
, int initial
, int count
)
7318 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHL_OUTBIT_INT
);
7321 cpu
.setOverflowFlag(result
, Processor
.OF_BIT31_XOR_CARRY
);
7323 cpu
.setZeroFlag(result
);
7324 cpu
.setParityFlag(result
);
7325 cpu
.setSignFlag(result
);
7329 private final void shr_flags(byte result
, int initial
, int count
)
7332 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHR_OUTBIT
);
7335 cpu
.setOverflowFlag(result
, initial
, Processor
.OF_BIT7_DIFFERENT
);
7337 cpu
.setZeroFlag(result
);
7338 cpu
.setParityFlag(result
);
7339 cpu
.setSignFlag(result
);
7343 private final void shr_flags(short result
, int initial
, int count
)
7346 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHR_OUTBIT
);
7349 cpu
.setOverflowFlag(result
, initial
, Processor
.OF_BIT15_DIFFERENT
);
7351 cpu
.setZeroFlag(result
);
7352 cpu
.setParityFlag(result
);
7353 cpu
.setSignFlag(result
);
7357 private final void shr_flags(int result
, int initial
, int count
)
7360 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHR_OUTBIT
);
7363 cpu
.setOverflowFlag(result
, initial
, Processor
.OF_BIT31_DIFFERENT
);
7365 cpu
.setZeroFlag(result
);
7366 cpu
.setParityFlag(result
);
7367 cpu
.setSignFlag(result
);
7372 private final void sar_flags(byte result
, byte initial
, int count
)
7375 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHR_OUTBIT
);
7376 if (count
== 1) cpu
.setOverflowFlag(false);
7378 cpu
.setSignFlag(result
);
7379 cpu
.setZeroFlag(result
);
7380 cpu
.setParityFlag(result
);
7384 private final void sar_flags(short result
, short initial
, int count
)
7387 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHR_OUTBIT
);
7388 if (count
== 1) cpu
.setOverflowFlag(false);
7390 cpu
.setSignFlag(result
);
7391 cpu
.setZeroFlag(result
);
7392 cpu
.setParityFlag(result
);
7396 private final void sar_flags(int result
, int initial
, int count
)
7399 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHR_OUTBIT
);
7400 if (count
== 1) cpu
.setOverflowFlag(false);
7402 cpu
.setSignFlag(result
);
7403 cpu
.setZeroFlag(result
);
7404 cpu
.setParityFlag(result
);
7408 private final void rol_flags(byte result
, int count
)
7411 cpu
.setCarryFlag(result
, Processor
.CY_LOWBIT
);
7413 cpu
.setOverflowFlag(result
, Processor
.OF_BIT7_XOR_CARRY
);
7417 private final void rol_flags(short result
, int count
)
7420 cpu
.setCarryFlag(result
, Processor
.CY_LOWBIT
);
7422 cpu
.setOverflowFlag(result
, Processor
.OF_BIT15_XOR_CARRY
);
7426 private final void rol_flags(int result
, int count
)
7429 cpu
.setCarryFlag(result
, Processor
.CY_LOWBIT
);
7431 cpu
.setOverflowFlag(result
, Processor
.OF_BIT31_XOR_CARRY
);
7435 private final void ror_flags(byte result
, int count
)
7438 cpu
.setCarryFlag(result
, Processor
.CY_HIGHBIT_BYTE
);
7440 cpu
.setOverflowFlag(result
, Processor
.OF_BIT6_XOR_CARRY
);
7444 private final void ror_flags(short result
, int count
)
7447 cpu
.setCarryFlag(result
, Processor
.CY_HIGHBIT_SHORT
);
7449 cpu
.setOverflowFlag(result
, Processor
.OF_BIT14_XOR_CARRY
);
7453 private final void ror_flags(int result
, int count
)
7456 cpu
.setCarryFlag(result
, Processor
.CY_HIGHBIT_INT
);
7458 cpu
.setOverflowFlag(result
, Processor
.OF_BIT30_XOR_CARRY
);
7462 private final void rcl_o8_flags(int result
, int count
)
7465 cpu
.setCarryFlag(result
, Processor
.CY_OFFENDBIT_BYTE
);
7467 cpu
.setOverflowFlag(result
, Processor
.OF_BIT7_XOR_CARRY
);
7471 private final void rcl_o16_flags(int result
, int count
)
7474 cpu
.setCarryFlag(result
, Processor
.CY_OFFENDBIT_SHORT
);
7476 cpu
.setOverflowFlag(result
, Processor
.OF_BIT15_XOR_CARRY
);
7480 private final void rcl_o32_flags(long result
, int count
)
7483 cpu
.setCarryFlag(result
, Processor
.CY_OFFENDBIT_INT
);
7485 cpu
.setOverflowFlag((int) result
, Processor
.OF_BIT31_XOR_CARRY
);
7489 private final void rcr_o8_flags(int result
, int count
, int overflow
)
7492 cpu
.setCarryFlag(result
, Processor
.CY_OFFENDBIT_BYTE
);
7494 cpu
.setOverflowFlag(overflow
> 0);
7498 private final void rcr_o16_flags(int result
, int count
, int overflow
)
7501 cpu
.setCarryFlag(result
, Processor
.CY_OFFENDBIT_SHORT
);
7503 cpu
.setOverflowFlag(overflow
> 0);
7507 private final void rcr_o32_flags(long result
, int count
, int overflow
)
7510 cpu
.setCarryFlag(result
, Processor
.CY_OFFENDBIT_INT
);
7512 cpu
.setOverflowFlag(overflow
> 0);
7516 private final void neg_flags(byte result
)
7518 cpu
.setCarryFlag(result
, Processor
.CY_NZ
);
7519 cpu
.setOverflowFlag(result
, Processor
.OF_MIN_BYTE
);
7521 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_NZERO
);
7522 cpu
.setZeroFlag(result
);
7523 cpu
.setParityFlag(result
);
7524 cpu
.setSignFlag(result
);
7527 private final void neg_flags(short result
)
7529 cpu
.setCarryFlag(result
, Processor
.CY_NZ
);
7530 cpu
.setOverflowFlag(result
, Processor
.OF_MIN_SHORT
);
7532 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_NZERO
);
7533 cpu
.setZeroFlag(result
);
7534 cpu
.setParityFlag(result
);
7535 cpu
.setSignFlag(result
);
7538 private final void neg_flags(int result
)
7540 cpu
.setCarryFlag(result
, Processor
.CY_NZ
);
7541 cpu
.setOverflowFlag(result
, Processor
.OF_MIN_INT
);
7543 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_NZERO
);
7544 cpu
.setZeroFlag(result
);
7545 cpu
.setParityFlag(result
);
7546 cpu
.setSignFlag(result
);
7549 private final Segment
loadSegment(int selector
)
7553 return SegmentFactory
.NULL_SEGMENT
;
7555 Segment s
= cpu
.getSegment(selector
);
7557 throw new ProcessorException(ProcessorException
.Type
.NOT_PRESENT
, selector
, true);
7561 private final boolean checkIOPermissionsByte(int ioportAddress
)
7563 if (cpu
.getCPL() <= cpu
.eflagsIOPrivilegeLevel
)
7566 int ioPermMapBaseAddress
= 0xffff & cpu
.tss
.getWord(102);
7568 byte ioPermMapByte
= cpu
.tss
.getByte(ioPermMapBaseAddress
+ (ioportAddress
>>> 3));
7569 return (ioPermMapByte
& (0x1 << (ioportAddress
& 0x7))) == 0;
7570 } catch (ProcessorException p
) {
7571 if (p
.getType() == ProcessorException
.Type
.GENERAL_PROTECTION
)
7578 private final boolean checkIOPermissionsShort(int ioportAddress
)
7580 if (cpu
.getCPL() <= cpu
.eflagsIOPrivilegeLevel
)
7583 int ioPermMapBaseAddress
= 0xffff & cpu
.tss
.getWord(102);
7585 short ioPermMapShort
= cpu
.tss
.getWord(ioPermMapBaseAddress
+ (ioportAddress
>>> 3));
7586 return (ioPermMapShort
& (0x3 << (ioportAddress
& 0x7))) == 0;
7587 } catch (ProcessorException p
) {
7588 if (p
.getType() == ProcessorException
.Type
.GENERAL_PROTECTION
)
7595 private final boolean checkIOPermissionsInt(int ioportAddress
)
7597 if (cpu
.getCPL() <= cpu
.eflagsIOPrivilegeLevel
)
7600 int ioPermMapBaseAddress
= 0xffff & cpu
.tss
.getWord(102);
7602 short ioPermMapShort
= cpu
.tss
.getWord(ioPermMapBaseAddress
+ (ioportAddress
>>> 3));
7603 return (ioPermMapShort
& (0xf << (ioportAddress
& 0x7))) == 0;
7604 } catch (ProcessorException p
) {
7605 if (p
.getType() == ProcessorException
.Type
.GENERAL_PROTECTION
)
7612 //borrowed from the j2se api as not in midp
7613 private static int numberOfTrailingZeros(int i
) {
7616 if (i
== 0) return 32;
7618 y
= i
<<16; if (y
!= 0) { n
= n
-16; i
= y
; }
7619 y
= i
<< 8; if (y
!= 0) { n
= n
- 8; i
= y
; }
7620 y
= i
<< 4; if (y
!= 0) { n
= n
- 4; i
= y
; }
7621 y
= i
<< 2; if (y
!= 0) { n
= n
- 2; i
= y
; }
7622 return n
- ((i
<< 1) >>> 31);
7625 private static int numberOfLeadingZeros(int i
) {
7630 if (i
>>> 16 == 0) { n
+= 16; i
<<= 16; }
7631 if (i
>>> 24 == 0) { n
+= 8; i
<<= 8; }
7632 if (i
>>> 28 == 0) { n
+= 4; i
<<= 4; }
7633 if (i
>>> 30 == 0) { n
+= 2; i
<<= 2; }
7638 private static int reverseBytes(int i
) {
7639 return ((i
>>> 24) ) |
7640 ((i
>> 8) & 0xFF00) |
7641 ((i
<< 8) & 0xFF0000) |