Implemented PCI interrupt controller ports 4D0 and 4D1;
Applied more mainline PCem commits; Repplied the CPU optimization commit alongside the fix commit.
This commit is contained in:
@@ -51,7 +51,6 @@ uint32_t cr2, cr3, cr4;
|
||||
uint32_t dr[8];
|
||||
|
||||
|
||||
|
||||
uint8_t romext[32768];
|
||||
uint8_t *ram,*rom;
|
||||
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
/* Copyright holders: Sarah Walker, Tenshi
|
||||
see COPYING for more details
|
||||
*/
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Common 386 CPU code.
|
||||
*
|
||||
* Version: @(#)386_common.h 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
extern uint16_t ea_rseg;
|
||||
|
||||
#undef readmemb
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||
|
||||
uint32_t cpu_cur_status = 0;
|
||||
|
||||
int cpu_reps, cpu_reps_latched;
|
||||
int cpu_notreps, cpu_notreps_latched;
|
||||
|
||||
@@ -1326,7 +1328,41 @@ void exec386_dynarec(int cycs)
|
||||
{
|
||||
int cycles_start;
|
||||
|
||||
#if 0
|
||||
switch(cpu_pci_speed)
|
||||
{
|
||||
case 16000000:
|
||||
cycles += 640;
|
||||
break;
|
||||
case 20000000:
|
||||
cycles += 800;
|
||||
break;
|
||||
case 25000000:
|
||||
default:
|
||||
cycles += 1000;
|
||||
break;
|
||||
case 27500000:
|
||||
cycles += 1100;
|
||||
break;
|
||||
case 30000000:
|
||||
cycles += 1200;
|
||||
break;
|
||||
case 333333333:
|
||||
cycles += 1333;
|
||||
break;
|
||||
case 37500000:
|
||||
cycles += 1500;
|
||||
break;
|
||||
case 40000000:
|
||||
cycles += 1600;
|
||||
break;
|
||||
case 41666667:
|
||||
cycles += 1666;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
cycles += cpu_cycle_period();
|
||||
|
||||
cycles_start = cycles;
|
||||
|
||||
timer_start_period(cycles << TIMER_SHIFT);
|
||||
@@ -1405,7 +1441,7 @@ void exec386_dynarec(int cycs)
|
||||
and physical address. The physical address check will
|
||||
also catch any page faults at this stage*/
|
||||
valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) &&
|
||||
(block->use32 == use32) && (block->phys == phys_addr) && (block->stack32 == stack32);
|
||||
(block->phys == phys_addr) && (block->status == cpu_cur_status);
|
||||
if (!valid_block)
|
||||
{
|
||||
uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
|
||||
@@ -1417,7 +1453,7 @@ void exec386_dynarec(int cycs)
|
||||
if (new_block)
|
||||
{
|
||||
valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) &&
|
||||
(new_block->use32 == use32) && (new_block->phys == phys_addr) && (new_block->stack32 == stack32);
|
||||
(new_block->phys == phys_addr) && (new_block->status == cpu_cur_status);
|
||||
if (valid_block)
|
||||
block = new_block;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,23 @@
|
||||
/* Copyright holders: Sarah Walker, Tenshi, leilei
|
||||
see COPYING for more details
|
||||
*/
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* 286/386+ instruction handlers list.
|
||||
*
|
||||
* Version: @(#)386_ops.h 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* leilei,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 leilei.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
#include "x86_ops.h"
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
/* Copyright holders: Sarah Walker, Tenshi
|
||||
see COPYING for more details
|
||||
*/
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* 808x CPU emulation.
|
||||
*
|
||||
* Version: @(#)808x.c 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
/*SHR AX,1
|
||||
|
||||
4 clocks - fetch opcode
|
||||
@@ -552,6 +567,7 @@ void resetx86()
|
||||
resets++;
|
||||
ins = 0;
|
||||
use32=0;
|
||||
cpu_cur_status = 0;
|
||||
stack32=0;
|
||||
cpu_state.pc=0;
|
||||
msw=0;
|
||||
@@ -589,6 +605,7 @@ void softresetx86()
|
||||
{
|
||||
use32=0;
|
||||
stack32=0;
|
||||
cpu_cur_status = 0;
|
||||
cpu_state.pc=0;
|
||||
msw=0;
|
||||
cr0=0;
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
|
||||
typedef struct codeblock_t
|
||||
{
|
||||
uint64_t page_mask, page_mask2;
|
||||
uint64_t cmp;
|
||||
|
||||
/*Previous and next pointers, for the codeblock list associated with
|
||||
each physical page. Two sets of pointers, as a codeblock can be
|
||||
present in two pages.*/
|
||||
@@ -45,21 +48,18 @@ typedef struct codeblock_t
|
||||
fails.*/
|
||||
struct codeblock_t *parent, *left, *right;
|
||||
|
||||
int pnt;
|
||||
int ins;
|
||||
|
||||
int was_recompiled;
|
||||
int TOP;
|
||||
|
||||
uint32_t pc;
|
||||
uint32_t _cs;
|
||||
uint32_t endpc;
|
||||
uint32_t phys, phys_2;
|
||||
uint32_t use32;
|
||||
int stack32;
|
||||
int pnt;
|
||||
int ins;
|
||||
uint64_t page_mask, page_mask2;
|
||||
|
||||
int was_recompiled;
|
||||
uint32_t status;
|
||||
uint32_t flags;
|
||||
int TOP;
|
||||
|
||||
uint64_t cmp;
|
||||
|
||||
uint8_t data[2048];
|
||||
} codeblock_t;
|
||||
|
||||
@@ -866,6 +866,8 @@ static void CHECK_SEG_READ(x86seg *seg)
|
||||
return;
|
||||
if (seg->checked)
|
||||
return;
|
||||
if ((seg == &_ds) && codegen_flat_ds)
|
||||
return;
|
||||
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
@@ -900,6 +902,8 @@ static void CHECK_SEG_WRITE(x86seg *seg)
|
||||
return;
|
||||
if (seg->checked)
|
||||
return;
|
||||
if ((seg == &_ds) && codegen_flat_ds)
|
||||
return;
|
||||
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
@@ -926,6 +930,9 @@ static void CHECK_SEG_WRITE(x86seg *seg)
|
||||
}
|
||||
static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
return;
|
||||
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/
|
||||
@@ -962,7 +969,12 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
|
||||
|
||||
static void MEM_LOAD_ADDR_EA_B(x86seg *seg)
|
||||
{
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
@@ -1030,7 +1042,12 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg)
|
||||
}
|
||||
static void MEM_LOAD_ADDR_EA_W(x86seg *seg)
|
||||
{
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
@@ -1114,7 +1131,12 @@ static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
|
||||
}
|
||||
static void MEM_LOAD_ADDR_EA_L(x86seg *seg)
|
||||
{
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
@@ -1190,7 +1212,12 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg)
|
||||
}
|
||||
static void MEM_LOAD_ADDR_EA_Q(x86seg *seg)
|
||||
{
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
@@ -1309,7 +1336,12 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
|
||||
addbyte(8);
|
||||
host_reg = 8;
|
||||
}
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
@@ -1388,7 +1420,12 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
|
||||
}
|
||||
static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
|
||||
{
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
@@ -1478,7 +1515,12 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
|
||||
}
|
||||
static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
|
||||
{
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
@@ -1566,7 +1608,12 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
|
||||
}
|
||||
static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2)
|
||||
{
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
@@ -5252,7 +5299,12 @@ static void MEM_CHECK_WRITE(x86seg *seg)
|
||||
|
||||
CHECK_SEG_WRITE(seg);
|
||||
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOV ESI, seg->base*/
|
||||
addbyte(0x34);
|
||||
@@ -5299,12 +5351,15 @@ static void MEM_CHECK_WRITE(x86seg *seg)
|
||||
addbyte(0xc1); /*SHR EDI, 12*/
|
||||
addbyte(0xef);
|
||||
addbyte(12);
|
||||
if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x83); /*CMP ESI, -1*/
|
||||
addbyte(0xfe);
|
||||
addbyte(-1);
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
jump3 = &codeblock[block_current].data[block_pos];
|
||||
addbyte(0);
|
||||
}
|
||||
if (IS_32_ADDR(writelookup2))
|
||||
{
|
||||
addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/
|
||||
@@ -5328,6 +5383,7 @@ static void MEM_CHECK_WRITE(x86seg *seg)
|
||||
addbyte(0);
|
||||
// addbyte(0xc3); /*RET*/
|
||||
|
||||
if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss))
|
||||
*jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1;
|
||||
/*slowpath:*/
|
||||
addbyte(0x67); /*LEA EDI, [EAX+ESI]*/
|
||||
@@ -5373,7 +5429,12 @@ static void MEM_CHECK_WRITE_W(x86seg *seg)
|
||||
|
||||
CHECK_SEG_WRITE(seg);
|
||||
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOV ESI, seg->base*/
|
||||
addbyte(0x34);
|
||||
@@ -5416,15 +5477,21 @@ static void MEM_CHECK_WRITE_W(x86seg *seg)
|
||||
addbyte(0x79); /*JNS +*/
|
||||
jump1 = &codeblock[block_current].data[block_pos];
|
||||
addbyte(0);
|
||||
if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x83); /*CMP ESI, -1*/
|
||||
addbyte(0xfe);
|
||||
addbyte(-1);
|
||||
}
|
||||
addbyte(0x8d); /*LEA ESI, 1[EDI]*/
|
||||
addbyte(0x77);
|
||||
addbyte(0x01);
|
||||
if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
jump4 = &codeblock[block_current].data[block_pos];
|
||||
addbyte(0);
|
||||
}
|
||||
addbyte(0x89); /*MOV EBX, EDI*/
|
||||
addbyte(0xfb);
|
||||
addbyte(0xc1); /*SHR EDI, 12*/
|
||||
@@ -5475,6 +5542,7 @@ static void MEM_CHECK_WRITE_W(x86seg *seg)
|
||||
|
||||
/*slowpath:*/
|
||||
*jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1;
|
||||
if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss))
|
||||
*jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1;
|
||||
jump_pos = block_pos;
|
||||
load_param_1_reg_32(REG_EBX);
|
||||
@@ -5510,7 +5578,12 @@ static void MEM_CHECK_WRITE_L(x86seg *seg)
|
||||
|
||||
CHECK_SEG_WRITE(seg);
|
||||
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOV ESI, seg->base*/
|
||||
addbyte(0x34);
|
||||
@@ -5553,15 +5626,21 @@ static void MEM_CHECK_WRITE_L(x86seg *seg)
|
||||
addbyte(0x79); /*JNS +*/
|
||||
jump1 = &codeblock[block_current].data[block_pos];
|
||||
addbyte(0);
|
||||
if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x83); /*CMP ESI, -1*/
|
||||
addbyte(0xfe);
|
||||
addbyte(-1);
|
||||
}
|
||||
addbyte(0x8d); /*LEA ESI, 3[EDI]*/
|
||||
addbyte(0x77);
|
||||
addbyte(0x03);
|
||||
if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
jump4 = &codeblock[block_current].data[block_pos];
|
||||
addbyte(0);
|
||||
}
|
||||
addbyte(0x89); /*MOV EBX, EDI*/
|
||||
addbyte(0xfb);
|
||||
addbyte(0xc1); /*SHR EDI, 12*/
|
||||
@@ -5612,6 +5691,7 @@ static void MEM_CHECK_WRITE_L(x86seg *seg)
|
||||
|
||||
/*slowpath:*/
|
||||
*jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1;
|
||||
if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss))
|
||||
*jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1;
|
||||
jump_pos = block_pos;
|
||||
load_param_1_reg_32(REG_EBX);
|
||||
@@ -5642,7 +5722,12 @@ static void MEM_CHECK_WRITE_L(x86seg *seg)
|
||||
|
||||
static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
|
||||
{
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
@@ -5709,7 +5794,12 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
|
||||
}
|
||||
static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
|
||||
{
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
@@ -5785,7 +5875,12 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
|
||||
}
|
||||
static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg)
|
||||
{
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
@@ -5883,7 +5978,13 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
|
||||
addbyte(8);
|
||||
host_reg = 8;
|
||||
}
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
|
||||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EBX, EBX*/
|
||||
addbyte(0xdb);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EBX, seg->base*/
|
||||
addbyte(0x1c);
|
||||
@@ -5955,7 +6056,13 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
|
||||
}
|
||||
static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
|
||||
{
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
|
||||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EBX, EBX*/
|
||||
addbyte(0xdb);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EBX, seg->base*/
|
||||
addbyte(0x1c);
|
||||
@@ -6038,7 +6145,13 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
|
||||
}
|
||||
static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg)
|
||||
{
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
|
||||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EBX, EBX*/
|
||||
addbyte(0xdb);
|
||||
}
|
||||
else if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EBX, seg->base*/
|
||||
addbyte(0x1c);
|
||||
|
||||
@@ -616,6 +616,8 @@ static void CHECK_SEG_READ(x86seg *seg)
|
||||
return;
|
||||
if (seg->checked)
|
||||
return;
|
||||
if (seg == &_ds && codegen_flat_ds)
|
||||
return;
|
||||
|
||||
addbyte(0x83); /*CMP seg->base, -1*/
|
||||
addbyte(0x05|0x38);
|
||||
@@ -637,6 +639,8 @@ static void CHECK_SEG_WRITE(x86seg *seg)
|
||||
return;
|
||||
if (seg->checked)
|
||||
return;
|
||||
if (seg == &_ds && codegen_flat_ds)
|
||||
return;
|
||||
|
||||
addbyte(0x83); /*CMP seg->base, -1*/
|
||||
addbyte(0x05|0x38);
|
||||
@@ -650,6 +654,9 @@ static void CHECK_SEG_WRITE(x86seg *seg)
|
||||
}
|
||||
static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
return;
|
||||
|
||||
addbyte(0x3b); /*CMP EAX, seg->limit_low*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&seg->limit_low);
|
||||
@@ -675,9 +682,18 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
|
||||
|
||||
static void MEM_LOAD_ADDR_EA_B(x86seg *seg)
|
||||
{
|
||||
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
|
||||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EDX, seg->base*/
|
||||
addbyte(0x05 | (REG_EDX << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
addbyte(0xe8); /*CALL mem_load_addr_ea_b*/
|
||||
addlong(mem_load_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
|
||||
@@ -685,9 +701,17 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg)
|
||||
}
|
||||
static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EDX, seg->base*/
|
||||
addbyte(0x05 | (REG_EDX << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
addbyte(0xe8); /*CALL mem_load_addr_ea_b_no_abrt*/
|
||||
addlong(mem_load_addr_ea_b_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
|
||||
@@ -697,9 +721,17 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
|
||||
}
|
||||
static void MEM_LOAD_ADDR_EA_W(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EDX, seg->base*/
|
||||
addbyte(0x05 | (REG_EDX << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
addbyte(0xe8); /*CALL mem_load_addr_ea_w*/
|
||||
addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
|
||||
@@ -707,9 +739,17 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg)
|
||||
}
|
||||
static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EDX, seg->base*/
|
||||
addbyte(0x05 | (REG_EDX << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
addbyte(0x83); /*ADD EAX, offset*/
|
||||
addbyte(0xc0);
|
||||
addbyte(offset);
|
||||
@@ -720,9 +760,17 @@ static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
|
||||
}
|
||||
static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EDX, seg->base*/
|
||||
addbyte(0x05 | (REG_EDX << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
addbyte(0xe8); /*CALL mem_load_addr_ea_w_no_abrt*/
|
||||
addlong(mem_load_addr_ea_w_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
|
||||
@@ -732,9 +780,17 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
|
||||
}
|
||||
static void MEM_LOAD_ADDR_EA_L(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EDX, seg->base*/
|
||||
addbyte(0x05 | (REG_EDX << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
addbyte(0xe8); /*CALL mem_load_addr_ea_l*/
|
||||
addlong(mem_load_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
|
||||
@@ -743,9 +799,17 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg)
|
||||
}
|
||||
static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EDX, seg->base*/
|
||||
addbyte(0x05 | (REG_EDX << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
addbyte(0xe8); /*CALL mem_load_addr_ea_l_no_abrt*/
|
||||
addlong(mem_load_addr_ea_l_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
|
||||
@@ -756,9 +820,17 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg)
|
||||
|
||||
static void MEM_LOAD_ADDR_EA_Q(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EDX, seg->base*/
|
||||
addbyte(0x05 | (REG_EDX << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
addbyte(0xe8); /*CALL mem_load_addr_ea_q*/
|
||||
addlong(mem_load_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
|
||||
@@ -786,9 +858,17 @@ static void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr)
|
||||
|
||||
static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ESI, seg->base*/
|
||||
addbyte(0x05 | (REG_ESI << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
if (host_reg != REG_ECX)
|
||||
{
|
||||
addbyte(0x89); /*MOV ECX, host_reg*/
|
||||
@@ -799,9 +879,17 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
|
||||
}
|
||||
static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ESI, seg->base*/
|
||||
addbyte(0x05 | (REG_ESI << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
if (host_reg != REG_ECX)
|
||||
{
|
||||
addbyte(0x89); /*MOV ECX, host_reg*/
|
||||
@@ -812,9 +900,17 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
|
||||
}
|
||||
static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ESI, seg->base*/
|
||||
addbyte(0x05 | (REG_ESI << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
if (host_reg != REG_ECX)
|
||||
{
|
||||
addbyte(0x89); /*MOV ECX, host_reg*/
|
||||
@@ -825,9 +921,17 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
|
||||
}
|
||||
static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ESI, seg->base*/
|
||||
addbyte(0x05 | (REG_ESI << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
if (host_reg != REG_ECX)
|
||||
{
|
||||
addbyte(0x89); /*MOV ECX, host_reg*/
|
||||
@@ -838,9 +942,17 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
|
||||
}
|
||||
static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ESI, seg->base*/
|
||||
addbyte(0x05 | (REG_ESI << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
if (host_reg != REG_ECX)
|
||||
{
|
||||
addbyte(0x89); /*MOV ECX, host_reg*/
|
||||
@@ -851,9 +963,17 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
|
||||
}
|
||||
static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ESI, seg->base*/
|
||||
addbyte(0x05 | (REG_ESI << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
if (host_reg != REG_ECX)
|
||||
{
|
||||
addbyte(0x89); /*MOV ECX, host_reg*/
|
||||
@@ -874,9 +994,17 @@ static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2)
|
||||
addbyte(0x89); /*MOV ECX, host_reg2*/
|
||||
addbyte(0xc0 | REG_ECX | (host_reg2 << 3));
|
||||
}
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ESI, seg->base*/
|
||||
addbyte(0x05 | (REG_ESI << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
addbyte(0xe8); /*CALL mem_store_addr_ea_q*/
|
||||
addlong(mem_store_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
}
|
||||
@@ -3792,9 +3920,17 @@ static void LOAD_EA()
|
||||
static void MEM_CHECK_WRITE(x86seg *seg)
|
||||
{
|
||||
CHECK_SEG_WRITE(seg);
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ESI, seg->base*/
|
||||
addbyte(0x05 | (REG_ESI << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
addbyte(0xe8); /*CALL mem_check_write*/
|
||||
addlong(mem_check_write - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
LOAD_EA();
|
||||
@@ -3802,9 +3938,17 @@ static void MEM_CHECK_WRITE(x86seg *seg)
|
||||
static void MEM_CHECK_WRITE_W(x86seg *seg)
|
||||
{
|
||||
CHECK_SEG_WRITE(seg);
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ESI, seg->base*/
|
||||
addbyte(0x05 | (REG_ESI << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
addbyte(0xe8); /*CALL mem_check_write_w*/
|
||||
addlong(mem_check_write_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
LOAD_EA();
|
||||
@@ -3812,9 +3956,17 @@ static void MEM_CHECK_WRITE_W(x86seg *seg)
|
||||
static void MEM_CHECK_WRITE_L(x86seg *seg)
|
||||
{
|
||||
CHECK_SEG_WRITE(seg);
|
||||
if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ESI, seg->base*/
|
||||
addbyte(0x05 | (REG_ESI << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
addbyte(0xe8); /*CALL mem_check_write_l*/
|
||||
addlong(mem_check_write_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
LOAD_EA();
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
int codegen_flat_ds, codegen_flat_ss;
|
||||
int codegen_flags_changed = 0;
|
||||
int codegen_fpu_entered = 0;
|
||||
int codegen_fpu_loaded_iq[8];
|
||||
@@ -274,13 +275,13 @@ void codegen_block_init(uint32_t phys_addr)
|
||||
block->_cs = cs;
|
||||
block->pnt = block_current;
|
||||
block->phys = phys_addr;
|
||||
block->use32 = use32;
|
||||
block->stack32 = stack32;
|
||||
block->next = block->prev = NULL;
|
||||
block->next_2 = block->prev_2 = NULL;
|
||||
block->page_mask = 0;
|
||||
block->flags = 0;
|
||||
|
||||
block->status = cpu_cur_status;
|
||||
|
||||
block->was_recompiled = 0;
|
||||
|
||||
recomp_page = block->phys & ~0xfff;
|
||||
@@ -386,6 +387,9 @@ void codegen_block_start_recompile(codeblock_t *block)
|
||||
codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0;
|
||||
|
||||
block->was_recompiled = 1;
|
||||
|
||||
codegen_flat_ds = cpu_cur_status & CPU_STATUS_FLATDS;
|
||||
codegen_flat_ss = cpu_cur_status & CPU_STATUS_FLATSS;
|
||||
}
|
||||
|
||||
void codegen_block_remove()
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
int codegen_flat_ds, codegen_flat_ss;
|
||||
int mmx_ebx_ecx_loaded;
|
||||
int codegen_flags_changed = 0;
|
||||
int codegen_fpu_entered = 0;
|
||||
@@ -1401,12 +1402,11 @@ void codegen_block_init(uint32_t phys_addr)
|
||||
block->_cs = cs;
|
||||
block->pnt = block_current;
|
||||
block->phys = phys_addr;
|
||||
block->use32 = use32;
|
||||
block->stack32 = stack32;
|
||||
block->next = block->prev = NULL;
|
||||
block->next_2 = block->prev_2 = NULL;
|
||||
block->page_mask = 0;
|
||||
block->flags = CODEBLOCK_STATIC_TOP;
|
||||
block->status = cpu_cur_status;
|
||||
|
||||
block->was_recompiled = 0;
|
||||
|
||||
@@ -1487,6 +1487,9 @@ void codegen_block_start_recompile(codeblock_t *block)
|
||||
|
||||
block->TOP = cpu_state.TOP;
|
||||
block->was_recompiled = 1;
|
||||
|
||||
codegen_flat_ds = cpu_cur_status & CPU_STATUS_FLATDS;
|
||||
codegen_flat_ss = cpu_cur_status & CPU_STATUS_FLATSS;
|
||||
}
|
||||
|
||||
void codegen_block_remove()
|
||||
|
||||
@@ -1,6 +1,23 @@
|
||||
/* Copyright holders: Sarah Walker, Tenshi, leilei
|
||||
see COPYING for more details
|
||||
*/
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* CPU type handler.
|
||||
*
|
||||
* Version: @(#)cpu.c 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* leilei,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 leilei.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
#include "../ibm.h"
|
||||
#include "cpu.h"
|
||||
#include "../model.h"
|
||||
@@ -74,7 +91,6 @@ int cpu_hasrdtsc;
|
||||
int cpu_hasMMX, cpu_hasMSR;
|
||||
int cpu_hasCR4;
|
||||
int cpu_use_dynarec;
|
||||
int cpu_pci_speed;
|
||||
|
||||
int hasfpu;
|
||||
|
||||
@@ -84,6 +100,7 @@ int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l;
|
||||
int cpu_prefetch_cycles, cpu_prefetch_width;
|
||||
int cpu_waitstates;
|
||||
int cpu_cache_int_enabled, cpu_cache_ext_enabled;
|
||||
int cpu_pci_speed;
|
||||
|
||||
int is286, is386;
|
||||
int israpidcad, is_pentium;
|
||||
@@ -408,7 +425,7 @@ CPU cpus_Cx486[] =
|
||||
{"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7},
|
||||
{"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9},
|
||||
{"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12},
|
||||
{"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -609,7 +626,6 @@ void cpu_set()
|
||||
if (cpu_s->multi)
|
||||
cpu_busspeed = cpu_s->rspeed / cpu_s->multi;
|
||||
cpu_multi = cpu_s->multi;
|
||||
cpu_pci_speed = cpu_s->pci_speed;
|
||||
cpu_hasrdtsc = 0;
|
||||
cpu_hasMMX = 0;
|
||||
cpu_hasMSR = 0;
|
||||
@@ -621,11 +637,6 @@ void cpu_set()
|
||||
if (enable_external_fpu)
|
||||
{
|
||||
hasfpu = 1;
|
||||
if (cpu_s->cpu_type == CPU_i486SX)
|
||||
{
|
||||
/* The 487SX is a full implementation of the 486DX and takes over the entire CPU's operation. */
|
||||
cpu_s->cpu_type = CPU_i486DX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,23 @@
|
||||
/* Copyright holders: Sarah Walker, Tenshi, leilei
|
||||
see COPYING for more details
|
||||
*/
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* CPU type handler.
|
||||
*
|
||||
* Version: @(#)cpu.h 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* leilei,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 leilei.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
#ifndef _CPU_H_
|
||||
#define _CPU_H_
|
||||
|
||||
@@ -117,7 +134,6 @@ extern int cpu_iscyrix;
|
||||
extern int cpu_16bitbus;
|
||||
extern int cpu_busspeed;
|
||||
extern int cpu_multi;
|
||||
extern int cpu_pci_speed;
|
||||
|
||||
extern int cpu_hasrdtsc;
|
||||
extern int cpu_hasMSR;
|
||||
@@ -139,6 +155,7 @@ extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_writ
|
||||
extern int cpu_prefetch_cycles, cpu_prefetch_width;
|
||||
extern int cpu_waitstates;
|
||||
extern int cpu_cache_int_enabled, cpu_cache_ext_enabled;
|
||||
extern int cpu_pci_speed;
|
||||
|
||||
extern uint64_t tsc;
|
||||
|
||||
|
||||
@@ -102,3 +102,6 @@ void x86gpf(char *s, uint16_t error);
|
||||
extern uint16_t zero;
|
||||
|
||||
extern int x86_was_reset;
|
||||
|
||||
extern int codegen_flat_ds;
|
||||
extern int codegen_flat_ss;
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Miscellaneous x86 CPU Instructions.
|
||||
*
|
||||
* Version: @(#)x86_ops_misc.h 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
static int opCBW(uint32_t fetchdat)
|
||||
{
|
||||
AH = (AL & 0x80) ? 0xff : 0;
|
||||
@@ -755,9 +773,17 @@ static int opLOADALL(uint32_t fetchdat)
|
||||
ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16);
|
||||
_ss.access = readmemb(0, 0x845);
|
||||
_ss.limit = readmemw(0, 0x846);
|
||||
if (_ss.base == 0 && _ss.limit_low == 0 && _ss.limit_high == 0xffffffff)
|
||||
cpu_cur_status |= CPU_STATUS_FLATSS;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_FLATSS;
|
||||
ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16);
|
||||
_ds.access = readmemb(0, 0x84B);
|
||||
_ds.limit = readmemw(0, 0x84C);
|
||||
if (_ds.base == 0 && _ds.limit_low == 0 && _ds.limit_high == 0xffffffff)
|
||||
cpu_cur_status |= CPU_STATUS_FLATDS;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_FLATDS;
|
||||
gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16);
|
||||
gdt.limit = readmemw(0, 0x852);
|
||||
ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16);
|
||||
@@ -797,8 +823,29 @@ static void loadall_load_segment(uint32_t addr, x86seg *s)
|
||||
|
||||
if (s == &_cs) use32 = (segdat3 & 0x40) ? 0x300 : 0;
|
||||
if (s == &_ss) stack32 = (segdat3 & 0x40) ? 1 : 0;
|
||||
cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32);
|
||||
if (use32)
|
||||
cpu_cur_status |= CPU_STATUS_USE32;
|
||||
if (stack32)
|
||||
cpu_cur_status |= CPU_STATUS_STACK32;
|
||||
|
||||
set_segment_limit(s, segdat3);
|
||||
|
||||
if (s == &_ds)
|
||||
{
|
||||
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
|
||||
|
||||
cpu_cur_status |= CPU_STATUS_FLATDS;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_FLATDS;
|
||||
}
|
||||
if (s == &_ss)
|
||||
{
|
||||
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
|
||||
cpu_cur_status |= CPU_STATUS_FLATSS;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_FLATSS;
|
||||
}
|
||||
}
|
||||
|
||||
static int opLOADALL386(uint32_t fetchdat)
|
||||
|
||||
127
src/CPU/x86seg.c
127
src/CPU/x86seg.c
@@ -1,6 +1,21 @@
|
||||
/* Copyright holders: Sarah Walker, SA1988
|
||||
see COPYING for more details
|
||||
*/
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* x86 CPU segment emulation.
|
||||
*
|
||||
* Version: @(#)x86seg.c 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
@@ -159,6 +174,29 @@ void x86np(char *s, uint16_t error)
|
||||
}
|
||||
|
||||
|
||||
static void set_stack32(int s)
|
||||
{
|
||||
stack32 = s;
|
||||
if (stack32)
|
||||
cpu_cur_status |= CPU_STATUS_STACK32;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_STACK32;
|
||||
}
|
||||
|
||||
static void set_use32(int u)
|
||||
{
|
||||
if (u)
|
||||
{
|
||||
use32 = 0x300;
|
||||
cpu_cur_status |= CPU_STATUS_USE32;
|
||||
}
|
||||
else
|
||||
{
|
||||
use32 = 0;
|
||||
cpu_cur_status &= ~CPU_STATUS_USE32;
|
||||
}
|
||||
}
|
||||
|
||||
void do_seg_load(x86seg *s, uint16_t *segdat)
|
||||
{
|
||||
s->limit = segdat[0] | ((segdat[3] & 0xF) << 16);
|
||||
@@ -179,6 +217,21 @@ void do_seg_load(x86seg *s, uint16_t *segdat)
|
||||
s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff;
|
||||
s->limit_low = s->limit + 1;
|
||||
}
|
||||
|
||||
if (s == &_ds)
|
||||
{
|
||||
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
|
||||
cpu_cur_status |= CPU_STATUS_FLATDS;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_FLATDS;
|
||||
}
|
||||
if (s == &_ss)
|
||||
{
|
||||
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
|
||||
cpu_cur_status |= CPU_STATUS_FLATSS;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_FLATSS;
|
||||
}
|
||||
}
|
||||
|
||||
static void do_seg_v86_init(x86seg *s)
|
||||
@@ -251,6 +304,8 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
s->seg=0;
|
||||
s->access = 0x80;
|
||||
s->base=-1;
|
||||
if (s == &_ds)
|
||||
cpu_cur_status &= ~CPU_STATUS_FLATDS;
|
||||
return;
|
||||
}
|
||||
addr=seg&~7;
|
||||
@@ -303,7 +358,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
x86ss(NULL,seg&~3);
|
||||
return;
|
||||
}
|
||||
stack32 = (segdat[3] & 0x40) ? 1 : 0;
|
||||
set_stack32((segdat[3] & 0x40) ? 1 : 0);
|
||||
}
|
||||
else if (s!=&_cs)
|
||||
{
|
||||
@@ -349,6 +404,10 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
}
|
||||
#endif
|
||||
s->checked = 0;
|
||||
if (s == &_ds)
|
||||
codegen_flat_ds = 0;
|
||||
if (s == &_ss)
|
||||
codegen_flat_ss = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -358,6 +417,26 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
if (s == &_ss)
|
||||
stack32 = 0;
|
||||
s->checked = 1;
|
||||
if (s == &_ds)
|
||||
codegen_flat_ds = 0;
|
||||
if (s == &_ss)
|
||||
codegen_flat_ss = 0;
|
||||
}
|
||||
|
||||
if (s == &_ds)
|
||||
{
|
||||
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
|
||||
cpu_cur_status |= CPU_STATUS_FLATDS;
|
||||
else
|
||||
|
||||
cpu_cur_status &= ~CPU_STATUS_FLATDS;
|
||||
}
|
||||
if (s == &_ss)
|
||||
{
|
||||
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
|
||||
cpu_cur_status |= CPU_STATUS_FLATSS;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_FLATSS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,8 +505,7 @@ void loadcs(uint16_t seg)
|
||||
x86np("Load CS not present", seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if (segdat[3]&0x40) use32=0x300;
|
||||
else use32=0;
|
||||
set_use32(segdat[3] & 0x40);
|
||||
CS=(seg&~3)|CPL;
|
||||
do_seg_load(&_cs, segdat);
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
@@ -530,8 +608,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
||||
x86np("Load CS JMP not present\n", seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if (segdat[3]&0x40) use32=0x300;
|
||||
else use32=0;
|
||||
set_use32(segdat[3]&0x40);
|
||||
|
||||
#ifdef CS_ACCESSED
|
||||
cpl_override = 1;
|
||||
@@ -544,7 +621,6 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
||||
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
cycles -= timing_jmp_pm;
|
||||
}
|
||||
else /*System segment*/
|
||||
@@ -642,7 +718,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
||||
CS=seg2;
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
set_use32(segdat[3]&0x40);
|
||||
cpu_state.pc=newpc;
|
||||
|
||||
#ifdef CS_ACCESSED
|
||||
@@ -828,8 +904,7 @@ void loadcscall(uint16_t seg)
|
||||
x86np("Load CS call not present", seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if (segdat[3]&0x40) use32=0x300;
|
||||
else use32=0;
|
||||
set_use32(segdat[3]&0x40);
|
||||
|
||||
#ifdef CS_ACCESSED
|
||||
cpl_override = 1;
|
||||
@@ -848,7 +923,6 @@ void loadcscall(uint16_t seg)
|
||||
CS=seg;
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
if (csout) pclog("Complete\n");
|
||||
cycles -= timing_call_pm;
|
||||
}
|
||||
@@ -1005,7 +1079,7 @@ void loadcscall(uint16_t seg)
|
||||
}
|
||||
if (!stack32) oldsp &= 0xFFFF;
|
||||
SS=newss;
|
||||
stack32 = (segdat2[3] & 0x40) ? 1 : 0;
|
||||
set_stack32((segdat2[3] & 0x40) ? 1 : 0);
|
||||
if (stack32) ESP=newsp;
|
||||
else SP=newsp;
|
||||
|
||||
@@ -1022,7 +1096,7 @@ void loadcscall(uint16_t seg)
|
||||
CS=seg2;
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
set_use32(segdat[3]&0x40);
|
||||
cpu_state.pc=newpc;
|
||||
|
||||
if (output) pclog("Set access 2\n");
|
||||
@@ -1101,7 +1175,7 @@ void loadcscall(uint16_t seg)
|
||||
CS=seg2;
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
set_use32(segdat[3]&0x40);
|
||||
cpu_state.pc=newpc;
|
||||
|
||||
#ifdef CS_ACCESSED
|
||||
@@ -1245,7 +1319,7 @@ void pmoderetf(int is32, uint16_t off)
|
||||
do_seg_load(&_cs, segdat);
|
||||
_cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
set_use32(segdat[3] & 0x40);
|
||||
|
||||
cycles -= timing_retf_pm;
|
||||
}
|
||||
@@ -1353,7 +1427,7 @@ void pmoderetf(int is32, uint16_t off)
|
||||
return;
|
||||
}
|
||||
SS=newss;
|
||||
stack32 = (segdat2[3] & 0x40) ? 1 : 0;
|
||||
set_stack32((segdat2[3] & 0x40) ? 1 : 0);
|
||||
if (stack32) ESP=newsp;
|
||||
else SP=newsp;
|
||||
do_seg_load(&_ss, segdat2);
|
||||
@@ -1375,7 +1449,7 @@ void pmoderetf(int is32, uint16_t off)
|
||||
CS=seg;
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
set_use32(segdat[3] & 0x40);
|
||||
|
||||
if (stack32) ESP+=off;
|
||||
else SP+=off;
|
||||
@@ -1570,7 +1644,7 @@ void pmodeint(int num, int soft)
|
||||
return;
|
||||
}
|
||||
SS=newss;
|
||||
stack32 = (segdat3[3] & 0x40) ? 1 : 0;
|
||||
set_stack32((segdat3[3] & 0x40) ? 1 : 0);
|
||||
if (stack32) ESP=newsp;
|
||||
else SP=newsp;
|
||||
do_seg_load(&_ss, segdat3);
|
||||
@@ -1655,7 +1729,7 @@ void pmodeint(int num, int soft)
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
if (type>0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16);
|
||||
else cpu_state.pc=segdat[0];
|
||||
use32=(segdat2[3]&0x40)?0x300:0;
|
||||
set_use32(segdat2[3]&0x40);
|
||||
|
||||
#ifdef CS_ACCESSED
|
||||
cpl_override = 1;
|
||||
@@ -1809,6 +1883,7 @@ void pmodeiret(int is32)
|
||||
do_seg_v86_init(&_es);
|
||||
loadseg(segs[1],&_ds);
|
||||
do_seg_v86_init(&_ds);
|
||||
cpu_cur_status &= ~CPU_STATUS_FLATDS;
|
||||
loadseg(segs[2],&_fs);
|
||||
do_seg_v86_init(&_fs);
|
||||
loadseg(segs[3],&_gs);
|
||||
@@ -1826,7 +1901,9 @@ void pmodeiret(int is32)
|
||||
ESP=newsp;
|
||||
loadseg(newss,&_ss);
|
||||
do_seg_v86_init(&_ss);
|
||||
cpu_cur_status &= ~CPU_STATUS_FLATSS;
|
||||
use32=0;
|
||||
cpu_cur_status &= ~CPU_STATUS_USE32;
|
||||
flags=(tempflags&0xFFD5)|2;
|
||||
cycles -= timing_iret_v86;
|
||||
return;
|
||||
@@ -1913,7 +1990,7 @@ void pmodeiret(int is32)
|
||||
do_seg_load(&_cs, segdat);
|
||||
_cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
set_use32(segdat[3]&0x40);
|
||||
|
||||
#ifdef CS_ACCESSED
|
||||
cpl_override = 1;
|
||||
@@ -1996,7 +2073,7 @@ void pmodeiret(int is32)
|
||||
return;
|
||||
}
|
||||
SS=newss;
|
||||
stack32 = (segdat2[3] & 0x40) ? 1 : 0;
|
||||
set_stack32((segdat2[3] & 0x40) ? 1 : 0);
|
||||
if (stack32) ESP=newsp;
|
||||
else SP=newsp;
|
||||
do_seg_load(&_ss, segdat2);
|
||||
@@ -2018,7 +2095,7 @@ void pmodeiret(int is32)
|
||||
do_seg_load(&_cs, segdat);
|
||||
_cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
set_use32(segdat[3] & 0x40);
|
||||
|
||||
check_seg_valid(&_ds);
|
||||
check_seg_valid(&_es);
|
||||
@@ -2208,7 +2285,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
CS=new_cs;
|
||||
do_seg_load(&_cs, segdat2);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat2[3]&0x40)?0x300:0;
|
||||
set_use32(segdat2[3] & 0x40);
|
||||
|
||||
EAX=new_eax;
|
||||
ECX=new_ecx;
|
||||
|
||||
@@ -1,4 +1,17 @@
|
||||
/* Copyright holders: Tenshi
|
||||
see COPYING for more details
|
||||
*/
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* x86 CPU segment emulation.
|
||||
*
|
||||
* Version: @(#)x86seg.h 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
void do_seg_load(x86seg *s, uint16_t *segdat);
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* x87 FPU instructions core.
|
||||
*
|
||||
* Version: @(#)x87_ops.h 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* leilei,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 leilei.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <fenv.h>
|
||||
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* x87 FPU instructions core.
|
||||
*
|
||||
* Version: @(#)x87_ops_loadstore.h 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
static int opFILDiw_a16(uint32_t fetchdat)
|
||||
{
|
||||
int16_t temp;
|
||||
|
||||
@@ -265,7 +265,14 @@ uint8_t sb_pro_mixer_read(uint16_t addr, void *p)
|
||||
if (!(addr & 1))
|
||||
return mixer->index;
|
||||
|
||||
switch (mixer->index)
|
||||
{
|
||||
case 0x00: case 0x04: case 0x0a: case 0x0c: case 0x0e:
|
||||
case 0x22: case 0x26: case 0x28: case 0x2e:
|
||||
return mixer->regs[mixer->index];
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void sb_16_mixer_write(uint16_t addr, uint8_t val, void *p)
|
||||
|
||||
@@ -514,6 +514,10 @@ void sb_exec_command(sb_dsp_t *dsp)
|
||||
if (dsp->sb_type < SB16) break;
|
||||
sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]);
|
||||
break;
|
||||
case 0xF8:
|
||||
if (dsp->sb_type < SB16) break;
|
||||
sb_add_data(dsp, 0);
|
||||
break;
|
||||
case 0xF9:
|
||||
if (dsp->sb_type < SB16) break;
|
||||
if (dsp->sb_data[0] == 0x0e) sb_add_data(dsp, 0xff);
|
||||
|
||||
@@ -137,6 +137,12 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
|
||||
return; /*Nothing to do*/
|
||||
}
|
||||
|
||||
if (h <= 0)
|
||||
{
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&ddsd, 0, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the Intel 430VX PCISet chip.
|
||||
*
|
||||
* Version: @(#)i430vx.c 1.0.0 2017/05/30
|
||||
* Version: @(#)i430vx.c 1.0.1 2017/06/02
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -84,7 +84,7 @@ void i430vx_write(int func, int addr, uint8_t val, void *priv)
|
||||
i430vx_map(0xf0000, 0x10000, val >> 4);
|
||||
shadowbios = (val & 0x10);
|
||||
}
|
||||
pclog("i430vx_write : PAM0 write %02X\n", val);
|
||||
/* pclog("i430vx_write : PAM0 write %02X\n", val); */
|
||||
break;
|
||||
case 0x5a: /*PAM1*/
|
||||
if ((card_i430vx[0x5a] ^ val) & 0x0f)
|
||||
@@ -115,14 +115,14 @@ void i430vx_write(int func, int addr, uint8_t val, void *priv)
|
||||
i430vx_map(0xe0000, 0x04000, val & 0xf);
|
||||
if ((card_i430vx[0x5e] ^ val) & 0xf0)
|
||||
i430vx_map(0xe4000, 0x04000, val >> 4);
|
||||
pclog("i430vx_write : PAM5 write %02X\n", val);
|
||||
/* pclog("i430vx_write : PAM5 write %02X\n", val); */
|
||||
break;
|
||||
case 0x5f: /*PAM6*/
|
||||
if ((card_i430vx[0x5f] ^ val) & 0x0f)
|
||||
i430vx_map(0xe8000, 0x04000, val & 0xf);
|
||||
if ((card_i430vx[0x5f] ^ val) & 0xf0)
|
||||
i430vx_map(0xec000, 0x04000, val >> 4);
|
||||
pclog("i430vx_write : PAM6 write %02X\n", val);
|
||||
/* pclog("i430vx_write : PAM6 write %02X\n", val); */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -177,6 +177,13 @@ struct
|
||||
|
||||
#define cycles cpu_state._cycles
|
||||
|
||||
extern uint32_t cpu_cur_status;
|
||||
|
||||
#define CPU_STATUS_USE32 (1 << 0)
|
||||
#define CPU_STATUS_STACK32 (1 << 1)
|
||||
#define CPU_STATUS_FLATDS (1 << 2)
|
||||
#define CPU_STATUS_FLATSS (1 << 3)
|
||||
|
||||
#define cpu_rm cpu_state.rm_data.rm_mod_reg.rm
|
||||
#define cpu_mod cpu_state.rm_data.rm_mod_reg.mod
|
||||
#define cpu_reg cpu_state.rm_data.rm_mod_reg.reg
|
||||
|
||||
43
src/pci.c
43
src/pci.c
@@ -61,6 +61,20 @@ uint8_t pci_read(uint16_t port, void *priv)
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
uint8_t elcr[2] = { 0, 0 };
|
||||
|
||||
void elcr_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
pclog("ELCR%i: WRITE %02X\n", port & 1, val);
|
||||
elcr[port & 1] = val;
|
||||
}
|
||||
|
||||
uint8_t elcr_read(uint16_t port, void *priv)
|
||||
{
|
||||
pclog("ELCR%i: READ %02X\n", port & 1, elcr[port & 1]);
|
||||
return elcr[port & 1];
|
||||
}
|
||||
|
||||
void pci_type2_write(uint16_t port, uint8_t val, void *priv);
|
||||
uint8_t pci_type2_read(uint16_t port, void *priv);
|
||||
|
||||
@@ -120,13 +134,38 @@ void pci_set_card_routing(int card, int pci_int)
|
||||
pci_irq_routing[card] = pci_int;
|
||||
}
|
||||
|
||||
void pci_issue_irq(int irq)
|
||||
{
|
||||
int real_irq = irq & 7;
|
||||
int irq_elcr = 0;
|
||||
|
||||
if (irq > 7)
|
||||
{
|
||||
irq_elcr = elcr[1] & (1 << real_irq);
|
||||
}
|
||||
else
|
||||
{
|
||||
irq_elcr = elcr[0] & (1 << real_irq);
|
||||
}
|
||||
|
||||
if (irq_elcr)
|
||||
{
|
||||
picintlevel(1 << irq);
|
||||
}
|
||||
else
|
||||
{
|
||||
picint(1 << irq);
|
||||
}
|
||||
}
|
||||
|
||||
void pci_set_irq(int card, int pci_int)
|
||||
{
|
||||
if (pci_irq_routing[card])
|
||||
{
|
||||
int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3;
|
||||
if (pci_irqs[irq] != PCI_IRQ_DISABLED && !pci_irq_active[card])
|
||||
picint(1 << pci_irqs[irq]);
|
||||
pci_issue_irq(pci_irqs[irq]);
|
||||
/* picint(1 << pci_irqs[irq]); */
|
||||
pci_irq_active[card] = 1;
|
||||
}
|
||||
}
|
||||
@@ -148,6 +187,8 @@ void pci_init(int type)
|
||||
|
||||
PCI = 1;
|
||||
|
||||
io_sethandler(0x04d0, 0x0002, elcr_read, NULL, NULL, elcr_write, NULL, NULL, NULL);
|
||||
|
||||
if (type == PCI_CONFIG_TYPE_1)
|
||||
{
|
||||
io_sethandler(0x0cf8, 0x0001, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL);
|
||||
|
||||
@@ -107,7 +107,8 @@ void piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addr >= 0x0f && addr < 0x4c)
|
||||
/* pclog("PIIX writing value %02X to register %02X\n", val, addr); */
|
||||
if ((addr >= 0x0f) && (addr < 0x4c))
|
||||
return;
|
||||
|
||||
switch (addr)
|
||||
@@ -118,24 +119,28 @@ void piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
return;
|
||||
|
||||
case 0x60:
|
||||
pclog("Set IRQ routing: INT A -> %02X\n", val);
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA, val & 0xf);
|
||||
break;
|
||||
case 0x61:
|
||||
pclog("Set IRQ routing: INT B -> %02X\n", val);
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTB, val & 0xf);
|
||||
break;
|
||||
case 0x62:
|
||||
pclog("Set IRQ routing: INT C -> %02X\n", val);
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTC, val & 0xf);
|
||||
break;
|
||||
case 0x63:
|
||||
pclog("Set IRQ routing: INT D -> %02X\n", val);
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
|
||||
else
|
||||
@@ -632,7 +637,6 @@ void piix_reset(void)
|
||||
card_piix_ide[0x0d] = 0x00;
|
||||
card_piix_ide[0x0e] = 0x00;
|
||||
card_piix_ide[0x20] = 0x01; card_piix_ide[0x21] = card_piix_ide[0x22] = card_piix_ide[0x23] = 0x00; /*Bus master interface base address*/
|
||||
card_piix_ide[0x3c] = 14; /* Default IRQ */
|
||||
card_piix_ide[0x40] = card_piix_ide[0x41] = 0x00;
|
||||
card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00;
|
||||
}
|
||||
@@ -672,7 +676,6 @@ void piix3_reset(void)
|
||||
card_piix_ide[0x0d] = 0x00;
|
||||
card_piix_ide[0x0e] = 0x00;
|
||||
card_piix_ide[0x20] = 0x01; card_piix_ide[0x21] = card_piix_ide[0x22] = card_piix_ide[0x23] = 0x00; /*Bus master interface base address*/
|
||||
card_piix_ide[0x3c] = 14; /* Default IRQ */
|
||||
card_piix_ide[0x40] = card_piix_ide[0x41] = 0x00;
|
||||
card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00;
|
||||
card_piix_ide[0x44] = 0x00;
|
||||
|
||||
@@ -528,7 +528,7 @@ BuslogicLog(const char *format, ...)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* #define pclog BuslogicLog */
|
||||
#define pclog BuslogicLog
|
||||
|
||||
|
||||
static void
|
||||
|
||||
Reference in New Issue
Block a user