aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Serpell <daniel.serpell@gmail.com>2020-01-12 13:00:13 -0300
committerDaniel Serpell <daniel.serpell@gmail.com>2020-01-12 13:00:13 -0300
commite41dbb0ca882dc315f63d19b6948b95a97d2171c (patch)
treeffc4447975e6c6ca6798712fdd98bf55708723be
parent5be05a753388fcf7fa1d57b844b6c88d761e2a7f (diff)
downloademu2-e41dbb0ca882dc315f63d19b6948b95a97d2171c.tar.gz
Document and properly handle 80186 / 80286 instruction behaviours.
-rw-r--r--src/cpu.c19
-rw-r--r--src/cpu.h14
2 files changed, 22 insertions, 11 deletions
diff --git a/src/cpu.c b/src/cpu.c
index f0f94ac..59a3208 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -110,18 +110,16 @@ static uint32_t GetAbsAddrSeg(int seg, uint16_t off)
return sregs[seg] * 16 + off;
}
-#ifdef CPU_8086
static void PushWord(uint16_t w)
{
wregs[SP] -= 2;
SetMemW(SS, wregs[SP], w);
}
-#else // 80186 and up
-static void PushWord(uint16_t w)
-{
- SetMemW(SS, wregs[SP] - 2, w);
- wregs[SP] -= 2;
-}
+
+#ifdef CPU_PUSH_80286
+# define PUSH_SP() PushWord(wregs[SP]); break;
+#else
+# define PUSH_SP() PushWord(wregs[SP] - 2); break;
#endif
static uint16_t PopWord(void)
@@ -1390,7 +1388,10 @@ static uint8_t shift1_b(uint8_t val, int ModRM)
static uint8_t shifts_b(uint8_t val, int ModRM, unsigned count)
{
+
+#ifdef CPU_SHIFT_80186
count &= 0x1F;
+#endif
if(!count)
return val; // No flags affected.
@@ -1542,7 +1543,9 @@ static uint16_t shift1_w(uint16_t val, int ModRM)
static uint16_t shifts_w(uint16_t val, int ModRM, unsigned count)
{
+#ifdef CPU_SHIFT_80186
count &= 0x1F;
+#endif
if(!count)
return val; // No flags affected.
@@ -2362,7 +2365,7 @@ static void do_instruction(uint8_t code)
case 0x51: PUSH_WR(CX);
case 0x52: PUSH_WR(DX);
case 0x53: PUSH_WR(BX);
- case 0x54: PUSH_WR(SP);
+ case 0x54: PUSH_SP();
case 0x55: PUSH_WR(BP);
case 0x56: PUSH_WR(SI);
case 0x57: PUSH_WR(DI);
diff --git a/src/cpu.h b/src/cpu.h
index 0fd45dc..d0b9b04 100644
--- a/src/cpu.h
+++ b/src/cpu.h
@@ -19,9 +19,17 @@
#include <stdint.h>
-// Enable/disable 8086 stack emulation, used by some software
-// to detect if the CPU is an 80186 and up.
-//#define CPU_8086
+// Enable/disable 80286 stack emulation, 80286 and higher push the old value of
+// SP, 8086/80186 push new value.
+//
+// This is used by some software to detect extra instructions that are present
+// in the 80186 also, so we emulate this even if no 80286 instructions are
+// supported.
+#define CPU_PUSH_80286
+
+// Enable 80186 shift behaviour - shift count is modulo 32.
+// This is used in some software to detect 80186 and higher.
+#define CPU_SHIFT_80186
enum
{
Un proyecto texto-plano.xyz