Add string prefixes and inc/dec to emulator
This commit is contained in:
parent
569e11aceb
commit
9bce345a3b
63
utils/emul.c
63
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();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user