Slight optimisation when DS/SS are 'flat' (base=0, limit=4G).

This commit is contained in:
SarahW 2017-05-24 21:50:37 +01:00
commit 083ca3d4a2
10 changed files with 564 additions and 139 deletions

View file

@ -17,6 +17,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;
@ -1433,7 +1435,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);
@ -1445,7 +1447,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;
}

View file

@ -623,6 +623,7 @@ void resetx86()
resets++;
ins = 0;
use32=0;
cpu_cur_status = 0;
stack32=0;
// i86_Reset();
// cs=0xFFFF0;
@ -662,6 +663,7 @@ void softresetx86()
// exit(-1);
use32=0;
stack32=0;
cpu_cur_status = 0;
// i86_Reset();
// cs=0xFFFF0;
cpu_state.pc=0;

View file

@ -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;

View file

@ -869,6 +869,10 @@ static inline void CHECK_SEG_READ(x86seg *seg)
return;
if (seg->checked)
return;
if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS))
return;
if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))
return;
if (IS_32_ADDR(&seg->base))
{
@ -903,6 +907,10 @@ static inline void CHECK_SEG_WRITE(x86seg *seg)
return;
if (seg->checked)
return;
if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS))
return;
if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))
return;
if (IS_32_ADDR(&seg->base))
{
@ -929,6 +937,11 @@ static inline void CHECK_SEG_WRITE(x86seg *seg)
}
static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
{
if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS))
return;
if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))
return;
if (IS_32_ADDR(&seg->base))
{
addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/
@ -965,7 +978,13 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg)
{
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 ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -1033,7 +1052,13 @@ static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg)
}
static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg)
{
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 ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -1117,7 +1142,13 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
}
static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
{
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 ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -1193,7 +1224,13 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
}
static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg)
{
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 ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -1312,7 +1349,13 @@ static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -1391,7 +1434,13 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
}
static inline void MEM_STORE_ADDR_EA_W(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 ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -1481,7 +1530,13 @@ static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
}
static inline void MEM_STORE_ADDR_EA_L(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 ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -1569,7 +1624,13 @@ static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
}
static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2)
{
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 ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -5253,11 +5314,17 @@ static inline void LOAD_EA()
static inline void MEM_CHECK_WRITE(x86seg *seg)
{
uint8_t *jump1, *jump2, *jump3;
uint8_t *jump1, *jump2, *jump3 = NULL;
CHECK_SEG_WRITE(seg);
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 ESI, ESI*/
addbyte(0xf6);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOV ESI, seg->base*/
addbyte(0x34);
@ -5304,12 +5371,16 @@ static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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*/
@ -5333,7 +5404,9 @@ static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
*jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1;
/*slowpath:*/
addbyte(0x67); /*LEA EDI, [EAX+ESI]*/
addbyte(0x8d);
@ -5373,12 +5446,18 @@ static inline void MEM_CHECK_WRITE(x86seg *seg)
static inline void MEM_CHECK_WRITE_W(x86seg *seg)
{
uint8_t *jump1, *jump2, *jump3, *jump4;
uint8_t *jump1, *jump2, *jump3, *jump4 = NULL;
int jump_pos;
CHECK_SEG_WRITE(seg);
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 ESI, ESI*/
addbyte(0xf6);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOV ESI, seg->base*/
addbyte(0x34);
@ -5421,15 +5500,23 @@ static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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*/
@ -5480,7 +5567,9 @@ static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
*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,12 +5599,18 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
static inline void MEM_CHECK_WRITE_L(x86seg *seg)
{
uint8_t *jump1, *jump2, *jump3, *jump4;
uint8_t *jump1, *jump2, *jump3, *jump4 = NULL;
int jump_pos;
CHECK_SEG_WRITE(seg);
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 ESI, ESI*/
addbyte(0xf6);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOV ESI, seg->base*/
addbyte(0x34);
@ -5558,15 +5653,23 @@ static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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*/
@ -5617,7 +5720,9 @@ static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
*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);
@ -5647,7 +5752,13 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg)
static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
{
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 ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -5714,7 +5825,13 @@ static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
}
static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
{
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 ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -5790,7 +5907,13 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
}
static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg)
{
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 ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -5888,7 +6011,13 @@ static inline 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);
@ -5960,7 +6089,13 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
}
static inline 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);
@ -6043,7 +6178,13 @@ static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
}
static inline 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);

View file

