2 JPC-RR: A x86 PC Hardware Emulator
5 Copyright (C) 2007-2009 Isis Innovation Limited
6 Copyright (C) 2009 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 static org
.jpc
.emulator
.memory
.codeblock
.optimised
.MicrocodeSet
.*;
40 * @author Chris Dennis
42 public final class RealModeUBlock
implements RealModeCodeBlock
44 private static final boolean[] parityMap
;
48 parityMap
= new boolean[256];
49 for (int i
= 0; i
< parityMap
.length
; i
++)
50 parityMap
[i
] = ((Integer
.bitCount(i
) & 0x1) == 0);
53 private Processor cpu
;
58 protected int[] microcodes
;
59 protected int[] cumulativeX86Length
;
60 private int executeCount
;
61 public static OpcodeLogger opcodeCounter
= null;//new OpcodeLogger("RM Stats:");
63 public RealModeUBlock()
67 public RealModeUBlock(int[] microcodes
, int[] x86lengths
)
69 this.microcodes
= microcodes
;
70 cumulativeX86Length
= x86lengths
;
71 if (cumulativeX86Length
.length
== 0)
75 for (int i
= 1; i
< cumulativeX86Length
.length
; i
++) {
76 if (cumulativeX86Length
[i
] > cumulativeX86Length
[i
-1]) count
++;
82 public int getX86Length()
84 if (microcodes
.length
== 0)
86 return cumulativeX86Length
[microcodes
.length
-1];
89 public int getX86Count()
94 public String
getDisplayString()
96 StringBuilder buf
= new StringBuilder();
97 buf
.append(this.toString()).append('\n');
98 for (int i
=0; i
<microcodes
.length
; i
++)
99 buf
.append(i
).append(": ").append(microcodes
[i
]).append('\n');
100 return buf
.toString();
103 public boolean handleMemoryRegionChange(int startAddress
, int endAddress
)
108 public String
toString()
110 return "Real Mode Interpreted Block: "+hashCode();
113 public InstructionSource
getAsInstructionSource()
115 int[] codes
= new int[microcodes
.length
];
116 int[] positions
= new int[microcodes
.length
];
117 System
.arraycopy(microcodes
, 0, codes
, 0, codes
.length
);
118 System
.arraycopy(cumulativeX86Length
, 0, positions
, 0, positions
.length
);
120 return new ArrayBackedInstructionSource(codes
, positions
);
123 public int[] getMicrocodes()
125 int[] result
= new int[microcodes
.length
];
126 System
.arraycopy(microcodes
, 0, result
, 0, result
.length
);
130 private Segment transferSeg0
= null;
131 private int transferAddr0
= 0;
132 private int transferReg0
= 0, transferReg1
= 0, transferReg2
= 0;
133 private long transferReg0l
= 0;
134 private boolean transferEipUpdated
= false;
135 private int transferPosition
= 0;
137 private int uCodeXferReg0
= 0, uCodeXferReg1
= 0, uCodeXferReg2
= 0;
138 private boolean uCodeXferLoaded
= false;
140 private boolean cachedSSSize
;
142 private void fullExecute(Processor cpu
)
144 FpuState fpu
= cpu
.fpu
;
146 //recover variables from instance storage
147 Segment seg0
= transferSeg0
;
148 int addr0
= transferAddr0
;
149 int reg0
= transferReg0
, reg1
= transferReg1
, reg2
= transferReg2
;
150 long reg0l
= transferReg0l
;
152 boolean eipUpdated
= transferEipUpdated
;
153 int position
= transferPosition
;
156 switch (microcodes
[position
++]) {
160 cpu
.eip
+= cumulativeX86Length
[position
- 1];
164 case UNDEFINED
: throw ProcessorException
.UNDEFINED
;
166 case MEM_RESET
: addr0
= 0; seg0
= null; break;
168 case LOAD0_EAX
: reg0
= cpu
.eax
; break;
169 case LOAD0_ECX
: reg0
= cpu
.ecx
; break;
170 case LOAD0_EDX
: reg0
= cpu
.edx
; break;
171 case LOAD0_EBX
: reg0
= cpu
.ebx
; break;
172 case LOAD0_ESP
: reg0
= cpu
.esp
; break;
173 case LOAD0_EBP
: reg0
= cpu
.ebp
; break;
174 case LOAD0_ESI
: reg0
= cpu
.esi
; break;
175 case LOAD0_EDI
: reg0
= cpu
.edi
; break;
177 case STORE0_EAX
: cpu
.eax
= reg0
; break;
178 case STORE0_ECX
: cpu
.ecx
= reg0
; break;
179 case STORE0_EDX
: cpu
.edx
= reg0
; break;
180 case STORE0_EBX
: cpu
.ebx
= reg0
; break;
181 case STORE0_ESP
: cpu
.esp
= reg0
; break;
182 case STORE0_EBP
: cpu
.ebp
= reg0
; break;
183 case STORE0_ESI
: cpu
.esi
= reg0
; break;
184 case STORE0_EDI
: cpu
.edi
= reg0
; break;
186 case LOAD1_EAX
: reg1
= cpu
.eax
; break;
187 case LOAD1_ECX
: reg1
= cpu
.ecx
; break;
188 case LOAD1_EDX
: reg1
= cpu
.edx
; break;
189 case LOAD1_EBX
: reg1
= cpu
.ebx
; break;
190 case LOAD1_ESP
: reg1
= cpu
.esp
; break;
191 case LOAD1_EBP
: reg1
= cpu
.ebp
; break;
192 case LOAD1_ESI
: reg1
= cpu
.esi
; break;
193 case LOAD1_EDI
: reg1
= cpu
.edi
; break;
195 case STORE1_EAX
: cpu
.eax
= reg1
; break;
196 case STORE1_ECX
: cpu
.ecx
= reg1
; break;
197 case STORE1_EDX
: cpu
.edx
= reg1
; break;
198 case STORE1_EBX
: cpu
.ebx
= reg1
; break;
199 case STORE1_ESP
: cpu
.esp
= reg1
; break;
200 case STORE1_EBP
: cpu
.ebp
= reg1
; break;
201 case STORE1_ESI
: cpu
.esi
= reg1
; break;
202 case STORE1_EDI
: cpu
.edi
= reg1
; break;
204 case LOAD0_AX
: reg0
= cpu
.eax
& 0xffff; break;
205 case LOAD0_CX
: reg0
= cpu
.ecx
& 0xffff; break;
206 case LOAD0_DX
: reg0
= cpu
.edx
& 0xffff; break;
207 case LOAD0_BX
: reg0
= cpu
.ebx
& 0xffff; break;
208 case LOAD0_SP
: reg0
= cpu
.esp
& 0xffff; break;
209 case LOAD0_BP
: reg0
= cpu
.ebp
& 0xffff; break;
210 case LOAD0_SI
: reg0
= cpu
.esi
& 0xffff; break;
211 case LOAD0_DI
: reg0
= cpu
.edi
& 0xffff; break;
213 case STORE0_AX
: cpu
.eax
= (cpu
.eax
& ~
0xffff) | (reg0
& 0xffff); break;
214 case STORE0_CX
: cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (reg0
& 0xffff); break;
215 case STORE0_DX
: cpu
.edx
= (cpu
.edx
& ~
0xffff) | (reg0
& 0xffff); break;
216 case STORE0_BX
: cpu
.ebx
= (cpu
.ebx
& ~
0xffff) | (reg0
& 0xffff); break;
217 case STORE0_SP
: cpu
.esp
= (cpu
.esp
& ~
0xffff) | (reg0
& 0xffff); break;
218 case STORE0_BP
: cpu
.ebp
= (cpu
.ebp
& ~
0xffff) | (reg0
& 0xffff); break;
219 case STORE0_SI
: cpu
.esi
= (cpu
.esi
& ~
0xffff) | (reg0
& 0xffff); break;
220 case STORE0_DI
: cpu
.edi
= (cpu
.edi
& ~
0xffff) | (reg0
& 0xffff); break;
222 case STORE1_AX
: cpu
.eax
= (cpu
.eax
& ~
0xffff) | (reg1
& 0xffff); break;
223 case STORE1_CX
: cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (reg1
& 0xffff); break;
224 case STORE1_DX
: cpu
.edx
= (cpu
.edx
& ~
0xffff) | (reg1
& 0xffff); break;
225 case STORE1_BX
: cpu
.ebx
= (cpu
.ebx
& ~
0xffff) | (reg1
& 0xffff); break;
226 case STORE1_SP
: cpu
.esp
= (cpu
.esp
& ~
0xffff) | (reg1
& 0xffff); break;
227 case STORE1_BP
: cpu
.ebp
= (cpu
.ebp
& ~
0xffff) | (reg1
& 0xffff); break;
228 case STORE1_SI
: cpu
.esi
= (cpu
.esi
& ~
0xffff) | (reg1
& 0xffff); break;
229 case STORE1_DI
: cpu
.edi
= (cpu
.edi
& ~
0xffff) | (reg1
& 0xffff); break;
231 case LOAD1_AX
: reg1
= cpu
.eax
& 0xffff; break;
232 case LOAD1_CX
: reg1
= cpu
.ecx
& 0xffff; break;
233 case LOAD1_DX
: reg1
= cpu
.edx
& 0xffff; break;
234 case LOAD1_SP
: reg1
= cpu
.esp
& 0xffff; break;
235 case LOAD1_BP
: reg1
= cpu
.ebp
& 0xffff; break;
236 case LOAD1_SI
: reg1
= cpu
.esi
& 0xffff; break;
237 case LOAD1_DI
: reg1
= cpu
.edi
& 0xffff; break;
239 case LOAD0_AL
: reg0
= cpu
.eax
& 0xff; break;
240 case LOAD0_CL
: reg0
= cpu
.ecx
& 0xff; break;
241 case LOAD0_DL
: reg0
= cpu
.edx
& 0xff; break;
242 case LOAD0_BL
: reg0
= cpu
.ebx
& 0xff; break;
243 case LOAD0_AH
: reg0
= (cpu
.eax
>> 8) & 0xff; break;
244 case LOAD0_CH
: reg0
= (cpu
.ecx
>> 8) & 0xff; break;
245 case LOAD0_DH
: reg0
= (cpu
.edx
>> 8) & 0xff; break;
246 case LOAD0_BH
: reg0
= (cpu
.ebx
>> 8) & 0xff; break;
248 case STORE0_AL
: cpu
.eax
= (cpu
.eax
& ~
0xff) | (reg0
& 0xff); break;
249 case STORE0_CL
: cpu
.ecx
= (cpu
.ecx
& ~
0xff) | (reg0
& 0xff); break;
250 case STORE0_DL
: cpu
.edx
= (cpu
.edx
& ~
0xff) | (reg0
& 0xff); break;
251 case STORE0_AH
: cpu
.eax
= (cpu
.eax
& ~
0xff00) | ((reg0
<< 8) & 0xff00); break;
252 case STORE0_CH
: cpu
.ecx
= (cpu
.ecx
& ~
0xff00) | ((reg0
<< 8) & 0xff00); break;
253 case STORE0_DH
: cpu
.edx
= (cpu
.edx
& ~
0xff00) | ((reg0
<< 8) & 0xff00); break;
254 case STORE0_BH
: cpu
.ebx
= (cpu
.ebx
& ~
0xff00) | ((reg0
<< 8) & 0xff00); break;
256 case LOAD1_AL
: reg1
= cpu
.eax
& 0xff; break;
257 case LOAD1_CL
: reg1
= cpu
.ecx
& 0xff; break;
258 case LOAD1_DL
: reg1
= cpu
.edx
& 0xff; break;
259 case LOAD1_BL
: reg1
= cpu
.ebx
& 0xff; break;
260 case LOAD1_AH
: reg1
= (cpu
.eax
>> 8) & 0xff; break;
261 case LOAD1_CH
: reg1
= (cpu
.ecx
>> 8) & 0xff; break;
262 case LOAD1_DH
: reg1
= (cpu
.edx
>> 8) & 0xff; break;
263 case LOAD1_BH
: reg1
= (cpu
.ebx
>> 8) & 0xff; break;
265 case STORE1_AL
: cpu
.eax
= (cpu
.eax
& ~
0xff) | (reg1
& 0xff); break;
266 case STORE1_CL
: cpu
.ecx
= (cpu
.ecx
& ~
0xff) | (reg1
& 0xff); break;
267 case STORE1_DL
: cpu
.edx
= (cpu
.edx
& ~
0xff) | (reg1
& 0xff); break;
268 case STORE1_BL
: cpu
.ebx
= (cpu
.ebx
& ~
0xff) | (reg1
& 0xff); break;
269 case STORE1_AH
: cpu
.eax
= (cpu
.eax
& ~
0xff00) | ((reg1
<< 8) & 0xff00); break;
270 case STORE1_CH
: cpu
.ecx
= (cpu
.ecx
& ~
0xff00) | ((reg1
<< 8) & 0xff00); break;
271 case STORE1_DH
: cpu
.edx
= (cpu
.edx
& ~
0xff00) | ((reg1
<< 8) & 0xff00); break;
272 case STORE1_BH
: cpu
.ebx
= (cpu
.ebx
& ~
0xff00) | ((reg1
<< 8) & 0xff00); break;
274 case LOAD0_CR0
: reg0
= cpu
.getCR0(); break;
275 case LOAD0_CR2
: reg0
= cpu
.getCR2(); break;
276 case LOAD0_CR3
: reg0
= cpu
.getCR3(); break;
277 case LOAD0_CR4
: reg0
= cpu
.getCR4(); break;
279 case STORE0_CR0
: cpu
.setCR0(reg0
); break;
280 case STORE0_CR2
: cpu
.setCR2(reg0
); break;
281 case STORE0_CR3
: cpu
.setCR3(reg0
); break;
282 case STORE0_CR4
: cpu
.setCR4(reg0
); break;
284 case LOAD0_DR0
: reg0
= cpu
.getDR0(); break;
285 case LOAD0_DR1
: reg0
= cpu
.getDR1(); break;
286 case LOAD0_DR2
: reg0
= cpu
.getDR2(); break;
287 case LOAD0_DR3
: reg0
= cpu
.getDR3(); break;
288 case LOAD0_DR6
: reg0
= cpu
.getDR6(); break;
289 case LOAD0_DR7
: reg0
= cpu
.getDR7(); break;
291 case STORE0_DR0
: cpu
.setDR0(reg0
); break;
292 case STORE0_DR1
: cpu
.setDR1(reg0
); break;
293 case STORE0_DR2
: cpu
.setDR2(reg0
); break;
294 case STORE0_DR3
: cpu
.setDR3(reg0
); break;
295 case STORE0_DR6
: cpu
.setDR6(reg0
); break;
296 case STORE0_DR7
: cpu
.setDR7(reg0
); break;
299 case LOAD0_ES
: reg0
= 0xffff & cpu
.es
.getSelector(); break;
300 case LOAD0_CS
: reg0
= 0xffff & cpu
.cs
.getSelector(); break;
301 case LOAD0_SS
: reg0
= 0xffff & cpu
.ss
.getSelector(); break;
302 case LOAD0_DS
: reg0
= 0xffff & cpu
.ds
.getSelector(); break;
303 case LOAD0_FS
: reg0
= 0xffff & cpu
.fs
.getSelector(); break;
304 case LOAD0_GS
: reg0
= 0xffff & cpu
.gs
.getSelector(); break;
306 case STORE0_ES
: cpu
.es
.setSelector(0xffff & reg0
); break;
307 case STORE0_CS
: cpu
.cs
.setSelector(0xffff & reg0
); break;
309 cpu
.ss
.setSelector(0xffff & reg0
);
311 cachedSSSize
= cpu
.ss
.getDefaultSizeFlag();
313 case STORE0_DS
: cpu
.ds
.setSelector(0xffff & reg0
);
314 System
.err
.println("Emulated: RM DS segment load, limit = " + Integer
.toHexString(cpu
.ds
.getLimit()) +
315 ", base=" + Integer
.toHexString(cpu
.ds
.getBase()));
317 case STORE0_FS
: cpu
.fs
.setSelector(0xffff & reg0
); break;
318 case STORE0_GS
: cpu
.gs
.setSelector(0xffff & reg0
); break;
320 case STORE1_CS
: cpu
.cs
.setSelector(0xffff & reg1
); break;
322 cpu
.ss
.setSelector(0xffff & reg1
);
324 cachedSSSize
= cpu
.ss
.getDefaultSizeFlag();
326 case STORE1_DS
: cpu
.ds
.setSelector(0xffff & reg1
); break;
327 case STORE1_FS
: cpu
.fs
.setSelector(0xffff & reg1
); break;
328 case STORE1_GS
: cpu
.gs
.setSelector(0xffff & reg1
); break;
330 case STORE0_FLAGS
: cpu
.setEFlags((cpu
.getEFlags() & ~
0xffff) | (reg0
& 0xffff)); break;
331 case STORE0_EFLAGS
: cpu
.setEFlags(reg0
); break;
333 case LOAD0_FLAGS
: reg0
= 0xffff & cpu
.getEFlags(); break;
334 case LOAD0_EFLAGS
: reg0
= cpu
.getEFlags(); break;
336 case LOAD0_IB
: reg0
= microcodes
[position
++] & 0xff; break;
337 case LOAD0_IW
: reg0
= microcodes
[position
++] & 0xffff; break;
338 case LOAD0_ID
: reg0
= microcodes
[position
++]; break;
340 case LOAD1_IB
: reg1
= microcodes
[position
++] & 0xff; break;
341 case LOAD1_IW
: reg1
= microcodes
[position
++] & 0xffff; break;
342 case LOAD1_ID
: reg1
= microcodes
[position
++]; break;
344 case LOAD2_EAX
: reg2
= cpu
.eax
; break;
345 case LOAD2_AX
: reg2
= 0xffff & cpu
.eax
; break;
346 case LOAD2_AL
: reg2
= 0xff & cpu
.eax
; break;
347 case LOAD2_CL
: reg2
= 0xff & cpu
.ecx
; break;
348 case LOAD2_IB
: reg2
= 0xff & microcodes
[position
++]; break;
350 case LOAD_SEG_ES
: seg0
= cpu
.es
; break;
351 case LOAD_SEG_CS
: seg0
= cpu
.cs
; break;
352 case LOAD_SEG_SS
: seg0
= cpu
.ss
; break;
353 case LOAD_SEG_DS
: seg0
= cpu
.ds
; break;
354 case LOAD_SEG_FS
: seg0
= cpu
.fs
; break;
355 case LOAD_SEG_GS
: seg0
= cpu
.gs
; break;
357 case ADDR_EAX
: addr0
+= cpu
.eax
; break;
358 case ADDR_ECX
: addr0
+= cpu
.ecx
; break;
359 case ADDR_EDX
: addr0
+= cpu
.edx
; break;
360 case ADDR_EBX
: addr0
+= cpu
.ebx
; break;
361 case ADDR_ESP
: addr0
+= cpu
.esp
; break;
362 case ADDR_EBP
: addr0
+= cpu
.ebp
; break;
363 case ADDR_ESI
: addr0
+= cpu
.esi
; break;
364 case ADDR_EDI
: addr0
+= cpu
.edi
; break;
366 case ADDR_AX
: addr0
+= ((short)cpu
.eax
); break;
367 case ADDR_CX
: addr0
+= ((short)cpu
.ecx
); break;
368 case ADDR_DX
: addr0
+= ((short)cpu
.edx
); break;
369 case ADDR_BX
: addr0
+= ((short)cpu
.ebx
); break;
370 case ADDR_SP
: addr0
+= ((short)cpu
.esp
); break;
371 case ADDR_BP
: addr0
+= ((short)cpu
.ebp
); break;
372 case ADDR_SI
: addr0
+= ((short)cpu
.esi
); break;
373 case ADDR_DI
: addr0
+= ((short)cpu
.edi
); break;
375 case ADDR_2EAX
: addr0
+= (cpu
.eax
<< 1); break;
376 case ADDR_2ECX
: addr0
+= (cpu
.ecx
<< 1); break;
377 case ADDR_2EDX
: addr0
+= (cpu
.edx
<< 1); break;
378 case ADDR_2EBX
: addr0
+= (cpu
.ebx
<< 1); break;
379 case ADDR_2ESP
: addr0
+= (cpu
.esp
<< 1); break;
380 case ADDR_2EBP
: addr0
+= (cpu
.ebp
<< 1); break;
381 case ADDR_2ESI
: addr0
+= (cpu
.esi
<< 1); break;
382 case ADDR_2EDI
: addr0
+= (cpu
.edi
<< 1); break;
384 case ADDR_4EAX
: addr0
+= (cpu
.eax
<< 2); break;
385 case ADDR_4ECX
: addr0
+= (cpu
.ecx
<< 2); break;
386 case ADDR_4EDX
: addr0
+= (cpu
.edx
<< 2); break;
387 case ADDR_4EBX
: addr0
+= (cpu
.ebx
<< 2); break;
388 case ADDR_4ESP
: addr0
+= (cpu
.esp
<< 2); break;
389 case ADDR_4EBP
: addr0
+= (cpu
.ebp
<< 2); break;
390 case ADDR_4ESI
: addr0
+= (cpu
.esi
<< 2); break;
391 case ADDR_4EDI
: addr0
+= (cpu
.edi
<< 2); break;
393 case ADDR_8EAX
: addr0
+= (cpu
.eax
<< 3); break;
394 case ADDR_8ECX
: addr0
+= (cpu
.ecx
<< 3); break;
395 case ADDR_8EDX
: addr0
+= (cpu
.edx
<< 3); break;
396 case ADDR_8EBX
: addr0
+= (cpu
.ebx
<< 3); break;
397 case ADDR_8ESP
: addr0
+= (cpu
.esp
<< 3); break;
398 case ADDR_8EBP
: addr0
+= (cpu
.ebp
<< 3); break;
399 case ADDR_8ESI
: addr0
+= (cpu
.esi
<< 3); break;
400 case ADDR_8EDI
: addr0
+= (cpu
.edi
<< 3); break;
402 case ADDR_IB
: addr0
+= ((byte)microcodes
[position
++]); break;
403 case ADDR_IW
: addr0
+= ((short)microcodes
[position
++]); break;
404 case ADDR_ID
: addr0
+= microcodes
[position
++]; break;
406 case ADDR_MASK16
: addr0
&= 0xffff; break;
408 case ADDR_uAL
: addr0
+= 0xff & cpu
.eax
; break;
410 case LOAD0_ADDR
: reg0
= addr0
; break;
412 case LOAD0_MEM_BYTE
: reg0
= 0xff & seg0
.getByte(addr0
); break;
413 case LOAD0_MEM_WORD
: reg0
= 0xffff & seg0
.getWord(addr0
); break;
414 case LOAD0_MEM_DWORD
: reg0
= seg0
.getDoubleWord(addr0
); break;
415 case LOAD0_MEM_QWORD
: reg0l
= seg0
.getQuadWord(addr0
); break;
417 case LOAD1_MEM_BYTE
: reg1
= 0xff & seg0
.getByte(addr0
); break;
418 case LOAD1_MEM_WORD
: reg1
= 0xffff & seg0
.getWord(addr0
); break;
419 case LOAD1_MEM_DWORD
: reg1
= seg0
.getDoubleWord(addr0
); break;
421 case STORE0_MEM_BYTE
: seg0
.setByte(addr0
, (byte)reg0
); break;
422 case STORE0_MEM_WORD
: seg0
.setWord(addr0
, (short)reg0
); break;
423 case STORE0_MEM_DWORD
: seg0
.setDoubleWord(addr0
, reg0
); break;
424 case STORE0_MEM_QWORD
: seg0
.setQuadWord(addr0
, reg0
); break;
426 case STORE1_MEM_BYTE
: seg0
.setByte(addr0
, (byte)reg1
); break;
427 case STORE1_MEM_WORD
: seg0
.setWord(addr0
, (short)reg1
); break;
428 case STORE1_MEM_DWORD
: seg0
.setDoubleWord(addr0
, reg1
); break;
430 case JUMP_FAR_O16
: jump_far_o16(reg0
, reg1
); break;
431 case JUMP_FAR_O32
: jump_far_o32(reg0
, reg1
); break;
433 case JUMP_ABS_O16
: cpu
.eip
= reg0
; break;
437 call_far_o16_a32(reg0
, reg1
);
439 call_far_o16_a16(reg0
, reg1
);
444 call_far_o32_a32(reg0
, reg1
);
446 call_far_o32_a16(reg0
, reg1
);
451 call_abs_o16_a32(reg0
);
453 call_abs_o16_a16(reg0
);
458 call_abs_o32_a32(reg0
);
460 call_abs_o32_a16(reg0
);
463 case JUMP_O8
: jump_o8((byte)reg0
); break;
464 case JUMP_O16
: jump_o16((short)reg0
); break;
465 case JUMP_O32
: jump_o32(reg0
); break;
467 case INT_O16
: int_o16_a16(reg0
); break;
468 case INT3_O16
: int3_o16_a16(); break;
469 case INT1_O16
: int1_o16_a16(); break;
471 case IRET_O16
: reg0
= iret_o16_a16(); break; //returns flags
473 case IN_O8
: reg0
= 0xff & cpu
.ioports
.ioPortReadByte(reg0
); break;
474 case IN_O16
: reg0
= 0xffff & cpu
.ioports
.ioPortReadWord(reg0
); break;
475 case IN_O32
: reg0
= cpu
.ioports
.ioPortReadLong(reg0
); break;
477 case OUT_O8
: cpu
.ioports
.ioPortWriteByte(reg0
, reg1
); break;
478 case OUT_O16
: cpu
.ioports
.ioPortWriteWord(reg0
, reg1
); break;
479 case OUT_O32
: cpu
.ioports
.ioPortWriteLong(reg0
, reg1
); break;
481 case CMOVNS
: if (!cpu
.getSignFlag()) reg0
= reg1
; break;
483 case XOR
: reg0 ^
= reg1
; break;
484 case AND
: reg0
&= reg1
; break;
485 case NOT
: reg0
= ~reg0
; break;
487 case SUB
: reg2
= reg0
; reg0
= reg2
- reg1
; break;
488 case SBB
: reg2
= reg0
; reg0
= reg2
- (reg1
+ (cpu
.getCarryFlag() ?
1 : 0)); break;
489 case ADD
: reg2
= reg0
; reg0
= reg2
+ reg1
; break;
490 case ADC
: reg2
= reg0
; reg0
= reg2
+ reg1
+ (cpu
.getCarryFlag() ?
1 : 0); break;
491 case NEG
: reg0
= -reg0
; break;
493 case MUL_O8
: mul_o8(reg0
); break;
494 case MUL_O16
: mul_o16(reg0
); break;
495 case MUL_O32
: mul_o32(reg0
); break;
497 case IMULA_O8
: imula_o8((byte)reg0
); break;
498 case IMULA_O16
: imula_o16((short)reg0
); break;
499 case IMULA_O32
: imula_o32(reg0
); break;
501 case IMUL_O16
: reg0
= imul_o16((short)reg0
, (short)reg1
); break;
502 case IMUL_O32
: reg0
= imul_o32(reg0
, reg1
); break;
504 case DIV_O8
: div_o8(reg0
); break;
505 case DIV_O16
: div_o16(reg0
); break;
506 case DIV_O32
: div_o32(reg0
); break;
508 case IDIV_O8
: idiv_o8((byte)reg0
); break;
509 case IDIV_O16
: idiv_o16((short)reg0
); break;
510 case IDIV_O32
: idiv_o32(reg0
); break;
512 case BSF
: reg0
= bsf(reg1
, reg0
); break;
513 case BSR
: reg0
= bsr(reg1
, reg0
); break;
515 case BT_MEM
: bt_mem(reg1
, seg0
, addr0
); break;
516 case BTS_MEM
: bts_mem(reg1
, seg0
, addr0
); break;
517 case BTR_MEM
: btr_mem(reg1
, seg0
, addr0
); break;
518 case BTC_MEM
: btc_mem(reg1
, seg0
, addr0
); break;
520 case BT_O32
: reg1
&= 0x1f; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); break;
521 case BT_O16
: reg1
&= 0xf; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); break;
522 case BTS_O32
: reg1
&= 0x1f; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); reg0
|= (1 << reg1
); break;
523 case BTS_O16
: reg1
&= 0xf; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); reg0
|= (1 << reg1
); break;
524 case BTR_O32
: reg1
&= 0x1f; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); reg0
&= ~
(1 << reg1
); break;
525 case BTR_O16
: reg1
&= 0xf; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); reg0
&= ~
(1 << reg1
); break;
526 case BTC_O32
: reg1
&= 0x1f; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); reg0 ^
= (1 << reg1
); break;
527 case BTC_O16
: reg1
&= 0xf; cpu
.setCarryFlag(reg0
, reg1
, Processor
.CY_NTH_BIT_SET
); reg0 ^
= (1 << reg1
); break;
529 case ROL_O8
: reg2
= reg1
& 0x7; reg0
= (reg0
<< reg2
) | (reg0
>>> (8 - reg2
)); break;
530 case ROL_O16
: reg2
= reg1
& 0xf; reg0
= (reg0
<< reg2
) | (reg0
>>> (16 - reg2
)); break;
531 case ROL_O32
: reg1
&= 0x1f; reg0
= (reg0
<< reg1
) | (reg0
>>> (32 - reg1
)); break;
533 case ROR_O8
: reg1
&= 0x7; reg0
= (reg0
>>> reg1
) | (reg0
<< (8 - reg1
)); break;
534 case ROR_O16
: reg1
&= 0xf; reg0
= (reg0
>>> reg1
) | (reg0
<< (16 - reg1
)); break;
535 case ROR_O32
: reg1
&= 0x1f; reg0
= (reg0
>>> reg1
) | (reg0
<< (32 - reg1
)); break;
537 case RCL_O8
: reg1
&= 0x1f; reg1
%= 9; reg0
|= (cpu
.getCarryFlag() ?
0x100 : 0);
538 reg0
= (reg0
<< reg1
) | (reg0
>>> (9 - reg1
)); break;
539 case RCL_O16
: reg1
&= 0x1f; reg1
%= 17; reg0
|= (cpu
.getCarryFlag() ?
0x10000 : 0);
540 reg0
= (reg0
<< reg1
) | (reg0
>>> (17 - reg1
)); break;
541 case RCL_O32
: reg1
&= 0x1f; reg0l
= (0xffffffffl
& reg0
) | (cpu
.getCarryFlag() ?
0x100000000l
: 0);
542 reg0
= (int)(reg0l
= (reg0l
<< reg1
) | (reg0l
>>> (33 - reg1
))); break;
547 reg0
|= (cpu
.getCarryFlag() ?
0x100 : 0);
548 reg2
= (cpu
.getCarryFlag() ^
((reg0
& 0x80) != 0) ?
1 : 0);
549 reg0
= (reg0
>>> reg1
) | (reg0
<< (9 - reg1
));
554 reg2
= (cpu
.getCarryFlag() ^
((reg0
& 0x8000) != 0) ?
1 : 0);
555 reg0
|= (cpu
.getCarryFlag() ?
0x10000 : 0);
556 reg0
= (reg0
>>> reg1
) | (reg0
<< (17 - reg1
));
560 reg0l
= (0xffffffffl
& reg0
) | (cpu
.getCarryFlag() ?
0x100000000L
: 0);
561 reg2
= (cpu
.getCarryFlag() ^
((reg0
& 0x80000000) != 0) ?
1 : 0);
562 reg0
= (int) (reg0l
= (reg0l
>>> reg1
) | (reg0l
<< (33 - reg1
)));
565 case SHR
: reg1
&= 0x1f; reg2
= reg0
; reg0
>>>= reg1
; break;
566 case SAR_O8
: reg1
&= 0x1f; reg2
= reg0
; reg0
= ((byte)reg0
) >> reg1
; break;
567 case SAR_O16
: reg1
&= 0x1f; reg2
= reg0
; reg0
= ((short)reg0
) >> reg1
; break;
568 case SAR_O32
: reg1
&= 0x1f; reg2
= reg0
; reg0
>>= reg1
; break;
575 reg0
= (reg0
<< reg2
) | (reg1
>>> (16 - reg2
));
581 i
= (reg1
& 0xFFFF) | (reg0
<< 16);
582 reg0
= (reg1
<< (reg2
- 16)) | ((reg0
& 0xFFFF) >>> (32 - reg2
));
588 int i
= reg0
; reg2
&= 0x1f;
590 reg0
= (reg0
<< reg2
) | (reg1
>>> (32 - reg2
));
591 reg1
= reg2
; reg2
= i
;
599 reg0
= (reg0
>>> reg2
) | (reg1
<< (16 - reg2
));
605 i
= (reg0
& 0xFFFF) | (reg1
<< 16);
606 reg0
= (reg1
>>> (reg2
- 16)) | (reg0
<< (32 - reg2
));
612 int i
= reg0
; reg2
&= 0x1f;
614 reg0
= (reg0
>>> reg2
) | (reg1
<< (32 - reg2
));
615 reg1
= reg2
; reg2
= i
;
618 case CWD
: if ((cpu
.eax
& 0x8000) == 0) cpu
.edx
&= 0xffff0000; else cpu
.edx
|= 0x0000ffff; break;
619 case CDQ
: if ((cpu
.eax
& 0x80000000) == 0) cpu
.edx
= 0; else cpu
.edx
= -1; break;
621 case AAA
: aaa(); break;
622 case AAD
: aad(reg0
); break;
623 case AAM
: reg0
= aam(reg0
); break;
624 case AAS
: aas(); break;
626 case DAA
: daa(); break;
627 case DAS
: das(); break;
630 short lower
= (short)reg0
;
631 short upper
= (short)(reg0
>> 16);
632 short index
= (short)reg1
;
633 if ((index
< lower
) || (index
> (upper
+ 2)))
634 throw ProcessorException
.BOUND_RANGE
;
637 case LAHF
: lahf(); break;
638 case SAHF
: sahf(); break;
640 case CLC
: cpu
.setCarryFlag(false); break;
641 case STC
: cpu
.setCarryFlag(true); break;
642 case CLI
: cpu
.eflagsInterruptEnable
= cpu
.eflagsInterruptEnableSoon
= false; break;
643 case STI
: cpu
.eflagsInterruptEnable
= cpu
.eflagsInterruptEnableSoon
= true; break;
644 case CLD
: cpu
.eflagsDirection
= false; break;
645 case STD
: cpu
.eflagsDirection
= true; break;
646 case CMC
: cpu
.setCarryFlag(cpu
.getCarryFlag() ^
true); break;
648 case CALL_O16
: call_o16_a16((short)reg0
); break;
649 case CALL_O32
: call_o32_a16(reg0
); break;
651 case RET_O16
: ret_o16_a16(); break;
652 case RET_O32
: ret_o32_a16(); break;
654 case RET_IW_O16
: ret_iw_o16_a16((short)reg0
); break;
656 case RET_FAR_O16
: ret_far_o16_a16(); break;
657 case RET_FAR_IW_O16
: ret_far_iw_o16_a16((short)reg0
); break;
658 case ENTER_O16
: enter_o16_a16(reg0
, reg1
); break;
659 case LEAVE_O16
: leave_o16_a16(); break;
661 case PUSH_O16
: push_o16((short)reg0
); break;
662 case PUSH_O32
: push_o32(reg0
); break;
664 case PUSHF_O16
: push_o16((short)reg0
); break;
665 case PUSHF_O32
: push_o32(~
0x30000 & reg0
); break;
670 if (microcodes
[position
] == STORE0_SS
)
671 cpu
.eflagsInterruptEnable
= false;
672 reg0
= 0xffff & cpu
.ss
.getWord(cpu
.esp
);
674 reg1
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 2) & 0xffff);
675 if (microcodes
[position
] == STORE0_SS
)
676 cpu
.eflagsInterruptEnable
= false;
677 reg0
= 0xffff & cpu
.ss
.getWord(0xffff & cpu
.esp
);
684 if (microcodes
[position
] == STORE0_SS
)
685 cpu
.eflagsInterruptEnable
= false;
686 reg0
= cpu
.ss
.getDoubleWord(cpu
.esp
);
688 reg1
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 4) & 0xffff);
689 if (microcodes
[position
] == STORE0_SS
)
690 cpu
.eflagsInterruptEnable
= false;
691 reg0
= cpu
.ss
.getDoubleWord(0xffff & cpu
.esp
);
697 reg0
= 0xffff & cpu
.ss
.getWord(cpu
.esp
);
698 cpu
.esp
= cpu
.esp
+ 2;
700 reg0
= 0xffff & cpu
.ss
.getWord(cpu
.esp
& 0xffff);
701 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 2) & 0xffff);
707 reg0
= (cpu
.getEFlags() & 0x20000) | (cpu
.ss
.getDoubleWord(cpu
.esp
) & ~
0x1a0000);
708 cpu
.esp
= cpu
.esp
+ 4;
710 reg0
= (cpu
.getEFlags() & 0x20000) | (cpu
.ss
.getDoubleWord(cpu
.esp
& 0xffff) & ~
0x1a0000);
711 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 4) & 0xffff);
715 case PUSHA
: pusha(); break;
716 case PUSHAD
: pushad(); break;
718 case POPA
: popa(); break;
719 case POPAD
: popad(); break;
721 case SIGN_EXTEND_8_16
: reg0
= 0xffff & ((byte)reg0
); break;
722 case SIGN_EXTEND_8_32
: reg0
= (byte)reg0
; break;
723 case SIGN_EXTEND_16_32
: reg0
= (short)reg0
; break;
725 case CMPSB_A16
: cmpsb_a16(seg0
); break;
726 case CMPSW_A16
: cmpsw_a16(seg0
); break;
727 case CMPSD_A16
: cmpsd_a16(seg0
); break;
728 case REPE_CMPSB_A16
: repe_cmpsb_a16(seg0
); break;
729 case REPE_CMPSW_A16
: repe_cmpsw_a16(seg0
); break;
730 case REPE_CMPSD_A16
: repe_cmpsd_a16(seg0
); break;
732 case INSB_A16
: insb_a16(reg0
); break;
733 case INSW_A16
: insw_a16(reg0
); break;
734 case INSD_A16
: insd_a16(reg0
); break;
735 case REP_INSB_A16
: rep_insb_a16(reg0
); break;
736 case REP_INSW_A16
: rep_insw_a16(reg0
); break;
737 case REP_INSD_A16
: rep_insd_a16(reg0
); break;
739 case LODSB_A16
: lodsb_a16(seg0
); break;
740 case LODSW_A16
: lodsw_a16(seg0
); break;
741 case LODSD_A16
: lodsd_a16(seg0
); break;
742 case REP_LODSB_A16
: rep_lodsb_a16(seg0
); break;
743 case REP_LODSW_A16
: rep_lodsw_a16(seg0
); break;
744 case REP_LODSD_A16
: rep_lodsd_a16(seg0
); break;
745 case LODSB_A32
: lodsb_a32(seg0
); break;
746 case LODSW_A32
: lodsw_a32(seg0
); break;
747 case LODSD_A32
: lodsd_a32(seg0
); break;
748 case REP_LODSB_A32
: rep_lodsb_a32(seg0
); break;
749 case REP_LODSW_A32
: rep_lodsw_a32(seg0
); break;
750 case REP_LODSD_A32
: rep_lodsd_a32(seg0
); break;
752 case MOVSB_A16
: movsb_a16(seg0
); break;
753 case MOVSW_A16
: movsw_a16(seg0
); break;
754 case MOVSD_A16
: movsd_a16(seg0
); break;
755 case REP_MOVSB_A16
: rep_movsb_a16(seg0
); break;
756 case REP_MOVSW_A16
: rep_movsw_a16(seg0
); break;
757 case REP_MOVSD_A16
: rep_movsd_a16(seg0
); break;
758 case MOVSB_A32
: movsb_a32(seg0
); break;
759 case MOVSW_A32
: movsw_a32(seg0
); break;
760 case MOVSD_A32
: movsd_a32(seg0
); break;
761 case REP_MOVSB_A32
: rep_movsb_a32(seg0
); break;
762 case REP_MOVSW_A32
: rep_movsw_a32(seg0
); break;
763 case REP_MOVSD_A32
: rep_movsd_a32(seg0
); break;
765 case OUTSB_A16
: outsb_a16(reg0
, seg0
); break;
766 case OUTSW_A16
: outsw_a16(reg0
, seg0
); break;
767 case OUTSD_A16
: outsd_a16(reg0
, seg0
); break;
768 case REP_OUTSB_A16
: rep_outsb_a16(reg0
, seg0
); break;
769 case REP_OUTSW_A16
: rep_outsw_a16(reg0
, seg0
); break;
770 case REP_OUTSD_A16
: rep_outsd_a16(reg0
, seg0
); break;
772 case SCASB_A16
: scasb_a16(reg0
); break;
773 case SCASW_A16
: scasw_a16(reg0
); break;
774 case SCASD_A16
: scasd_a16(reg0
); break;
775 case REPE_SCASB_A16
: repe_scasb_a16(reg0
); break;
776 case REPE_SCASW_A16
: repe_scasw_a16(reg0
); break;
777 case REPE_SCASD_A16
: repe_scasd_a16(reg0
); break;
778 case REPNE_SCASB_A16
: repne_scasb_a16(reg0
); break;
779 case REPNE_SCASW_A16
: repne_scasw_a16(reg0
); break;
780 case REPNE_SCASD_A16
: repne_scasd_a16(reg0
); break;
782 case STOSB_A16
: stosb_a16(reg0
); break;
783 case STOSW_A16
: stosw_a16(reg0
); break;
784 case STOSD_A16
: stosd_a16(reg0
); break;
785 case REP_STOSB_A16
: rep_stosb_a16(reg0
); break;
786 case REP_STOSW_A16
: rep_stosw_a16(reg0
); break;
787 case REP_STOSD_A16
: rep_stosd_a16(reg0
); break;
788 case STOSB_A32
: stosb_a32(reg0
); break;
789 case STOSW_A32
: stosw_a32(reg0
); break;
790 case STOSD_A32
: stosd_a32(reg0
); break;
791 case REP_STOSB_A32
: rep_stosb_a32(reg0
); break;
792 case REP_STOSW_A32
: rep_stosw_a32(reg0
); break;
793 case REP_STOSD_A32
: rep_stosd_a32(reg0
); break;
795 case LOOP_ECX
: cpu
.ecx
--; if (cpu
.ecx
!= 0) jump_o8((byte)reg0
); break;
796 case LOOP_CX
: cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | ((cpu
.ecx
- 1) & 0xffff); if ((0xffff & cpu
.ecx
) != 0) jump_o8((byte)reg0
); break;
797 case LOOPZ_ECX
: cpu
.ecx
--; if ((cpu
.ecx
!= 0) && cpu
.getZeroFlag()) jump_o8((byte)reg0
); break;
798 case LOOPZ_CX
: cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | ((cpu
.ecx
- 1) & 0xffff); if (((0xffff & cpu
.ecx
) != 0) && cpu
.getZeroFlag()) jump_o8((byte)reg0
); break;
799 case LOOPNZ_ECX
: cpu
.ecx
--; if ((cpu
.ecx
!= 0) && !cpu
.getZeroFlag()) jump_o8((byte)reg0
); break;
800 case LOOPNZ_CX
: cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | ((cpu
.ecx
- 1) & 0xffff); if (((0xffff & cpu
.ecx
) != 0) && !cpu
.getZeroFlag()) jump_o8((byte)reg0
); break;
802 case JO_O8
: jo_o8((byte)reg0
); break;
803 case JNO_O8
: jno_o8((byte)reg0
); break;
804 case JC_O8
: jc_o8((byte)reg0
); break;
805 case JNC_O8
: jnc_o8((byte)reg0
); break;
806 case JZ_O8
: jz_o8((byte)reg0
); break;
807 case JNZ_O8
: jnz_o8((byte)reg0
); break;
808 case JNA_O8
: jna_o8((byte)reg0
); break;
809 case JA_O8
: ja_o8((byte)reg0
); break;
810 case JS_O8
: js_o8((byte)reg0
); break;
811 case JNS_O8
: jns_o8((byte)reg0
); break;
812 case JP_O8
: jp_o8((byte)reg0
); break;
813 case JNP_O8
: jnp_o8((byte)reg0
); break;
814 case JL_O8
: jl_o8((byte)reg0
); break;
815 case JNL_O8
: jnl_o8((byte)reg0
); break;
816 case JNG_O8
: jng_o8((byte)reg0
); break;
817 case JG_O8
: jg_o8((byte)reg0
); break;
819 case JO_O16
: jo_o16((short)reg0
); break;
820 case JNO_O16
: jno_o16((short)reg0
); break;
821 case JC_O16
: jc_o16((short)reg0
); break;
822 case JNC_O16
: jnc_o16((short)reg0
); break;
823 case JZ_O16
: jz_o16((short)reg0
); break;
824 case JNZ_O16
: jnz_o16((short)reg0
); break;
825 case JNA_O16
: jna_o16((short)reg0
); break;
826 case JA_O16
: ja_o16((short)reg0
); break;
827 case JS_O16
: js_o16((short)reg0
); break;
828 case JNS_O16
: jns_o16((short)reg0
); break;
829 case JP_O16
: jp_o16((short)reg0
); break;
830 case JNP_O16
: jnp_o16((short)reg0
); break;
831 case JL_O16
: jl_o16((short)reg0
); break;
832 case JNL_O16
: jnl_o16((short)reg0
); break;
833 case JNG_O16
: jng_o16((short)reg0
); break;
834 case JG_O16
: jg_o16((short)reg0
); break;
836 case JO_O32
: jo_o32(reg0
); break;
837 case JNO_O32
: jno_o32(reg0
); break;
838 case JC_O32
: jc_o32(reg0
); break;
839 case JNC_O32
: jnc_o32(reg0
); break;
840 case JZ_O32
: jz_o32(reg0
); break;
841 case JNZ_O32
: jnz_o32(reg0
); break;
842 case JNA_O32
: jna_o32(reg0
); break;
843 case JA_O32
: ja_o32(reg0
); break;
844 case JS_O32
: js_o32(reg0
); break;
845 case JNS_O32
: jns_o32(reg0
); break;
846 case JP_O32
: jp_o32(reg0
); break;
847 case JNP_O32
: jnp_o32(reg0
); break;
848 case JL_O32
: jl_o32(reg0
); break;
849 case JNL_O32
: jnl_o32(reg0
); break;
850 case JNG_O32
: jng_o32(reg0
); break;
851 case JG_O32
: jg_o32(reg0
); break;
853 case JCXZ
: jcxz((byte)reg0
); break;
854 case JECXZ
: jecxz((byte)reg0
); break;
856 case INC
: reg0
++; break;
857 case DEC
: reg0
--; break;
859 case HALT
: cpu
.waitForInterrupt(); break;
861 case RDTSC
: long tsc
= cpu
.getClockCount(); reg0
= (int)tsc
; reg1
= (int)(tsc
>>> 32); break;
862 case WRMSR
: cpu
.setMSR(reg0
, (reg2
& 0xffffffffl
) | ((reg1
& 0xffffffffl
) << 32)); break;
863 case RDMSR
: long msr
= cpu
.getMSR(reg0
); reg0
= (int)msr
; reg1
= (int)(msr
>>> 32); break;
865 case SETO
: reg0
= cpu
.getOverflowFlag() ?
1 : 0; break;
866 case SETNO
: reg0
= cpu
.getOverflowFlag() ?
0 : 1; break;
867 case SETC
: reg0
= cpu
.getCarryFlag() ?
1 : 0; break;
868 case SETNC
: reg0
= cpu
.getCarryFlag() ?
0 : 1; break;
869 case SETZ
: reg0
= cpu
.getZeroFlag() ?
1 : 0; break;
870 case SETNZ
: reg0
= cpu
.getZeroFlag() ?
0 : 1; break;
871 case SETNA
: reg0
= cpu
.getCarryFlag() || cpu
.getZeroFlag() ?
1 : 0; break;
872 case SETA
: reg0
= cpu
.getCarryFlag() || cpu
.getZeroFlag() ?
0 : 1; break;
873 case SETS
: reg0
= cpu
.getSignFlag() ?
1 : 0; break;
874 case SETNS
: reg0
= cpu
.getSignFlag() ?
0 : 1; break;
875 case SETP
: reg0
= cpu
.getParityFlag() ?
1 : 0; break;
876 case SETNP
: reg0
= cpu
.getParityFlag() ?
0 : 1; break;
877 case SETL
: reg0
= cpu
.getSignFlag() != cpu
.getOverflowFlag() ?
1 : 0; break;
878 case SETNL
: reg0
= cpu
.getSignFlag() != cpu
.getOverflowFlag() ?
0 : 1; break;
879 case SETNG
: reg0
= cpu
.getZeroFlag() || (cpu
.getSignFlag() != cpu
.getOverflowFlag()) ?
1 : 0; break;
880 case SETG
: reg0
= cpu
.getZeroFlag() || (cpu
.getSignFlag() != cpu
.getOverflowFlag()) ?
0 : 1; break;
882 case SALC
: reg0
= cpu
.getCarryFlag() ?
-1 : 0; break;
883 case CPL_CHECK
: break;
885 case SMSW
: reg0
= cpu
.getCR0() & 0xffff; break;
886 case LMSW
: cpu
.setCR0((cpu
.getCR0() & ~
0xf) | (reg0
& 0xf)); break;
888 case LGDT_O16
: cpu
.gdtr
= cpu
.createDescriptorTableSegment(reg1
& 0x00ffffff, reg0
); break;
889 case LGDT_O32
: cpu
.gdtr
= cpu
.createDescriptorTableSegment(reg1
, reg0
); break;
890 case LIDT_O16
: cpu
.idtr
= cpu
.createDescriptorTableSegment(reg1
& 0x00ffffff, reg0
); break;
891 case LIDT_O32
: cpu
.idtr
= cpu
.createDescriptorTableSegment(reg1
, reg0
); break;
893 case SGDT_O16
: reg0
= cpu
.gdtr
.getLimit(); reg1
= 0x00ffffff & cpu
.gdtr
.getBase(); break;
894 case SGDT_O32
: reg0
= cpu
.gdtr
.getLimit(); reg1
= cpu
.gdtr
.getBase(); break;
895 case SIDT_O16
: reg0
= cpu
.idtr
.getLimit(); reg1
= 0x00ffffff & cpu
.idtr
.getBase(); break;
896 case SIDT_O32
: reg0
= cpu
.idtr
.getLimit(); reg1
= cpu
.idtr
.getBase(); break;
898 case CPUID
: cpuid(); break;
900 case CLTS
: cpu
.setCR0(cpu
.getCR0() & ~
0x8); break;
902 case BITWISE_FLAGS_O8
: bitwise_flags((byte)reg0
); break;
903 case BITWISE_FLAGS_O16
: bitwise_flags((short)reg0
); break;
904 case BITWISE_FLAGS_O32
: bitwise_flags(reg0
); break;
906 case SUB_O8_FLAGS
: sub_o8_flags(reg0
, reg2
, reg1
); break;
907 case SUB_O16_FLAGS
: sub_o16_flags(reg0
, reg2
, reg1
); break;
908 case SUB_O32_FLAGS
: sub_o32_flags(reg0l
, reg2
, reg1
); break;
910 case REP_SUB_O8_FLAGS
: rep_sub_o8_flags(reg0
, reg2
, reg1
); break;
911 case REP_SUB_O16_FLAGS
: rep_sub_o16_flags(reg0
, reg2
, reg1
); break;
912 case REP_SUB_O32_FLAGS
: rep_sub_o32_flags(reg0
, reg2
, reg1
); break;
914 case ADD_O8_FLAGS
: add_o8_flags(reg0
, reg2
, reg1
); break;
915 case ADD_O16_FLAGS
: add_o16_flags(reg0
, reg2
, reg1
); break;
916 case ADD_O32_FLAGS
: add_o32_flags(reg0l
, reg2
, reg1
); break;
918 case ADC_O8_FLAGS
: adc_o8_flags(reg0
, reg2
, reg1
); break;
919 case ADC_O16_FLAGS
: adc_o16_flags(reg0
, reg2
, reg1
); break;
920 case ADC_O32_FLAGS
: adc_o32_flags(reg0l
, reg2
, reg1
); break;
922 case SBB_O8_FLAGS
: sbb_o8_flags(reg0
, reg2
, reg1
); break;
923 case SBB_O16_FLAGS
: sbb_o16_flags(reg0
, reg2
, reg1
); break;
924 case SBB_O32_FLAGS
: sbb_o32_flags(reg0l
, reg2
, reg1
); break;
926 case INC_O8_FLAGS
: inc_flags((byte)reg0
); break;
927 case INC_O16_FLAGS
: inc_flags((short)reg0
); break;
928 case INC_O32_FLAGS
: inc_flags(reg0
); break;
930 case DEC_O8_FLAGS
: dec_flags((byte)reg0
); break;
931 case DEC_O16_FLAGS
: dec_flags((short)reg0
); break;
932 case DEC_O32_FLAGS
: dec_flags(reg0
); break;
934 case SHL_O8_FLAGS
: shl_flags((byte)reg0
, (byte)reg2
, reg1
); break;
935 case SHL_O32_FLAGS
: shl_flags(reg0
, reg2
, reg1
); break;
937 case SHR_O8_FLAGS
: shr_flags((byte)reg0
, reg2
, reg1
); break;
938 case SHR_O16_FLAGS
: shr_flags((short)reg0
, reg2
, reg1
); break;
939 case SHR_O32_FLAGS
: shr_flags(reg0
, reg2
, reg1
); break;
941 case SAR_O8_FLAGS
: sar_flags((byte)reg0
, (byte)reg2
, reg1
); break;
942 case SAR_O16_FLAGS
: sar_flags((short)reg0
, (short)reg2
, reg1
); break;
943 case SAR_O32_FLAGS
: sar_flags(reg0
, reg2
, reg1
); break;
945 case RCL_O8_FLAGS
: rcl_o8_flags(reg0
, reg1
); break;
946 case RCL_O16_FLAGS
: rcl_o16_flags(reg0
, reg1
); break;
947 case RCL_O32_FLAGS
: rcl_o32_flags(reg0l
, reg1
); break;
949 case RCR_O8_FLAGS
: rcr_o8_flags(reg0
, reg1
, reg2
); break;
950 case RCR_O16_FLAGS
: rcr_o16_flags(reg0
, reg1
, reg2
); break;
951 case RCR_O32_FLAGS
: rcr_o32_flags(reg0l
, reg1
, reg2
); break;
953 case ROL_O8_FLAGS
: rol_flags((byte)reg0
, reg1
); break;
954 case ROL_O16_FLAGS
: rol_flags((short)reg0
, reg1
); break;
955 case ROL_O32_FLAGS
: rol_flags(reg0
, reg1
); break;
957 case ROR_O8_FLAGS
: ror_flags((byte)reg0
, reg1
); break;
958 case ROR_O16_FLAGS
: ror_flags((short)reg0
, reg1
); break;
959 case ROR_O32_FLAGS
: ror_flags(reg0
, reg1
); break;
961 case NEG_O8_FLAGS
: neg_flags((byte)reg0
); break;
962 case NEG_O16_FLAGS
: neg_flags((short)reg0
); break;
963 case NEG_O32_FLAGS
: neg_flags(reg0
); break;
966 if(!Misc
.isFPUOp(microcodes
[position
- 1])) {
967 System
.err
.println("Critical error: Unknown uCode " + microcodes
[position
- 1] + ".");
968 throw new IllegalStateException("Unknown uCode R" + microcodes
[position
- 1]);
971 cpu
.useFPU(microcodes
[position
- 1] == FWAIT
);
972 int x
= fpu
.doFPUOp(microcodes
[position
- 1], microcodes
[position
], seg0
, addr0
, reg0
, reg1
, reg2
,
974 //Handle buffer updates.
975 if((x
& 1) != 0) reg0
= fpu
.getReg0();
976 if((x
& 2) != 0) reg1
= fpu
.getReg1();
977 if((x
& 4) != 0) reg2
= fpu
.getReg2();
978 if((x
& 8) != 0) reg0l
= fpu
.getReg0l();
979 if((x
& 16) != 0) position
++;
983 //copy local variables back to instance storage
985 transferAddr0
= addr0
;
989 transferReg0l
= reg0l
;
990 transferEipUpdated
= eipUpdated
;
991 transferPosition
= position
;
995 public int execute(Processor cpu
)
1000 if (opcodeCounter
!= null)
1001 opcodeCounter
.addBlock(getMicrocodes());
1003 cachedSSSize
= false;
1005 cachedSSSize
= cpu
.ss
.getDefaultSizeFlag();
1007 Segment seg0
= null;
1009 int reg0
= 0, reg1
= 0, reg2
= 0;
1013 boolean eipUpdated
= false;
1017 cpu
.eflagsLastAborted
= false;
1019 fpu
.setProtectedMode(false);
1023 while (position
< microcodes
.length
) {
1024 if (uCodeXferLoaded
)
1026 uCodeXferLoaded
= false;
1027 reg0
= uCodeXferReg0
;
1028 reg1
= uCodeXferReg1
;
1029 reg2
= uCodeXferReg2
;
1031 switch (microcodes
[position
++]) {
1032 case MEM_RESET
: addr0
= 0; seg0
= null; break; //4653406
1033 case ADDR_MASK16
: addr0
&= 0xffff; break; //4653406
1034 case EIP_UPDATE
: if (!eipUpdated
) { //4253320
1036 cpu
.eip
+= cumulativeX86Length
[position
- 1];
1038 case ADDR_IB
: addr0
+= ((byte)microcodes
[position
++]); break; //3832219
1039 case PUSH_O16
: push_o16((short)reg0
); break; //3221577
1040 case LOAD_SEG_SS
: seg0
= cpu
.ss
; break; //2739696
1041 case LOAD0_AX
: reg0
= cpu
.eax
& 0xffff; break; //2718333
1042 case ADDR_BP
: addr0
+= ((short)cpu
.ebp
); break; //2701629
1043 case LOAD0_IB
: reg0
= microcodes
[position
++] & 0xff; break; //2567113
1044 case LOAD0_MEM_WORD
: reg0
= 0xffff & seg0
.getWord(addr0
); break; //2352051
1046 case STORE1_ESP
: cpu
.esp
= reg1
; break; //2252894
1047 case POP_O16
: { //2251454
1048 if (cpu
.ss
.getDefaultSizeFlag()) {
1050 if (microcodes
[position
] == STORE0_SS
)
1051 cpu
.eflagsInterruptEnable
= false;
1052 reg0
= 0xffff & cpu
.ss
.getWord(cpu
.esp
);
1054 reg1
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 2) & 0xffff);
1055 if (microcodes
[position
] == STORE0_SS
)
1056 cpu
.eflagsInterruptEnable
= false;
1057 reg0
= 0xffff & cpu
.ss
.getWord(0xffff & cpu
.esp
);
1060 case STORE0_AX
: cpu
.eax
= (cpu
.eax
& ~
0xffff) | (reg0
& 0xffff); break; //2211780
1061 case LOAD0_IW
: reg0
= microcodes
[position
++] & 0xffff; break; //1748064
1062 case LOAD_SEG_DS
: seg0
= cpu
.ds
; break; //1556141
1063 case STORE0_BX
: cpu
.ebx
= (cpu
.ebx
& ~
0xffff) | (reg0
& 0xffff); break; //1295862
1064 case SUB
: reg2
= reg0
; reg0
= reg2
- reg1
; break; //1166414
1065 case STORE0_BP
: cpu
.ebp
= (cpu
.ebp
& ~
0xffff) | (reg0
& 0xffff); break; //1077742
1066 case ADDR_BX
: addr0
+= ((short)cpu
.ebx
); break; //1018423
1067 case LOAD0_SP
: reg0
= cpu
.esp
& 0xffff; break; //1017910
1069 case ADD
: reg2
= reg0
; reg0
= reg2
+ reg1
; break; //1004121
1070 case STORE0_MEM_WORD
: seg0
.setWord(addr0
, (short)reg0
); break; //896323
1071 case LOAD0_MEM_BYTE
: reg0
= 0xff & seg0
.getByte(addr0
); break; //839821
1072 case JNZ_O8
: jnz_o8((byte)reg0
); break; //837018
1073 case STORE0_AL
: cpu
.eax
= (cpu
.eax
& ~
0xff) | (reg0
& 0xff); break; //814558
1074 case LOAD0_BX
: reg0
= cpu
.ebx
& 0xffff; break; //813659
1075 case LOAD1_IB
: reg1
= microcodes
[position
++] & 0xff; break; //809491
1076 case LOAD1_IW
: reg1
= microcodes
[position
++] & 0xffff; break; //805651
1077 case CALL_O16
: call_o16_a16((short)reg0
); break; //791837
1078 case STORE0_CX
: cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (reg0
& 0xffff); break; //775713
1080 case LOAD0_CX
: reg0
= cpu
.ecx
& 0xffff; break; //773832
1081 case LOAD0_BP
: reg0
= cpu
.ebp
& 0xffff; break; //763561
1082 case RET_O16
: ret_o16_a16(); break; //720729
1083 case STORE0_SP
: cpu
.esp
= (cpu
.esp
& ~
0xffff) | (reg0
& 0xffff); break; //681228
1084 case LOAD0_AL
: reg0
= cpu
.eax
& 0xff; break; //680163
1085 case ADD_O16_FLAGS
: add_o16_flags(reg0
, reg2
, reg1
); break; //667848
1086 case SUB_O16_FLAGS
: sub_o16_flags(reg0
, reg2
, reg1
); break; //664323
1087 case STORE0_DS
: cpu
.ds
.setSelector(0xffff & reg0
); break; //654678
1088 case LOAD0_DX
: reg0
= cpu
.edx
& 0xffff; break; //620350
1089 case BITWISE_FLAGS_O8
: bitwise_flags((byte)reg0
); break; //606068
1091 case STORE0_SI
: cpu
.esi
= (cpu
.esi
& ~
0xffff) | (reg0
& 0xffff); break; //601955
1092 case XOR
: reg0 ^
= reg1
; break; //552649
1093 case STORE0_DX
: cpu
.edx
= (cpu
.edx
& ~
0xffff) | (reg0
& 0xffff); break; //516299
1094 case ADDR_SI
: addr0
+= ((short)cpu
.esi
); break; //514379
1095 case SUB_O8_FLAGS
: sub_o8_flags(reg0
, reg2
, reg1
); break; //500672
1096 case JZ_O8
: jz_o8((byte)reg0
); break; //499451
1097 case LOAD0_AH
: reg0
= (cpu
.eax
>> 8) & 0xff; break; //497132
1098 case STORE0_DI
: cpu
.edi
= (cpu
.edi
& ~
0xffff) | (reg0
& 0xffff); break; //490840
1099 case LOAD0_SI
: reg0
= cpu
.esi
& 0xffff; break; //473018
1100 case ADDR_IW
: addr0
+= ((short)microcodes
[position
++]); break; //449628
1102 case BITWISE_FLAGS_O16
: bitwise_flags((short)reg0
); break; //426086
1103 case LOAD0_DS
: reg0
= 0xffff & cpu
.ds
.getSelector(); break; //425449
1104 case LOAD1_MEM_WORD
: reg1
= 0xffff & seg0
.getWord(addr0
); break; //417691
1105 case LOAD0_DI
: reg0
= cpu
.edi
& 0xffff; break; //402655
1106 case INC
: reg0
++; break; //377084
1107 case STORE0_ES
: cpu
.es
.setSelector(0xffff & reg0
); break; //374908
1108 case INC_O16_FLAGS
: inc_flags((short)reg0
); break; //369608
1109 case AND
: reg0
&= reg1
; break; //364104
1110 case STORE0_BH
: cpu
.ebx
= (cpu
.ebx
& ~
0xff00) | ((reg0
<< 8) & 0xff00); break; //363053
1111 case LOAD_SEG_ES
: seg0
= cpu
.es
; break; //345778
1113 case STORE0_AH
: cpu
.eax
= (cpu
.eax
& ~
0xff00) | ((reg0
<< 8) & 0xff00); break; //341158
1114 case LOAD1_CX
: reg1
= cpu
.ecx
& 0xffff; break; //338002
1115 case ADD_O8_FLAGS
: add_o8_flags(reg0
, reg2
, reg1
); break; //336258
1116 case LOAD1_AX
: reg1
= cpu
.eax
& 0xffff; break; //330347
1117 case LOAD1_BH
: reg1
= (cpu
.ebx
>> 8) & 0xff; break; //322337
1118 case LOAD0_BH
: reg0
= (cpu
.ebx
>> 8) & 0xff; break; //295205
1119 case STORE0_MEM_BYTE
: seg0
.setByte(addr0
, (byte)reg0
); break; //259410
1120 case LOAD0_ES
: reg0
= 0xffff & cpu
.es
.getSelector(); break; //239972
1121 case LOAD1_AH
: reg1
= (cpu
.eax
>> 8) & 0xff; break; //233962
1122 case ADC
: reg2
= reg0
; reg0
= reg2
+ reg1
+ (cpu
.getCarryFlag() ?
1 : 0); break; //219410
1124 case JUMP_O8
: jump_o8((byte)reg0
); break; //189393
1125 case JNC_O8
: jnc_o8((byte)reg0
); break; //183798
1126 case JC_O8
: jc_o8((byte)reg0
); break; //174366
1127 case LOAD1_AL
: reg1
= cpu
.eax
& 0xff; break; //169225
1128 case ADC_O16_FLAGS
: adc_o16_flags(reg0
, reg2
, reg1
); break; //164196
1129 case JUMP_O16
: jump_o16((short)reg0
); break; //159616
1130 case LOAD_SEG_CS
: seg0
= cpu
.cs
; break; //151531
1131 case DEC
: reg0
--; break; //150476
1132 case DEC_O16_FLAGS
: dec_flags((short)reg0
); break; //143631
1133 case LOAD0_ADDR
: reg0
= addr0
; break; //131311
1135 case SHL
: reg1
&= 0x1f; reg2
= reg0
; reg0
<<= reg1
; break;
1136 case STORE0_BL
: cpu
.ebx
= (cpu
.ebx
& ~
0xff) | (reg0
& 0xff); break;
1137 case SHL_O16_FLAGS
: shl_flags((short)reg0
, (short)reg2
, reg1
); break;
1138 case LOAD1_BX
: reg1
= cpu
.ebx
& 0xffff; break;
1139 case OR
: reg0
|= reg1
; break;
1140 case STORE1_ES
: cpu
.es
.setSelector(0xffff & reg1
); break;
1141 case STORE1_AX
: cpu
.eax
= (cpu
.eax
& ~
0xffff) | (reg1
& 0xffff); break;
1142 case LOAD1_DI
: reg1
= cpu
.edi
& 0xffff; break;
1143 case LOAD1_MEM_BYTE
: reg1
= 0xff & seg0
.getByte(addr0
); break;
1144 case JCXZ
: jcxz((byte)reg0
); break;
1146 case LOAD1_SI
: reg1
= cpu
.esi
& 0xffff; break;
1147 case STORE1_DS
: cpu
.ds
.setSelector(0xffff & reg1
); break;
1148 case LOAD1_CL
: reg1
= cpu
.ecx
& 0xff; break;
1149 case JUMP_ABS_O16
: cpu
.eip
= reg0
; break;
1150 case STORE0_CL
: cpu
.ecx
= (cpu
.ecx
& ~
0xff) | (reg0
& 0xff); break;
1151 case ADDR_DI
: addr0
+= ((short)cpu
.edi
); break;
1152 case SHR
: reg2
= reg0
; reg0
>>>= reg1
; break;
1153 case SHR_O16_FLAGS
: shr_flags((short)reg0
, reg2
, reg1
); break;
1154 case JA_O8
: ja_o8((byte)reg0
); break;
1155 case JNA_O8
: jna_o8((byte)reg0
); break;
1156 case INSTRUCTION_START
:
1158 if(cpu
.eflagsMachineHalt
) throw ProcessorException
.TRACESTOP
;
1159 //Handle special case of continuing WAIT after abort.
1160 if(!cpu
.eflagsWaiting
)
1161 cpu
.instructionExecuted();
1166 //copy local variables to instance storage
1167 transferSeg0
= seg0
;
1168 transferAddr0
= addr0
;
1169 transferReg0
= reg0
;
1170 transferReg1
= reg1
;
1171 transferReg2
= reg2
;
1172 transferReg0l
= reg0l
;
1173 transferEipUpdated
= eipUpdated
;
1174 transferPosition
= position
- 1;
1178 seg0
= transferSeg0
;
1179 addr0
= transferAddr0
;
1180 reg0
= transferReg0
;
1181 reg1
= transferReg1
;
1182 reg2
= transferReg2
;
1183 reg0l
= transferReg0l
;
1184 eipUpdated
= transferEipUpdated
;
1185 position
= transferPosition
;
1191 catch (ProcessorException e
)
1193 int nextPosition
= position
- 1; //this makes position point at the microcode that just barfed
1196 cpu
.eip
-= cumulativeX86Length
[nextPosition
]; // undo the eipUpdate
1198 if (!e
.pointsToSelf()) {
1199 cpu
.eip
+= cumulativeX86Length
[nextPosition
];
1201 for (int selfPosition
= nextPosition
; selfPosition
>= 0; selfPosition
--) {
1202 if (cumulativeX86Length
[selfPosition
] != cumulativeX86Length
[nextPosition
]) {
1203 cpu
.eip
+= cumulativeX86Length
[selfPosition
];
1209 if(e
.getType() != ProcessorException
.Type
.PAGE_FAULT
&& e
.getType() != ProcessorException
.Type
.TRACESTOP
&& e
.getType() != ProcessorException
.Type
.NO_FPU
)
1210 System
.err
.println("Emulated: processor exception at 0x" +
1211 Integer
.toHexString(cpu
.cs
.translateAddressRead(cpu
.eip
)) + ":" + e
);
1212 if(e
.getType() != ProcessorException
.Type
.TRACESTOP
) //Swallow trace stops!
1213 cpu
.handleRealModeException(e
);
1215 cpu
.eflagsLastAborted
= true;
1220 return Math
.max(executeCount
, 0);
1223 private final void jo_o8(byte offset
)
1225 if (cpu
.getOverflowFlag()) jump_o8(offset
);
1228 private final void jno_o8(byte offset
)
1230 if (!cpu
.getOverflowFlag()) jump_o8(offset
);
1233 private final void jc_o8(byte offset
)
1235 if (cpu
.getCarryFlag()) jump_o8(offset
);
1238 private final void jnc_o8(byte offset
)
1240 if (!cpu
.getCarryFlag()) jump_o8(offset
);
1243 private final void jz_o8(byte offset
)
1245 if (cpu
.getZeroFlag()) jump_o8(offset
);
1248 private final void jnz_o8(byte offset
)
1250 if (!cpu
.getZeroFlag()) jump_o8(offset
);
1253 private final void jna_o8(byte offset
)
1255 if (cpu
.getCarryFlag() || cpu
.getZeroFlag()) jump_o8(offset
);
1258 private final void ja_o8(byte offset
)
1260 if ((!cpu
.getCarryFlag()) && (!cpu
.getZeroFlag())) jump_o8(offset
);
1263 private final void js_o8(byte offset
)
1265 if (cpu
.getSignFlag()) jump_o8(offset
);
1268 private final void jns_o8(byte offset
)
1270 if (!cpu
.getSignFlag()) jump_o8(offset
);
1273 private final void jp_o8(byte offset
)
1275 if (cpu
.getParityFlag()) jump_o8(offset
);
1278 private final void jnp_o8(byte offset
)
1280 if (!cpu
.getParityFlag()) jump_o8(offset
);
1283 private final void jl_o8(byte offset
)
1285 if (cpu
.getSignFlag() != cpu
.getOverflowFlag()) jump_o8(offset
);
1288 private final void jnl_o8(byte offset
)
1290 if (cpu
.getSignFlag() == cpu
.getOverflowFlag()) jump_o8(offset
);
1293 private final void jng_o8(byte offset
)
1295 if (cpu
.getZeroFlag() || (cpu
.getSignFlag() != cpu
.getOverflowFlag())) jump_o8(offset
);
1298 private final void jg_o8(byte offset
)
1300 if ((!cpu
.getZeroFlag()) && (cpu
.getSignFlag() == cpu
.getOverflowFlag())) jump_o8(offset
);
1303 private final void jo_o16(short offset
)
1305 if (cpu
.getOverflowFlag()) jump_o16(offset
);
1308 private final void jno_o16(short offset
)
1310 if (!cpu
.getOverflowFlag()) jump_o16(offset
);
1313 private final void jc_o16(short offset
)
1315 if (cpu
.getCarryFlag()) jump_o16(offset
);
1318 private final void jnc_o16(short offset
)
1320 if (!cpu
.getCarryFlag()) jump_o16(offset
);
1323 private final void jz_o16(short offset
)
1325 if (cpu
.getZeroFlag()) jump_o16(offset
);
1328 private final void jnz_o16(short offset
)
1330 if (!cpu
.getZeroFlag()) jump_o16(offset
);
1333 private final void jna_o16(short offset
)
1335 if (cpu
.getCarryFlag() || cpu
.getZeroFlag()) jump_o16(offset
);
1338 private final void ja_o16(short offset
)
1340 if ((!cpu
.getCarryFlag()) && (!cpu
.getZeroFlag())) jump_o16(offset
);
1343 private final void js_o16(short offset
)
1345 if (cpu
.getSignFlag()) jump_o16(offset
);
1348 private final void jns_o16(short offset
)
1350 if (!cpu
.getSignFlag()) jump_o16(offset
);
1353 private final void jp_o16(short offset
)
1355 if (cpu
.getParityFlag()) jump_o16(offset
);
1358 private final void jnp_o16(short offset
)
1360 if (!cpu
.getParityFlag()) jump_o16(offset
);
1363 private final void jl_o16(short offset
)
1365 if (cpu
.getSignFlag() != cpu
.getOverflowFlag()) jump_o16(offset
);
1368 private final void jnl_o16(short offset
)
1370 if (cpu
.getSignFlag() == cpu
.getOverflowFlag()) jump_o16(offset
);
1373 private final void jng_o16(short offset
)
1375 if (cpu
.getZeroFlag() || (cpu
.getSignFlag() != cpu
.getOverflowFlag())) jump_o16(offset
);
1378 private final void jg_o16(short offset
)
1380 if ((!cpu
.getZeroFlag()) && (cpu
.getSignFlag() == cpu
.getOverflowFlag())) jump_o16(offset
);
1383 private final void jo_o32(int offset
)
1385 if (cpu
.getOverflowFlag()) jump_o32(offset
);
1388 private final void jno_o32(int offset
)
1390 if (!cpu
.getOverflowFlag()) jump_o32(offset
);
1393 private final void jc_o32(int offset
)
1395 if (cpu
.getCarryFlag()) jump_o32(offset
);
1398 private final void jnc_o32(int offset
)
1400 if (!cpu
.getCarryFlag()) jump_o32(offset
);
1403 private final void jz_o32(int offset
)
1405 if (cpu
.getZeroFlag()) jump_o32(offset
);
1408 private final void jnz_o32(int offset
)
1410 if (!cpu
.getZeroFlag()) jump_o32(offset
);
1413 private final void jna_o32(int offset
)
1415 if (cpu
.getCarryFlag() || cpu
.getZeroFlag()) jump_o32(offset
);
1418 private final void ja_o32(int offset
)
1420 if ((!cpu
.getCarryFlag()) && (!cpu
.getZeroFlag())) jump_o32(offset
);
1423 private final void js_o32(int offset
)
1425 if (cpu
.getSignFlag()) jump_o32(offset
);
1428 private final void jns_o32(int offset
)
1430 if (!cpu
.getSignFlag()) jump_o32(offset
);
1433 private final void jp_o32(int offset
)
1435 if (cpu
.getParityFlag()) jump_o32(offset
);
1438 private final void jnp_o32(int offset
)
1440 if (!cpu
.getParityFlag()) jump_o32(offset
);
1443 private final void jl_o32(int offset
)
1445 if (cpu
.getSignFlag() != cpu
.getOverflowFlag()) jump_o32(offset
);
1448 private final void jnl_o32(int offset
)
1450 if (cpu
.getSignFlag() == cpu
.getOverflowFlag()) jump_o32(offset
);
1453 private final void jng_o32(int offset
)
1455 if (cpu
.getZeroFlag() || (cpu
.getSignFlag() != cpu
.getOverflowFlag())) jump_o32(offset
);
1458 private final void jg_o32(int offset
)
1460 if ((!cpu
.getZeroFlag()) && (cpu
.getSignFlag() == cpu
.getOverflowFlag())) jump_o32(offset
);
1463 private final void jcxz(byte offset
)
1465 if ((cpu
.ecx
& 0xffff) == 0) jump_o8(offset
);
1468 private final void jecxz(byte offset
)
1470 if (cpu
.ecx
== 0) jump_o8(offset
);
1474 private final void jump_o8(byte offset
)
1477 // check whether eip is outside of 0x0000 and 0xffff
1478 if ((cpu
.eip
& 0xFFFF0000) != 0)
1481 throw ProcessorException
.GENERAL_PROTECTION_0
;
1485 private final void jump_o16(short offset
)
1487 cpu
.eip
= (cpu
.eip
+ offset
) & 0xffff;
1490 private final void jump_o32(int offset
)
1493 if ((cpu
.eip
& 0xFFFF0000) != 0)
1496 throw ProcessorException
.GENERAL_PROTECTION_0
;
1500 private final void call_o16_a16(short target
)
1502 if (((cpu
.esp
& 0xffff) < 2) && ((cpu
.esp
& 0xffff) > 0))
1503 throw ProcessorException
.STACK_SEGMENT_0
;
1505 int offset
= (cpu
.esp
- 2) & 0xffff;
1506 cpu
.ss
.setWord(offset
, (short)cpu
.eip
);
1507 cpu
.esp
= (cpu
.esp
& 0xffff0000) | offset
;
1508 cpu
.eip
= (cpu
.eip
+ target
) & 0xffff;
1511 private final void call_o32_a16(int target
)
1513 if (((cpu
.esp
& 0xffff) < 4) && ((cpu
.esp
& 0xffff) > 0))
1514 throw ProcessorException
.STACK_SEGMENT_0
;
1516 if ((cpu
.eip
+ target
) > 0xffff)
1517 throw ProcessorException
.GENERAL_PROTECTION_0
;
1519 int offset
= (cpu
.esp
- 4) & 0xffff;
1520 cpu
.ss
.setDoubleWord(offset
, cpu
.eip
);
1521 cpu
.esp
= (cpu
.esp
& 0xffff0000) | offset
;
1522 cpu
.eip
= cpu
.eip
+ target
;
1525 private final void ret_o16_a16()
1527 // TODO: supposed to throw SS exception
1528 // "if top 6 bytes of stack not within stack limits"
1529 cpu
.eip
= cpu
.ss
.getWord(cpu
.esp
& 0xffff) & 0xffff;
1530 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 2) & 0xffff);
1533 private final void ret_o32_a16()
1535 // TODO: supposed to throw SS exception
1536 // "if top 6 bytes of stack not within stack limits"
1537 cpu
.eip
= cpu
.ss
.getDoubleWord(cpu
.esp
& 0xffff) & 0xffff;
1538 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 4) & 0xffff);
1541 private final void ret_iw_o16_a16(short data
)
1544 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ data
) & 0xffff);
1547 private final void ret_far_o16_a16()
1549 // TODO: supposed to throw SS exception
1550 // "if top 6 bytes of stack not within stack limits"
1551 cpu
.eip
= cpu
.ss
.getWord(cpu
.esp
& 0xffff) & 0xffff;
1552 cpu
.cs
.setSelector(cpu
.ss
.getWord((cpu
.esp
+ 2) & 0xffff) & 0xffff);
1553 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ 4) & 0xffff);
1556 private final void ret_far_iw_o16_a16(short offset
)
1558 // TODO: supposed to throw SS exception
1559 // "if top 6 bytes of stack not within stack limits"
1561 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
+ offset
) & 0xffff);
1564 private final void enter_o16_a16(int frameSize
, int nestingLevel
)
1568 int tempESP
= cpu
.esp
;
1569 int tempEBP
= cpu
.ebp
;
1571 tempESP
= (tempESP
& ~
0xffff) | ((tempESP
- 2) & 0xffff);
1572 cpu
.ss
.setWord(tempESP
& 0xffff, (short)tempEBP
);
1574 int frameTemp
= tempESP
& 0xffff;
1576 if (nestingLevel
!= 0) {
1577 while (--nestingLevel
!= 0) {
1578 tempEBP
= (tempEBP
& ~
0xffff) | ((tempEBP
- 2) & 0xffff);
1579 tempESP
= (tempESP
& ~
0xffff) | ((tempESP
- 2) & 0xffff);
1580 cpu
.ss
.setWord(tempESP
& 0xffff, cpu
.ss
.getWord(tempEBP
& 0xffff));
1583 tempESP
= (tempESP
& ~
0xffff) | ((tempESP
- 2) & 0xffff);
1584 cpu
.ss
.setWord(tempESP
& 0xffff, (short)frameTemp
);
1587 cpu
.ebp
= (tempEBP
& ~
0xffff) | (frameTemp
& 0xffff);
1588 cpu
.esp
= (tempESP
& ~
0xffff) | ((tempESP
- frameSize
-2*nestingLevel
) & 0xffff);
1591 private final void leave_o16_a16()
1594 cpu
.ss
.checkAddress(cpu
.ebp
& 0xffff);
1595 } catch (ProcessorException e
) {
1596 throw ProcessorException
.STACK_SEGMENT_0
;
1598 int tempESP
= (cpu
.esp
& ~
0xffff) | (cpu
.ebp
& 0xffff);
1599 int tempEBP
= (cpu
.ebp
& ~
0xffff) | (cpu
.ss
.getWord(tempESP
& 0xffff) & 0xffff);
1600 if (((tempESP
& 0xffff) > 0xffff) || ((tempESP
& 0xffff) < 0)) {
1601 System
.err
.println("Emulated: Throwing dodgy leave exception.");
1602 throw ProcessorException
.GENERAL_PROTECTION_0
;
1604 cpu
.esp
= (tempESP
& ~
0xffff) | ((tempESP
+ 2) & 0xffff);
1608 private final void push_o16(short data
)
1611 if ((cpu
.esp
< 2) && (cpu
.esp
> 0))
1612 throw ProcessorException
.STACK_SEGMENT_0
;
1614 int offset
= cpu
.esp
- 2;
1615 cpu
.ss
.setWord(offset
, data
);
1618 if (((cpu
.esp
& 0xffff) < 2) && ((cpu
.esp
& 0xffff) > 0))
1619 throw ProcessorException
.STACK_SEGMENT_0
;
1621 int offset
= (cpu
.esp
- 2) & 0xffff;
1622 cpu
.ss
.setWord(offset
, data
);
1623 cpu
.esp
= (cpu
.esp
& ~
0xffff) | offset
;
1627 private final void push_o32(int data
)
1630 if ((cpu
.esp
< 4) && (cpu
.esp
> 0))
1631 throw ProcessorException
.STACK_SEGMENT_0
;
1633 int offset
= cpu
.esp
- 4;
1634 cpu
.ss
.setDoubleWord(offset
, data
);
1637 if (((cpu
.esp
& 0xffff) < 4) && ((cpu
.esp
& 0xffff) > 0))
1638 throw ProcessorException
.STACK_SEGMENT_0
;
1640 int offset
= (cpu
.esp
- 4) & 0xffff;
1641 cpu
.ss
.setDoubleWord(offset
, data
);
1642 cpu
.esp
= (cpu
.esp
& ~
0xffff) | offset
;
1646 private final void pusha()
1648 int offset
, offmask
;
1651 offmask
= 0xffffffff;
1653 offset
= cpu
.esp
& 0xffff;
1657 //it seems that it checks at every push (we will simulate this)
1658 if ((offset
< 16) && ((offset
& 0x1) == 0x1)) {
1660 System
.err
.println("Emulated: Should shutdown machine (PUSHA with small ESP).");
1661 throw ProcessorException
.GENERAL_PROTECTION_0
;
1667 cpu
.ss
.setWord(offset
, (short) cpu
.eax
);
1669 cpu
.ss
.setWord(offset
, (short) cpu
.ecx
);
1671 cpu
.ss
.setWord(offset
, (short) cpu
.edx
);
1673 cpu
.ss
.setWord(offset
, (short) cpu
.ebx
);
1675 cpu
.ss
.setWord(offset
, (short) temp
);
1677 cpu
.ss
.setWord(offset
, (short) cpu
.ebp
);
1679 cpu
.ss
.setWord(offset
, (short) cpu
.esi
);
1681 cpu
.ss
.setWord(offset
, (short) cpu
.edi
);
1683 cpu
.esp
= (cpu
.esp
& ~offmask
) | (offset
& offmask
);
1686 private final void pushad()
1688 int offset
, offmask
;
1691 offmask
= 0xffffffff;
1693 offset
= cpu
.esp
& 0xffff;
1698 if ((offset
< 32) && (offset
> 0)) {
1699 System
.err
.println("Emulated: Throwing dodgy pushad exception.");
1700 throw ProcessorException
.GENERAL_PROTECTION_0
;
1704 cpu
.ss
.setDoubleWord(offset
, cpu
.eax
);
1706 cpu
.ss
.setDoubleWord(offset
, cpu
.ecx
);
1708 cpu
.ss
.setDoubleWord(offset
, cpu
.edx
);
1710 cpu
.ss
.setDoubleWord(offset
, cpu
.ebx
);
1712 cpu
.ss
.setDoubleWord(offset
, temp
);
1714 cpu
.ss
.setDoubleWord(offset
, cpu
.ebp
);
1716 cpu
.ss
.setDoubleWord(offset
, cpu
.esi
);
1718 cpu
.ss
.setDoubleWord(offset
, cpu
.edi
);
1720 cpu
.esp
= (cpu
.esp
& ~offmask
) | (offset
& offmask
);
1723 private final void popa()
1725 int offset
, offmask
;
1728 offmask
= 0xffffffff;
1730 offset
= cpu
.esp
& 0xffff;
1734 //Bochs claims no checking need on POPs
1735 //if (offset + 16 >= cpu.ss.limit)
1736 // throw exceptionSS;
1737 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offmask
& offset
));
1739 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offmask
& offset
));
1741 cpu
.ebp
= (cpu
.ebp
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offmask
& offset
));
1742 offset
+= 4;// yes - skip 2 bytes in order to skip SP
1743 cpu
.ebx
= (cpu
.ebx
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offmask
& offset
));
1745 cpu
.edx
= (cpu
.edx
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offmask
& offset
));
1747 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offmask
& offset
));
1749 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (0xffff & cpu
.ss
.getWord(offmask
& offset
));
1752 cpu
.esp
= (cpu
.esp
& ~offmask
) | (offset
& offmask
);
1755 private final void popad()
1757 int offset
, offmask
;
1760 offmask
= 0xffffffff;
1762 offset
= cpu
.esp
& 0xffff;
1766 //Bochs claims no checking need on POPs
1767 //if (offset + 16 >= cpu.ss.limit)
1768 // throw exceptionSS;
1770 cpu
.edi
= cpu
.ss
.getDoubleWord(offmask
& offset
);
1772 cpu
.esi
= cpu
.ss
.getDoubleWord(offmask
& offset
);
1774 cpu
.ebp
= cpu
.ss
.getDoubleWord(offmask
& offset
);
1775 offset
+= 8;// yes - skip an extra 4 bytes in order to skip SP
1777 cpu
.ebx
= cpu
.ss
.getDoubleWord(offmask
& offset
);
1779 cpu
.edx
= cpu
.ss
.getDoubleWord(offmask
& offset
);
1781 cpu
.ecx
= cpu
.ss
.getDoubleWord(offmask
& offset
);
1783 cpu
.eax
= cpu
.ss
.getDoubleWord(offmask
& offset
);
1786 cpu
.esp
= (cpu
.esp
& ~offmask
) | (offset
& offmask
);
1789 private final void jump_far_o16(int targetEIP
, int targetSelector
)
1791 cpu
.eip
= targetEIP
;
1792 cpu
.cs
.setSelector(targetSelector
);
1795 private final void jump_far_o32(int targetEIP
, int targetSelector
)
1797 cpu
.eip
= targetEIP
;
1798 cpu
.cs
.setSelector(targetSelector
);
1801 private final void call_far_o16_a16(int targetEIP
, int targetSelector
)
1803 if (((cpu
.esp
& 0xffff) < 4) && ((cpu
.esp
& 0xffff) > 0))
1804 throw ProcessorException
.STACK_SEGMENT_0
;
1806 cpu
.ss
.setWord((cpu
.esp
- 2) & 0xffff, (short)cpu
.cs
.getSelector());
1807 cpu
.ss
.setWord((cpu
.esp
- 4) & 0xffff, (short)cpu
.eip
);
1808 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
- 4) & 0xffff);
1810 cpu
.eip
= targetEIP
;
1811 cpu
.cs
.setSelector(targetSelector
);
1814 private final void call_far_o16_a32(int targetEIP
, int targetSelector
)
1816 if ((cpu
.esp
< 4) && (cpu
.esp
> 0))
1817 throw ProcessorException
.STACK_SEGMENT_0
;
1819 cpu
.ss
.setWord(cpu
.esp
- 2, (short)cpu
.cs
.getSelector());
1820 cpu
.ss
.setWord(cpu
.esp
- 4, (short)cpu
.eip
);
1823 cpu
.eip
= targetEIP
;
1824 cpu
.cs
.setSelector(targetSelector
);
1827 private final void call_far_o32_a16(int targetEIP
, int targetSelector
)
1829 if (((cpu
.esp
& 0xffff) < 8) && ((cpu
.esp
& 0xffff) > 0))
1830 throw ProcessorException
.STACK_SEGMENT_0
;
1832 cpu
.ss
.setDoubleWord((cpu
.esp
- 4) & 0xffff, 0xffff & cpu
.cs
.getSelector());
1833 cpu
.ss
.setDoubleWord((cpu
.esp
- 8) & 0xffff, cpu
.eip
);
1834 cpu
.esp
= (cpu
.esp
& ~
0xffff) | ((cpu
.esp
- 8) & 0xffff);
1836 cpu
.eip
= targetEIP
;
1837 cpu
.cs
.setSelector(targetSelector
);
1840 private final void call_far_o32_a32(int targetEIP
, int targetSelector
)
1842 if ((cpu
.esp
< 8) && (cpu
.esp
> 0))
1843 throw ProcessorException
.STACK_SEGMENT_0
;
1845 cpu
.ss
.setDoubleWord(cpu
.esp
- 4, 0xffff & cpu
.cs
.getSelector());
1846 cpu
.ss
.setDoubleWord(cpu
.esp
- 8, cpu
.eip
);
1849 cpu
.eip
= targetEIP
;
1850 cpu
.cs
.setSelector(targetSelector
);
1853 private final void call_abs_o32_a32(int target
)
1855 if (((cpu
.esp
) < 4) && ((cpu
.esp
) > 0))
1856 throw ProcessorException
.STACK_SEGMENT_0
;
1857 cpu
.ss
.setDoubleWord(cpu
.esp
- 4, cpu
.eip
);
1862 private final void call_abs_o32_a16(int target
)
1864 if (((cpu
.esp
& 0xffff) < 4) && ((cpu
.esp
& 0xffff) > 0))
1865 throw ProcessorException
.STACK_SEGMENT_0
;
1866 cpu
.ss
.setDoubleWord((cpu
.esp
- 4) & 0xffff, cpu
.eip
);
1867 cpu
.esp
= (cpu
.esp
& 0xffff0000) | ((cpu
.esp
- 4) & 0xffff);
1871 private final void call_abs_o16_a16(int target
)
1873 if (((cpu
.esp
& 0xffff) < 2) && ((cpu
.esp
& 0xffff) > 0))
1874 throw ProcessorException
.STACK_SEGMENT_0
;
1875 cpu
.ss
.setWord((cpu
.esp
- 2) & 0xffff, (short)cpu
.eip
);
1880 private final void call_abs_o16_a32(int target
)
1882 if ((cpu
.esp
< 2) && (cpu
.esp
> 0))
1883 throw ProcessorException
.STACK_SEGMENT_0
;
1884 cpu
.ss
.setWord(cpu
.esp
- 2, (short)cpu
.eip
);
1885 cpu
.esp
= (cpu
.esp
& 0xffff0000) | ((cpu
.esp
- 2) & 0xffff);
1889 private final void int_o16_a16(int vector
)
1892 System
.err
.println("Critical error: INT 0 executed.");
1893 //throw new IllegalStateException("INT 0 allowed? 0x" + Integer.toHexString(cpu.getInstructionPointer()));
1895 if(((cpu
.esp
& 0xffff) < 6) && ((cpu
.esp
& 0xffff) > 0)) {
1896 System
.err
.println("Critical error: SS Processor Exception Thrown in \"handleInterrupt("+vector
+")\".");
1897 throw new IllegalStateException("SS Processor Exception Thrown in \"handleInterrupt("+vector
+")\"");
1898 //throw exceptionSS; //?
1899 //maybe just change vector value
1901 cpu
.esp
= (cpu
.esp
& 0xffff0000) | (0xffff & (cpu
.esp
- 2));
1902 int eflags
= cpu
.getEFlags() & 0xffff;
1903 cpu
.ss
.setWord(cpu
.esp
& 0xffff, (short)eflags
);
1904 cpu
.eflagsInterruptEnable
= false;
1905 cpu
.eflagsInterruptEnableSoon
= false;
1906 cpu
.eflagsTrap
= false;
1907 cpu
.eflagsAlignmentCheck
= false;
1908 cpu
.eflagsResume
=false;
1909 cpu
.esp
= (cpu
.esp
& 0xffff0000) | (0xffff & (cpu
.esp
- 2));
1910 cpu
.ss
.setWord(cpu
.esp
& 0xffff, (short)cpu
.cs
.getSelector());
1911 cpu
.esp
= (cpu
.esp
& 0xffff0000) | (0xffff & (cpu
.esp
- 2));
1912 cpu
.ss
.setWord(cpu
.esp
& 0xffff, (short)cpu
.eip
);
1913 // read interrupt vector
1914 cpu
.eip
= 0xffff & cpu
.idtr
.getWord(4*vector
);
1915 cpu
.cs
.setSelector(0xffff & cpu
.idtr
.getWord(4*vector
+2));
1918 private final void int3_o16_a16()
1922 if (((cpu
.esp
& 0xffff) < 6) && ((cpu
.esp
& 0xffff) > 0)) {
1923 System
.err
.println("Critical error: SS Processor Exception Thrown in \"handleInterrupt("+vector
+")\".");
1924 throw new IllegalStateException("SS Processor Exception Thrown in \"handleInterrupt(DEBUG)\"");
1925 //throw exceptionSS; //?
1926 //maybe just change vector value
1928 cpu
.esp
= (cpu
.esp
& 0xffff0000) | (0xffff & (cpu
.esp
- 2));
1929 int eflags
= cpu
.getEFlags() & 0xffff;
1930 cpu
.ss
.setWord(cpu
.esp
& 0xffff, (short)eflags
);
1931 cpu
.eflagsInterruptEnable
= false;
1932 cpu
.eflagsInterruptEnableSoon
= false;
1933 cpu
.eflagsTrap
= false;
1934 cpu
.eflagsAlignmentCheck
= false;
1935 cpu
.esp
= (cpu
.esp
& 0xffff0000) | (0xffff & (cpu
.esp
- 2));
1936 cpu
.ss
.setWord(cpu
.esp
& 0xffff, (short)cpu
.cs
.getSelector());
1937 cpu
.esp
= (cpu
.esp
& 0xffff0000) | (0xffff & (cpu
.esp
- 2));
1938 cpu
.ss
.setWord(cpu
.esp
& 0xffff, (short)cpu
.eip
);
1939 // read interrupt vector
1940 cpu
.eip
= 0xffff & cpu
.idtr
.getWord(4*vector
);
1941 cpu
.cs
.setSelector(0xffff & cpu
.idtr
.getWord(4*vector
+2));
1944 private final void int1_o16_a16()
1948 if (((cpu
.esp
& 0xffff) < 6) && ((cpu
.esp
& 0xffff) > 0)) {
1949 System
.err
.println("Critical error: SS Processor Exception Thrown in \"handleInterrupt("+vector
+")\".");
1950 throw new IllegalStateException("SS Processor Exception Thrown in \"handleInterrupt(INT1)\"");
1951 //throw exceptionSS; //?
1952 //maybe just change vector value
1954 cpu
.esp
= (cpu
.esp
& 0xffff0000) | (0xffff & (cpu
.esp
- 2));
1955 int eflags
= cpu
.getEFlags() & 0xffff;
1956 cpu
.ss
.setWord(cpu
.esp
& 0xffff, (short)eflags
);
1957 cpu
.eflagsInterruptEnable
= false;
1958 cpu
.eflagsInterruptEnableSoon
= false;
1959 cpu
.eflagsTrap
= false;
1960 cpu
.eflagsAlignmentCheck
= false;
1961 cpu
.esp
= (cpu
.esp
& 0xffff0000) | (0xffff & (cpu
.esp
- 2));
1962 cpu
.ss
.setWord(cpu
.esp
& 0xffff, (short)cpu
.cs
.getSelector());
1963 cpu
.esp
= (cpu
.esp
& 0xffff0000) | (0xffff & (cpu
.esp
- 2));
1964 cpu
.ss
.setWord(cpu
.esp
& 0xffff, (short)cpu
.eip
);
1965 // read interrupt vector
1966 cpu
.eip
= 0xffff & cpu
.idtr
.getWord(4*vector
);
1967 cpu
.cs
.setSelector(0xffff & cpu
.idtr
.getWord(4*vector
+2));
1970 private final int iret_o16_a16()
1972 // TODO: supposed to throw SS exception
1973 // "if top 6 bytes of stack not within stack limits"
1974 cpu
.eip
= cpu
.ss
.getWord(cpu
.esp
& 0xffff) & 0xffff;
1975 cpu
.esp
= (cpu
.esp
& 0xffff0000) | ((cpu
.esp
+ 2) & 0xffff);
1976 cpu
.cs
.setSelector(cpu
.ss
.getWord(cpu
.esp
& 0xffff) & 0xffff);
1977 cpu
.esp
= (cpu
.esp
& 0xffff0000) | ((cpu
.esp
+ 2) & 0xffff);
1978 int flags
= cpu
.ss
.getWord(cpu
.esp
& 0xffff);
1979 cpu
.esp
= (cpu
.esp
& 0xffff0000) | ((cpu
.esp
+ 2) & 0xffff);
1983 private final void cmpsb_a16(Segment seg0
)
1985 int addrOne
= cpu
.esi
& 0xffff;
1986 int addrTwo
= cpu
.edi
& 0xffff;
1988 int dataOne
= 0xff & seg0
.getByte(addrOne
);
1989 int dataTwo
= 0xff & cpu
.es
.getByte(addrTwo
);
1990 if (cpu
.eflagsDirection
) {
1998 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addrOne
& 0xffff);
1999 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addrTwo
& 0xffff);
2001 // sub_o8_flags(dataOne - dataTwo, dataOne, dataTwo);
2002 uCodeXferReg0
= dataOne
- dataTwo
;
2003 uCodeXferReg1
= dataTwo
;
2004 uCodeXferReg2
= dataOne
;
2005 uCodeXferLoaded
= true;
2008 private final void cmpsw_a16(Segment seg0
)
2010 int addrOne
= cpu
.esi
& 0xffff;
2011 int addrTwo
= cpu
.edi
& 0xffff;
2013 int dataOne
= 0xffff & seg0
.getWord(addrOne
);
2014 int dataTwo
= 0xffff & cpu
.es
.getWord(addrTwo
);
2015 if (cpu
.eflagsDirection
) {
2023 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addrOne
& 0xffff);
2024 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addrTwo
& 0xffff);
2026 // sub_o16_flags(dataOne - dataTwo, dataOne, dataTwo);
2027 uCodeXferReg0
= dataOne
- dataTwo
;
2028 uCodeXferReg1
= dataTwo
;
2029 uCodeXferReg2
= dataOne
;
2030 uCodeXferLoaded
= true;
2033 private final void cmpsd_a16(Segment seg0
)
2035 int addrOne
= cpu
.esi
& 0xffff;
2036 int addrTwo
= cpu
.edi
& 0xffff;
2038 int dataOne
= seg0
.getDoubleWord(addrOne
);
2039 int dataTwo
= cpu
.es
.getDoubleWord(addrTwo
);
2040 if (cpu
.eflagsDirection
) {
2048 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addrOne
& 0xffff);
2049 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addrTwo
& 0xffff);
2051 // sub_o32_flags((0xffffffffl & dataOne) - (0xffffffffl & dataTwo), dataOne, dataTwo);
2052 uCodeXferReg0
= (int) ((0xffffffffl
& dataOne
) - (0xffffffffl
& dataTwo
));
2053 uCodeXferReg1
= dataTwo
;
2054 uCodeXferReg2
= dataOne
;
2055 uCodeXferLoaded
= true;
2058 private final void repe_cmpsb_a16(Segment seg0
)
2060 int count
= cpu
.ecx
& 0xffff;
2061 int addrOne
= cpu
.esi
& 0xffff;
2062 int addrTwo
= cpu
.edi
& 0xffff;
2063 boolean used
= count
!= 0;
2068 if (cpu
.eflagsDirection
) {
2069 while (count
!= 0) {
2070 //check hardware interrupts
2071 dataOne
= 0xff & seg0
.getByte(addrOne
);
2072 dataTwo
= 0xff & cpu
.es
.getByte(addrTwo
);
2076 if (dataOne
!= dataTwo
) break;
2079 while (count
!= 0) {
2080 //check hardware interrupts
2081 dataOne
= 0xff & seg0
.getByte(addrOne
);
2082 dataTwo
= 0xff & cpu
.es
.getByte(addrTwo
);
2086 if (dataOne
!= dataTwo
) break;
2091 executeCount
+= ((cpu
.ecx
& 0xffff) - count
);
2092 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2093 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addrOne
& 0xffff);
2094 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addrTwo
& 0xffff);
2097 // sub_o8_flags(dataOne - dataTwo, dataOne, dataTwo);
2098 uCodeXferReg0
= used ?
1 : 0;
2099 uCodeXferReg1
= dataTwo
;
2100 uCodeXferReg2
= dataOne
;
2101 uCodeXferLoaded
= true;
2105 private final void repe_cmpsw_a16(Segment seg0
)
2107 int count
= cpu
.ecx
& 0xffff;
2108 int addrOne
= cpu
.esi
& 0xffff;
2109 int addrTwo
= cpu
.edi
& 0xffff;
2110 boolean used
= count
!= 0;
2115 if (cpu
.eflagsDirection
) {
2116 while (count
!= 0) {
2117 //check hardware interrupts
2118 dataOne
= 0xffff & seg0
.getWord(addrOne
);
2119 dataTwo
= 0xffff & cpu
.es
.getWord(addrTwo
);
2123 if (dataOne
!= dataTwo
) break;
2126 while (count
!= 0) {
2127 //check hardware interrupts
2128 dataOne
= 0xffff & seg0
.getWord(addrOne
);
2129 dataTwo
= 0xffff & cpu
.es
.getWord(addrTwo
);
2133 if (dataOne
!= dataTwo
) break;
2138 executeCount
+= ((cpu
.ecx
& 0xffff) - count
);
2139 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2140 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addrOne
& 0xffff);
2141 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addrTwo
& 0xffff);
2144 // sub_o16_flags(dataOne - dataTwo, dataOne, dataTwo);
2145 uCodeXferReg0
= used ?
1 : 0;
2146 uCodeXferReg1
= dataTwo
;
2147 uCodeXferReg2
= dataOne
;
2148 uCodeXferLoaded
= true;
2152 private final void repe_cmpsd_a16(Segment seg0
)
2154 int count
= cpu
.ecx
& 0xffff;
2155 int addrOne
= cpu
.esi
& 0xffff;
2156 int addrTwo
= cpu
.edi
& 0xffff;
2157 boolean used
= count
!= 0;
2162 if (cpu
.eflagsDirection
) {
2163 while (count
!= 0) {
2164 //check hardware interrupts
2165 dataOne
= seg0
.getDoubleWord(addrOne
);
2166 dataTwo
= cpu
.es
.getDoubleWord(addrTwo
);
2170 if (dataOne
!= dataTwo
) break;
2173 while (count
!= 0) {
2174 //check hardware interrupts
2175 dataOne
= seg0
.getDoubleWord(addrOne
);
2176 dataTwo
= cpu
.es
.getDoubleWord(addrTwo
);
2180 if (dataOne
!= dataTwo
) break;
2185 executeCount
+= ((cpu
.ecx
& 0xffff) - count
);
2186 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2187 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addrOne
& 0xffff);
2188 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addrTwo
& 0xffff);
2191 // sub_o32_flags((0xffffffffl & dataOne) - (0xffffffffl & dataTwo), dataOne, dataTwo);
2192 uCodeXferReg0
= used ?
1 : 0;
2193 uCodeXferReg1
= dataTwo
;
2194 uCodeXferReg2
= dataOne
;
2195 uCodeXferLoaded
= true;
2199 private final void insb_a16(int port
)
2201 int addr
= cpu
.edi
& 0xffff;
2203 cpu
.es
.setByte(addr
& 0xffff, (byte)cpu
.ioports
.ioPortReadByte(port
));
2204 if (cpu
.eflagsDirection
) {
2210 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
2213 private final void insw_a16(int port
)
2215 int addr
= cpu
.edi
& 0xffff;
2217 cpu
.es
.setWord(addr
& 0xffff, (short)cpu
.ioports
.ioPortReadWord(port
));
2218 if (cpu
.eflagsDirection
) {
2224 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
2227 private final void insd_a16(int port
)
2229 int addr
= cpu
.edi
& 0xffff;
2231 cpu
.es
.setDoubleWord(addr
& 0xffff, cpu
.ioports
.ioPortReadLong(port
));
2232 if (cpu
.eflagsDirection
) {
2238 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
2241 private final void rep_insb_a16(int port
)
2243 int count
= cpu
.ecx
& 0xffff;
2244 int addr
= cpu
.edi
& 0xffff;
2245 executeCount
+= count
;
2248 if (cpu
.eflagsDirection
) {
2249 while (count
!= 0) {
2250 //check hardware interrupts
2251 cpu
.es
.setByte(addr
& 0xffff, (byte)cpu
.ioports
.ioPortReadByte(port
));
2256 while (count
!= 0) {
2257 //check hardware interrupts
2258 cpu
.es
.setByte(addr
& 0xffff, (byte)cpu
.ioports
.ioPortReadByte(port
));
2265 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2266 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
2270 private final void rep_insw_a16(int port
)
2272 int count
= cpu
.ecx
& 0xffff;
2273 int addr
= cpu
.edi
& 0xffff;
2274 executeCount
+= count
;
2277 if (cpu
.eflagsDirection
) {
2278 while (count
!= 0) {
2279 //check hardware interrupts
2280 cpu
.es
.setWord(addr
& 0xffff, (short)cpu
.ioports
.ioPortReadWord(port
));
2285 while (count
!= 0) {
2286 //check hardware interrupts
2287 cpu
.es
.setWord(addr
& 0xffff, (short)cpu
.ioports
.ioPortReadWord(port
));
2294 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2295 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
2299 private final void rep_insd_a16(int port
)
2301 int count
= cpu
.ecx
& 0xffff;
2302 int addr
= cpu
.edi
& 0xffff;
2303 executeCount
+= count
;
2306 if (cpu
.eflagsDirection
) {
2307 while (count
!= 0) {
2308 //check hardware interrupts
2309 cpu
.es
.setDoubleWord(addr
& 0xffff, cpu
.ioports
.ioPortReadLong(port
));
2314 while (count
!= 0) {
2315 //check hardware interrupts
2316 cpu
.es
.setDoubleWord(addr
& 0xffff, cpu
.ioports
.ioPortReadLong(port
));
2323 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2324 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
2328 private final void lodsb_a16(Segment dataSegment
)
2330 int addr
= cpu
.esi
& 0xffff;
2331 cpu
.eax
= (cpu
.eax
& ~
0xff) | (0xff & dataSegment
.getByte(addr
));
2333 if (cpu
.eflagsDirection
)
2338 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2341 private final void lodsw_a16(Segment dataSegment
)
2343 int addr
= cpu
.esi
& 0xffff;
2344 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (0xffff & dataSegment
.getWord(addr
));
2346 if (cpu
.eflagsDirection
)
2351 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2354 private final void lodsd_a16(Segment dataSegment
)
2356 int addr
= cpu
.esi
& 0xffff;
2357 cpu
.eax
= dataSegment
.getDoubleWord(addr
);
2359 if (cpu
.eflagsDirection
)
2364 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2367 private final void rep_lodsb_a16(Segment dataSegment
)
2369 int count
= cpu
.ecx
& 0xffff;
2370 int addr
= cpu
.esi
& 0xffff;
2371 int data
= cpu
.eax
& 0xff;
2372 executeCount
+= count
;
2375 if (cpu
.eflagsDirection
) {
2376 while (count
!= 0) {
2377 //check hardware interrupts
2378 data
= 0xff & dataSegment
.getByte(addr
& 0xffff);
2383 while (count
!= 0) {
2384 //check hardware interrupts
2385 data
= 0xff & dataSegment
.getByte(addr
& 0xffff);
2392 cpu
.eax
= (cpu
.eax
& ~
0xff) | data
;
2393 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2394 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2398 private final void rep_lodsw_a16(Segment dataSegment
)
2400 int count
= cpu
.ecx
& 0xffff;
2401 int addr
= cpu
.esi
& 0xffff;
2402 int data
= cpu
.eax
& 0xffff;
2403 executeCount
+= count
;
2406 if (cpu
.eflagsDirection
) {
2407 while (count
!= 0) {
2408 //check hardware interrupts
2409 data
= 0xffff & dataSegment
.getWord(addr
& 0xffff);
2414 while (count
!= 0) {
2415 //check hardware interrupts
2416 data
= 0xffff & dataSegment
.getWord(addr
& 0xffff);
2423 cpu
.eax
= (cpu
.eax
& ~
0xffff) | data
;
2424 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2425 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2429 private final void rep_lodsd_a16(Segment dataSegment
)
2431 int count
= cpu
.ecx
& 0xffff;
2432 int addr
= cpu
.esi
& 0xffff;
2434 executeCount
+= count
;
2437 if (cpu
.eflagsDirection
) {
2438 while (count
!= 0) {
2439 //check hardware interrupts
2440 data
= dataSegment
.getDoubleWord(addr
& 0xffff);
2445 while (count
!= 0) {
2446 //check hardware interrupts
2447 data
= dataSegment
.getDoubleWord(addr
& 0xffff);
2455 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2456 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2460 private final void lodsb_a32(Segment dataSegment
)
2463 cpu
.eax
= (cpu
.eax
& ~
0xff) | (0xff & dataSegment
.getByte(addr
));
2465 if (cpu
.eflagsDirection
)
2473 private final void lodsw_a32(Segment dataSegment
)
2476 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (0xffff & dataSegment
.getWord(addr
));
2478 if (cpu
.eflagsDirection
)
2486 private final void lodsd_a32(Segment dataSegment
)
2489 cpu
.eax
= dataSegment
.getDoubleWord(addr
);
2491 if (cpu
.eflagsDirection
)
2499 private final void rep_lodsb_a32(Segment dataSegment
)
2501 int count
= cpu
.ecx
;
2503 int data
= cpu
.eax
& 0xff;
2504 executeCount
+= count
;
2507 if (cpu
.eflagsDirection
) {
2508 while (count
!= 0) {
2509 //check hardware interrupts
2510 data
= 0xff & dataSegment
.getByte(addr
);
2515 while (count
!= 0) {
2516 //check hardware interrupts
2517 data
= 0xff & dataSegment
.getByte(addr
);
2524 cpu
.eax
= (cpu
.eax
& ~
0xff) | data
;
2530 private final void rep_lodsw_a32(Segment dataSegment
)
2532 int count
= cpu
.ecx
;
2534 int data
= cpu
.eax
& 0xffff;
2535 executeCount
+= count
;
2538 if (cpu
.eflagsDirection
) {
2539 while (count
!= 0) {
2540 //check hardware interrupts
2541 data
= 0xffff & dataSegment
.getWord(addr
);
2546 while (count
!= 0) {
2547 //check hardware interrupts
2548 data
= 0xffff & dataSegment
.getWord(addr
);
2555 cpu
.eax
= (cpu
.eax
& ~
0xffff) | data
;
2561 private final void rep_lodsd_a32(Segment dataSegment
)
2563 int count
= cpu
.ecx
;
2566 executeCount
+= count
;
2569 if (cpu
.eflagsDirection
) {
2570 while (count
!= 0) {
2571 //check hardware interrupts
2572 data
= dataSegment
.getDoubleWord(addr
);
2577 while (count
!= 0) {
2578 //check hardware interrupts
2579 data
= dataSegment
.getDoubleWord(addr
);
2592 private final void movsb_a16(Segment outSegment
)
2594 int inAddr
= cpu
.edi
& 0xffff;
2595 int outAddr
= cpu
.esi
& 0xffff;
2597 cpu
.es
.setByte(inAddr
, outSegment
.getByte(outAddr
));
2598 if (cpu
.eflagsDirection
) {
2606 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (inAddr
& 0xffff);
2607 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (outAddr
& 0xffff);
2610 private final void movsw_a16(Segment outSegment
)
2612 int inAddr
= cpu
.edi
& 0xffff;
2613 int outAddr
= cpu
.esi
& 0xffff;
2615 cpu
.es
.setWord(inAddr
, outSegment
.getWord(outAddr
));
2616 if (cpu
.eflagsDirection
) {
2624 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (inAddr
& 0xffff);
2625 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (outAddr
& 0xffff);
2628 private final void movsd_a16(Segment outSegment
)
2630 int inAddr
= cpu
.edi
& 0xffff;
2631 int outAddr
= cpu
.esi
& 0xffff;
2633 cpu
.es
.setDoubleWord(inAddr
, outSegment
.getDoubleWord(outAddr
));
2634 if (cpu
.eflagsDirection
) {
2642 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (inAddr
& 0xffff);
2643 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (outAddr
& 0xffff);
2646 private final void rep_movsb_a16(Segment outSegment
)
2648 int count
= cpu
.ecx
& 0xffff;
2649 int inAddr
= cpu
.edi
& 0xffff;
2650 int outAddr
= cpu
.esi
& 0xffff;
2651 executeCount
+= count
;
2654 if (cpu
.eflagsDirection
) {
2655 while (count
!= 0) {
2656 //check hardware interrupts
2657 cpu
.es
.setByte(inAddr
& 0xffff, outSegment
.getByte(outAddr
& 0xffff));
2663 while (count
!= 0) {
2664 //check hardware interrupts
2665 cpu
.es
.setByte(inAddr
& 0xffff, outSegment
.getByte(outAddr
& 0xffff));
2673 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2674 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (inAddr
& 0xffff);
2675 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (outAddr
& 0xffff);
2679 private final void rep_movsw_a16(Segment outSegment
)
2681 int count
= cpu
.ecx
& 0xffff;
2682 int inAddr
= cpu
.edi
& 0xffff;
2683 int outAddr
= cpu
.esi
& 0xffff;
2684 executeCount
+= count
;
2687 if (cpu
.eflagsDirection
) {
2688 while (count
!= 0) {
2689 //check hardware interrupts
2690 cpu
.es
.setWord(inAddr
& 0xffff, outSegment
.getWord(outAddr
& 0xffff));
2696 while (count
!= 0) {
2697 //check hardware interrupts
2698 cpu
.es
.setWord(inAddr
& 0xffff, outSegment
.getWord(outAddr
& 0xffff));
2706 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2707 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (inAddr
& 0xffff);
2708 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (outAddr
& 0xffff);
2712 private final void rep_movsd_a16(Segment outSegment
)
2714 int count
= cpu
.ecx
& 0xffff;
2715 int inAddr
= cpu
.edi
& 0xffff;
2716 int outAddr
= cpu
.esi
& 0xffff;
2717 executeCount
+= count
;
2720 if (cpu
.eflagsDirection
) {
2721 while (count
!= 0) {
2722 //check hardware interrupts
2723 cpu
.es
.setDoubleWord(inAddr
& 0xffff, outSegment
.getDoubleWord(outAddr
& 0xffff));
2729 while (count
!= 0) {
2730 //check hardware interrupts
2731 cpu
.es
.setDoubleWord(inAddr
& 0xffff, outSegment
.getDoubleWord(outAddr
& 0xffff));
2739 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2740 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (inAddr
& 0xffff);
2741 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (outAddr
& 0xffff);
2745 private final void movsb_a32(Segment outSegment
)
2747 int inAddr
= cpu
.edi
;
2748 int outAddr
= cpu
.esi
;
2750 cpu
.es
.setByte(inAddr
, outSegment
.getByte(outAddr
));
2751 if (cpu
.eflagsDirection
) {
2763 private final void movsw_a32(Segment outSegment
)
2765 int inAddr
= cpu
.edi
;
2766 int outAddr
= cpu
.esi
;
2768 cpu
.es
.setWord(inAddr
, outSegment
.getWord(outAddr
));
2769 if (cpu
.eflagsDirection
) {
2781 private final void movsd_a32(Segment outSegment
)
2783 int inAddr
= cpu
.edi
;
2784 int outAddr
= cpu
.esi
;
2786 cpu
.es
.setDoubleWord(inAddr
, outSegment
.getDoubleWord(outAddr
));
2787 if (cpu
.eflagsDirection
) {
2795 cpu
.edi
= inAddr
& 0xffff;
2796 cpu
.esi
= outAddr
& 0xffff;
2799 private final void rep_movsb_a32(Segment outSegment
)
2801 int count
= cpu
.ecx
;
2802 int inAddr
= cpu
.edi
;
2803 int outAddr
= cpu
.esi
;
2804 executeCount
+= count
;
2807 if (cpu
.eflagsDirection
) {
2808 while (count
!= 0) {
2809 //check hardware interrupts
2810 cpu
.es
.setByte(inAddr
, outSegment
.getByte(outAddr
));
2816 while (count
!= 0) {
2817 //check hardware interrupts
2818 cpu
.es
.setByte(inAddr
, outSegment
.getByte(outAddr
));
2832 private final void rep_movsw_a32(Segment outSegment
)
2834 int count
= cpu
.ecx
;
2835 int inAddr
= cpu
.edi
;
2836 int outAddr
= cpu
.esi
;
2837 executeCount
+= count
;
2840 if (cpu
.eflagsDirection
) {
2841 while (count
!= 0) {
2842 //check hardware interrupts
2843 cpu
.es
.setWord(inAddr
, outSegment
.getWord(outAddr
));
2849 while (count
!= 0) {
2850 //check hardware interrupts
2851 cpu
.es
.setWord(inAddr
, outSegment
.getWord(outAddr
));
2865 private final void rep_movsd_a32(Segment outSegment
)
2867 int count
= cpu
.ecx
;
2868 int inAddr
= cpu
.edi
;
2869 int outAddr
= cpu
.esi
;
2870 executeCount
+= count
;
2873 if (cpu
.eflagsDirection
) {
2874 while (count
!= 0) {
2875 //check hardware interrupts
2876 cpu
.es
.setDoubleWord(inAddr
, outSegment
.getDoubleWord(outAddr
));
2882 while (count
!= 0) {
2883 //check hardware interrupts
2884 cpu
.es
.setDoubleWord(inAddr
, outSegment
.getDoubleWord(outAddr
));
2895 executeCount
-= count
;
2899 private final void outsb_a16(int port
, Segment storeSegment
)
2901 int addr
= cpu
.esi
& 0xffff;
2903 cpu
.ioports
.ioPortWriteByte(port
, 0xff & storeSegment
.getByte(addr
));
2905 if (cpu
.eflagsDirection
)
2910 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2913 private final void outsw_a16(int port
, Segment storeSegment
)
2915 int addr
= cpu
.esi
& 0xffff;
2917 cpu
.ioports
.ioPortWriteWord(port
, 0xffff & storeSegment
.getWord(addr
));
2919 if (cpu
.eflagsDirection
)
2924 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2927 private final void outsd_a16(int port
, Segment storeSegment
)
2929 int addr
= cpu
.esi
& 0xffff;
2931 cpu
.ioports
.ioPortWriteLong(port
, storeSegment
.getDoubleWord(addr
));
2933 if (cpu
.eflagsDirection
)
2938 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2941 private final void rep_outsb_a16(int port
, Segment storeSegment
)
2943 int count
= cpu
.ecx
& 0xffff;
2944 int addr
= cpu
.esi
& 0xffff;
2945 executeCount
+= count
;
2948 if (cpu
.eflagsDirection
) {
2949 while (count
!= 0) {
2950 //check hardware interrupts
2951 cpu
.ioports
.ioPortWriteByte(port
, 0xffff & storeSegment
.getByte(addr
& 0xffff));
2956 while (count
!= 0) {
2957 //check hardware interrupts
2958 cpu
.ioports
.ioPortWriteByte(port
, 0xffff & storeSegment
.getByte(addr
& 0xffff));
2965 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2966 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2970 private final void rep_outsw_a16(int port
, Segment storeSegment
)
2972 int count
= cpu
.ecx
& 0xffff;
2973 int addr
= cpu
.esi
& 0xffff;
2974 executeCount
+= count
;
2977 if (cpu
.eflagsDirection
) {
2978 while (count
!= 0) {
2979 //check hardware interrupts
2980 cpu
.ioports
.ioPortWriteWord(port
, 0xffff & storeSegment
.getWord(addr
& 0xffff));
2985 while (count
!= 0) {
2986 //check hardware interrupts
2987 cpu
.ioports
.ioPortWriteWord(port
, 0xffff & storeSegment
.getWord(addr
& 0xffff));
2994 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
2995 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
2999 private final void rep_outsd_a16(int port
, Segment storeSegment
)
3001 int count
= cpu
.ecx
& 0xffff;
3002 int addr
= cpu
.esi
& 0xffff;
3003 executeCount
+= count
;
3006 if (cpu
.eflagsDirection
) {
3007 while (count
!= 0) {
3008 //check hardware interrupts
3009 cpu
.ioports
.ioPortWriteLong(port
, storeSegment
.getDoubleWord(addr
& 0xffff));
3014 while (count
!= 0) {
3015 //check hardware interrupts
3016 cpu
.ioports
.ioPortWriteLong(port
, storeSegment
.getDoubleWord(addr
& 0xffff));
3023 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
3024 cpu
.esi
= (cpu
.esi
& ~
0xffff) | (addr
& 0xffff);
3028 private final void scasb_a16(int data
)
3030 int addr
= cpu
.edi
& 0xffff;
3031 int input
= 0xff & cpu
.es
.getByte(addr
);
3033 if (cpu
.eflagsDirection
)
3038 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3039 // sub_o8_flags(data - input, data, input);
3040 uCodeXferReg0
= data
- input
;
3041 uCodeXferReg1
= input
;
3042 uCodeXferReg2
= data
;
3043 uCodeXferLoaded
= true;
3046 private final void scasw_a16(int data
)
3048 int addr
= cpu
.edi
& 0xffff;
3049 int input
= 0xffff & cpu
.es
.getWord(addr
);
3051 if (cpu
.eflagsDirection
)
3056 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3057 // sub_o16_flags(data - input, data, input);
3058 uCodeXferReg0
= data
- input
;
3059 uCodeXferReg1
= input
;
3060 uCodeXferReg2
= data
;
3061 uCodeXferLoaded
= true;
3064 private final void scasd_a16(int data
)
3066 int addr
= cpu
.edi
& 0xffff;
3067 int input
= cpu
.es
.getDoubleWord(addr
);
3069 if (cpu
.eflagsDirection
)
3074 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3075 // sub_o32_flags((0xffffffffl & data) - (0xffffffffl & input), data, input);
3076 uCodeXferReg0
= (int) ((0xffffffffl
& data
) - (0xffffffffl
& input
));
3077 uCodeXferReg1
= input
;
3078 uCodeXferReg2
= data
;
3079 uCodeXferLoaded
= true;
3082 private final void repe_scasb_a16(int data
)
3084 int count
= cpu
.ecx
& 0xffff;
3085 int addr
= cpu
.edi
& 0xffff;
3086 boolean used
= count
!= 0;
3090 if (cpu
.eflagsDirection
) {
3091 while (count
!= 0) {
3092 input
= 0xff & cpu
.es
.getByte(addr
);
3095 if (data
!= input
) break;
3098 while (count
!= 0) {
3099 input
= 0xff & cpu
.es
.getByte(addr
);
3102 if (data
!= input
) break;
3106 executeCount
+= ((cpu
.ecx
& 0xffff) - count
);
3107 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
3108 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3110 // sub_o8_flags(data - input, data, input);
3111 uCodeXferReg0
= used ?
1 : 0;
3112 uCodeXferReg1
= input
;
3113 uCodeXferReg2
= data
;
3114 uCodeXferLoaded
= true;
3118 private final void repe_scasw_a16(int data
)
3120 int count
= cpu
.ecx
& 0xffff;
3121 int addr
= cpu
.edi
& 0xffff;
3125 if (cpu
.eflagsDirection
) {
3126 while (count
!= 0) {
3127 input
= 0xffff & cpu
.es
.getWord(addr
);
3130 if (data
!= input
) break;
3133 while (count
!= 0) {
3134 input
= 0xffff & cpu
.es
.getWord(addr
);
3137 if (data
!= input
) break;
3141 executeCount
+= ((cpu
.ecx
& 0xffff) - count
);
3142 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
3143 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3145 // sub_o16_flags(data - input, data, input);
3146 uCodeXferReg0
= data
- input
;
3147 uCodeXferReg1
= input
;
3148 uCodeXferReg2
= data
;
3149 uCodeXferLoaded
= true;
3153 private final void repe_scasd_a16(int data
)
3155 int count
= cpu
.ecx
& 0xffff;
3156 int addr
= cpu
.edi
& 0xffff;
3157 boolean used
= count
!= 0;
3161 if (cpu
.eflagsDirection
) {
3162 while (count
!= 0) {
3163 input
= cpu
.es
.getDoubleWord(addr
);
3166 if (data
!= input
) break;
3169 while (count
!= 0) {
3170 input
= cpu
.es
.getDoubleWord(addr
);
3173 if (data
!= input
) break;
3177 executeCount
+= ((cpu
.ecx
& 0xffff) - count
);
3178 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
3179 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3181 // sub_o32_flags((0xffffffffl & data) - (0xffffffffl & input), data, input);
3182 uCodeXferReg0
= used ?
1 : 0;
3183 uCodeXferReg1
= input
;
3184 uCodeXferReg2
= data
;
3185 uCodeXferLoaded
= true;
3189 private final void repne_scasb_a16(int data
)
3191 int count
= cpu
.ecx
& 0xffff;
3192 int addr
= cpu
.edi
& 0xffff;
3193 boolean used
= count
!= 0;
3197 if (cpu
.eflagsDirection
) {
3198 while (count
!= 0) {
3199 input
= 0xff & cpu
.es
.getByte(addr
);
3202 if (data
== input
) break;
3205 while (count
!= 0) {
3206 input
= 0xff & cpu
.es
.getByte(addr
);
3209 if (data
== input
) break;
3213 executeCount
+= ((cpu
.ecx
& 0xffff) - count
);
3214 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
3215 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3217 // sub_o8_flags(data - input, data, input);
3218 uCodeXferReg0
= used ?
1 : 0;
3219 uCodeXferReg1
= input
;
3220 uCodeXferReg2
= data
;
3221 uCodeXferLoaded
= true;
3225 private final void repne_scasw_a16(int data
)
3227 int count
= cpu
.ecx
& 0xffff;
3228 int addr
= cpu
.edi
& 0xffff;
3229 boolean used
= count
!= 0;
3233 if (cpu
.eflagsDirection
) {
3234 while (count
!= 0) {
3235 input
= 0xffff & cpu
.es
.getWord(addr
);
3238 if (data
== input
) break;
3241 while (count
!= 0) {
3242 input
= 0xffff & cpu
.es
.getWord(addr
);
3245 if (data
== input
) break;
3249 executeCount
+= ((cpu
.ecx
& 0xffff) - count
);
3250 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
3251 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3253 // sub_o16_flags(data - input, data, input);
3254 uCodeXferReg0
= used ?
1 : 0;
3255 uCodeXferReg1
= input
;
3256 uCodeXferReg2
= data
;
3257 uCodeXferLoaded
= true;
3261 private final void repne_scasd_a16(int data
)
3263 int count
= cpu
.ecx
& 0xffff;
3264 int addr
= cpu
.edi
& 0xffff;
3265 boolean used
= count
!= 0;
3269 if (cpu
.eflagsDirection
) {
3270 while (count
!= 0) {
3271 input
= cpu
.es
.getDoubleWord(addr
);
3274 if (data
== input
) break;
3277 while (count
!= 0) {
3278 input
= cpu
.es
.getDoubleWord(addr
);
3281 if (data
== input
) break;
3285 executeCount
+= ((cpu
.ecx
& 0xffff) - count
);
3286 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
3287 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3289 // sub_o32_flags((0xffffffffl & data) - (0xffffffffl & input), data, input);
3290 uCodeXferReg0
= used ?
1 : 0;
3291 uCodeXferReg1
= input
;
3292 uCodeXferReg2
= data
;
3293 uCodeXferLoaded
= true;
3297 private final void stosb_a16(int data
)
3299 int addr
= cpu
.edi
& 0xffff;
3300 cpu
.es
.setByte(addr
, (byte)data
);
3302 if (cpu
.eflagsDirection
)
3307 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3310 private final void stosw_a16(int data
)
3312 int addr
= cpu
.edi
& 0xffff;
3313 cpu
.es
.setWord(addr
, (short)data
);
3315 if (cpu
.eflagsDirection
)
3320 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3323 private final void stosd_a16(int data
)
3325 int addr
= cpu
.edi
& 0xffff;
3326 cpu
.es
.setDoubleWord(addr
, data
);
3328 if (cpu
.eflagsDirection
)
3333 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3336 private final void rep_stosb_a16(int data
)
3338 int count
= cpu
.ecx
& 0xffff;
3339 int addr
= cpu
.edi
& 0xffff;
3340 executeCount
+= count
;
3343 if (cpu
.eflagsDirection
) {
3344 while (count
!= 0) {
3345 //check hardware interrupts
3346 cpu
.es
.setByte(addr
& 0xffff, (byte)data
);
3351 while (count
!= 0) {
3352 //check hardware interrupts
3353 cpu
.es
.setByte(addr
& 0xffff, (byte)data
);
3360 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
3361 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3365 private final void rep_stosw_a16(int data
)
3367 int count
= cpu
.ecx
& 0xffff;
3368 int addr
= cpu
.edi
& 0xffff;
3369 executeCount
+= count
;
3372 if (cpu
.eflagsDirection
) {
3373 while (count
!= 0) {
3374 //check hardware interrupts
3375 cpu
.es
.setWord(addr
& 0xffff, (short)data
);
3380 while (count
!= 0) {
3381 //check hardware interrupts
3382 cpu
.es
.setWord(addr
& 0xffff, (short)data
);
3389 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
3390 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3394 private final void rep_stosd_a16(int data
)
3396 int count
= cpu
.ecx
& 0xffff;
3397 int addr
= cpu
.edi
& 0xffff;
3398 executeCount
+= count
;
3401 if (cpu
.eflagsDirection
) {
3402 while (count
!= 0) {
3403 //check hardware interrupts
3404 cpu
.es
.setDoubleWord(addr
& 0xffff, data
);
3409 while (count
!= 0) {
3410 //check hardware interrupts
3411 cpu
.es
.setDoubleWord(addr
& 0xffff, data
);
3418 cpu
.ecx
= (cpu
.ecx
& ~
0xffff) | (count
& 0xffff);
3419 cpu
.edi
= (cpu
.edi
& ~
0xffff) | (addr
& 0xffff);
3423 private final void stosb_a32(int data
)
3426 cpu
.es
.setByte(addr
, (byte)data
);
3428 if (cpu
.eflagsDirection
)
3436 private final void stosw_a32(int data
)
3439 cpu
.es
.setWord(addr
, (short)data
);
3441 if (cpu
.eflagsDirection
)
3449 private final void stosd_a32(int data
)
3452 cpu
.es
.setDoubleWord(addr
, data
);
3454 if (cpu
.eflagsDirection
)
3462 private final void rep_stosb_a32(int data
)
3464 int count
= cpu
.ecx
;
3466 executeCount
+= count
;
3469 if (cpu
.eflagsDirection
) {
3470 while (count
!= 0) {
3471 //check hardware interrupts
3472 cpu
.es
.setByte(addr
, (byte)data
);
3477 while (count
!= 0) {
3478 //check hardware interrupts
3479 cpu
.es
.setByte(addr
, (byte)data
);
3491 private final void rep_stosw_a32(int data
)
3493 int count
= cpu
.ecx
;
3495 executeCount
+= count
;
3498 if (cpu
.eflagsDirection
) {
3499 while (count
!= 0) {
3500 //check hardware interrupts
3501 cpu
.es
.setWord(addr
, (short)data
);
3506 while (count
!= 0) {
3507 //check hardware interrupts
3508 cpu
.es
.setWord(addr
, (short)data
);
3520 private final void rep_stosd_a32(int data
)
3522 int count
= cpu
.ecx
;
3524 executeCount
+= count
;
3527 if (cpu
.eflagsDirection
) {
3528 while (count
!= 0) {
3529 //check hardware interrupts
3530 cpu
.es
.setDoubleWord(addr
, data
);
3535 while (count
!= 0) {
3536 //check hardware interrupts
3537 cpu
.es
.setDoubleWord(addr
, data
);
3549 private final void mul_o8(int data
)
3551 int x
= cpu
.eax
& 0xff;
3553 int result
= x
* data
;
3554 cpu
.eax
&= 0xffff0000;
3555 cpu
.eax
|= (result
& 0xffff);
3557 cpu
.setOverflowFlag(result
, Processor
.OF_HIGH_BYTE_NZ
);
3558 cpu
.setCarryFlag(result
, Processor
.CY_HIGH_BYTE_NZ
);
3561 private final void mul_o16(int data
)
3563 int x
= cpu
.eax
& 0xffff;
3565 int result
= x
* data
;
3566 cpu
.eax
= (cpu
.eax
& 0xffff0000) | (0xffff & result
);
3567 result
= result
>> 16;
3568 cpu
.edx
= (cpu
.edx
& 0xffff0000) | (0xffff & result
);
3570 cpu
.setOverflowFlag(result
, Processor
.OF_LOW_WORD_NZ
);
3571 cpu
.setCarryFlag(result
, Processor
.CY_LOW_WORD_NZ
);
3574 private final void mul_o32(int data
)
3576 long x
= cpu
.eax
& 0xffffffffl
;
3577 long y
= 0xffffffffl
& data
;
3579 long result
= x
* y
;
3580 cpu
.eax
= (int)result
;
3581 result
= result
>>> 32;
3582 cpu
.edx
= (int)result
;
3584 cpu
.setOverflowFlag((int)result
, Processor
.OF_NZ
);
3585 cpu
.setCarryFlag((int)result
, Processor
.CY_NZ
);
3588 private final void imula_o8(byte data
)
3590 byte al
= (byte)cpu
.eax
;
3591 int result
= al
* data
;
3593 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (result
& 0xffff);
3595 cpu
.setOverflowFlag(result
, Processor
.OF_NOT_BYTE
);
3596 cpu
.setCarryFlag(result
, Processor
.CY_NOT_BYTE
);
3599 private final void imula_o16(short data
)
3601 short ax
= (short)cpu
.eax
;
3602 int result
= ax
* data
;
3604 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (result
& 0xffff);
3605 cpu
.edx
= (cpu
.edx
& ~
0xffff) | (result
>>> 16);
3607 //answer too wide for 16-bits?
3608 cpu
.setOverflowFlag(result
, Processor
.OF_NOT_SHORT
);
3609 cpu
.setCarryFlag(result
, Processor
.CY_NOT_SHORT
);
3612 private final void imula_o32(int data
)
3614 long eax
= (long)cpu
.eax
;
3615 long y
= (long)data
;
3616 long result
= eax
* y
;
3618 cpu
.eax
= (int)result
;
3619 cpu
.edx
= (int)(result
>>> 32);
3621 //answer too wide for 32-bits?
3622 cpu
.setOverflowFlag(result
, Processor
.OF_NOT_INT
);
3623 cpu
.setCarryFlag(result
, Processor
.CY_NOT_INT
);
3626 private final int imul_o16(short data0
, short data1
)
3628 int result
= data0
* data1
;
3629 cpu
.setOverflowFlag(result
, Processor
.OF_NOT_SHORT
);
3630 cpu
.setCarryFlag(result
, Processor
.CY_NOT_SHORT
);
3634 private final int imul_o32(int data0
, int data1
)
3636 long x
= (long)data0
;
3637 long y
= (long)data1
;
3639 long result
= x
* y
;
3640 cpu
.setOverflowFlag(result
, Processor
.OF_NOT_INT
);
3641 cpu
.setCarryFlag(result
, Processor
.CY_NOT_INT
);
3645 private final void div_o8(int data
)
3648 throw ProcessorException
.DIVIDE_ERROR
;
3650 int x
= (cpu
.eax
& 0xffff);
3652 int result
= x
/ data
;
3654 throw ProcessorException
.DIVIDE_ERROR
;
3656 int remainder
= (x
% data
) << 8;
3657 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (0xff & result
) | (0xff00 & remainder
);
3660 private final void div_o16(int data
)
3663 throw ProcessorException
.DIVIDE_ERROR
;
3665 long x
= (cpu
.edx
& 0xffffl
);
3667 x
|= (cpu
.eax
& 0xffffl
);
3669 long result
= x
/ data
;
3670 if (result
> 0xffffl
)
3671 throw ProcessorException
.DIVIDE_ERROR
;
3673 long remainder
= x
% data
;
3674 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (int)(result
& 0xffff);
3675 cpu
.edx
= (cpu
.edx
& ~
0xffff) | (int)(remainder
& 0xffff);
3678 private final void div_o32(int data
)
3680 long d
= 0xffffffffl
& data
;
3683 throw ProcessorException
.DIVIDE_ERROR
;
3685 long temp
= (long)cpu
.edx
;
3687 temp
|= (0xffffffffl
& cpu
.eax
);
3689 long r2
= (temp
& 1);
3690 long n2
= (temp
>>> 1);
3696 long r
= (m2
<< 1) + r2
;
3700 if (q
> 0xffffffffl
)
3701 throw ProcessorException
.DIVIDE_ERROR
;
3707 private final void idiv_o8(byte data
)
3710 throw ProcessorException
.DIVIDE_ERROR
;
3712 short temp
= (short)cpu
.eax
;
3713 int result
= temp
/ data
;
3714 int remainder
= temp
% data
;
3715 if ((result
> Byte
.MAX_VALUE
) || (result
< Byte
.MIN_VALUE
))
3716 throw ProcessorException
.DIVIDE_ERROR
;
3718 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (0xff & result
) | ((0xff & remainder
) << 8); //AH is remainder
3721 private final void idiv_o16(short data
)
3724 throw ProcessorException
.DIVIDE_ERROR
;
3726 int temp
= (cpu
.edx
<< 16) | (cpu
.eax
& 0xffff);
3727 int result
= temp
/ (int)data
;
3728 int remainder
= temp
% data
;
3730 if ((result
> Short
.MAX_VALUE
) || (result
< Short
.MIN_VALUE
))
3731 throw ProcessorException
.DIVIDE_ERROR
;
3733 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (0xffff & result
); //AX is result
3734 cpu
.edx
= (cpu
.edx
& ~
0xffff) | (0xffff & remainder
); //DX is remainder
3737 private final void idiv_o32(int data
)
3740 throw ProcessorException
.DIVIDE_ERROR
;
3742 long temp
= (0xffffffffl
& cpu
.edx
) << 32;
3743 temp
|= (0xffffffffl
& cpu
.eax
);
3744 long result
= temp
/ data
;
3745 if ((result
> Integer
.MAX_VALUE
) || (result
< Integer
.MIN_VALUE
))
3746 throw ProcessorException
.DIVIDE_ERROR
;
3748 long remainder
= temp
% data
;
3750 cpu
.eax
= (int)result
; //EAX is result
3751 cpu
.edx
= (int)remainder
; //EDX is remainder
3754 private final void btc_mem(int offset
, Segment segment
, int address
) throws ProcessorException
3756 address
+= (offset
>>> 3);
3759 byte data
= segment
.getByte(address
);
3760 segment
.setByte(address
, (byte)(data ^
(1 << offset
)));
3761 cpu
.setCarryFlag(data
, offset
, Processor
.CY_NTH_BIT_SET
);
3764 private final void bts_mem(int offset
, Segment segment
, int address
) throws ProcessorException
3766 address
+= (offset
>>> 3);
3769 byte data
= segment
.getByte(address
);
3770 segment
.setByte(address
, (byte)(data
| (1 << offset
)));
3771 cpu
.setCarryFlag(data
, offset
, Processor
.CY_NTH_BIT_SET
);
3774 private final void btr_mem(int offset
, Segment segment
, int address
) throws ProcessorException
3776 address
+= (offset
>>> 3);
3779 byte data
= segment
.getByte(address
);
3780 segment
.setByte(address
, (byte)(data
& ~
(1 << offset
)));
3781 cpu
.setCarryFlag(data
, offset
, Processor
.CY_NTH_BIT_SET
);
3784 private final void bt_mem(int offset
, Segment segment
, int address
) throws ProcessorException
3786 address
+= (offset
>>> 3);
3788 cpu
.setCarryFlag(segment
.getByte(address
), offset
, Processor
.CY_NTH_BIT_SET
);
3791 private final int bsf(int source
, int initial
) throws ProcessorException
3794 cpu
.setZeroFlag(true);
3797 cpu
.setZeroFlag(false);
3798 return numberOfTrailingZeros(source
);
3802 private final int bsr(int source
, int initial
) throws ProcessorException
3805 cpu
.setZeroFlag(true);
3808 cpu
.setZeroFlag(false);
3809 return 31 - numberOfLeadingZeros(source
);
3813 private final void aaa()
3815 if (((cpu
.eax
& 0xf) > 0x9) || cpu
.getAuxiliaryCarryFlag()) {
3816 int alCarry
= ((cpu
.eax
& 0xff) > 0xf9) ?
0x100 : 0x000;
3817 cpu
.eax
= (0xffff0000 & cpu
.eax
) | (0x0f & (cpu
.eax
+ 6)) | (0xff00 & (cpu
.eax
+ 0x100 + alCarry
));
3818 cpu
.setAuxiliaryCarryFlag(true);
3819 cpu
.setCarryFlag(true);
3821 cpu
.setAuxiliaryCarryFlag(false);
3822 cpu
.setCarryFlag(false);
3823 cpu
.eax
= cpu
.eax
& 0xffffff0f;
3827 private final void aad(int base
) throws ProcessorException
3829 int tl
= (cpu
.eax
& 0xff);
3830 int th
= ((cpu
.eax
>> 8) & 0xff);
3832 int ax1
= th
* base
;
3835 cpu
.eax
= (cpu
.eax
& ~
0xffff) | (ax2
& 0xff);
3838 // bitwise_flags((byte)ax2);
3840 cpu
.setZeroFlag((byte)ax2
);
3841 cpu
.setParityFlag((byte)ax2
);
3842 cpu
.setSignFlag((byte)ax2
);
3844 cpu
.setAuxiliaryCarryFlag(ax1
, ax2
, Processor
.AC_BIT4_NEQ
);
3845 cpu
.setCarryFlag(ax2
, Processor
.CY_GREATER_FF
);
3846 cpu
.setOverflowFlag(ax2
, tl
, Processor
.OF_BIT7_DIFFERENT
);
3849 private final int aam(int base
) throws ProcessorException
3851 int tl
= 0xff & cpu
.eax
;
3853 throw ProcessorException
.DIVIDE_ERROR
;
3854 int ah
= 0xff & (tl
/ base
);
3855 int al
= 0xff & (tl
% base
);
3857 cpu
.eax
|= (al
| (ah
<< 8));
3859 cpu
.setAuxiliaryCarryFlag(false);
3861 // bitwise_flags((byte)al);
3865 private final void aas()
3867 if (((cpu
.eax
& 0xf) > 0x9) || cpu
.getAuxiliaryCarryFlag()) {
3868 int alBorrow
= (cpu
.eax
& 0xff) < 6 ?
0x100 : 0x000;
3869 cpu
.eax
= (0xffff0000 & cpu
.eax
) | (0x0f & (cpu
.eax
- 6)) | (0xff00 & (cpu
.eax
- 0x100 - alBorrow
));
3870 cpu
.setAuxiliaryCarryFlag(true);
3871 cpu
.setCarryFlag(true);
3873 cpu
.setAuxiliaryCarryFlag(false);
3874 cpu
.setCarryFlag(false);
3875 cpu
.eax
= cpu
.eax
& 0xffffff0f;
3879 private final void daa()
3881 int al
= cpu
.eax
& 0xff;
3883 if (((cpu
.eax
& 0xf) > 0x9) || cpu
.getAuxiliaryCarryFlag()) {
3885 cpu
.setAuxiliaryCarryFlag(true);
3887 cpu
.setAuxiliaryCarryFlag(false);
3889 if (((al
& 0xff) > 0x9f) || cpu
.getCarryFlag()) {
3895 cpu
.eax
= (cpu
.eax
& ~
0xff) | (0xff & al
);
3897 // bitwise_flags((byte)al);
3899 cpu
.setOverflowFlag(false);
3900 cpu
.setZeroFlag((byte)al
);
3901 cpu
.setParityFlag((byte)al
);
3902 cpu
.setSignFlag((byte)al
);
3904 cpu
.setCarryFlag(newCF
);
3907 private final void das()
3909 boolean tempCF
= false;
3910 int tempAL
= 0xff & cpu
.eax
;
3911 if (((tempAL
& 0xf) > 0x9) || cpu
.getAuxiliaryCarryFlag()) {
3912 cpu
.setAuxiliaryCarryFlag(true);
3913 cpu
.eax
= (cpu
.eax
& ~
0xff) | ((cpu
.eax
- 0x06) & 0xff);
3914 tempCF
= (tempAL
< 0x06) || cpu
.getCarryFlag();
3917 if ((tempAL
> 0x99) || cpu
.getCarryFlag()) {
3918 cpu
.eax
= (cpu
.eax
& ~
0xff) | ((cpu
.eax
- 0x60) & 0xff);
3922 // bitwise_flags((byte)cpu.eax);
3924 cpu
.setOverflowFlag(false);
3925 cpu
.setZeroFlag((byte)cpu
.eax
);
3926 cpu
.setParityFlag((byte)cpu
.eax
);
3927 cpu
.setSignFlag((byte)cpu
.eax
);
3929 cpu
.setCarryFlag(tempCF
);
3932 private final void lahf()
3934 int result
= 0x0200;
3935 if (cpu
.getSignFlag()) result
|= 0x8000;
3936 if (cpu
.getZeroFlag()) result
|= 0x4000;
3937 if (cpu
.getAuxiliaryCarryFlag()) result
|= 0x1000;
3938 if (cpu
.getParityFlag()) result
|= 0x0400;
3939 if (cpu
.getCarryFlag()) result
|= 0x0100;
3940 cpu
.eax
&= 0xffff00ff;
3944 private final void sahf()
3946 int ah
= (cpu
.eax
& 0xff00);
3947 cpu
.setCarryFlag(0 != (ah
& 0x0100));
3948 cpu
.setParityFlag(0 != (ah
& 0x0400));
3949 cpu
.setAuxiliaryCarryFlag(0 != (ah
& 0x1000));
3950 cpu
.setZeroFlag(0 != (ah
& 0x4000));
3951 cpu
.setSignFlag(0 != (ah
& 0x8000));
3954 private final void cpuid()
3959 cpu
.ebx
= 0x756e6547; /* "Genu", with G in the low nibble of BL */
3960 cpu
.edx
= 0x49656e69; /* "ineI", with i in the low nibble of DL */
3961 cpu
.ecx
= 0x6c65746e; /* "ntel", with n in the low nibble of CL */
3964 cpu
.eax
= 0x00000633; // Pentium II Model 8 Stepping 3
3965 cpu
.ebx
= 8 << 8; //not implemented (should be brand index)
3969 features
|= 0x01; //Have an FPU;
3970 features
|= (1<< 8); // Support CMPXCHG8B instruction
3971 features
|= (1<< 4); // implement TSC
3972 features
|= (1<< 5); // support RDMSR/WRMSR
3973 //features |= (1<<23); // support MMX
3974 //features |= (1<<24); // Implement FSAVE/FXRSTOR instructions.
3975 features
|= (1<<15); // Implement CMOV instructions.
3976 //features |= (1<< 9); // APIC on chip
3977 //features |= (1<<25); // support SSE
3978 features
|= (1<< 3); // Support Page-Size Extension (4M pages)
3979 features
|= (1<<13); // Support Global pages.
3980 //features |= (1<< 6); // Support PAE.
3981 features
|= (1<<11); // SYSENTER/SYSEXIT
3994 private final void bitwise_flags(byte result
)
3996 cpu
.setOverflowFlag(false);
3997 cpu
.setCarryFlag(false);
3998 cpu
.setZeroFlag(result
);
3999 cpu
.setParityFlag(result
);
4000 cpu
.setSignFlag(result
);
4003 private final void bitwise_flags(short result
)
4005 cpu
.setOverflowFlag(false);
4006 cpu
.setCarryFlag(false);
4007 cpu
.setZeroFlag(result
);
4008 cpu
.setParityFlag(result
);
4009 cpu
.setSignFlag(result
);
4012 private final void bitwise_flags(int result
)
4014 cpu
.setOverflowFlag(false);
4015 cpu
.setCarryFlag(false);
4016 cpu
.setZeroFlag(result
);
4017 cpu
.setParityFlag(result
);
4018 cpu
.setSignFlag(result
);
4021 private final void arithmetic_flags_o8(int result
, int operand1
, int operand2
)
4023 cpu
.setZeroFlag((byte)result
);
4024 cpu
.setParityFlag(result
);
4025 cpu
.setSignFlag((byte)result
);
4027 cpu
.setCarryFlag(result
, Processor
.CY_TWIDDLE_FF
);
4028 cpu
.setAuxiliaryCarryFlag(operand1
, operand2
, result
, Processor
.AC_XOR
);
4031 private final void arithmetic_flags_o16(int result
, int operand1
, int operand2
)
4033 cpu
.setZeroFlag((short)result
);
4034 cpu
.setParityFlag(result
);
4035 cpu
.setSignFlag((short)result
);
4037 cpu
.setCarryFlag(result
, Processor
.CY_TWIDDLE_FFFF
);
4038 cpu
.setAuxiliaryCarryFlag(operand1
, operand2
, result
, Processor
.AC_XOR
);
4041 private final void arithmetic_flags_o32(long result
, int operand1
, int operand2
)
4043 cpu
.setZeroFlag((int)result
);
4044 cpu
.setParityFlag((int)result
);
4045 cpu
.setSignFlag((int)result
);
4047 cpu
.setCarryFlag(result
, Processor
.CY_TWIDDLE_FFFFFFFF
);
4048 cpu
.setAuxiliaryCarryFlag(operand1
, operand2
, (int)result
, Processor
.AC_XOR
);
4051 private final void add_o32_flags(long result
, int operand1
, int operand2
)
4053 result
= (0xffffffffl
& operand1
) + (0xffffffffl
& operand2
);
4055 arithmetic_flags_o32(result
, operand1
, operand2
);
4056 cpu
.setOverflowFlag((int)result
, operand1
, operand2
, Processor
.OF_ADD_INT
);
4059 private final void add_o16_flags(int result
, int operand1
, int operand2
)
4061 arithmetic_flags_o16(result
, operand1
, operand2
);
4062 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_ADD_SHORT
);
4065 private final void add_o8_flags(int result
, int operand1
, int operand2
)
4067 arithmetic_flags_o8(result
, operand1
, operand2
);
4068 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_ADD_BYTE
);
4071 private final void adc_o32_flags(long result
, int operand1
, int operand2
)
4073 int carry
= (cpu
.getCarryFlag() ?
1 : 0);
4075 result
= (0xffffffffl
& operand1
) + (0xffffffffl
& operand2
) + carry
;
4077 if (cpu
.getCarryFlag() && (operand2
== 0xffffffff)) {
4078 arithmetic_flags_o32(result
, operand1
, operand2
);
4079 cpu
.setOverflowFlag(false);
4080 cpu
.setCarryFlag(true);
4082 cpu
.setOverflowFlag((int)result
, operand1
, operand2
, Processor
.OF_ADD_INT
);
4083 arithmetic_flags_o32(result
, operand1
, operand2
);
4087 private final void adc_o16_flags(int result
, int operand1
, int operand2
)
4089 if (cpu
.getCarryFlag() && (operand2
== 0xffff)) {
4090 arithmetic_flags_o16(result
, operand1
, operand2
);
4091 cpu
.setOverflowFlag(false);
4092 cpu
.setCarryFlag(true);
4094 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_ADD_SHORT
);
4095 arithmetic_flags_o16(result
, operand1
, operand2
);
4099 private final void adc_o8_flags(int result
, int operand1
, int operand2
)
4101 if (cpu
.getCarryFlag() && (operand2
== 0xff)) {
4102 arithmetic_flags_o8(result
, operand1
, operand2
);
4103 cpu
.setOverflowFlag(false);
4104 cpu
.setCarryFlag(true);
4106 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_ADD_BYTE
);
4107 arithmetic_flags_o8(result
, operand1
, operand2
);
4111 private final void sub_o32_flags(long result
, int operand1
, int operand2
)
4113 result
= (0xffffffffl
& operand1
) - (0xffffffffl
& operand2
);
4115 arithmetic_flags_o32(result
, operand1
, operand2
);
4116 cpu
.setOverflowFlag((int)result
, operand1
, operand2
, Processor
.OF_SUB_INT
);
4119 private final void sub_o16_flags(int result
, int operand1
, int operand2
)
4121 arithmetic_flags_o16(result
, operand1
, operand2
);
4122 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_SUB_SHORT
);
4125 private final void sub_o8_flags(int result
, int operand1
, int operand2
)
4127 arithmetic_flags_o8(result
, operand1
, operand2
);
4128 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_SUB_BYTE
);
4131 private final void rep_sub_o32_flags(int used
, int operand1
, int operand2
)
4136 long result
= (0xffffffffl
& operand1
) - (0xffffffffl
& operand2
);
4138 arithmetic_flags_o32(result
, operand1
, operand2
);
4139 cpu
.setOverflowFlag((int)result
, operand1
, operand2
, Processor
.OF_SUB_INT
);
4142 private final void rep_sub_o16_flags(int used
, int operand1
, int operand2
)
4147 int result
= operand1
- operand2
;
4149 arithmetic_flags_o16(result
, operand1
, operand2
);
4150 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_SUB_SHORT
);
4153 private final void rep_sub_o8_flags(int used
, int operand1
, int operand2
)
4158 int result
= operand1
- operand2
;
4160 arithmetic_flags_o8(result
, operand1
, operand2
);
4161 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_SUB_BYTE
);
4164 private final void sbb_o32_flags(long result
, int operand1
, int operand2
)
4166 int carry
= (cpu
.getCarryFlag() ?
1 : 0);
4167 result
= (0xffffffffl
& operand1
) - ((0xffffffffl
& operand2
) + carry
);
4169 cpu
.setOverflowFlag((int)result
, operand1
, operand2
, Processor
.OF_SUB_INT
);
4170 arithmetic_flags_o32(result
, operand1
, operand2
);
4173 private final void sbb_o16_flags(int result
, int operand1
, int operand2
)
4175 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_SUB_SHORT
);
4176 arithmetic_flags_o16(result
, operand1
, operand2
);
4179 private final void sbb_o8_flags(int result
, int operand1
, int operand2
)
4181 cpu
.setOverflowFlag(result
, operand1
, operand2
, Processor
.OF_SUB_BYTE
);
4182 arithmetic_flags_o8(result
, operand1
, operand2
);
4185 private final void dec_flags(int result
)
4187 cpu
.setZeroFlag(result
);
4188 cpu
.setParityFlag(result
);
4189 cpu
.setSignFlag(result
);
4190 cpu
.setOverflowFlag(result
, Processor
.OF_MAX_INT
);
4191 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_MAX
);
4194 private final void dec_flags(short result
)
4196 cpu
.setZeroFlag(result
);
4197 cpu
.setParityFlag(result
);
4198 cpu
.setSignFlag(result
);
4199 cpu
.setOverflowFlag(result
, Processor
.OF_MAX_SHORT
);
4200 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_MAX
);
4203 private final void dec_flags(byte result
)
4205 cpu
.setZeroFlag(result
);
4206 cpu
.setParityFlag(result
);
4207 cpu
.setSignFlag(result
);
4208 cpu
.setOverflowFlag(result
, Processor
.OF_MAX_BYTE
);
4209 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_MAX
);
4212 private final void inc_flags(int result
)
4214 cpu
.setZeroFlag(result
);
4215 cpu
.setParityFlag(result
);
4216 cpu
.setSignFlag(result
);
4217 cpu
.setOverflowFlag(result
, Processor
.OF_MIN_INT
);
4218 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_ZERO
);
4221 private final void inc_flags(short result
)
4223 cpu
.setZeroFlag(result
);
4224 cpu
.setParityFlag(result
);
4225 cpu
.setSignFlag(result
);
4226 cpu
.setOverflowFlag(result
, Processor
.OF_MIN_SHORT
);
4227 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_ZERO
);
4230 private final void inc_flags(byte result
)
4232 cpu
.setZeroFlag(result
);
4233 cpu
.setParityFlag(result
);
4234 cpu
.setSignFlag(result
);
4235 cpu
.setOverflowFlag(result
, Processor
.OF_MIN_BYTE
);
4236 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_ZERO
);
4239 private final void shl_flags(byte result
, byte initial
, int count
)
4242 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHL_OUTBIT_BYTE
);
4245 cpu
.setOverflowFlag(result
, Processor
.OF_BIT7_XOR_CARRY
);
4247 cpu
.setZeroFlag(result
);
4248 cpu
.setParityFlag(result
);
4249 cpu
.setSignFlag(result
);
4253 private final void shl_flags(short result
, short initial
, int count
)
4256 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHL_OUTBIT_SHORT
);
4259 cpu
.setOverflowFlag(result
, Processor
.OF_BIT15_XOR_CARRY
);
4261 cpu
.setZeroFlag(result
);
4262 cpu
.setParityFlag(result
);
4263 cpu
.setSignFlag(result
);
4267 private final void shl_flags(int result
, int initial
, int count
)
4270 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHL_OUTBIT_INT
);
4273 cpu
.setOverflowFlag(result
, Processor
.OF_BIT31_XOR_CARRY
);
4275 cpu
.setZeroFlag(result
);
4276 cpu
.setParityFlag(result
);
4277 cpu
.setSignFlag(result
);
4281 private final void shr_flags(byte result
, int initial
, int count
)
4284 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHR_OUTBIT
);
4287 cpu
.setOverflowFlag(result
, initial
, Processor
.OF_BIT7_DIFFERENT
);
4289 cpu
.setZeroFlag(result
);
4290 cpu
.setParityFlag(result
);
4291 cpu
.setSignFlag(result
);
4295 private final void shr_flags(short result
, int initial
, int count
)
4298 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHR_OUTBIT
);
4301 cpu
.setOverflowFlag(result
, initial
, Processor
.OF_BIT15_DIFFERENT
);
4303 cpu
.setZeroFlag(result
);
4304 cpu
.setParityFlag(result
);
4305 cpu
.setSignFlag(result
);
4309 private final void shr_flags(int result
, int initial
, int count
)
4312 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHR_OUTBIT
);
4315 cpu
.setOverflowFlag(result
, initial
, Processor
.OF_BIT31_DIFFERENT
);
4317 cpu
.setZeroFlag(result
);
4318 cpu
.setParityFlag(result
);
4319 cpu
.setSignFlag(result
);
4324 private final void sar_flags(byte result
, byte initial
, int count
)
4327 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHR_OUTBIT
);
4328 if (count
== 1) cpu
.setOverflowFlag(false);
4330 cpu
.setSignFlag(result
);
4331 cpu
.setZeroFlag(result
);
4332 cpu
.setParityFlag(result
);
4336 private final void sar_flags(short result
, short initial
, int count
)
4339 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHR_OUTBIT
);
4340 if (count
== 1) cpu
.setOverflowFlag(false);
4342 cpu
.setSignFlag(result
);
4343 cpu
.setZeroFlag(result
);
4344 cpu
.setParityFlag(result
);
4348 private final void sar_flags(int result
, int initial
, int count
)
4351 cpu
.setCarryFlag(initial
, count
, Processor
.CY_SHR_OUTBIT
);
4352 if (count
== 1) cpu
.setOverflowFlag(false);
4354 cpu
.setSignFlag(result
);
4355 cpu
.setZeroFlag(result
);
4356 cpu
.setParityFlag(result
);
4360 private final void rol_flags(byte result
, int count
)
4363 cpu
.setCarryFlag(result
, Processor
.CY_LOWBIT
);
4365 cpu
.setOverflowFlag(result
, Processor
.OF_BIT7_XOR_CARRY
);
4369 private final void rol_flags(short result
, int count
)
4372 cpu
.setCarryFlag(result
, Processor
.CY_LOWBIT
);
4374 cpu
.setOverflowFlag(result
, Processor
.OF_BIT15_XOR_CARRY
);
4378 private final void rol_flags(int result
, int count
)
4381 cpu
.setCarryFlag(result
, Processor
.CY_LOWBIT
);
4383 cpu
.setOverflowFlag(result
, Processor
.OF_BIT31_XOR_CARRY
);
4387 private final void ror_flags(byte result
, int count
)
4390 cpu
.setCarryFlag(result
, Processor
.CY_HIGHBIT_BYTE
);
4392 cpu
.setOverflowFlag(result
, Processor
.OF_BIT6_XOR_CARRY
);
4396 private final void ror_flags(short result
, int count
)
4399 cpu
.setCarryFlag(result
, Processor
.CY_HIGHBIT_SHORT
);
4401 cpu
.setOverflowFlag(result
, Processor
.OF_BIT14_XOR_CARRY
);
4405 private final void ror_flags(int result
, int count
)
4408 cpu
.setCarryFlag(result
, Processor
.CY_HIGHBIT_INT
);
4410 cpu
.setOverflowFlag(result
, Processor
.OF_BIT30_XOR_CARRY
);
4414 private final void rcl_o8_flags(int result
, int count
)
4417 cpu
.setCarryFlag(result
, Processor
.CY_OFFENDBIT_BYTE
);
4419 cpu
.setOverflowFlag(result
, Processor
.OF_BIT7_XOR_CARRY
);
4423 private final void rcl_o16_flags(int result
, int count
)
4426 cpu
.setCarryFlag(result
, Processor
.CY_OFFENDBIT_SHORT
);
4428 cpu
.setOverflowFlag(result
, Processor
.OF_BIT15_XOR_CARRY
);
4432 private final void rcl_o32_flags(long result
, int count
)
4435 cpu
.setCarryFlag(result
, Processor
.CY_OFFENDBIT_INT
);
4437 cpu
.setOverflowFlag(result
, Processor
.OF_BIT31_XOR_CARRY
);
4441 private final void rcr_o8_flags(int result
, int count
, int overflow
)
4444 cpu
.setCarryFlag(result
, Processor
.CY_OFFENDBIT_BYTE
);
4446 cpu
.setOverflowFlag(overflow
> 0);
4450 private final void rcr_o16_flags(int result
, int count
, int overflow
)
4453 cpu
.setCarryFlag(result
, Processor
.CY_OFFENDBIT_SHORT
);
4455 cpu
.setOverflowFlag(overflow
> 0);
4459 private final void rcr_o32_flags(long result
, int count
, int overflow
)
4462 cpu
.setCarryFlag(result
, Processor
.CY_OFFENDBIT_INT
);
4464 cpu
.setOverflowFlag(overflow
> 0);
4468 private final void neg_flags(byte result
)
4470 cpu
.setCarryFlag(result
, Processor
.CY_NZ
);
4471 cpu
.setOverflowFlag(result
, Processor
.OF_MIN_BYTE
);
4473 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_NZERO
);
4474 cpu
.setZeroFlag(result
);
4475 cpu
.setParityFlag(result
);
4476 cpu
.setSignFlag(result
);
4479 private final void neg_flags(short result
)
4481 cpu
.setCarryFlag(result
, Processor
.CY_NZ
);
4482 cpu
.setOverflowFlag(result
, Processor
.OF_MIN_SHORT
);
4484 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_NZERO
);
4485 cpu
.setZeroFlag(result
);
4486 cpu
.setParityFlag(result
);
4487 cpu
.setSignFlag(result
);
4490 private final void neg_flags(int result
)
4492 cpu
.setCarryFlag(result
, Processor
.CY_NZ
);
4493 cpu
.setOverflowFlag(result
, Processor
.OF_MIN_INT
);
4495 cpu
.setAuxiliaryCarryFlag(result
, Processor
.AC_LNIBBLE_NZERO
);
4496 cpu
.setZeroFlag(result
);
4497 cpu
.setParityFlag(result
);
4498 cpu
.setSignFlag(result
);
4501 //borrowed from the j2se api as not in midp
4502 private static int numberOfTrailingZeros(int i
) {
4505 if (i
== 0) return 32;
4507 y
= i
<<16; if (y
!= 0) { n
= n
-16; i
= y
; }
4508 y
= i
<< 8; if (y
!= 0) { n
= n
- 8; i
= y
; }
4509 y
= i
<< 4; if (y
!= 0) { n
= n
- 4; i
= y
; }
4510 y
= i
<< 2; if (y
!= 0) { n
= n
- 2; i
= y
; }
4511 return n
- ((i
<< 1) >>> 31);
4514 private static int numberOfLeadingZeros(int i
) {
4519 if (i
>>> 16 == 0) { n
+= 16; i
<<= 16; }
4520 if (i
>>> 24 == 0) { n
+= 8; i
<<= 8; }
4521 if (i
>>> 28 == 0) { n
+= 4; i
<<= 4; }
4522 if (i
>>> 30 == 0) { n
+= 2; i
<<= 2; }