diff --git a/utils/emul.c b/utils/emul.c index f076cd4..8072d81 100644 --- a/utils/emul.c +++ b/utils/emul.c @@ -36,8 +36,8 @@ union flags { uint16_t ip = 0x100; uint16_t scratch; +uint16_t prefixes = 0; uint16_t reg; -int off; void* rmptr; #define RM8 *(uint8_t*)rmptr @@ -46,28 +46,20 @@ void* rmptr; #define R8(x) regset.r8[fixr8ref(x)] #define R16(x) regset.r16[x] -#define FLAGMASK 0xF02A -#define CF 0 -#define PF 2 -#define AF 4 -#define ZF 6 -#define SF 7 -#define TF 8 -#define IF 9 -#define DF 10 -#define OF 11 - #define AL regset.r8[0] #define AH regset.r8[1] #define CL regset.r8[2] #define DL regset.r8[4] #define AX regset.r16[0] +#define CX regset.r16[1] #define BX regset.r16[3] #define SP regset.r16[4] #define BP regset.r16[5] #define SI regset.r16[6] #define DI regset.r16[7] +#define FLAGMASK 0xF02A + #define ADD 0 #define OR 1 #define ADC 2 @@ -78,6 +70,9 @@ void* rmptr; #define CMP 7 #define TEST 8 +#define PREFIX_REPE 1 +#define PREFIX_REPNE 2 + const char* const regnames[] = { "AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI", 0 }; // Dump registers @@ -272,6 +267,14 @@ void step() { modrm(BIT16); arith16(opcode >> 3, &RM16, R16(reg)); break; + case 0x40 ... 0x47: // INC reg16 + R16(opcode - 0x40)++; + flags.bit.z=!R16(opcode - 0x40); + break; + case 0x48 ... 0x4F: // DEC reg16 + R16(opcode - 0x48)--; + flags.bit.z=!R16(opcode - 0x48); + break; case 0x50 ... 0x57: // PUSH reg16 push(R16(opcode-0x50)); break; @@ -320,9 +323,27 @@ void step() { case 0xA1: // MOV AX,memoffs16 AX = *(uint16_t*)&mem[imm16()]; break; + case 0xAA: // STOSB + scratch = 1; + if (prefixes & PREFIX_REPE) { + scratch = CX; + CX = 0; + } + for(;scratch>0;scratch--) { + mem[DI] = AL; + DI += 1 - (flags.bit.d << 1); + } + break; case 0xAC: // LODSB - AL = mem[SI]; - SI++; + scratch = 1; + if (prefixes & PREFIX_REPE) { + scratch = CX; + CX = 0; + } + for(;scratch>0;scratch--) { + AL = mem[SI]; + SI += 1 - (flags.bit.d << 1); + } break; case 0xB0 ... 0xB7: // MOV reg8,imm8 reg = opcode-0xB0; @@ -357,9 +378,18 @@ void step() { case 0xEB: // JMP rb ip = ip + (int8_t)imm8(); break; + case 0xF2: + prefixes |= PREFIX_REPNE; + return; + case 0xF3: + prefixes |= PREFIX_REPE; + return; case 0xFA: // CLI + flags.bit.i = 0; + break; case 0xFB: // STI - break; // no-op, since we dont have interrupts + flags.bit.i = 1; + break; default: ip--; dump(); @@ -367,6 +397,8 @@ void step() { exit(1); break; } + prefixes = 0; + if (flags.bit.t) dump(); } void copy_cmdline(char* str) { @@ -427,6 +459,5 @@ int main(int argc, char** argv) { while(1) { step(); - if (flags.bit.t) dump(); } }