diff --git a/lib/soft386/common.c b/lib/soft386/common.c index f7547f6c074..569c1cf48fc 100644 --- a/lib/soft386/common.c +++ b/lib/soft386/common.c @@ -494,7 +494,8 @@ Soft386ExceptionWithErrorCode(PSOFT386_STATE State, 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); diff --git a/lib/soft386/opcodes.c b/lib/soft386/opcodes.c index c0907cc946e..632426266b9 100644 --- a/lib/soft386/opcodes.c +++ b/lib/soft386/opcodes.c @@ -6168,6 +6168,15 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeStos) { 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 */ @@ -6437,6 +6446,15 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeIns) { 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, State->GeneralRegs[SOFT386_REG_EDX].LowWord, @@ -6574,6 +6592,15 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeOuts) { 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, diff --git a/lib/soft386/opgroups.c b/lib/soft386/opgroups.c index 2822305a16c..d55ad87a89c 100644 --- a/lib/soft386/opgroups.c +++ b/lib/soft386/opgroups.c @@ -1414,21 +1414,22 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupFE) 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 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupFF) 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 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupFF) /* 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 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupFF) /* 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 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupFF) /* 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 */