diff options
author | Daniel Serpell <daniel.serpell@gmail.com> | 2020-01-12 13:00:13 -0300 |
---|---|---|
committer | Daniel Serpell <daniel.serpell@gmail.com> | 2020-01-12 13:00:13 -0300 |
commit | e41dbb0ca882dc315f63d19b6948b95a97d2171c (patch) | |
tree | ffc4447975e6c6ca6798712fdd98bf55708723be | |
parent | 5be05a753388fcf7fa1d57b844b6c88d761e2a7f (diff) | |
download | emu2-e41dbb0ca882dc315f63d19b6948b95a97d2171c.tar.gz |
Document and properly handle 80186 / 80286 instruction behaviours.
-rw-r--r-- | src/cpu.c | 19 | ||||
-rw-r--r-- | src/cpu.h | 14 |
2 files changed, 22 insertions, 11 deletions
@@ -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); @@ -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 { |