|
@@ -24,6 +24,25 @@
|
|
|
#include <thread.h>
|
|
|
#include <memory.h>
|
|
|
|
|
|
+#define PREFIX_LOCK (1 << 0)
|
|
|
+#define PREFIX_OPSIZE (1 << 1)
|
|
|
+#define PREFIX_ADDRSIZE (1 << 2)
|
|
|
+#define PREFIX_REP (1 << 3)
|
|
|
+#define PREFIX_REPNZ (1 << 4)
|
|
|
+#define PREFIX_ES (1 << 5)
|
|
|
+#define PREFIX_SS (1 << 6)
|
|
|
+#define PREFIX_FS (1 << 7)
|
|
|
+#define PREFIX_GS (1 << 8)
|
|
|
+
|
|
|
+#define VM86_MEM_START 0x10000
|
|
|
+#define VM86_MEM_END 0x90000
|
|
|
+#define VM86_MEM_PARAGRAPHS ((VM86_MEM_END - VM86_MEM_START) >> 4)
|
|
|
+
|
|
|
+#define VM86_TRAMPOLINE_CS 0x0000
|
|
|
+#define VM86_TRAMPOLINE_IP 0xE000
|
|
|
+#define VM86_TRAMPOLINE_SS 0x0000
|
|
|
+#define VM86_TRAMPOLINE_SP 0xDFFA
|
|
|
+
|
|
|
extern void vm86_start(vm86_registers_t input_regs, vm86_registers_t *output_regs);
|
|
|
|
|
|
static bool_t vm86_interrupts = TRUE;
|
|
@@ -150,8 +169,8 @@ void vm86_handler(registers_ext_vm86_t *regs)
|
|
|
{
|
|
|
for (i = 0; i < count; i++)
|
|
|
{
|
|
|
- pokeb(regs->es, regs->edi, inportb(regs->edx));
|
|
|
- if (!(regs->eflags & EFLAGS_DF)) regs->edi++;
|
|
|
+ pokeb(regs->es, regs->edi, cpu_read_port_byte(regs->edx));
|
|
|
+ if (!(regs->eflags & CPU_STATUS_FLAG_DF)) regs->edi++;
|
|
|
else regs->edi--;
|
|
|
}
|
|
|
|
|
@@ -164,16 +183,16 @@ void vm86_handler(registers_ext_vm86_t *regs)
|
|
|
{
|
|
|
if (!(prefix & PREFIX_OPSIZE))
|
|
|
{
|
|
|
- pokew(regs->es, regs->edi, inportw(regs->edx));
|
|
|
+ pokew(regs->es, regs->edi, cpu_read_port_word(regs->edx));
|
|
|
|
|
|
- if (!(regs->eflags & EFLAGS_DF)) regs->edi += 2;
|
|
|
+ if (!(regs->eflags & CPU_STATUS_FLAG_DF)) regs->edi += 2;
|
|
|
else regs->edi -= 2;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- pokel(regs->es, regs->edi, inportl(regs->edx));
|
|
|
+ pokel(regs->es, regs->edi, cpu_read_port_dword(regs->edx));
|
|
|
|
|
|
- if (!(regs->eflags & EFLAGS_DF)) regs->edi += 4;
|
|
|
+ if (!(regs->eflags & CPU_STATUS_FLAG_DF)) regs->edi += 4;
|
|
|
else regs->edi -= 4;
|
|
|
}
|
|
|
}
|
|
@@ -185,9 +204,9 @@ void vm86_handler(registers_ext_vm86_t *regs)
|
|
|
{
|
|
|
for (i = 0; i < count; i++)
|
|
|
{
|
|
|
- outportb(regs->edx, peekb(segment, regs->esi));
|
|
|
+ cpu_write_port_byte(regs->edx, peekb(segment, regs->esi));
|
|
|
|
|
|
- if (!(regs->eflags & EFLAGS_DF)) regs->esi++;
|
|
|
+ if (!(regs->eflags & CPU_STATUS_FLAG_DF)) regs->esi++;
|
|
|
else regs->esi--;
|
|
|
}
|
|
|
|
|
@@ -200,16 +219,16 @@ void vm86_handler(registers_ext_vm86_t *regs)
|
|
|
{
|
|
|
if (!(prefix & PREFIX_OPSIZE))
|
|
|
{
|
|
|
- outportw(regs->edx, peekw(segment, regs->esi));
|
|
|
+ cpu_write_port_word(regs->edx, peekw(segment, regs->esi));
|
|
|
|
|
|
- if (!(regs->eflags & EFLAGS_DF)) regs->esi += 2;
|
|
|
+ if (!(regs->eflags & CPU_STATUS_FLAG_DF)) regs->esi += 2;
|
|
|
else regs->esi -= 2;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- outportl(regs->edx, peekl(segment, regs->esi));
|
|
|
+ cpu_write_port_dword(regs->edx, peekl(segment, regs->esi));
|
|
|
|
|
|
- if (!(regs->eflags & EFLAGS_DF)) regs->esi += 4;
|
|
|
+ if (!(regs->eflags & CPU_STATUS_FLAG_DF)) regs->esi += 4;
|
|
|
else regs->esi -= 4;
|
|
|
}
|
|
|
}
|
|
@@ -220,10 +239,10 @@ void vm86_handler(registers_ext_vm86_t *regs)
|
|
|
case 0x9C: // pushf
|
|
|
{
|
|
|
operand = regs->eflags;
|
|
|
- operand &= ~EFLAGS_VM;
|
|
|
+ operand &= ~CPU_STATUS_FLAG_VM;
|
|
|
|
|
|
- if (vm86_interrupts) operand |= EFLAGS_IF;
|
|
|
- else operand &= ~EFLAGS_IF;
|
|
|
+ if (vm86_interrupts) operand |= CPU_STATUS_FLAG_IF;
|
|
|
+ else operand &= ~CPU_STATUS_FLAG_IF;
|
|
|
|
|
|
if (!(prefix & PREFIX_OPSIZE))
|
|
|
{
|
|
@@ -244,17 +263,17 @@ void vm86_handler(registers_ext_vm86_t *regs)
|
|
|
if (!(prefix & PREFIX_OPSIZE))
|
|
|
{
|
|
|
regs->eflags &= 0xFFFF0000;
|
|
|
- regs->eflags |= peekw(regs->ss, regs->esp3) | EFLAGS_VM;
|
|
|
+ regs->eflags |= peekw(regs->ss, regs->esp3) | CPU_STATUS_FLAG_VM;
|
|
|
regs->esp3 += 2;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- regs->eflags = peekl(regs->ss, regs->esp3) | EFLAGS_VM;
|
|
|
+ regs->eflags = peekl(regs->ss, regs->esp3) | CPU_STATUS_FLAG_VM;
|
|
|
regs->esp3 += 4;
|
|
|
}
|
|
|
|
|
|
- vm86_interrupts = (regs->eflags & EFLAGS_IF) ? TRUE : FALSE;
|
|
|
- regs->eflags |= EFLAGS_IF;
|
|
|
+ vm86_interrupts = (regs->eflags & CPU_STATUS_FLAG_IF) ? TRUE : FALSE;
|
|
|
+ regs->eflags |= CPU_STATUS_FLAG_IF;
|
|
|
|
|
|
break;
|
|
|
}
|
|
@@ -265,7 +284,7 @@ void vm86_handler(registers_ext_vm86_t *regs)
|
|
|
regs->eip++;
|
|
|
|
|
|
regs->esp3 -= 2;
|
|
|
- pokew(regs->ss, regs->esp3, (regs->eflags & (~EFLAGS_VM)) | (vm86_interrupts ? EFLAGS_IF : 0));
|
|
|
+ pokew(regs->ss, regs->esp3, (regs->eflags & (~CPU_STATUS_FLAG_VM)) | (vm86_interrupts ? CPU_STATUS_FLAG_IF : 0));
|
|
|
|
|
|
regs->esp3 -= 2;
|
|
|
pokew(regs->ss, regs->esp3, regs->cs);
|
|
@@ -318,11 +337,11 @@ void vm86_handler(registers_ext_vm86_t *regs)
|
|
|
regs->cs = peekw(regs->ss, regs->esp3);
|
|
|
regs->esp3 += 2;
|
|
|
|
|
|
- regs->eflags = peekw(regs->ss, regs->esp3) | EFLAGS_VM;
|
|
|
+ regs->eflags = peekw(regs->ss, regs->esp3) | CPU_STATUS_FLAG_VM;
|
|
|
regs->esp3 += 2;
|
|
|
|
|
|
- vm86_interrupts = (regs->eflags & EFLAGS_IF) ? TRUE : FALSE;
|
|
|
- regs->eflags |= EFLAGS_IF;
|
|
|
+ vm86_interrupts = (regs->eflags & CPU_STATUS_FLAG_IF) ? TRUE : FALSE;
|
|
|
+ regs->eflags |= CPU_STATUS_FLAG_IF;
|
|
|
|
|
|
break;
|
|
|
}
|
|
@@ -332,7 +351,7 @@ void vm86_handler(registers_ext_vm86_t *regs)
|
|
|
operand = peekb(regs->cs, regs->eip);
|
|
|
regs->eip++;
|
|
|
regs->eax &= 0xFFFFFF00;
|
|
|
- regs->eax |= inportb(operand & 0xFF) & 0xFF;
|
|
|
+ regs->eax |= cpu_read_port_byte(operand & 0xFF) & 0xFF;
|
|
|
|
|
|
break;
|
|
|
}
|
|
@@ -345,9 +364,9 @@ void vm86_handler(registers_ext_vm86_t *regs)
|
|
|
if (!(prefix & PREFIX_OPSIZE))
|
|
|
{
|
|
|
regs->eax &= 0xFFFF0000;
|
|
|
- regs->eax |= inportw(operand & 0xFF) & 0xFFFF;
|
|
|
+ regs->eax |= cpu_read_port_word(operand & 0xFF) & 0xFFFF;
|
|
|
}
|
|
|
- else regs->eax = inportl(operand & 0xFF);
|
|
|
+ else regs->eax = cpu_read_port_dword(operand & 0xFF);
|
|
|
|
|
|
break;
|
|
|
}
|
|
@@ -356,7 +375,7 @@ void vm86_handler(registers_ext_vm86_t *regs)
|
|
|
{
|
|
|
operand = peekb(regs->cs, regs->eip);
|
|
|
regs->eip++;
|
|
|
- outportb(operand & 0xFF, regs->eax & 0xFF);
|
|
|
+ cpu_write_port_byte(operand & 0xFF, regs->eax & 0xFF);
|
|
|
|
|
|
break;
|
|
|
}
|
|
@@ -366,8 +385,8 @@ void vm86_handler(registers_ext_vm86_t *regs)
|
|
|
operand = peekb(regs->cs, regs->eip);
|
|
|
regs->eip++;
|
|
|
|
|
|
- if (!(prefix & PREFIX_OPSIZE)) outportw(operand & 0xFF, regs->eax & 0xFFFF);
|
|
|
- else outportl(operand & 0xFF, regs->eax);
|
|
|
+ if (!(prefix & PREFIX_OPSIZE)) cpu_write_port_word(operand & 0xFF, regs->eax & 0xFFFF);
|
|
|
+ else cpu_write_port_dword(operand & 0xFF, regs->eax);
|
|
|
|
|
|
break;
|
|
|
}
|
|
@@ -375,7 +394,7 @@ void vm86_handler(registers_ext_vm86_t *regs)
|
|
|
case 0xEC: // in al, dx
|
|
|
{
|
|
|
regs->eax &= 0xFFFFFF00;
|
|
|
- regs->eax |= inportb(regs->edx & 0xFFFF) & 0xFF;
|
|
|
+ regs->eax |= cpu_read_port_byte(regs->edx & 0xFFFF) & 0xFF;
|
|
|
|
|
|
break;
|
|
|
}
|
|
@@ -385,23 +404,23 @@ void vm86_handler(registers_ext_vm86_t *regs)
|
|
|
if (!(prefix & PREFIX_OPSIZE))
|
|
|
{
|
|
|
regs->eax &= 0xFFFF0000;
|
|
|
- regs->eax |= inportw(regs->edx & 0xFFFF) & 0xFFFF;
|
|
|
+ regs->eax |= cpu_read_port_word(regs->edx & 0xFFFF) & 0xFFFF;
|
|
|
}
|
|
|
- else regs->eax = inportl(regs->edx & 0xFFFF);
|
|
|
+ else regs->eax = cpu_read_port_dword(regs->edx & 0xFFFF);
|
|
|
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
case 0xEE: // out dx, al
|
|
|
{
|
|
|
- outportb(regs->edx & 0xFFFF, regs->eax & 0xFF);
|
|
|
+ cpu_write_port_byte(regs->edx & 0xFFFF, regs->eax & 0xFF);
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
case 0xEF: // out dx, (e)ax
|
|
|
{
|
|
|
- if (!(prefix & PREFIX_OPSIZE)) outportw(regs->edx & 0xFFFF, regs->eax & 0xFFFF);
|
|
|
- else outportl(regs->edx & 0xFFFF, regs->eax);
|
|
|
+ if (!(prefix & PREFIX_OPSIZE)) cpu_write_port_word(regs->edx & 0xFFFF, regs->eax & 0xFFFF);
|
|
|
+ else cpu_write_port_dword(regs->edx & 0xFFFF, regs->eax);
|
|
|
|
|
|
break;
|
|
|
}
|