Subversion Repositories shark

Compare Revisions

Regard whitespace Rev 39 → Rev 40

/shark/trunk/oslib/xlib/vm86.c
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;