27,10 → 27,12 |
* native VBE compliant Video card, without writing an explicit driver |
*/ |
|
#include <ll/i386/hw-data.h> |
#include <ll/i386/hw-instr.h> |
#include <ll/i386/hw-func.h> |
#include <ll/i386/mem.h> |
#include <ll/i386/x-bios.h> |
#include <ll/i386/hw-func.h> |
#include <ll/i386/hw-instr.h> |
#include <ll/i386/x-dosmem.h> |
#include <ll/i386/cons.h> |
#include <ll/i386/error.h> |
|
44,6 → 46,8 |
|
#define VM86_STACK_SIZE 1024 |
|
extern DWORD ll_irq_table[256]; |
|
/* TSS optional section */ |
static BYTE vm86_stack0[VM86_STACK_SIZE]; |
|
55,9 → 59,8 |
static LIN_ADDR vm86_iretAddress; |
|
|
DWORD *GLOBesp; |
struct registers *global_regs; |
|
|
#ifdef __DUMB_CODE__ |
static LIN_ADDR vm86_code; |
static BYTE prova86[] = { |
76,8 → 79,7 |
#endif |
0xcf, /* iret */ |
0xf4, /* hlt */ |
0 |
}; |
0}; |
#endif |
|
#ifdef __LL_DEBUG__ |
89,17 → 91,21 |
0xb0, '%', /* mov ax,'%' */ |
0x88, 0x05, /* mov ds:[di],al */ |
0x1f, /* pop ds */ |
0xcd, 0x48 |
}; /* int 0x48 */ |
0xcd, 0x48}; /* int 0x48 */ |
#else |
static BYTE vm86_retAddr[] = { 0xcd, 0x48 }; /* int 48h */ |
#endif |
|
TSS *vm86_get_tss(void) |
{ |
return &(vm86_TSS.t); |
} |
|
/* This is the return point from V86 mode, called through int 0x48 |
* (see vm86-exc.s). We double check that this function is called in |
* the V86 TSS. Otherwise, Panic!!! |
*/ |
void vm86_return(DWORD * tos) |
void vm86_return(DWORD n, struct registers r) |
{ |
CONTEXT c = get_TR(); |
#ifdef __LL_DEBUG__ |
109,7 → 115,7 |
/* message("Gotta code=%d [0 called from GPF/1 int 0x48]\n",code);*/ |
#endif |
if (c == X_VM86_TSS) { |
GLOBesp = tos; |
global_regs = &r; |
#ifdef __LL_DEBUG__ |
message("TSS CS=%x IP=%lx\n", vm86_TSS.t.cs, vm86_TSS.t.eip); |
message("Switching to %x\n", vm86_TSS.t.back_link); |
116,9 → 122,8 |
a = (DWORD) (vm86_iretAddress); |
cs = (a & 0xFF000) >> 4; |
eip = (a & 0xFFF); |
message("Real-Mode Address is CS=%lx IP=%lx\nLinear=%lx\n", cs, |
eip, a); |
esp = (void *) (tos); |
message("Real-Mode Address is CS=%lx IP=%lx\nLinear=%lx\n",cs,eip,a); |
esp = /* (void *)(tos)*/ 0x69; |
message("Stack frame: %p %lx %lx\n", |
esp, vm86_TSS.t.esp0, vm86_TSS.t.esp); |
message("%lx ", lmempeekd(esp)); /* bp */ |
143,6 → 148,7 |
#endif |
ll_context_load(vm86_TSS.t.back_link); |
} |
message("Here?\n"); |
halt(); |
} |
|
171,7 → 177,7 |
int register i; |
|
/* Init the DOS memory allocator */ |
// DOS_mem_init(); |
DOS_mem_init(); |
|
/* First of all, we need to setup a GDT entries to |
* allow vm86 task execution. We just need a free 386 TSS, which |
180,8 → 186,12 |
*/ |
GDT_place(X_VM86_TSS, (DWORD) (&vm86_TSS), |
sizeof(vm86_TSS), FREE_TSS386, GRAN_16); |
IDT_place(0x48, vm86_exc); |
|
/* HACKME!!! */ |
// IDT_place(0x48,vm86_exc); |
l1_int_bind(0x48, vm86_return); |
// ll_irq_table[0x48] = (DWORD)vm86_return; |
|
/* Prepare a real-mode stack, obtaining it from the |
* DOS memory allocator! |
* 8K should be OK! Stack top is vm86_stack + SIZE! |
196,7 → 206,7 |
vm86_iretAddress = DOS_alloc(sizeof(vm86_retAddr)); |
memcpy(vm86_iretAddress, vm86_retAddr, sizeof(vm86_retAddr)); |
#ifdef __LL_DEBUG__ |
message("PM reentry linear address=%p\n", vm86_iretAddress); |
message("PM reentry linear address=0x%lx\n", (DWORD)vm86_iretAddress); |
#endif |
#ifdef __DUMB_CODE__ |
vm86_code = DOS_alloc(2048); |
222,13 → 232,11 |
*/ |
vm86_TSS.t.io_base = (DWORD) (&(vm86_TSS.io_map)) - |
(DWORD) (&(vm86_TSS)); |
for (i = 0; i < 2047; i++) |
vm86_TSS.io_map[i] = 0; |
for (i = 0; i < 2047; i++) vm86_TSS.io_map[i] = 0; |
vm86_TSS.io_map[2047] = 0xFF000000; |
} |
|
int vm86_callBIOS(int service, X_REGS16 * in, X_REGS16 * out, |
X_SREGS16 * s) |
int vm86_callBIOS(int service,X_REGS16 *in,X_REGS16 *out,X_SREGS16 *s) |
{ |
DWORD vm86_tmpAddr; |
DWORD vm86_flags, vm86_cs, vm86_ip; |
235,8 → 243,7 |
LIN_ADDR vm86_stackPtr; |
DWORD *IRQTable_entry; |
|
if (service < 0x10 || in == NULL) |
return -1; |
if (service < 0x10 || in == NULL) return -1; |
/* Setup the stack frame */ |
vm86_tmpAddr = (DWORD) (vm86_stack); |
vm86_TSS.t.ss = (vm86_tmpAddr & 0xFF000) >> 4; |
253,8 → 260,7 |
lmempokew(vm86_stackPtr - 2, vm86_flags); |
#ifdef __LL_DEBUG__ |
message("Stack: %lx SS: %lx SP: %lx\n", |
vm86_tmpAddr + VM86_STACK_SIZE, (DWORD) vm86_TSS.t.ss, |
vm86_TSS.t.esp); |
vm86_tmpAddr + VM86_STACK_SIZE,(DWORD)vm86_TSS.t.ss,vm86_TSS.t.esp); |
#endif |
/* Wanted VM86 mode + IOPL = 3! */ |
vm86_TSS.t.eflags = CPU_FLAG_VM | CPU_FLAG_IOPL; |
302,7 → 308,7 |
vm86_TSS.t.cs = ((IRQTable_entry[service]) & 0xFFFF0000) >> 16; |
vm86_TSS.t.eip = ((IRQTable_entry[service]) & 0x0000FFFF); |
#ifdef __LL_DEBUG__ |
message("CS:%hx IP:%lx\n", vm86_TSS.t.cs, vm86_TSS.t.eip); |
message("CS:%x IP:%lx\n", vm86_TSS.t.cs, vm86_TSS.t.eip); |
#endif |
/* Let's use the ll standard call... */ |
vm86_TSS.t.back_link = ll_context_save(); |
310,13 → 316,10 |
#ifdef __LL_DEBUG__ |
message("I am back...\n"); |
message("TSS CS=%hx IP=%lx\n", vm86_TSS.t.cs, vm86_TSS.t.eip); |
{ |
char *xp = (char *) (vm86_iretAddress + 0xe); |
{ char *xp = (char *)(vm86_iretAddress + 0xe); |
message("PM reentry linear address=%p\n", vm86_iretAddress); |
message("Executing code: %x ", (unsigned char) (*xp)); |
xp++; |
message("%x\n", (unsigned char) (*xp)); |
} |
message("Executing code: %x ",(unsigned char)(*xp)); xp++; |
message("%x\n",(unsigned char)(*xp));} |
#endif |
/* Send back in the X_*REGS structure the value obtained with |
* the real-mode interrupt call |
332,22 → 335,22 |
out->x.cflag = (WORD)vm86_TSS.t.eflags; |
*/ |
#ifdef __LL_DEBUG__ |
#error Fix the following: use global_regs->xxx ??? |
message("%x\n", (WORD) * (GLOBesp)); |
message("%x\n", (WORD) * (GLOBesp + 1)); |
/*EDI*/ message("%x\n", (WORD) * (GLOBesp + 2)); |
/*ESI*/ message("%x\n", (WORD) * (GLOBesp + 3)); |
/*EBP*/ message("%x\n", (WORD) * (GLOBesp + 4)); |
/*ESP*/ message("%x\n", (WORD) * (GLOBesp + 5)); |
/*EBX*/ message("%x\n", (WORD) * (GLOBesp + 6)); |
/*EDX*/ |
message("%x\n", (WORD)*(GLOBesp+1)); /*EDI*/ |
message("%x\n", (WORD)*(GLOBesp+2)); /*ESI*/ |
message("%x\n", (WORD)*(GLOBesp+3)); /*EBP*/ |
message("%x\n", (WORD)*(GLOBesp+4)); /*ESP*/ |
message("%x\n", (WORD)*(GLOBesp+5)); /*EBX*/ |
message("%x\n", (WORD)*(GLOBesp+6)); /*EDX*/ |
#endif |
out->x.ax = (WORD) * (GLOBesp + 8); |
out->x.bx = (WORD) * (GLOBesp + 5); |
out->x.cx = (WORD) * (GLOBesp + 7); |
out->x.dx = (WORD) * (GLOBesp + 6); |
out->x.si = (WORD) * (GLOBesp + 2); |
out->x.di = (WORD) * (GLOBesp + 1); |
out->x.cflag = (WORD) * (GLOBesp); |
out->x.ax = global_regs->eax; |
out->x.bx = global_regs->ebx; |
out->x.cx = global_regs->ecx; |
out->x.dx = global_regs->edx; |
out->x.si = global_regs->esi; |
out->x.di = global_regs->edi; |
out->x.cflag = global_regs->flags; |
} |
if (s != NULL) { |
s->es = vm86_TSS.t.es; |