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 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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user