Beispiel #1
0
Datei: v86.c Projekt: 1tgr/mobius
static void ShV86Handler(void)
{
    context_v86_t ctx;
    uint8_t *ip;

    ThrGetV86Context(&ctx);
    
    ip = FP_TO_LINEAR(ctx.cs, ctx.eip);
    switch (ip[0])
    {
    case 0xcd:
	switch (ip[1])
	{
	case 0x20:
	    ThrExitThread(0);
	    break;

	case 0x21:
	    ShInt21(&ctx);
	    break;
	}

	ctx.eip += 2;
	break;

    default:
	wprintf(L"v86: illegal instruction %x\n", ip[0]);
	ThrExitThread(0);
	break;
    }

    ThrSetV86Context(&ctx);
    ThrContinueV86();
}
Beispiel #2
0
Datei: v86.c Projekt: 1tgr/mobius
static void ShInt21(context_v86_t *ctx)
{
    void *ptr;
    char *ch;
    uint32_t key;
    
    switch ((uint16_t) ctx->regs.eax >> 8)
    {
    case 0:
	ThrExitThread(0);
	break;

    case 1:
        while (!FsRead(ProcGetProcessInfo()->std_in, &key, 0, sizeof(key), NULL))
            ;

	wprintf(L"%c", (uint8_t) key);
	ctx->regs.eax = (ctx->regs.eax & 0xffffff00) | (uint8_t) key;
	break;

    case 2:
	wprintf(L"%c", ctx->regs.edx & 0xff);
	break;

    case 9:
	ptr = FP_TO_LINEAR(ctx->v86_ds, ctx->regs.edx);
	ch = strchr(ptr, '$');
	fwrite(ptr, 1, ch - (char*) ptr, stdout);
	break;

    case 0x4c:
	ThrExitThread(ctx->regs.eax & 0xff);
	break;
    }
}
Beispiel #3
0
void
graphics_install_vesa(uint16_t x, uint16_t y) {
	blog("Setting up VESA video controller...");

	/* VESA Structs */
	struct VesaControllerInfo *info = (void*)0x10000;
	struct VesaModeInfo *modeinfo = (void*)0x9000;

	/* 8086 Emulator Status */
	tRME_State *emu;
	void * lowCache;
	lowCache = malloc(RME_BLOCK_SIZE);
	memcpy(lowCache, NULL, RME_BLOCK_SIZE);
	emu = RME_CreateState();
	emu->Memory[0] = lowCache;
	for (int i = RME_BLOCK_SIZE; i < 0x100000; i += RME_BLOCK_SIZE) {
		emu->Memory[i/RME_BLOCK_SIZE] = (void*)i;
	}
	int ret, mode;

	/* Find modes */
	uint16_t * modes;
	memcpy(info->Signature, "VBE2", 4);
	emu->AX.W = 0x4F00;
	emu->ES   = 0x1000;
	emu->DI.W = 0;
	ret = RME_CallInt(emu, 0x10);
	if (info->Version < 0x200 || info->Version > 0x300) {
		bfinish(2);
		kprintf("\033[JYou have attempted to use the VESA/VBE2 driver\nwith a card that does not support VBE2.\n");
		kprintf("\nSystem responded to VBE request with version: 0x%x\n", info->Version);

		STOP;
	}
	modes = (void*)FP_TO_LINEAR(info->Videomodes.Segment,info->Videomodes.Offset);

	uint16_t best_x    = 0;
	uint16_t best_y    = 0;
	uint16_t best_b    = 0;
	uint16_t best_mode = 0;

	for (int i = 1; modes[i] != 0xFFFF; ++i) {
		emu->AX.W = 0x4F01;
		emu->CX.W = modes[i];
		emu->ES   = 0x0900;
		emu->DI.W = 0x0000;
		RME_CallInt(emu, 0x10);
#if PROMPT_FOR_MODE
		kprintf("%d = %dx%d:%d\n", i, modeinfo->Xres, modeinfo->Yres, modeinfo->bpp);
	}

	kprintf("Please select a mode: ");
	char buf[10];
	kgets(buf, 10);
	mode = atoi(buf);
#else
		if ((abs(modeinfo->Xres - x) < abs(best_x - x)) && (abs(modeinfo->Yres - y) < abs(best_y - y))) {
				best_mode = i;
				best_x = modeinfo->Xres;
				best_y = modeinfo->Yres;
				best_b = modeinfo->bpp;
		}
	}
Beispiel #4
0
uint8_t *ip;
uint16_t *stack, *ivt;

/* xxx - need to validate CS, EIP, SS and ESP here */

ip = FP_TO_LINEAR(ctx->cs, ctx->eip);
ivt = (uint16_t*) 0;
stack = (uint16_t*) FP_TO_LINEAR(ctx->ss, ctx->esp);

