Clean up emulator internal error messages
[jpcrr.git] / org / jpc / emulator / memory / codeblock / optimised / RealModeUBlock.java
blobde0cb4b75e06cb31e04dd81c8b6eaed31da19e21
1 /*
2 JPC-RR: A x86 PC Hardware Emulator
3 Release 1
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.*;
35 import org.jpc.Misc;
36 import static org.jpc.emulator.memory.codeblock.optimised.MicrocodeSet.*;
38 /**
40 * @author Chris Dennis
42 public final class RealModeUBlock implements RealModeCodeBlock
44 private static final boolean[] parityMap;
46 static
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;
54 private FpuState fpu;
56 private int x86Count;
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)
72 x86Count = 0;
73 else {
74 int count = 1;
75 for (int i = 1; i < cumulativeX86Length.length; i++) {
76 if (cumulativeX86Length[i] > cumulativeX86Length[i-1]) count++;
78 x86Count = count;
82 public int getX86Length()
84 if (microcodes.length == 0)
85 return 0;
86 return cumulativeX86Length[microcodes.length-1];
89 public int getX86Count()
91 return x86Count;
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)
105 return false;
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);
127 return result;
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;
155 try {
156 switch (microcodes[position++]) {
157 case EIP_UPDATE:
158 if (!eipUpdated) {
159 eipUpdated = true;
160 cpu.eip += cumulativeX86Length[position - 1];
162 break;
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;
308 case STORE0_SS:
309 cpu.ss.setSelector(0xffff & reg0);
310 if(cpu.ss != null)
311 cachedSSSize = cpu.ss.getDefaultSizeFlag();
312 break;
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()));
316 break;
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;
321 case STORE1_SS:
322 cpu.ss.setSelector(0xffff & reg1);
323 if(cpu.ss != null)
324 cachedSSSize = cpu.ss.getDefaultSizeFlag();
325 break;
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;
435 case CALL_FAR_O16:
436 if (cachedSSSize)
437 call_far_o16_a32(reg0, reg1);
438 else
439 call_far_o16_a16(reg0, reg1);
440 break;
442 case CALL_FAR_O32:
443 if (cachedSSSize)
444 call_far_o32_a32(reg0, reg1);
445 else
446 call_far_o32_a16(reg0, reg1);
447 break;
449 case CALL_ABS_O16:
450 if (cachedSSSize)
451 call_abs_o16_a32(reg0);
452 else
453 call_abs_o16_a16(reg0);
454 break;
456 case CALL_ABS_O32:
457 if (cachedSSSize)
458 call_abs_o32_a32(reg0);
459 else
460 call_abs_o32_a16(reg0);
461 break;
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;
544 case RCR_O8:
545 reg1 &= 0x1f;
546 reg1 %= 9;
547 reg0 |= (cpu.getCarryFlag() ? 0x100 : 0);
548 reg2 = (cpu.getCarryFlag() ^ ((reg0 & 0x80) != 0) ? 1 : 0);
549 reg0 = (reg0 >>> reg1) | (reg0 << (9 - reg1));
550 break;
551 case RCR_O16:
552 reg1 &= 0x1f;
553 reg1 %= 17;
554 reg2 = (cpu.getCarryFlag() ^ ((reg0 & 0x8000) != 0) ? 1 : 0);
555 reg0 |= (cpu.getCarryFlag() ? 0x10000 : 0);
556 reg0 = (reg0 >>> reg1) | (reg0 << (17 - reg1));
557 break;
558 case RCR_O32:
559 reg1 &= 0x1f;
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)));
563 break;
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;
570 case SHLD_O16: {
571 int i = reg0;
572 reg2 &= 0x1f;
573 if (reg2 < 16)
575 reg0 = (reg0 << reg2) | (reg1 >>> (16 - reg2));
576 reg1 = reg2;
577 reg2 = i;
579 else
581 i = (reg1 & 0xFFFF) | (reg0 << 16);
582 reg0 = (reg1 << (reg2 - 16)) | ((reg0 & 0xFFFF) >>> (32 - reg2));
583 reg1 = reg2 - 15;
584 reg2 = i >> 1;
586 } break;
587 case SHLD_O32: {
588 int i = reg0; reg2 &= 0x1f;
589 if (reg2 != 0)
590 reg0 = (reg0 << reg2) | (reg1 >>> (32 - reg2));
591 reg1 = reg2; reg2 = i;
592 } break;
594 case SHRD_O16: {
595 int i = reg0;
596 reg2 &= 0x1f;
597 if (reg2 < 16)
599 reg0 = (reg0 >>> reg2) | (reg1 << (16 - reg2));
600 reg1 = reg2;
601 reg2 = i;
603 else
605 i = (reg0 & 0xFFFF) | (reg1 << 16);
606 reg0 = (reg1 >>> (reg2 - 16)) | (reg0 << (32 - reg2));
607 reg1 = reg2;
608 reg2 = i;
610 } break;
611 case SHRD_O32: {
612 int i = reg0; reg2 &= 0x1f;
613 if (reg2 != 0)
614 reg0 = (reg0 >>> reg2) | (reg1 << (32 - reg2));
615 reg1 = reg2; reg2 = i;
616 } break;
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;
629 case BOUND_O16: {
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;
635 } break;
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;
667 case POP_O16: {
668 if(cachedSSSize) {
669 reg1 = cpu.esp + 2;
670 if (microcodes[position] == STORE0_SS)
671 cpu.eflagsInterruptEnable = false;
672 reg0 = 0xffff & cpu.ss.getWord(cpu.esp);
673 } else {
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);
679 } break;
681 case POP_O32: {
682 if(cachedSSSize) {
683 reg1 = cpu.esp + 4;
684 if (microcodes[position] == STORE0_SS)
685 cpu.eflagsInterruptEnable = false;
686 reg0 = cpu.ss.getDoubleWord(cpu.esp);
687 } else {
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);
693 } break;
695 case POPF_O16:
696 if(cachedSSSize) {
697 reg0 = 0xffff & cpu.ss.getWord(cpu.esp);
698 cpu.esp = cpu.esp + 2;
699 } else {
700 reg0 = 0xffff & cpu.ss.getWord(cpu.esp & 0xffff);
701 cpu.esp = (cpu.esp & ~0xffff) | ((cpu.esp + 2) & 0xffff);
703 break;
705 case POPF_O32:
706 if(cachedSSSize) {
707 reg0 = (cpu.getEFlags() & 0x20000) | (cpu.ss.getDoubleWord(cpu.esp) & ~0x1a0000);
708 cpu.esp = cpu.esp + 4;
709 } else {
710 reg0 = (cpu.getEFlags() & 0x20000) | (cpu.ss.getDoubleWord(cpu.esp & 0xffff) & ~0x1a0000);
711 cpu.esp = (cpu.esp & ~0xffff) | ((cpu.esp + 4) & 0xffff);
713 break;
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;
965 default: {
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,
973 reg0l);
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++;
982 } finally {
983 //copy local variables back to instance storage
984 transferSeg0 = seg0;
985 transferAddr0 = addr0;
986 transferReg0 = reg0;
987 transferReg1 = reg1;
988 transferReg2 = reg2;
989 transferReg0l = reg0l;
990 transferEipUpdated = eipUpdated;
991 transferPosition = position;
995 public int execute(Processor cpu)
997 this.fpu = cpu.fpu;
998 this.cpu = cpu;
1000 if (opcodeCounter != null)
1001 opcodeCounter.addBlock(getMicrocodes());
1003 cachedSSSize = false;
1004 if(cpu.ss != null)
1005 cachedSSSize = cpu.ss.getDefaultSizeFlag();
1007 Segment seg0 = null;
1008 int addr0 = 0;
1009 int reg0 = 0, reg1 = 0, reg2 = 0;
1010 long reg0l = 0;
1012 executeCount = 0;
1013 boolean eipUpdated = false;
1015 int position = 0;
1017 cpu.eflagsLastAborted = false;
1018 if(fpu != null)
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
1035 eipUpdated = true;
1036 cpu.eip += cumulativeX86Length[position - 1];
1037 } break;
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()) {
1049 reg1 = cpu.esp + 2;
1050 if (microcodes[position] == STORE0_SS)
1051 cpu.eflagsInterruptEnable = false;
1052 reg0 = 0xffff & cpu.ss.getWord(cpu.esp);
1053 } else {
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);
1059 } break;
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:
1157 executeCount++;
1158 if(cpu.eflagsMachineHalt) throw ProcessorException.TRACESTOP;
1159 //Handle special case of continuing WAIT after abort.
1160 if(!cpu.eflagsWaiting)
1161 cpu.instructionExecuted();
1162 break;
1164 default:
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;
1175 try {
1176 fullExecute(cpu);
1177 } finally {
1178 seg0 = transferSeg0;
1179 addr0 = transferAddr0;
1180 reg0 = transferReg0;
1181 reg1 = transferReg1;
1182 reg2 = transferReg2;
1183 reg0l = transferReg0l;
1184 eipUpdated = transferEipUpdated;
1185 position = transferPosition;
1187 } break;
1191 catch (ProcessorException e)
1193 int nextPosition = position - 1; //this makes position point at the microcode that just barfed
1195 if (eipUpdated)
1196 cpu.eip -= cumulativeX86Length[nextPosition]; // undo the eipUpdate
1198 if (!e.pointsToSelf()) {
1199 cpu.eip += cumulativeX86Length[nextPosition];
1200 } else {
1201 for (int selfPosition = nextPosition; selfPosition >= 0; selfPosition--) {
1202 if (cumulativeX86Length[selfPosition] != cumulativeX86Length[nextPosition]) {
1203 cpu.eip += cumulativeX86Length[selfPosition];
1204 break;
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);
1214 else {
1215 cpu.eflagsLastAborted = true;
1216 executeCount--;
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)
1476 cpu.eip += offset;
1477 // check whether eip is outside of 0x0000 and 0xffff
1478 if ((cpu.eip & 0xFFFF0000) != 0)
1480 cpu.eip -= offset;
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)
1492 cpu.eip += offset;
1493 if ((cpu.eip & 0xFFFF0000) != 0)
1495 cpu.eip -= offset;
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)
1543 ret_o16_a16();
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"
1560 ret_far_o16_a16();
1561 cpu.esp = (cpu.esp & ~0xffff) | ((cpu.esp + offset) & 0xffff);
1564 private final void enter_o16_a16(int frameSize, int nestingLevel)
1566 nestingLevel %= 32;
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()
1593 try {
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);
1605 cpu.ebp = tempEBP;
1608 private final void push_o16(short data)
1610 if(cachedSSSize) {
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);
1616 cpu.esp = offset;
1617 } else {
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)
1629 if(cachedSSSize) {
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);
1635 cpu.esp = offset;
1636 } else {
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;
1649 if(cachedSSSize) {
1650 offset = cpu.esp;
1651 offmask = 0xffffffff;
1652 } else {
1653 offset = cpu.esp & 0xffff;
1654 offmask = 0xffff;
1657 //it seems that it checks at every push (we will simulate this)
1658 if ((offset < 16) && ((offset & 0x1) == 0x1)) {
1659 if (offset < 6)
1660 System.err.println("Emulated: Should shutdown machine (PUSHA with small ESP).");
1661 throw ProcessorException.GENERAL_PROTECTION_0;
1664 int temp = cpu.esp;
1666 offset -= 2;
1667 cpu.ss.setWord(offset, (short) cpu.eax);
1668 offset -= 2;
1669 cpu.ss.setWord(offset, (short) cpu.ecx);
1670 offset -= 2;
1671 cpu.ss.setWord(offset, (short) cpu.edx);
1672 offset -= 2;
1673 cpu.ss.setWord(offset, (short) cpu.ebx);
1674 offset -= 2;
1675 cpu.ss.setWord(offset, (short) temp);
1676 offset -= 2;
1677 cpu.ss.setWord(offset, (short) cpu.ebp);
1678 offset -= 2;
1679 cpu.ss.setWord(offset, (short) cpu.esi);
1680 offset -= 2;
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;
1689 if(cachedSSSize) {
1690 offset = cpu.esp;
1691 offmask = 0xffffffff;
1692 } else {
1693 offset = cpu.esp & 0xffff;
1694 offmask = 0xffff;
1697 int temp = cpu.esp;
1698 if ((offset < 32) && (offset > 0)) {
1699 System.err.println("Emulated: Throwing dodgy pushad exception.");
1700 throw ProcessorException.GENERAL_PROTECTION_0;
1703 offset -= 4;
1704 cpu.ss.setDoubleWord(offset, cpu.eax);
1705 offset -= 4;
1706 cpu.ss.setDoubleWord(offset, cpu.ecx);
1707 offset -= 4;
1708 cpu.ss.setDoubleWord(offset, cpu.edx);
1709 offset -= 4;
1710 cpu.ss.setDoubleWord(offset, cpu.ebx);
1711 offset -= 4;
1712 cpu.ss.setDoubleWord(offset, temp);
1713 offset -= 4;
1714 cpu.ss.setDoubleWord(offset, cpu.ebp);
1715 offset -= 4;
1716 cpu.ss.setDoubleWord(offset, cpu.esi);
1717 offset -= 4;
1718 cpu.ss.setDoubleWord(offset, cpu.edi);
1720 cpu.esp = (cpu.esp & ~offmask) | (offset & offmask);
1723 private final void popa()
1725 int offset, offmask;
1726 if(cachedSSSize) {
1727 offset = cpu.esp;
1728 offmask = 0xffffffff;
1729 } else {
1730 offset = cpu.esp & 0xffff;
1731 offmask = 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));
1738 offset += 2;
1739 cpu.esi = (cpu.esi & ~0xffff) | (0xffff & cpu.ss.getWord(offmask & offset));
1740 offset += 2;
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));
1744 offset += 2;
1745 cpu.edx = (cpu.edx & ~0xffff) | (0xffff & cpu.ss.getWord(offmask & offset));
1746 offset += 2;
1747 cpu.ecx = (cpu.ecx & ~0xffff) | (0xffff & cpu.ss.getWord(offmask & offset));
1748 offset += 2;
1749 cpu.eax = (cpu.eax & ~0xffff) | (0xffff & cpu.ss.getWord(offmask & offset));
1750 offset += 2;
1752 cpu.esp = (cpu.esp & ~offmask) | (offset & offmask);
1755 private final void popad()
1757 int offset, offmask;
1758 if(cachedSSSize) {
1759 offset = cpu.esp;
1760 offmask = 0xffffffff;
1761 } else {
1762 offset = cpu.esp & 0xffff;
1763 offmask = 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);
1771 offset += 4;
1772 cpu.esi = cpu.ss.getDoubleWord(offmask & offset);
1773 offset += 4;
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);
1778 offset += 4;
1779 cpu.edx = cpu.ss.getDoubleWord(offmask & offset);
1780 offset += 4;
1781 cpu.ecx = cpu.ss.getDoubleWord(offmask & offset);
1782 offset += 4;
1783 cpu.eax = cpu.ss.getDoubleWord(offmask & offset);
1784 offset += 4;
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);
1821 cpu.esp -= 4;
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);
1847 cpu.esp -= 8;
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);
1858 cpu.esp -= 4;
1859 cpu.eip = target;
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);
1868 cpu.eip = target;
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);
1876 cpu.esp -= 2;
1877 cpu.eip = target;
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);
1886 cpu.eip = target;
1889 private final void int_o16_a16(int vector)
1891 if(vector == 0) {
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()
1920 int vector = 3;
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()
1946 int vector = 1;
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);
1980 return flags;
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) {
1991 addrOne -= 1;
1992 addrTwo -= 1;
1993 } else {
1994 addrOne += 1;
1995 addrTwo += 1;
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) {
2016 addrOne -= 2;
2017 addrTwo -= 2;
2018 } else {
2019 addrOne += 2;
2020 addrTwo += 2;
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) {
2041 addrOne -= 4;
2042 addrTwo -= 4;
2043 } else {
2044 addrOne += 4;
2045 addrTwo += 4;
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;
2064 int dataOne = 0;
2065 int dataTwo = 0;
2067 try {
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);
2073 count--;
2074 addrOne -= 1;
2075 addrTwo -= 1;
2076 if (dataOne != dataTwo) break;
2078 } else {
2079 while (count != 0) {
2080 //check hardware interrupts
2081 dataOne = 0xff & seg0.getByte(addrOne);
2082 dataTwo = 0xff & cpu.es.getByte(addrTwo);
2083 count--;
2084 addrOne += 1;
2085 addrTwo += 1;
2086 if (dataOne != dataTwo) break;
2090 finally {
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);
2096 // if (used)
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;
2111 int dataOne = 0;
2112 int dataTwo = 0;
2114 try {
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);
2120 count--;
2121 addrOne -= 2;
2122 addrTwo -= 2;
2123 if (dataOne != dataTwo) break;
2125 } else {
2126 while (count != 0) {
2127 //check hardware interrupts
2128 dataOne = 0xffff & seg0.getWord(addrOne);
2129 dataTwo = 0xffff & cpu.es.getWord(addrTwo);
2130 count--;
2131 addrOne += 2;
2132 addrTwo += 2;
2133 if (dataOne != dataTwo) break;
2137 finally {
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);
2143 // if (used)
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;
2158 int dataOne = 0;
2159 int dataTwo = 0;
2161 try {
2162 if (cpu.eflagsDirection) {
2163 while (count != 0) {
2164 //check hardware interrupts
2165 dataOne = seg0.getDoubleWord(addrOne);
2166 dataTwo = cpu.es.getDoubleWord(addrTwo);
2167 count--;
2168 addrOne -= 4;
2169 addrTwo -= 4;
2170 if (dataOne != dataTwo) break;
2172 } else {
2173 while (count != 0) {
2174 //check hardware interrupts
2175 dataOne = seg0.getDoubleWord(addrOne);
2176 dataTwo = cpu.es.getDoubleWord(addrTwo);
2177 count--;
2178 addrOne += 4;
2179 addrTwo += 4;
2180 if (dataOne != dataTwo) break;
2184 finally {
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);
2190 // if (used)
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) {
2205 addr -= 1;
2206 } else {
2207 addr += 1;
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) {
2219 addr -= 2;
2220 } else {
2221 addr += 2;
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) {
2233 addr -= 4;
2234 } else {
2235 addr += 4;
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;
2247 try {
2248 if (cpu.eflagsDirection) {
2249 while (count != 0) {
2250 //check hardware interrupts
2251 cpu.es.setByte(addr & 0xffff, (byte)cpu.ioports.ioPortReadByte(port));
2252 count--;
2253 addr -= 1;
2255 } else {
2256 while (count != 0) {
2257 //check hardware interrupts
2258 cpu.es.setByte(addr & 0xffff, (byte)cpu.ioports.ioPortReadByte(port));
2259 count--;
2260 addr += 1;
2264 finally {
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;
2276 try {
2277 if (cpu.eflagsDirection) {
2278 while (count != 0) {
2279 //check hardware interrupts
2280 cpu.es.setWord(addr & 0xffff, (short)cpu.ioports.ioPortReadWord(port));
2281 count--;
2282 addr -= 2;
2284 } else {
2285 while (count != 0) {
2286 //check hardware interrupts
2287 cpu.es.setWord(addr & 0xffff, (short)cpu.ioports.ioPortReadWord(port));
2288 count--;
2289 addr += 2;
2293 finally {
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;
2305 try {
2306 if (cpu.eflagsDirection) {
2307 while (count != 0) {
2308 //check hardware interrupts
2309 cpu.es.setDoubleWord(addr & 0xffff, cpu.ioports.ioPortReadLong(port));
2310 count--;
2311 addr -= 4;
2313 } else {
2314 while (count != 0) {
2315 //check hardware interrupts
2316 cpu.es.setDoubleWord(addr & 0xffff, cpu.ioports.ioPortReadLong(port));
2317 count--;
2318 addr += 4;
2322 finally {
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)
2334 addr -= 1;
2335 else
2336 addr += 1;
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)
2347 addr -= 2;
2348 else
2349 addr += 2;
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)
2360 addr -= 4;
2361 else
2362 addr += 4;
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;
2374 try {
2375 if (cpu.eflagsDirection) {
2376 while (count != 0) {
2377 //check hardware interrupts
2378 data = 0xff & dataSegment.getByte(addr & 0xffff);
2379 count--;
2380 addr -= 1;
2382 } else {
2383 while (count != 0) {
2384 //check hardware interrupts
2385 data = 0xff & dataSegment.getByte(addr & 0xffff);
2386 count--;
2387 addr += 1;
2391 finally {
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;
2405 try {
2406 if (cpu.eflagsDirection) {
2407 while (count != 0) {
2408 //check hardware interrupts
2409 data = 0xffff & dataSegment.getWord(addr & 0xffff);
2410 count--;
2411 addr -= 2;
2413 } else {
2414 while (count != 0) {
2415 //check hardware interrupts
2416 data = 0xffff & dataSegment.getWord(addr & 0xffff);
2417 count--;
2418 addr += 2;
2422 finally {
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;
2433 int data = cpu.eax;
2434 executeCount += count;
2436 try {
2437 if (cpu.eflagsDirection) {
2438 while (count != 0) {
2439 //check hardware interrupts
2440 data = dataSegment.getDoubleWord(addr & 0xffff);
2441 count--;
2442 addr -= 4;
2444 } else {
2445 while (count != 0) {
2446 //check hardware interrupts
2447 data = dataSegment.getDoubleWord(addr & 0xffff);
2448 count--;
2449 addr += 4;
2453 finally {
2454 cpu.eax = data;
2455 cpu.ecx = (cpu.ecx & ~0xffff) | (count & 0xffff);
2456 cpu.esi = (cpu.esi & ~0xffff) | (addr & 0xffff);
2460 private final void lodsb_a32(Segment dataSegment)
2462 int addr = cpu.esi;
2463 cpu.eax = (cpu.eax & ~0xff) | (0xff & dataSegment.getByte(addr));
2465 if (cpu.eflagsDirection)
2466 addr -= 1;
2467 else
2468 addr += 1;
2470 cpu.esi = addr;
2473 private final void lodsw_a32(Segment dataSegment)
2475 int addr = cpu.esi;
2476 cpu.eax = (cpu.eax & ~0xffff) | (0xffff & dataSegment.getWord(addr));
2478 if (cpu.eflagsDirection)
2479 addr -= 2;
2480 else
2481 addr += 2;
2483 cpu.esi = addr;
2486 private final void lodsd_a32(Segment dataSegment)
2488 int addr = cpu.esi;
2489 cpu.eax = dataSegment.getDoubleWord(addr);
2491 if (cpu.eflagsDirection)
2492 addr -= 4;
2493 else
2494 addr += 4;
2496 cpu.esi = addr;
2499 private final void rep_lodsb_a32(Segment dataSegment)
2501 int count = cpu.ecx;
2502 int addr = cpu.esi;
2503 int data = cpu.eax & 0xff;
2504 executeCount += count;
2506 try {
2507 if (cpu.eflagsDirection) {
2508 while (count != 0) {
2509 //check hardware interrupts
2510 data = 0xff & dataSegment.getByte(addr);
2511 count--;
2512 addr -= 1;
2514 } else {
2515 while (count != 0) {
2516 //check hardware interrupts
2517 data = 0xff & dataSegment.getByte(addr);
2518 count--;
2519 addr += 1;
2523 finally {
2524 cpu.eax = (cpu.eax & ~0xff) | data;
2525 cpu.ecx = count;
2526 cpu.esi = addr;
2530 private final void rep_lodsw_a32(Segment dataSegment)
2532 int count = cpu.ecx;
2533 int addr = cpu.esi;
2534 int data = cpu.eax & 0xffff;
2535 executeCount += count;
2537 try {
2538 if (cpu.eflagsDirection) {
2539 while (count != 0) {
2540 //check hardware interrupts
2541 data = 0xffff & dataSegment.getWord(addr);
2542 count--;
2543 addr -= 2;
2545 } else {
2546 while (count != 0) {
2547 //check hardware interrupts
2548 data = 0xffff & dataSegment.getWord(addr);
2549 count--;
2550 addr += 2;
2554 finally {
2555 cpu.eax = (cpu.eax & ~0xffff) | data;
2556 cpu.ecx = count;
2557 cpu.esi = addr;
2561 private final void rep_lodsd_a32(Segment dataSegment)
2563 int count = cpu.ecx;
2564 int addr = cpu.esi;
2565 int data = cpu.eax;
2566 executeCount += count;
2568 try {
2569 if (cpu.eflagsDirection) {
2570 while (count != 0) {
2571 //check hardware interrupts
2572 data = dataSegment.getDoubleWord(addr);
2573 count--;
2574 addr -= 4;
2576 } else {
2577 while (count != 0) {
2578 //check hardware interrupts
2579 data = dataSegment.getDoubleWord(addr);
2580 count--;
2581 addr += 4;
2585 finally {
2586 cpu.eax = data;
2587 cpu.ecx = count;
2588 cpu.esi = 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) {
2599 outAddr -= 1;
2600 inAddr -= 1;
2601 } else {
2602 outAddr += 1;
2603 inAddr += 1;
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) {
2617 outAddr -= 2;
2618 inAddr -= 2;
2619 } else {
2620 outAddr += 2;
2621 inAddr += 2;
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) {
2635 outAddr -= 4;
2636 inAddr -= 4;
2637 } else {
2638 outAddr += 4;
2639 inAddr += 4;
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;
2653 try {
2654 if (cpu.eflagsDirection) {
2655 while (count != 0) {
2656 //check hardware interrupts
2657 cpu.es.setByte(inAddr & 0xffff, outSegment.getByte(outAddr & 0xffff));
2658 count--;
2659 outAddr -= 1;
2660 inAddr -= 1;
2662 } else {
2663 while (count != 0) {
2664 //check hardware interrupts
2665 cpu.es.setByte(inAddr & 0xffff, outSegment.getByte(outAddr & 0xffff));
2666 count--;
2667 outAddr += 1;
2668 inAddr += 1;
2672 finally {
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;
2686 try {
2687 if (cpu.eflagsDirection) {
2688 while (count != 0) {
2689 //check hardware interrupts
2690 cpu.es.setWord(inAddr & 0xffff, outSegment.getWord(outAddr & 0xffff));
2691 count--;
2692 outAddr -= 2;
2693 inAddr -= 2;
2695 } else {
2696 while (count != 0) {
2697 //check hardware interrupts
2698 cpu.es.setWord(inAddr & 0xffff, outSegment.getWord(outAddr & 0xffff));
2699 count--;
2700 outAddr += 2;
2701 inAddr += 2;
2705 finally {
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;
2719 try {
2720 if (cpu.eflagsDirection) {
2721 while (count != 0) {
2722 //check hardware interrupts
2723 cpu.es.setDoubleWord(inAddr & 0xffff, outSegment.getDoubleWord(outAddr & 0xffff));
2724 count--;
2725 outAddr -= 4;
2726 inAddr -= 4;
2728 } else {
2729 while (count != 0) {
2730 //check hardware interrupts
2731 cpu.es.setDoubleWord(inAddr & 0xffff, outSegment.getDoubleWord(outAddr & 0xffff));
2732 count--;
2733 outAddr += 4;
2734 inAddr += 4;
2738 finally {
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) {
2752 outAddr -= 1;
2753 inAddr -= 1;
2754 } else {
2755 outAddr += 1;
2756 inAddr += 1;
2759 cpu.edi = inAddr;
2760 cpu.esi = outAddr;
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) {
2770 outAddr -= 2;
2771 inAddr -= 2;
2772 } else {
2773 outAddr += 2;
2774 inAddr += 2;
2777 cpu.edi = inAddr;
2778 cpu.esi = outAddr;
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) {
2788 outAddr -= 4;
2789 inAddr -= 4;
2790 } else {
2791 outAddr += 4;
2792 inAddr += 4;
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;
2806 try {
2807 if (cpu.eflagsDirection) {
2808 while (count != 0) {
2809 //check hardware interrupts
2810 cpu.es.setByte(inAddr, outSegment.getByte(outAddr));
2811 count--;
2812 outAddr -= 1;
2813 inAddr -= 1;
2815 } else {
2816 while (count != 0) {
2817 //check hardware interrupts
2818 cpu.es.setByte(inAddr, outSegment.getByte(outAddr));
2819 count--;
2820 outAddr += 1;
2821 inAddr += 1;
2825 finally {
2826 cpu.ecx = count;
2827 cpu.edi = inAddr;
2828 cpu.esi = 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;
2839 try {
2840 if (cpu.eflagsDirection) {
2841 while (count != 0) {
2842 //check hardware interrupts
2843 cpu.es.setWord(inAddr, outSegment.getWord(outAddr));
2844 count--;
2845 outAddr -= 2;
2846 inAddr -= 2;
2848 } else {
2849 while (count != 0) {
2850 //check hardware interrupts
2851 cpu.es.setWord(inAddr, outSegment.getWord(outAddr));
2852 count--;
2853 outAddr += 2;
2854 inAddr += 2;
2858 finally {
2859 cpu.ecx = count;
2860 cpu.edi = inAddr;
2861 cpu.esi = 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;
2872 try {
2873 if (cpu.eflagsDirection) {
2874 while (count != 0) {
2875 //check hardware interrupts
2876 cpu.es.setDoubleWord(inAddr, outSegment.getDoubleWord(outAddr));
2877 count--;
2878 outAddr -= 4;
2879 inAddr -= 4;
2881 } else {
2882 while (count != 0) {
2883 //check hardware interrupts
2884 cpu.es.setDoubleWord(inAddr, outSegment.getDoubleWord(outAddr));
2885 count--;
2886 outAddr += 4;
2887 inAddr += 4;
2891 finally {
2892 cpu.ecx = count;
2893 cpu.edi = inAddr;
2894 cpu.esi = 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)
2906 addr -= 1;
2907 else
2908 addr += 1;
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)
2920 addr -= 2;
2921 else
2922 addr += 2;
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)
2934 addr -= 4;
2935 else
2936 addr += 4;
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;
2947 try {
2948 if (cpu.eflagsDirection) {
2949 while (count != 0) {
2950 //check hardware interrupts
2951 cpu.ioports.ioPortWriteByte(port, 0xffff & storeSegment.getByte(addr & 0xffff));
2952 count--;
2953 addr -= 1;
2955 } else {
2956 while (count != 0) {
2957 //check hardware interrupts
2958 cpu.ioports.ioPortWriteByte(port, 0xffff & storeSegment.getByte(addr & 0xffff));
2959 count--;
2960 addr += 1;
2964 finally {
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;
2976 try {
2977 if (cpu.eflagsDirection) {
2978 while (count != 0) {
2979 //check hardware interrupts
2980 cpu.ioports.ioPortWriteWord(port, 0xffff & storeSegment.getWord(addr & 0xffff));
2981 count--;
2982 addr -= 2;
2984 } else {
2985 while (count != 0) {
2986 //check hardware interrupts
2987 cpu.ioports.ioPortWriteWord(port, 0xffff & storeSegment.getWord(addr & 0xffff));
2988 count--;
2989 addr += 2;
2993 finally {
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;
3005 try {
3006 if (cpu.eflagsDirection) {
3007 while (count != 0) {
3008 //check hardware interrupts
3009 cpu.ioports.ioPortWriteLong(port, storeSegment.getDoubleWord(addr & 0xffff));
3010 count--;
3011 addr -= 4;
3013 } else {
3014 while (count != 0) {
3015 //check hardware interrupts
3016 cpu.ioports.ioPortWriteLong(port, storeSegment.getDoubleWord(addr & 0xffff));
3017 count--;
3018 addr += 4;
3022 finally {
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)
3034 addr -= 1;
3035 else
3036 addr += 1;
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)
3052 addr -= 2;
3053 else
3054 addr += 2;
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)
3070 addr -= 4;
3071 else
3072 addr += 4;
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;
3087 int input = 0;
3089 try {
3090 if (cpu.eflagsDirection) {
3091 while (count != 0) {
3092 input = 0xff & cpu.es.getByte(addr);
3093 count--;
3094 addr -= 1;
3095 if (data != input) break;
3097 } else {
3098 while (count != 0) {
3099 input = 0xff & cpu.es.getByte(addr);
3100 count--;
3101 addr += 1;
3102 if (data != input) break;
3105 } finally {
3106 executeCount += ((cpu.ecx & 0xffff) - count);
3107 cpu.ecx = (cpu.ecx & ~0xffff) | (count & 0xffff);
3108 cpu.edi = (cpu.edi & ~0xffff) | (addr & 0xffff);
3109 // if (used)
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;
3122 int input = 0;
3124 try {
3125 if (cpu.eflagsDirection) {
3126 while (count != 0) {
3127 input = 0xffff & cpu.es.getWord(addr);
3128 count--;
3129 addr -= 2;
3130 if (data != input) break;
3132 } else {
3133 while (count != 0) {
3134 input = 0xffff & cpu.es.getWord(addr);
3135 count--;
3136 addr += 2;
3137 if (data != input) break;
3140 } finally {
3141 executeCount += ((cpu.ecx & 0xffff) - count);
3142 cpu.ecx = (cpu.ecx & ~0xffff) | (count & 0xffff);
3143 cpu.edi = (cpu.edi & ~0xffff) | (addr & 0xffff);
3144 // if (used)
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;
3158 int input = 0;
3160 try {
3161 if (cpu.eflagsDirection) {
3162 while (count != 0) {
3163 input = cpu.es.getDoubleWord(addr);
3164 count--;
3165 addr -= 4;
3166 if (data != input) break;
3168 } else {
3169 while (count != 0) {
3170 input = cpu.es.getDoubleWord(addr);
3171 count--;
3172 addr += 4;
3173 if (data != input) break;
3176 } finally {
3177 executeCount += ((cpu.ecx & 0xffff) - count);
3178 cpu.ecx = (cpu.ecx & ~0xffff) | (count & 0xffff);
3179 cpu.edi = (cpu.edi & ~0xffff) | (addr & 0xffff);
3180 // if (used)
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;
3194 int input = 0;
3196 try {
3197 if (cpu.eflagsDirection) {
3198 while (count != 0) {
3199 input = 0xff & cpu.es.getByte(addr);
3200 count--;
3201 addr -= 1;
3202 if (data == input) break;
3204 } else {
3205 while (count != 0) {
3206 input = 0xff & cpu.es.getByte(addr);
3207 count--;
3208 addr += 1;
3209 if (data == input) break;
3212 } finally {
3213 executeCount += ((cpu.ecx & 0xffff) - count);
3214 cpu.ecx = (cpu.ecx & ~0xffff) | (count & 0xffff);
3215 cpu.edi = (cpu.edi & ~0xffff) | (addr & 0xffff);
3216 // if (used)
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;
3230 int input = 0;
3232 try {
3233 if (cpu.eflagsDirection) {
3234 while (count != 0) {
3235 input = 0xffff & cpu.es.getWord(addr);
3236 count--;
3237 addr -= 2;
3238 if (data == input) break;
3240 } else {
3241 while (count != 0) {
3242 input = 0xffff & cpu.es.getWord(addr);
3243 count--;
3244 addr += 2;
3245 if (data == input) break;
3248 } finally {
3249 executeCount += ((cpu.ecx & 0xffff) - count);
3250 cpu.ecx = (cpu.ecx & ~0xffff) | (count & 0xffff);
3251 cpu.edi = (cpu.edi & ~0xffff) | (addr & 0xffff);
3252 // if (used)
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;
3266 int input = 0;
3268 try {
3269 if (cpu.eflagsDirection) {
3270 while (count != 0) {
3271 input = cpu.es.getDoubleWord(addr);
3272 count--;
3273 addr -= 4;
3274 if (data == input) break;
3276 } else {
3277 while (count != 0) {
3278 input = cpu.es.getDoubleWord(addr);
3279 count--;
3280 addr += 4;
3281 if (data == input) break;
3284 } finally {
3285 executeCount += ((cpu.ecx & 0xffff) - count);
3286 cpu.ecx = (cpu.ecx & ~0xffff) | (count & 0xffff);
3287 cpu.edi = (cpu.edi & ~0xffff) | (addr & 0xffff);
3288 // if (used)
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)
3303 addr -= 1;
3304 else
3305 addr += 1;
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)
3316 addr -= 2;
3317 else
3318 addr += 2;
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)
3329 addr -= 4;
3330 else
3331 addr += 4;
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;
3342 try {
3343 if (cpu.eflagsDirection) {
3344 while (count != 0) {
3345 //check hardware interrupts
3346 cpu.es.setByte(addr & 0xffff, (byte)data);
3347 count--;
3348 addr -= 1;
3350 } else {
3351 while (count != 0) {
3352 //check hardware interrupts
3353 cpu.es.setByte(addr & 0xffff, (byte)data);
3354 count--;
3355 addr += 1;
3359 finally {
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;
3371 try {
3372 if (cpu.eflagsDirection) {
3373 while (count != 0) {
3374 //check hardware interrupts
3375 cpu.es.setWord(addr & 0xffff, (short)data);
3376 count--;
3377 addr -= 2;
3379 } else {
3380 while (count != 0) {
3381 //check hardware interrupts
3382 cpu.es.setWord(addr & 0xffff, (short)data);
3383 count--;
3384 addr += 2;
3388 finally {
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;
3400 try {
3401 if (cpu.eflagsDirection) {
3402 while (count != 0) {
3403 //check hardware interrupts
3404 cpu.es.setDoubleWord(addr & 0xffff, data);
3405 count--;
3406 addr -= 4;
3408 } else {
3409 while (count != 0) {
3410 //check hardware interrupts
3411 cpu.es.setDoubleWord(addr & 0xffff, data);
3412 count--;
3413 addr += 4;
3417 finally {
3418 cpu.ecx = (cpu.ecx & ~0xffff) | (count & 0xffff);
3419 cpu.edi = (cpu.edi & ~0xffff) | (addr & 0xffff);
3423 private final void stosb_a32(int data)
3425 int addr = cpu.edi;
3426 cpu.es.setByte(addr, (byte)data);
3428 if (cpu.eflagsDirection)
3429 addr -= 1;
3430 else
3431 addr += 1;
3433 cpu.edi = addr;
3436 private final void stosw_a32(int data)
3438 int addr = cpu.edi;
3439 cpu.es.setWord(addr, (short)data);
3441 if (cpu.eflagsDirection)
3442 addr -= 2;
3443 else
3444 addr += 2;
3446 cpu.edi = addr;
3449 private final void stosd_a32(int data)
3451 int addr = cpu.edi;
3452 cpu.es.setDoubleWord(addr, data);
3454 if (cpu.eflagsDirection)
3455 addr -= 4;
3456 else
3457 addr += 4;
3459 cpu.edi = addr;
3462 private final void rep_stosb_a32(int data)
3464 int count = cpu.ecx;
3465 int addr = cpu.edi;
3466 executeCount += count;
3468 try {
3469 if (cpu.eflagsDirection) {
3470 while (count != 0) {
3471 //check hardware interrupts
3472 cpu.es.setByte(addr, (byte)data);
3473 count--;
3474 addr -= 1;
3476 } else {
3477 while (count != 0) {
3478 //check hardware interrupts
3479 cpu.es.setByte(addr, (byte)data);
3480 count--;
3481 addr += 1;
3485 finally {
3486 cpu.ecx = count;
3487 cpu.edi = addr;
3491 private final void rep_stosw_a32(int data)
3493 int count = cpu.ecx;
3494 int addr = cpu.edi;
3495 executeCount += count;
3497 try {
3498 if (cpu.eflagsDirection) {
3499 while (count != 0) {
3500 //check hardware interrupts
3501 cpu.es.setWord(addr, (short)data);
3502 count--;
3503 addr -= 2;
3505 } else {
3506 while (count != 0) {
3507 //check hardware interrupts
3508 cpu.es.setWord(addr, (short)data);
3509 count--;
3510 addr += 2;
3514 finally {
3515 cpu.ecx = count;
3516 cpu.edi = addr;
3520 private final void rep_stosd_a32(int data)
3522 int count = cpu.ecx;
3523 int addr = cpu.edi;
3524 executeCount += count;
3526 try {
3527 if (cpu.eflagsDirection) {
3528 while (count != 0) {
3529 //check hardware interrupts
3530 cpu.es.setDoubleWord(addr, data);
3531 count--;
3532 addr -= 4;
3534 } else {
3535 while (count != 0) {
3536 //check hardware interrupts
3537 cpu.es.setDoubleWord(addr, data);
3538 count--;
3539 addr += 4;
3543 finally {
3544 cpu.ecx = count;
3545 cpu.edi = addr;
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);
3631 return result;
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);
3642 return (int)result;
3645 private final void div_o8(int data)
3647 if (data == 0)
3648 throw ProcessorException.DIVIDE_ERROR;
3650 int x = (cpu.eax & 0xffff);
3652 int result = x / data;
3653 if (result > 0xff)
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)
3662 if (data == 0)
3663 throw ProcessorException.DIVIDE_ERROR;
3665 long x = (cpu.edx & 0xffffl);
3666 x <<= 16;
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;
3682 if (d == 0)
3683 throw ProcessorException.DIVIDE_ERROR;
3685 long temp = (long)cpu.edx;
3686 temp <<= 32;
3687 temp |= (0xffffffffl & cpu.eax);
3689 long r2 = (temp & 1);
3690 long n2 = (temp >>> 1);
3692 long q2 = n2 / d;
3693 long m2 = n2 % d;
3695 long q = (q2 << 1);
3696 long r = (m2 << 1) + r2;
3698 q += (r / d);
3699 r %= d;
3700 if (q > 0xffffffffl)
3701 throw ProcessorException.DIVIDE_ERROR;
3703 cpu.eax = (int)q;
3704 cpu.edx = (int)r;
3707 private final void idiv_o8(byte data)
3709 if (data == 0)
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)
3723 if (data == 0) {
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)
3739 if (data == 0)
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);
3757 offset &= 0x7;
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);
3767 offset &= 0x7;
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);
3777 offset &= 0x7;
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);
3787 offset &= 0x7;
3788 cpu.setCarryFlag(segment.getByte(address), offset, Processor.CY_NTH_BIT_SET);
3791 private final int bsf(int source, int initial) throws ProcessorException
3793 if (source == 0) {
3794 cpu.setZeroFlag(true);
3795 return initial;
3796 } else {
3797 cpu.setZeroFlag(false);
3798 return numberOfTrailingZeros(source);
3802 private final int bsr(int source, int initial) throws ProcessorException
3804 if (source == 0) {
3805 cpu.setZeroFlag(true);
3806 return initial;
3807 } else {
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);
3820 } else {
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;
3833 int ax2 = ax1 + tl;
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;
3852 if (base == 0)
3853 throw ProcessorException.DIVIDE_ERROR;
3854 int ah = 0xff & (tl / base);
3855 int al = 0xff & (tl % base);
3856 cpu.eax &= ~0xffff;
3857 cpu.eax |= (al | (ah << 8));
3859 cpu.setAuxiliaryCarryFlag(false);
3861 // bitwise_flags((byte)al);
3862 return (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);
3872 } else {
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;
3882 boolean newCF;
3883 if (((cpu.eax & 0xf) > 0x9) || cpu.getAuxiliaryCarryFlag()) {
3884 al += 6;
3885 cpu.setAuxiliaryCarryFlag(true);
3886 } else
3887 cpu.setAuxiliaryCarryFlag(false);
3889 if (((al & 0xff) > 0x9f) || cpu.getCarryFlag()) {
3890 al += 0x60;
3891 newCF = true;
3892 } else
3893 newCF = false;
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);
3919 tempCF = true;
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;
3941 cpu.eax |= result;
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()
3956 switch (cpu.eax) {
3957 case 0x00:
3958 cpu.eax = 0x02;
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 */
3962 return;
3963 case 0x01:
3964 cpu.eax = 0x00000633; // Pentium II Model 8 Stepping 3
3965 cpu.ebx = 8 << 8; //not implemented (should be brand index)
3966 cpu.ecx = 0;
3968 int features = 0;
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
3982 cpu.edx = features;
3983 return;
3984 default:
3985 case 0x02:
3986 cpu.eax = 0x410601;
3987 cpu.ebx = 0;
3988 cpu.ecx = 0;
3989 cpu.edx = 0;
3990 return;
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);
4081 } else {
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);
4093 } else {
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);
4105 } else {
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)
4133 if (used == 0)
4134 return;
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)
4144 if (used == 0)
4145 return;
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)
4155 if (used == 0)
4156 return;
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)
4241 if (count > 0) {
4242 cpu.setCarryFlag(initial, count, Processor.CY_SHL_OUTBIT_BYTE);
4244 if (count == 1)
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)
4255 if (count > 0) {
4256 cpu.setCarryFlag(initial, count, Processor.CY_SHL_OUTBIT_SHORT);
4258 if (count == 1)
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)
4269 if (count > 0) {
4270 cpu.setCarryFlag(initial, count, Processor.CY_SHL_OUTBIT_INT);
4272 if (count == 1)
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)
4283 if (count > 0) {
4284 cpu.setCarryFlag(initial, count, Processor.CY_SHR_OUTBIT);
4286 if (count == 1)
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)
4297 if (count > 0) {
4298 cpu.setCarryFlag(initial, count, Processor.CY_SHR_OUTBIT);
4300 if (count == 1)
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)
4311 if (count > 0) {
4312 cpu.setCarryFlag(initial, count, Processor.CY_SHR_OUTBIT);
4314 if (count == 1)
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)
4326 if (count > 0) {
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)
4338 if (count > 0) {
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)
4350 if (count > 0) {
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)
4362 if (count > 0) {
4363 cpu.setCarryFlag(result, Processor.CY_LOWBIT);
4364 if (count == 1)
4365 cpu.setOverflowFlag(result, Processor.OF_BIT7_XOR_CARRY);
4369 private final void rol_flags(short result, int count)
4371 if (count > 0) {
4372 cpu.setCarryFlag(result, Processor.CY_LOWBIT);
4373 if (count == 1)
4374 cpu.setOverflowFlag(result, Processor.OF_BIT15_XOR_CARRY);
4378 private final void rol_flags(int result, int count)
4380 if (count > 0) {
4381 cpu.setCarryFlag(result, Processor.CY_LOWBIT);
4382 if (count == 1)
4383 cpu.setOverflowFlag(result, Processor.OF_BIT31_XOR_CARRY);
4387 private final void ror_flags(byte result, int count)
4389 if (count > 0) {
4390 cpu.setCarryFlag(result, Processor.CY_HIGHBIT_BYTE);
4391 if (count == 1)
4392 cpu.setOverflowFlag(result, Processor.OF_BIT6_XOR_CARRY);
4396 private final void ror_flags(short result, int count)
4398 if (count > 0) {
4399 cpu.setCarryFlag(result, Processor.CY_HIGHBIT_SHORT);
4400 if (count == 1)
4401 cpu.setOverflowFlag(result, Processor.OF_BIT14_XOR_CARRY);
4405 private final void ror_flags(int result, int count)
4407 if (count > 0) {
4408 cpu.setCarryFlag(result, Processor.CY_HIGHBIT_INT);
4409 if (count == 1)
4410 cpu.setOverflowFlag(result, Processor.OF_BIT30_XOR_CARRY);
4414 private final void rcl_o8_flags(int result, int count)
4416 if (count > 0) {
4417 cpu.setCarryFlag(result, Processor.CY_OFFENDBIT_BYTE);
4418 if (count == 1)
4419 cpu.setOverflowFlag(result, Processor.OF_BIT7_XOR_CARRY);
4423 private final void rcl_o16_flags(int result, int count)
4425 if (count > 0) {
4426 cpu.setCarryFlag(result, Processor.CY_OFFENDBIT_SHORT);
4427 if (count == 1)
4428 cpu.setOverflowFlag(result, Processor.OF_BIT15_XOR_CARRY);
4432 private final void rcl_o32_flags(long result, int count)
4434 if (count > 0) {
4435 cpu.setCarryFlag(result, Processor.CY_OFFENDBIT_INT);
4436 if (count == 1)
4437 cpu.setOverflowFlag(result, Processor.OF_BIT31_XOR_CARRY);
4441 private final void rcr_o8_flags(int result, int count, int overflow)
4443 if (count > 0) {
4444 cpu.setCarryFlag(result, Processor.CY_OFFENDBIT_BYTE);
4445 if (count == 1)
4446 cpu.setOverflowFlag(overflow > 0);
4450 private final void rcr_o16_flags(int result, int count, int overflow)
4452 if (count > 0) {
4453 cpu.setCarryFlag(result, Processor.CY_OFFENDBIT_SHORT);
4454 if (count == 1)
4455 cpu.setOverflowFlag(overflow > 0);
4459 private final void rcr_o32_flags(long result, int count, int overflow)
4461 if (count > 0) {
4462 cpu.setCarryFlag(result, Processor.CY_OFFENDBIT_INT);
4463 if (count == 1)
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) {
4503 // HD, Figure 5-14
4504 int y;
4505 if (i == 0) return 32;
4506 int n = 31;
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) {
4515 // HD, Figure 5-6
4516 if (i == 0)
4517 return 32;
4518 int n = 1;
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; }
4523 n -= i >>> 31;
4524 return n;