Author: aandrejevic
Date: Fri Oct 11 23:45:42 2013
New Revision: 60625
URL:
http://svn.reactos.org/svn/reactos?rev=60625&view=rev
Log:
[SOFT386]
- Fix calculation of the AF flag in opcode groups 0xFE and 0xFF (INC/DEC).
- Fix a bug in the REP prefix by simulating the wrap-around of DI which
can occur when the current address size is 16-bit.
- Exception error codes are only pushed on the stack in protected mode.
Modified:
branches/ntvdm/lib/soft386/common.c
branches/ntvdm/lib/soft386/opcodes.c
branches/ntvdm/lib/soft386/opgroups.c
Modified: branches/ntvdm/lib/soft386/common.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/common.c?rev=…
==============================================================================
--- branches/ntvdm/lib/soft386/common.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/soft386/common.c [iso-8859-1] Fri Oct 11 23:45:42 2013
@@ -494,7 +494,8 @@
return;
}
- if (EXCEPTION_HAS_ERROR_CODE(ExceptionCode))
+ if (EXCEPTION_HAS_ERROR_CODE(ExceptionCode)
+ && (State->ControlRegisters[SOFT386_REG_CR0] & SOFT386_CR0_PE))
{
/* Push the error code */
Soft386StackPush(State, ErrorCode);
Modified: branches/ntvdm/lib/soft386/opcodes.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/opcodes.c?rev…
==============================================================================
--- branches/ntvdm/lib/soft386/opcodes.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/soft386/opcodes.c [iso-8859-1] Fri Oct 11 23:45:42 2013
@@ -6168,6 +6168,15 @@
{
ULONG Processed = min(Count, STRING_BLOCK_SIZE / DataSize);
+ /* Simulate the 16-bit wrap-around of DI in 16-bit address mode */
+ if (!AddressSize)
+ {
+ ULONG MaxBytes = 0x10000 -
(ULONG)State->GeneralRegs[SOFT386_REG_EDI].LowWord;
+
+ Processed = min(Processed, MaxBytes / DataSize);
+ if (Processed == 0) Processed = 1;
+ }
+
if (State->Flags.Df)
{
/* Reduce EDI by the number of bytes to transfer */
@@ -6436,6 +6445,15 @@
while (Count)
{
ULONG Processed = min(Count, STRING_BLOCK_SIZE / DataSize);
+
+ /* Simulate the 16-bit wrap-around of DI in 16-bit address mode */
+ if (!AddressSize)
+ {
+ ULONG MaxBytes = 0x10000 -
(ULONG)State->GeneralRegs[SOFT386_REG_EDI].LowWord;
+
+ Processed = min(Processed, MaxBytes / DataSize);
+ if (Processed == 0) Processed = 1;
+ }
/* Read from the I/O port */
State->IoReadCallback(State,
@@ -6574,6 +6592,15 @@
{
ULONG Processed = min(Count, STRING_BLOCK_SIZE / DataSize);
+ /* Simulate the 16-bit wrap-around of DI in 16-bit address mode */
+ if (!AddressSize)
+ {
+ ULONG MaxBytes = 0x10000 -
(ULONG)State->GeneralRegs[SOFT386_REG_EDI].LowWord;
+
+ Processed = min(Processed, MaxBytes / DataSize);
+ if (Processed == 0) Processed = 1;
+ }
+
/* Read from memory */
if (!Soft386ReadMemory(State,
SOFT386_REG_ES,
Modified: branches/ntvdm/lib/soft386/opgroups.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/opgroups.c?re…
==============================================================================
--- branches/ntvdm/lib/soft386/opgroups.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/soft386/opgroups.c [iso-8859-1] Fri Oct 11 23:45:42 2013
@@ -1414,21 +1414,22 @@
if (ModRegRm.Register == 0)
{
- /* Increment and update OF */
+ /* Increment and update OF and AF */
Value++;
State->Flags.Of = (Value == SIGN_FLAG_BYTE) ? TRUE : FALSE;
+ State->Flags.Af = ((Value & 0x0F) == 0);
}
else
{
- /* Decrement and update OF */
+ /* Decrement and update OF and AF */
State->Flags.Of = (Value == SIGN_FLAG_BYTE) ? TRUE : FALSE;
Value--;
+ State->Flags.Af = ((Value & 0x0F) == 0x0F);
}
/* Update flags */
State->Flags.Sf = (Value & SIGN_FLAG_BYTE) ? TRUE : FALSE;
State->Flags.Zf = (Value == 0) ? TRUE : FALSE;
- State->Flags.Af = ((Value & 0x0F) == 0) ? TRUE : FALSE;
State->Flags.Pf = Soft386CalculateParity(Value);
/* Write back the result */
@@ -1483,15 +1484,17 @@
if (ModRegRm.Register == 0)
{
- /* Increment and update OF */
+ /* Increment and update OF and AF */
Value++;
State->Flags.Of = (Value == SIGN_FLAG_LONG) ? TRUE : FALSE;
+ State->Flags.Af = ((Value & 0x0F) == 0);
}
else if (ModRegRm.Register == 1)
{
- /* Decrement and update OF */
+ /* Decrement and update OF and AF */
State->Flags.Of = (Value == SIGN_FLAG_LONG) ? TRUE : FALSE;
Value--;
+ State->Flags.Af = ((Value & 0x0F) == 0x0F);
}
if (ModRegRm.Register <= 1)
@@ -1499,7 +1502,6 @@
/* Update flags */
State->Flags.Sf = (Value & SIGN_FLAG_LONG) ? TRUE : FALSE;
State->Flags.Zf = (Value == 0) ? TRUE : FALSE;
- State->Flags.Af = ((Value & 0x0F) == 0) ? TRUE : FALSE;
State->Flags.Pf = Soft386CalculateParity(Value);
/* Write back the result */
@@ -1524,12 +1526,14 @@
/* Increment and update OF */
Value++;
State->Flags.Of = (Value == SIGN_FLAG_WORD) ? TRUE : FALSE;
+ State->Flags.Af = ((Value & 0x0F) == 0);
}
else if (ModRegRm.Register == 1)
{
/* Decrement and update OF */
State->Flags.Of = (Value == SIGN_FLAG_WORD) ? TRUE : FALSE;
Value--;
+ State->Flags.Af = ((Value & 0x0F) == 0x0F);
}
if (ModRegRm.Register <= 1)
@@ -1537,7 +1541,6 @@
/* Update flags */
State->Flags.Sf = (Value & SIGN_FLAG_WORD) ? TRUE : FALSE;
State->Flags.Zf = (Value == 0) ? TRUE : FALSE;
- State->Flags.Af = ((Value & 0x0F) == 0) ? TRUE : FALSE;
State->Flags.Pf = Soft386CalculateParity(Value);
/* Write back the result */