Make the kernel dir overridable.
[v86d.git] / v86_x86emu.c
blob1f2036b743361be43a9d1442de762baf54727019
1 #include <stdarg.h>
2 #include <string.h>
3 #include <x86emu.h>
4 #include "v86.h"
5 #include "v86_x86emu.h"
7 u8 *stack;
8 u8 *halt;
10 __BUILDIO(b,b,u8);
11 __BUILDIO(w,w,u16);
12 __BUILDIO(l,,u32);
14 void printk(const char *fmt, ...)
16 va_list argptr;
17 va_start(argptr, fmt);
18 vsyslog(LOG_INFO, fmt, argptr);
19 va_end(argptr);
22 void pushw(u16 val)
24 X86_ESP -= 2;
25 wrw(((u32) X86_SS << 4) + X86_SP, val);
28 static void x86emu_do_int(int num)
30 u32 eflags;
32 eflags = X86_EFLAGS;
33 eflags = eflags | X86_IF_MASK;
35 /* Return address and flags */
36 pushw(eflags);
37 pushw(X86_CS);
38 pushw(X86_IP);
39 X86_EFLAGS = X86_EFLAGS & ~(X86_VIF_MASK | X86_TF_MASK);
41 X86_CS = rdw((num << 2) + 2);
42 X86_IP = rdw((num << 2));
45 int v86_init()
47 X86EMU_intrFuncs intFuncs[256];
48 X86EMU_pioFuncs pioFuncs = {
49 .inb = x_inb,
50 .inw = x_inw,
51 .inl = x_inl,
52 .outb = x_outb,
53 .outw = x_outw,
54 .outl = x_outl,
56 int i;
58 v86_mem_init();
60 stack = v86_mem_alloc(DEFAULT_STACK_SIZE);
61 X86_SS = (u32)stack >> 4;
62 X86_ESP = 0xfffe;
64 halt = v86_mem_alloc(0x100);
65 *halt = 0xF4;
67 /* Setup x86emu I/O functions */
68 X86EMU_setupPioFuncs(&pioFuncs);
70 /* Setup interrupt handlers */
71 for (i = 0; i < 256; i++) {
72 intFuncs[i] = x86emu_do_int;
74 X86EMU_setupIntrFuncs(intFuncs);
76 /* Set the default flags */
77 X86_EFLAGS = X86_IF_MASK | X86_IOPL_MASK;
79 /* M is a macro poiting to the global virtual machine state
80 * for x86emu. */
81 M.mem_base = 0x0;
82 M.mem_size = 0x100000;
84 ioperm(0, 1024, 1);
85 iopl(3);
87 return 0;
90 void v86_cleanup()
92 v86_mem_cleanup();
95 void rconv_vm86_to_x86emu(struct vm86_regs *rs)
97 X86_EAX = rs->eax;
98 X86_EBX = rs->ebx;
99 X86_ECX = rs->ecx;
100 X86_EDX = rs->edx;
101 X86_EDI = rs->edi;
102 X86_ESI = rs->esi;
103 X86_EBP = rs->ebp;
104 X86_ESP = rs->esp;
105 X86_EFLAGS = rs->eflags;
106 X86_EIP = rs->eip;
107 X86_CS = rs->cs;
108 X86_DS = rs->ds;
109 X86_ES = rs->es;
110 X86_FS = rs->fs;
111 X86_GS = rs->gs;
114 void rconv_x86emu_to_vm86(struct vm86_regs *rd)
116 rd->eax = X86_EAX;
117 rd->ebx = X86_EBX;
118 rd->ecx = X86_ECX;
119 rd->edx = X86_EDX;
120 rd->edi = X86_EDI;
121 rd->esi = X86_ESI;
122 rd->ebp = X86_EBP;
123 rd->esp = X86_ESP;
124 rd->eflags = X86_EFLAGS;
125 rd->eip = X86_EIP;
126 rd->cs = X86_CS;
127 rd->ds = X86_DS;
128 rd->es = X86_ES;
129 rd->fs = X86_FS;
130 rd->gs = X86_GS;
134 * Perform a simulated interrupt call.
136 int v86_int(int num, struct vm86_regs *regs)
138 int err;
140 rconv_vm86_to_x86emu(regs);
142 X86_DS = 0x0040;
143 X86_CS = get_int_seg(num);
144 X86_EIP = get_int_off(num);
145 X86_SS = (u32)stack >> 4;
146 X86_ESP = 0xffff;
147 X86_EFLAGS = DEFAULT_V86_FLAGS | X86_IF_MASK;
148 X86_EFLAGS &= ~(X86_VIF_MASK | X86_TF_MASK | X86_IF_MASK | X86_NT_MASK);
150 pushw(DEFAULT_V86_FLAGS);
151 pushw(((u32)halt >> 4));
152 pushw(0x0);
154 X86EMU_exec();
156 rconv_x86emu_to_vm86(regs);
157 return 0;