Add string prefixes and inc/dec to emulator

This commit is contained in:
Nero 2019-10-04 22:54:37 +00:00
parent 569e11aceb
commit 9bce345a3b

View File

@ -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();
}
}