@ -618,6 +618,10 @@ static inline void CHECK_SEG_READ(x86seg *seg)
return;
if (seg->checked)
return;
if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS))
return;
if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))
return;
addbyte(0x83); /*CMP seg->base, -1*/
addbyte(0x05|0x38);
@ -639,6 +643,10 @@ static inline void CHECK_SEG_WRITE(x86seg *seg)
return;
if (seg->checked)
return;
if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS))
return;
if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))
return;
addbyte(0x83); /*CMP seg->base, -1*/
addbyte(0x05|0x38);
@ -652,6 +660,11 @@ static inline void CHECK_SEG_WRITE(x86seg *seg)
}
static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
{
if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS))
return;
if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))
return;
addbyte(0x3b); /*CMP EAX, seg->limit_low*/
addbyte(0x05);
addlong((uint32_t)&seg->limit_low);
@ -677,9 +690,18 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
static inline 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]));
@ -687,9 +709,18 @@ static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg)
}
static inline 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) && (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_no_abrt*/
addlong(mem_load_addr_ea_b_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
@ -699,9 +730,18 @@ static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
}
static inline 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) && (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_w*/
addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
@ -709,9 +749,18 @@ static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg)
}
static inline 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) && (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(0x83); /*ADD EAX, offset*/
addbyte(0xc0);
addbyte(offset);
@ -722,9 +771,18 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
}
static inline 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) && (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_w_no_abrt*/
addlong(mem_load_addr_ea_w_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
@ -734,9 +792,18 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
}
static inline 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) && (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_l*/
addlong(mem_load_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
@ -745,9 +812,18 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
}
static inline 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) && (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_l_no_abrt*/
addlong(mem_load_addr_ea_l_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
@ -758,9 +834,18 @@ static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg)
static inline 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) && (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_q*/
addlong(mem_load_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
@ -788,9 +873,18 @@ static inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr)
static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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*/
@ -801,9 +895,18 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
}
static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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*/
@ -814,9 +917,18 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
}
static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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*/
@ -827,9 +939,18 @@ static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
}
static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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*/
@ -840,9 +961,18 @@ static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
}
static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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*/
@ -853,9 +983,18 @@ static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
}
static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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*/
@ -876,9 +1015,18 @@ static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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]));
}
@ -3795,9 +3943,18 @@ static inline void LOAD_EA()
static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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();
@ -3805,9 +3962,18 @@ static inline void MEM_CHECK_WRITE(x86seg *seg)
static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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();
@ -3815,9 +3981,18 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
static inline 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) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
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();

View file

@ -274,13 +274,12 @@ 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;

View file

@ -1394,12 +1394,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;

View file

@ -167,6 +167,14 @@ struct
#define cycles cpu_state._cycles
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 COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0];
COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128);

View file

@ -761,9 +761,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);
@ -803,8 +811,28 @@ 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)

View file

@ -174,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;
}
}
static void do_seg_load(x86seg *s, uint16_t *segdat)
{
s->limit = segdat[0] | ((segdat[3] & 0xF) << 16);
@ -195,6 +218,21 @@ static void do_seg_load(x86seg *s, uint16_t *segdat)
s->limit_low = s->limit + 1;
}
// if (output) pclog("SEG : base=%08x limit=%08x low=%08x high=%08x\n", s->base, s->limit, s->limit_low, s->limit_high);
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)
@ -275,6 +313,8 @@ void loadseg(uint16_t seg, x86seg *s)
s->seg=0;
s->access = 0;
s->base=-1;
if (s == &_ds)
cpu_cur_status &= ~CPU_STATUS_FLATDS;
// pclog("NULL selector %s%s%s%s %04X(%06X):%06X\n",(s==&_ds)?"DS":"",(s==&_es)?"ES":"",(s==&_fs)?"FS":"",(s==&_gs)?"GS":"",CS,cs,pc);
return;
}
@ -343,7 +383,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);
// pclog("Load SS %04x %04x %04x %04x\n", segdat[0], segdat[1], segdat[2], segdat[3]);
}
else if (s!=&_cs)
@ -400,10 +440,23 @@ void loadseg(uint16_t seg, x86seg *s)
s->access = (3 << 5) | 2;
s->base = seg << 4;
s->seg = seg;
if (s == &_ss)
stack32 = 0;
s->checked = 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;
}
}
#define DPL ((segdat[2]>>13)&3)
@ -484,8 +537,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;
@ -601,8 +653,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;
@ -615,7 +666,16 @@ 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;
/* if (segdat[3]&0x40)
{
use32=0x300;
cpu_cur_status |= CPU_STATUS_USE32;
}
else
{
use32=0;
cpu_cur_status &= ~CPU_STATUS_USE32;
}*/
cycles -= timing_jmp_pm;
}
else /*System segment*/
@ -710,8 +770,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;
@ -920,8 +980,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;
@ -940,7 +999,16 @@ 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 (segdat[3]&0x40)
{
use32=0x300;
cpu_cur_status |= CPU_STATUS_USE32;
}
else
{
use32=0;
cpu_cur_status &= ~CPU_STATUS_USE32;
}*/
if (csout) pclog("Complete\n");
cycles -= timing_call_pm;
}
@ -1102,7 +1170,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;
@ -1119,7 +1187,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");
@ -1223,8 +1291,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;
@ -1397,7 +1465,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);
// pclog("CPL=RPL return to %04X:%08X\n",CS,pc);
cycles -= timing_retf_pm;
@ -1526,7 +1594,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);
@ -1548,7 +1616,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;
@ -1777,7 +1845,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);
@ -1881,7 +1949,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);
// pclog("Int gate done!\n");
#ifdef CS_ACCESSED
@ -2056,6 +2124,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);
@ -2076,7 +2145,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;
// pclog("V86 IRET to %04X:%04X %04X:%04X %04X %04X %04X %04X %i\n",CS,pc,SS,SP,DS,ES,FS,GS,abrt);
@ -2189,7 +2260,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;
@ -2283,7 +2354,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);
@ -2305,7 +2376,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);
@ -2522,7 +2593,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;