switch (ip[0])
{
case 0xcd:  /* INT n */
    stack -= 3;
    ctx->esp = ((ctx->esp & 0xffff) - 6) & 0xffff;

    stack[0] = (uint16_t) (ctx->eip + 2);
    stack[1] = ctx->cs;
    stack[2] = (uint16_t) ctx->eflags;

    if (current->v86_if)
        stack[2] |= EFLAG_IF;
    else
        stack[2] &= ~EFLAG_IF;

    current->v86_if = false;
    ctx->cs = ivt[ip[1] * 2 + 1];
    ctx->eip = ivt[ip[1] * 2];
    return true;  /* continue execution */

default:  /* something wrong */
    return false; /* terminate the app */
Beispiel #5
0
bool i386V86Gpf(context_v86_t *ctx)
{
    uint8_t *ip;
    uint16_t *stack, *ivt;
    uint32_t *stack32;
    bool is_operand32, is_address32;

    ip = FP_TO_LINEAR(ctx->cs, ctx->eip);
    ivt = (uint16_t*) 0;
    stack = (uint16_t*) FP_TO_LINEAR(ctx->ss, ctx->esp);
    stack32 = (uint32_t*) stack;
    is_operand32 = is_address32 = false;
    TRACE4("i386V86Gpf: cs:ip = %04x:%04x ss:sp = %04x:%04x: ", 
        ctx->cs, ctx->eip,
        ctx->ss, ctx->esp);

    while (true)
    {
        switch (ip[0])
        {
        case 0x66:            /* O32 */
            TRACE0("o32 ");
            is_operand32 = true;
            ip++;
            ctx->eip = (uint16_t) (ctx->eip + 1);
            break;

        case 0x67:            /* A32 */
            TRACE0("a32 ");
            is_address32 = true;
            ip++;
            ctx->eip = (uint16_t) (ctx->eip + 1);
            break;
            
        case 0x9c:            /* PUSHF */
            TRACE0("pushf\n");

            if (is_operand32)
            {
                ctx->esp = ((ctx->esp & 0xffff) - 4) & 0xffff;
                stack32--;
                stack32[0] = ctx->eflags & VALID_FLAGS;

                if (current->v86_if)
                    stack32[0] |= EFLAG_IF;
                else
                    stack32[0] &= ~EFLAG_IF;
            }
            else
            {
                ctx->esp = ((ctx->esp & 0xffff) - 2) & 0xffff;
                stack--;
                stack[0] = (uint16_t) ctx->eflags;

                if (current->v86_if)
                    stack[0] |= EFLAG_IF;
                else
                    stack[0] &= ~EFLAG_IF;
            }

            ctx->eip = (uint16_t) (ctx->eip + 1);
            return true;

        case 0x9d:            /* POPF */
            TRACE0("popf\n");

            if (is_operand32)
            {
                ctx->eflags = EFLAG_IF | EFLAG_VM | (stack32[0] & VALID_FLAGS);
                current->v86_if = (stack32[0] & EFLAG_IF) != 0;
                ctx->esp = ((ctx->esp & 0xffff) + 4) & 0xffff;
            }
            else
            {
                ctx->eflags = EFLAG_IF | EFLAG_VM | stack[0];
                current->v86_if = (stack[0] & EFLAG_IF) != 0;
                ctx->esp = ((ctx->esp & 0xffff) + 2) & 0xffff;
            }
            
            ctx->eip = (uint16_t) (ctx->eip + 1);
            return true;

        case 0xcd:            /* INT n */
            TRACE1("interrupt 0x%x => ", ip[1]);
            switch (ip[1])
            {
            case 0x30:
                TRACE0("syscall\n");
                if (ctx->regs.eax == SYS_ThrExitThread)
                    ThrExitThread(0);
                return true;

            case 0x20:
            case 0x21:
                /*i386V86EmulateInt21(ctx);*/
                if (current->v86_in_handler)
                    return false;

                TRACE1("redirect to %x\n", current->v86_handler);
                current->v86_in_handler = true;
                current->v86_context = *ctx;
                current->kernel_esp += sizeof(context_v86_t) - sizeof(context_t);
                ctx->eflags = EFLAG_IF | 2;
                ctx->eip = current->v86_handler;
                ctx->cs = USER_FLAT_CODE | 3;
                ctx->ds = ctx->es = ctx->gs = ctx->ss = USER_FLAT_DATA | 3;
                ctx->fs = USER_THREAD_INFO | 3;
                ctx->esp = current->user_stack_top;
                return true;

            default:
                stack -= 3;
                ctx->esp = ((ctx->esp & 0xffff) - 6) & 0xffff;

                stack[0] = (uint16_t) (ctx->eip + 2);
                stack[1] = ctx->cs;
                stack[2] = (uint16_t) ctx->eflags;
                
                if (current->v86_if)
                    stack[2] |= EFLAG_IF;
                else
                    stack[2] &= ~EFLAG_IF;

                ctx->cs = ivt[ip[1] * 2 + 1];
                ctx->eip = ivt[ip[1] * 2];
                TRACE2("%04x:%04x\n", ctx->cs, ctx->eip);
                return true;
            }

            break;

        case 0xcf:            /* IRET */
            TRACE0("iret => ");
            ctx->eip = stack[0];
            ctx->cs = stack[1];
            ctx->eflags = EFLAG_IF | EFLAG_VM | stack[2];
            current->v86_if = (stack[2] & EFLAG_IF) != 0;

            ctx->esp = ((ctx->esp & 0xffff) + 6) & 0xffff;
            TRACE2("%04x:%04x\n", ctx->cs, ctx->eip);
            return true;

        case 0xfa:            /* CLI */
            TRACE0("cli\n");
            current->v86_if = false;
            ctx->eip = (uint16_t) (ctx->eip + 1);
            return true;

        case 0xfb:            /* STI */
            TRACE0("sti\n");
            current->v86_if = true;
            ctx->eip = (uint16_t) (ctx->eip + 1);
            return true;

        default:
            wprintf(L"unhandled opcode 0x%x\n", ip[0]);
            return false;
        }
    }

    return false;
}