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