diff --git a/src/CPU/386.c b/src/CPU/386.c
index 0422036b4..074fa9696 100644
--- a/src/CPU/386.c
+++ b/src/CPU/386.c
@@ -51,7 +51,6 @@ uint32_t cr2, cr3, cr4;
uint32_t dr[8];
-
uint8_t romext[32768];
uint8_t *ram,*rom;
diff --git a/src/CPU/386_common.h b/src/CPU/386_common.h
index a091a817d..6042cc151 100644
--- a/src/CPU/386_common.h
+++ b/src/CPU/386_common.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.
+ *
+ * Common 386 CPU code.
+ *
+ * Version: @(#)386_common.h 1.0.0 2017/05/30
+ *
+ * Author: Sarah Walker,
+ * Miran Grca,
+ * Copyright 2008-2017 Sarah Walker.
+ * Copyright 2016-2017 Miran Grca.
+ */
+
extern uint16_t ea_rseg;
#undef readmemb
diff --git a/src/CPU/386_dynarec.c b/src/CPU/386_dynarec.c
index 1463f844e..61db68737 100644
--- a/src/CPU/386_dynarec.c
+++ b/src/CPU/386_dynarec.c
@@ -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;
@@ -1325,8 +1327,42 @@ void exec386_dynarec(int cycs)
while (cycles_main > 0)
{
int cycles_start;
-
- cycles += cpu_cycle_period();
+
+#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;
}
diff --git a/src/CPU/386_ops.h b/src/CPU/386_ops.h
index 4e5d78125..0217c384d 100644
--- a/src/CPU/386_ops.h
+++ b/src/CPU/386_ops.h
@@ -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,
+ * leilei,
+ * Miran Grca,
+ * Copyright 2008-2017 Sarah Walker.
+ * Copyright 2016-2017 leilei.
+ * Copyright 2016-2017 Miran Grca.
+ */
+
#include "x86_ops.h"
diff --git a/src/CPU/808x.c b/src/CPU/808x.c
index 5c48a4bb0..32a52e955 100644
--- a/src/CPU/808x.c
+++ b/src/CPU/808x.c
@@ -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,
+ * Miran Grca,
+ * 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;
diff --git a/src/CPU/codegen.h b/src/CPU/codegen.h
index ad0b3f63a..5a076db8f 100644
--- a/src/CPU/codegen.h
+++ b/src/CPU/codegen.h
@@ -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,22 +48,19 @@ 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;
diff --git a/src/CPU/codegen_ops_x86-64.h b/src/CPU/codegen_ops_x86-64.h
index 8573ab495..f08db0b31 100644
--- a/src/CPU/codegen_ops_x86-64.h
+++ b/src/CPU/codegen_ops_x86-64.h
@@ -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);
- addbyte(0x83); /*CMP ESI, -1*/
- addbyte(0xfe);
- addbyte(-1);
- addbyte(0x74); /*JE slowpath*/
- jump3 = &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(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,7 +5383,8 @@ static void MEM_CHECK_WRITE(x86seg *seg)
addbyte(0);
// addbyte(0xc3); /*RET*/
- *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1;
+ 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]*/
addbyte(0x8d);
@@ -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);
- addbyte(0x83); /*CMP ESI, -1*/
- addbyte(0xfe);
- addbyte(-1);
+ 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);
- addbyte(0x74); /*JE slowpath*/
- jump4 = &codeblock[block_current].data[block_pos];
- addbyte(0);
+ 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,7 +5542,8 @@ static void MEM_CHECK_WRITE_W(x86seg *seg)
/*slowpath:*/
*jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1;
- *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 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);
load_param_2_32(&codeblock[block_current], 1);
@@ -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);
- addbyte(0x83); /*CMP ESI, -1*/
- addbyte(0xfe);
- addbyte(-1);
+ 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);
- addbyte(0x74); /*JE slowpath*/
- jump4 = &codeblock[block_current].data[block_pos];
- addbyte(0);
+ 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,7 +5691,8 @@ static void MEM_CHECK_WRITE_L(x86seg *seg)
/*slowpath:*/
*jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1;
- *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 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);
load_param_2_32(&codeblock[block_current], 1);
@@ -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);
diff --git a/src/CPU/codegen_ops_x86.h b/src/CPU/codegen_ops_x86.h
index c8c18a28c..5251884b7 100644
--- a/src/CPU/codegen_ops_x86.h
+++ b/src/CPU/codegen_ops_x86.h
@@ -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)
{
- addbyte(0x8b); /*MOVL EDX, seg->base*/
- addbyte(0x05 | (REG_EDX << 3));
- addlong((uint32_t)&seg->base);
+ 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)
{
- addbyte(0x8b); /*MOVL EDX, seg->base*/
- addbyte(0x05 | (REG_EDX << 3));
- addlong((uint32_t)&seg->base);
+ 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)
{
- addbyte(0x8b); /*MOVL EDX, seg->base*/
- addbyte(0x05 | (REG_EDX << 3));
- addlong((uint32_t)&seg->base);
+ 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)
{
- addbyte(0x8b); /*MOVL EDX, seg->base*/
- addbyte(0x05 | (REG_EDX << 3));
- addlong((uint32_t)&seg->base);
+ 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)
{
- addbyte(0x8b); /*MOVL EDX, seg->base*/
- addbyte(0x05 | (REG_EDX << 3));
- addlong((uint32_t)&seg->base);
+ 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)
{
- addbyte(0x8b); /*MOVL EDX, seg->base*/
- addbyte(0x05 | (REG_EDX << 3));
- addlong((uint32_t)&seg->base);
+ 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)
{
- addbyte(0x8b); /*MOVL EDX, seg->base*/
- addbyte(0x05 | (REG_EDX << 3));
- addlong((uint32_t)&seg->base);
+ 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)
{
- addbyte(0x8b); /*MOVL EDX, seg->base*/
- addbyte(0x05 | (REG_EDX << 3));
- addlong((uint32_t)&seg->base);
+ 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)
{
- addbyte(0x8b); /*MOVL ESI, seg->base*/
- addbyte(0x05 | (REG_ESI << 3));
- addlong((uint32_t)&seg->base);
+ 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)
{
- addbyte(0x8b); /*MOVL ESI, seg->base*/
- addbyte(0x05 | (REG_ESI << 3));
- addlong((uint32_t)&seg->base);
+ 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)
{
- addbyte(0x8b); /*MOVL ESI, seg->base*/
- addbyte(0x05 | (REG_ESI << 3));
- addlong((uint32_t)&seg->base);
+ 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)
{
- addbyte(0x8b); /*MOVL ESI, seg->base*/
- addbyte(0x05 | (REG_ESI << 3));
- addlong((uint32_t)&seg->base);
+ 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)
{
- addbyte(0x8b); /*MOVL ESI, seg->base*/
- addbyte(0x05 | (REG_ESI << 3));
- addlong((uint32_t)&seg->base);
+ 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)
{
- addbyte(0x8b); /*MOVL ESI, seg->base*/
- addbyte(0x05 | (REG_ESI << 3));
- addlong((uint32_t)&seg->base);
+ 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));
}
- addbyte(0x8b); /*MOVL ESI, seg->base*/
- addbyte(0x05 | (REG_ESI << 3));
- addlong((uint32_t)&seg->base);
+ 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);
- addbyte(0x8b); /*MOVL ESI, seg->base*/
- addbyte(0x05 | (REG_ESI << 3));
- addlong((uint32_t)&seg->base);
+ 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);
- addbyte(0x8b); /*MOVL ESI, seg->base*/
- addbyte(0x05 | (REG_ESI << 3));
- addlong((uint32_t)&seg->base);
+ 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);
- addbyte(0x8b); /*MOVL ESI, seg->base*/
- addbyte(0x05 | (REG_ESI << 3));
- addlong((uint32_t)&seg->base);
+ 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();
diff --git a/src/CPU/codegen_x86-64.c b/src/CPU/codegen_x86-64.c
index e591adc95..c5214bd4b 100644
--- a/src/CPU/codegen_x86-64.c
+++ b/src/CPU/codegen_x86-64.c
@@ -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()
diff --git a/src/CPU/codegen_x86.c b/src/CPU/codegen_x86.c
index a42b32104..82b8e5575 100644
--- a/src/CPU/codegen_x86.c
+++ b/src/CPU/codegen_x86.c
@@ -22,6 +22,7 @@
#include
#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()
diff --git a/src/CPU/cpu.c b/src/CPU/cpu.c
index a55e7e86e..cbb7161fb 100644
--- a/src/CPU/cpu.c
+++ b/src/CPU/cpu.c
@@ -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,
+ * leilei,
+ * Miran Grca,
+ * 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;
- }
}
}
diff --git a/src/CPU/cpu.h b/src/CPU/cpu.h
index d8d24b27a..ce0955b7f 100644
--- a/src/CPU/cpu.h
+++ b/src/CPU/cpu.h
@@ -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,
+ * leilei,
+ * Miran Grca,
+ * 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;
diff --git a/src/CPU/x86.h b/src/CPU/x86.h
index 565d52591..deb210cb6 100644
--- a/src/CPU/x86.h
+++ b/src/CPU/x86.h
@@ -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;
diff --git a/src/CPU/x86_ops_misc.h b/src/CPU/x86_ops_misc.h
index a2b4f6f31..7734217eb 100644
--- a/src/CPU/x86_ops_misc.h
+++ b/src/CPU/x86_ops_misc.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.
+ *
+ * Miscellaneous x86 CPU Instructions.
+ *
+ * Version: @(#)x86_ops_misc.h 1.0.0 2017/05/30
+ *
+ * Author: Sarah Walker,
+ * Miran Grca,
+ * 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)
diff --git a/src/CPU/x86seg.c b/src/CPU/x86seg.c
index cc0cc6dbc..c200b3121 100644
--- a/src/CPU/x86seg.c
+++ b/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,
+ * Miran Grca,
+ * Copyright 2008-2017 Sarah Walker.
+ * Copyright 2016-2017 Miran Grca.
+ */
+
#include
#include
#include
@@ -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,8 +718,8 @@ 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;
- cpu_state.pc=newpc;
+ set_use32(segdat[3]&0x40);
+ cpu_state.pc=newpc;
#ifdef CS_ACCESSED
cpl_override = 1;
@@ -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,8 +1175,8 @@ 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;
- cpu_state.pc=newpc;
+ set_use32(segdat[3]&0x40);
+ cpu_state.pc=newpc;
#ifdef CS_ACCESSED
cpl_override = 1;
@@ -1245,8 +1319,8 @@ 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;
}
else
@@ -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;
diff --git a/src/CPU/x86seg.h b/src/CPU/x86seg.h
index 4a36f360b..f4badadf4 100644
--- a/src/CPU/x86seg.h
+++ b/src/CPU/x86seg.h
@@ -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,
+ * Copyright 2016-2017 Miran Grca.
+ */
+
void do_seg_load(x86seg *s, uint16_t *segdat);
diff --git a/src/CPU/x87_ops.h b/src/CPU/x87_ops.h
index e212c6ccb..b9320081f 100644
--- a/src/CPU/x87_ops.h
+++ b/src/CPU/x87_ops.h
@@ -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,
+ * leilei,
+ * Miran Grca,
+ * Copyright 2008-2017 Sarah Walker.
+ * Copyright 2016-2017 leilei.
+ * Copyright 2016-2017 Miran Grca.
+ */
+
#include
#include
diff --git a/src/CPU/x87_ops_loadstore.h b/src/CPU/x87_ops_loadstore.h
index ed083b921..39a14c4fb 100644
--- a/src/CPU/x87_ops_loadstore.h
+++ b/src/CPU/x87_ops_loadstore.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,
+ * Miran Grca,
+ * Copyright 2008-2017 Sarah Walker.
+ * Copyright 2016-2017 Miran Grca.
+ */
+
static int opFILDiw_a16(uint32_t fetchdat)
{
int16_t temp;
diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c
index 25963e1a1..8f310d9af 100644
--- a/src/SOUND/snd_sb.c
+++ b/src/SOUND/snd_sb.c
@@ -265,7 +265,14 @@ uint8_t sb_pro_mixer_read(uint16_t addr, void *p)
if (!(addr & 1))
return mixer->index;
- return mixer->regs[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)
diff --git a/src/SOUND/snd_sb_dsp.c b/src/SOUND/snd_sb_dsp.c
index 8c6f4a036..ba4e556f0 100644
--- a/src/SOUND/snd_sb_dsp.c
+++ b/src/SOUND/snd_sb_dsp.c
@@ -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);
diff --git a/src/WIN/win_ddraw.cc b/src/WIN/win_ddraw.cc
index c5c111734..dc111bab1 100644
--- a/src/WIN/win_ddraw.cc
+++ b/src/WIN/win_ddraw.cc
@@ -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);
diff --git a/src/i430vx.c b/src/i430vx.c
index bbe88865c..be47835fa 100644
--- a/src/i430vx.c
+++ b/src/i430vx.c
@@ -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,
* Miran Grca,
@@ -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;
}
diff --git a/src/ibm.h b/src/ibm.h
index 99e02db34..e2f9c8de5 100644
--- a/src/ibm.h
+++ b/src/ibm.h
@@ -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
diff --git a/src/pci.c b/src/pci.c
index 022286669..f56c3de85 100644
--- a/src/pci.c
+++ b/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;
}
}
@@ -147,6 +186,8 @@ void pci_init(int type)
int c;
PCI = 1;
+
+ io_sethandler(0x04d0, 0x0002, elcr_read, NULL, NULL, elcr_write, NULL, NULL, NULL);
if (type == PCI_CONFIG_TYPE_1)
{
diff --git a/src/piix.c b/src/piix.c
index f2a38bf46..584f1ccc3 100644
--- a/src/piix.c
+++ b/src/piix.c
@@ -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;
diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c
index 207e8ea79..610bc39e4 100644
--- a/src/scsi_buslogic.c
+++ b/src/scsi_buslogic.c
@@ -528,7 +528,7 @@ BuslogicLog(const char *format, ...)
}
#endif
}
-/* #define pclog BuslogicLog */
+#define pclog BuslogicLog
static void