Merge branch 'master' of github.com:86Box/86Box into tc1995
This commit is contained in:
@@ -1,607 +0,0 @@
|
||||
#define OP_SHIFT_b(c, ea32) \
|
||||
{ \
|
||||
uint8_t temp_orig = temp; \
|
||||
if (!c) return 0; \
|
||||
flags_rebuild(); \
|
||||
switch (rmdat & 0x38) \
|
||||
{ \
|
||||
case 0x00: /*ROL b, c*/ \
|
||||
temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_rotate(FLAGS_ROL8, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x08: /*ROR b,CL*/ \
|
||||
temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_rotate(FLAGS_ROR8, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x10: /*RCL b,CL*/ \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
tempc = temp2 ? 1 : 0; \
|
||||
temp2 = temp & 0x80; \
|
||||
temp = (temp << 1) | tempc; \
|
||||
c--; \
|
||||
} \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x18: /*RCR b,CL*/ \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
tempc = temp2 ? 0x80 : 0; \
|
||||
temp2 = temp & 1; \
|
||||
temp = (temp >> 1) | tempc; \
|
||||
c--; \
|
||||
} \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x20: case 0x30: /*SHL b,CL*/ \
|
||||
seteab(temp << c); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x28: /*SHR b,CL*/ \
|
||||
seteab(temp >> c); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x38: /*SAR b,CL*/ \
|
||||
temp = (int8_t)temp >> c; \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define OP_SHIFT_w(c, ea32) \
|
||||
{ \
|
||||
uint16_t temp_orig = temp; \
|
||||
if (!c) return 0; \
|
||||
flags_rebuild(); \
|
||||
switch (rmdat & 0x38) \
|
||||
{ \
|
||||
case 0x00: /*ROL w, c*/ \
|
||||
temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_rotate(FLAGS_ROL16, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x08: /*ROR w,CL*/ \
|
||||
temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_rotate(FLAGS_ROR16, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x10: /*RCL w, c*/ \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
tempc = temp2 ? 1 : 0; \
|
||||
temp2 = temp & 0x8000; \
|
||||
temp = (temp << 1) | tempc; \
|
||||
c--; \
|
||||
} \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x18: /*RCR w, c*/ \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
tempc = temp2 ? 0x8000 : 0; \
|
||||
temp2 = temp & 1; \
|
||||
temp = (temp >> 1) | tempc; \
|
||||
c--; \
|
||||
} \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x20: case 0x30: /*SHL w, c*/ \
|
||||
seteaw(temp << c); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x28: /*SHR w, c*/ \
|
||||
seteaw(temp >> c); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x38: /*SAR w, c*/ \
|
||||
temp = (int16_t)temp >> c; \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define OP_SHIFT_l(c, ea32) \
|
||||
{ \
|
||||
uint32_t temp_orig = temp; \
|
||||
if (!c) return 0; \
|
||||
flags_rebuild(); \
|
||||
switch (rmdat & 0x38) \
|
||||
{ \
|
||||
case 0x00: /*ROL l, c*/ \
|
||||
temp = (temp << c) | (temp >> (32-c)); \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_rotate(FLAGS_ROL32, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x08: /*ROR l,CL*/ \
|
||||
temp = (temp >> c) | (temp << (32-c)); \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_rotate(FLAGS_ROR32, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x10: /*RCL l, c*/ \
|
||||
temp2 = CF_SET(); \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
tempc = temp2 ? 1 : 0; \
|
||||
temp2 = temp & 0x80000000; \
|
||||
temp = (temp << 1) | tempc; \
|
||||
c--; \
|
||||
} \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
|
||||
break; \
|
||||
case 0x18: /*RCR l, c*/ \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
tempc = temp2 ? 0x80000000 : 0; \
|
||||
temp2 = temp & 1; \
|
||||
temp = (temp >> 1) | tempc; \
|
||||
c--; \
|
||||
} \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
|
||||
break; \
|
||||
case 0x20: case 0x30: /*SHL l, c*/ \
|
||||
seteal(temp << c); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
|
||||
break; \
|
||||
case 0x28: /*SHR l, c*/ \
|
||||
seteal(temp >> c); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
|
||||
break; \
|
||||
case 0x38: /*SAR l, c*/ \
|
||||
temp = (int32_t)temp >> c; \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
static int opC0_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint8_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
|
||||
PREFETCH_PREFIX();
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_b(c, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opC0_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint8_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
|
||||
PREFETCH_PREFIX();
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_b(c, 1);
|
||||
return 0;
|
||||
}
|
||||
static int opC1_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint16_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
|
||||
PREFETCH_PREFIX();
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_w(c, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opC1_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint16_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
|
||||
PREFETCH_PREFIX();
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_w(c, 1);
|
||||
return 0;
|
||||
}
|
||||
static int opC1_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint32_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
|
||||
PREFETCH_PREFIX();
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_l(c, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opC1_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint32_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
|
||||
PREFETCH_PREFIX();
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_l(c, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opD0_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c = 1;
|
||||
int tempc;
|
||||
uint8_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_b(c, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opD0_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c = 1;
|
||||
int tempc;
|
||||
uint8_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_b(c, 1);
|
||||
return 0;
|
||||
}
|
||||
static int opD1_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c = 1;
|
||||
int tempc;
|
||||
uint16_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_w(c, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opD1_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c = 1;
|
||||
int tempc;
|
||||
uint16_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_w(c, 1);
|
||||
return 0;
|
||||
}
|
||||
static int opD1_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c = 1;
|
||||
int tempc;
|
||||
uint32_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_l(c, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opD1_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c = 1;
|
||||
int tempc;
|
||||
uint32_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_l(c, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opD2_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint8_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = CL & 31;
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_b(c, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opD2_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint8_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = CL & 31;
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_b(c, 1);
|
||||
return 0;
|
||||
}
|
||||
static int opD3_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint16_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = CL & 31;
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_w(c, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opD3_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint16_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = CL & 31;
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_w(c, 1);
|
||||
return 0;
|
||||
}
|
||||
static int opD3_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint32_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = CL & 31;
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_l(c, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opD3_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint32_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = CL & 31;
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_l(c, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define SHLD_w() \
|
||||
if (count) \
|
||||
{ \
|
||||
int tempc; \
|
||||
uint32_t templ; \
|
||||
uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \
|
||||
templ = (tempw << 16) | cpu_state.regs[cpu_reg].w; \
|
||||
if (count <= 16) tempw = templ >> (16 - count); \
|
||||
else tempw = (templ << count) >> 16; \
|
||||
seteaw(tempw); if (cpu_state.abrt) return 1; \
|
||||
setznp16(tempw); \
|
||||
flags_rebuild(); \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
}
|
||||
|
||||
#define SHLD_l() \
|
||||
if (count) \
|
||||
{ \
|
||||
int tempc; \
|
||||
uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \
|
||||
tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \
|
||||
templ = (templ << count) | (cpu_state.regs[cpu_reg].l >> (32 - count)); \
|
||||
seteal(templ); if (cpu_state.abrt) return 1; \
|
||||
setznp32(templ); \
|
||||
flags_rebuild(); \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
}
|
||||
|
||||
|
||||
#define SHRD_w() \
|
||||
if (count) \
|
||||
{ \
|
||||
int tempc; \
|
||||
uint32_t templ; \
|
||||
uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
tempc = (tempw >> (count - 1)) & 1; \
|
||||
templ = tempw | (cpu_state.regs[cpu_reg].w << 16); \
|
||||
tempw = templ >> count; \
|
||||
seteaw(tempw); if (cpu_state.abrt) return 1; \
|
||||
setznp16(tempw); \
|
||||
flags_rebuild(); \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
}
|
||||
|
||||
#define SHRD_l() \
|
||||
if (count) \
|
||||
{ \
|
||||
int tempc; \
|
||||
uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \
|
||||
tempc = (templ >> (count - 1)) & 1; \
|
||||
templ = (templ >> count) | (cpu_state.regs[cpu_reg].l << (32 - count)); \
|
||||
seteal(templ); if (cpu_state.abrt) return 1; \
|
||||
setznp32(templ); \
|
||||
flags_rebuild(); \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
}
|
||||
|
||||
#define opSHxD(operation) \
|
||||
static int op ## operation ## _i_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
int count; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
count = getbyte() & 31; \
|
||||
operation(); \
|
||||
\
|
||||
CLOCK_CYCLES(3); \
|
||||
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
static int op ## operation ## _CL_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
int count; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
count = CL & 31; \
|
||||
operation(); \
|
||||
\
|
||||
CLOCK_CYCLES(3); \
|
||||
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
static int op ## operation ## _i_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
int count; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
count = getbyte() & 31; \
|
||||
operation(); \
|
||||
\
|
||||
CLOCK_CYCLES(3); \
|
||||
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \
|
||||
return 0; \
|
||||
} \
|
||||
static int op ## operation ## _CL_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
int count; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
count = CL & 31; \
|
||||
operation(); \
|
||||
\
|
||||
CLOCK_CYCLES(3); \
|
||||
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
opSHxD(SHLD_w)
|
||||
opSHxD(SHLD_l)
|
||||
opSHxD(SHRD_w)
|
||||
opSHxD(SHRD_l)
|
File diff suppressed because it is too large
Load Diff
@@ -1726,6 +1726,7 @@ cpu_set(void)
|
||||
x87_timings = x87_timings_387;
|
||||
break;
|
||||
|
||||
case FPU_487SX:
|
||||
default:
|
||||
x87_timings = x87_timings_486;
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@ enum {
|
||||
FPU_287,
|
||||
FPU_287XL,
|
||||
FPU_387,
|
||||
FPU_487SX,
|
||||
FPU_INTERNAL
|
||||
};
|
||||
|
||||
|
@@ -73,6 +73,12 @@ FPU fpus_80386[] =
|
||||
{"387", "387", FPU_387},
|
||||
{NULL, NULL, 0}
|
||||
};
|
||||
FPU fpus_486sx[] =
|
||||
{
|
||||
{"None", "none", FPU_NONE},
|
||||
{"487SX","487sx", FPU_487SX},
|
||||
{NULL, NULL, 0}
|
||||
};
|
||||
FPU fpus_internal[] =
|
||||
{
|
||||
{"Internal", "internal", FPU_INTERNAL},
|
||||
@@ -259,12 +265,12 @@ CPU cpus_486DLC[] = {
|
||||
|
||||
CPU cpus_i486S1[] = {
|
||||
/*i486*/
|
||||
{"i486SX/16", CPU_i486SX, fpus_none, 16000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2},
|
||||
{"i486SX/20", CPU_i486SX, fpus_none, 20000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486SX/25", CPU_i486SX, fpus_none, 25000000, 1, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486SX/33", CPU_i486SX, fpus_none, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
|
||||
{"i486SX2/50", CPU_i486SX2, fpus_none, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
|
||||
{"i486SX2/66 (Q0569)", CPU_i486SX2, fpus_none, 66666666, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8},
|
||||
{"i486SX/16", CPU_i486SX, fpus_486sx, 16000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2},
|
||||
{"i486SX/20", CPU_i486SX, fpus_486sx, 20000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486SX/25", CPU_i486SX, fpus_486sx, 25000000, 1, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486SX/33", CPU_i486SX, fpus_486sx, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
|
||||
{"i486SX2/50", CPU_i486SX2, fpus_486sx, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
|
||||
{"i486SX2/66 (Q0569)", CPU_i486SX2, fpus_486sx, 66666666, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8},
|
||||
{"i486DX/25", CPU_i486DX, fpus_internal, 25000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486DX/33", CPU_i486DX, fpus_internal, 33333333, 1, 0x414, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
|
||||
{"i486DX/50", CPU_i486DX, fpus_internal, 50000000, 1, 0x411, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6},
|
||||
@@ -277,10 +283,10 @@ CPU cpus_i486S1[] = {
|
||||
};
|
||||
CPU cpus_Am486S1[] = {
|
||||
/*Am486*/
|
||||
{"Am486SX/33", CPU_Am486SX, fpus_none, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Am486SX/40", CPU_Am486SX, fpus_none, 40000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Am486SX2/50", CPU_Am486SX2, fpus_none, 50000000, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
|
||||
{"Am486SX2/66", CPU_Am486SX2, fpus_none, 66666666, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/
|
||||
{"Am486SX/33", CPU_Am486SX, fpus_486sx, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Am486SX/40", CPU_Am486SX, fpus_486sx, 40000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Am486SX2/50", CPU_Am486SX2, fpus_486sx, 50000000, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
|
||||
{"Am486SX2/66", CPU_Am486SX2, fpus_486sx, 66666666, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/
|
||||
{"Am486DX/33", CPU_Am486DX, fpus_internal, 33333333, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Am486DX/40", CPU_Am486DX, fpus_internal, 40000000, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Am486DX2/50", CPU_Am486DX2, fpus_internal, 50000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
@@ -290,9 +296,9 @@ CPU cpus_Am486S1[] = {
|
||||
};
|
||||
CPU cpus_Cx486S1[] = {
|
||||
/*Cyrix 486*/
|
||||
{"Cx486S/25", CPU_Cx486S, fpus_none, 25000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"Cx486S/33", CPU_Cx486S, fpus_none, 33333333, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Cx486S/40", CPU_Cx486S, fpus_none, 40000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Cx486S/25", CPU_Cx486S, fpus_486sx, 25000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"Cx486S/33", CPU_Cx486S, fpus_486sx, 33333333, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Cx486S/40", CPU_Cx486S, fpus_486sx, 40000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Cx486DX/33", CPU_Cx486DX, fpus_internal, 33333333, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Cx486DX/40", CPU_Cx486DX, fpus_internal, 40000000, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Cx486DX2/50", CPU_Cx486DX2, fpus_internal, 50000000, 2.0, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
@@ -303,12 +309,12 @@ CPU cpus_Cx486S1[] = {
|
||||
|
||||
CPU cpus_i486[] = {
|
||||
/*i486/P24T*/
|
||||
{"i486SX/16", CPU_i486SX, fpus_none, 16000000, 1.0, 0x420, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 3, 3, 3, 3, 2},
|
||||
{"i486SX/20", CPU_i486SX, fpus_none, 20000000, 1.0, 0x420, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"i486SX/25", CPU_i486SX, fpus_none, 25000000, 1.0, 0x422, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"i486SX/33", CPU_i486SX, fpus_none, 33333333, 1.0, 0x42a, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"i486SX2/50", CPU_i486SX2, fpus_none, 50000000, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
{"i486SX2/66 (Q0569)", CPU_i486SX2, fpus_none, 66666666, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 8},
|
||||
{"i486SX/16", CPU_i486SX, fpus_486sx, 16000000, 1.0, 0x420, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 3, 3, 3, 3, 2},
|
||||
{"i486SX/20", CPU_i486SX, fpus_486sx, 20000000, 1.0, 0x420, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"i486SX/25", CPU_i486SX, fpus_486sx, 25000000, 1.0, 0x422, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"i486SX/33", CPU_i486SX, fpus_486sx, 33333333, 1.0, 0x42a, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"i486SX2/50", CPU_i486SX2, fpus_486sx, 50000000, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
{"i486SX2/66 (Q0569)", CPU_i486SX2, fpus_486sx, 66666666, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 8},
|
||||
{"i486DX/25", CPU_i486DX, fpus_internal, 25000000, 1.0, 0x404, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"i486DX/33", CPU_i486DX, fpus_internal, 33333333, 1.0, 0x414, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"i486DX/50", CPU_i486DX, fpus_internal, 50000000, 1.0, 0x411, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 6},
|
||||
@@ -326,10 +332,10 @@ CPU cpus_i486[] = {
|
||||
|
||||
CPU cpus_Am486[] = {
|
||||
/*Am486/5x86*/
|
||||
{"Am486SX/33", CPU_Am486SX, fpus_none, 33333333, 1.0, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Am486SX/40", CPU_Am486SX, fpus_none, 40000000, 1.0, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Am486SX2/50", CPU_Am486SX2, fpus_none, 50000000, 2.0, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
|
||||
{"Am486SX2/66", CPU_Am486SX2, fpus_none, 66666666, 2.0, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
|
||||
{"Am486SX/33", CPU_Am486SX, fpus_486sx, 33333333, 1.0, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Am486SX/40", CPU_Am486SX, fpus_486sx, 40000000, 1.0, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Am486SX2/50", CPU_Am486SX2, fpus_486sx, 50000000, 2.0, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
|
||||
{"Am486SX2/66", CPU_Am486SX2, fpus_486sx, 66666666, 2.0, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
|
||||
{"Am486DX/33", CPU_Am486DX, fpus_internal, 33333333, 1.0, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Am486DX/40", CPU_Am486DX, fpus_internal, 40000000, 1.0, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Am486DX2/50", CPU_Am486DX2, fpus_internal, 50000000, 2.0, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
@@ -347,9 +353,9 @@ CPU cpus_Am486[] = {
|
||||
|
||||
CPU cpus_Cx486[] = {
|
||||
/*Cyrix 486*/
|
||||
{"Cx486S/25", CPU_Cx486S, fpus_none, 25000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"Cx486S/33", CPU_Cx486S, fpus_none, 33333333, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Cx486S/40", CPU_Cx486S, fpus_none, 40000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Cx486S/25", CPU_Cx486S, fpus_486sx, 25000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"Cx486S/33", CPU_Cx486S, fpus_486sx, 33333333, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Cx486S/40", CPU_Cx486S, fpus_486sx, 40000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Cx486DX/33", CPU_Cx486DX, fpus_internal, 33333333, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Cx486DX/40", CPU_Cx486DX, fpus_internal, 40000000, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Cx486DX2/50", CPU_Cx486DX2, fpus_internal, 50000000, 2.0, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
|
@@ -1,3 +1,235 @@
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
#define OP_SHIFT_b(c, ea32) \
|
||||
{ \
|
||||
uint8_t temp_orig = temp; \
|
||||
if (!c) return 0; \
|
||||
flags_rebuild(); \
|
||||
switch (rmdat & 0x38) \
|
||||
{ \
|
||||
case 0x00: /*ROL b, c*/ \
|
||||
temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_rotate(FLAGS_ROL8, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x08: /*ROR b,CL*/ \
|
||||
temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_rotate(FLAGS_ROR8, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x10: /*RCL b,CL*/ \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
tempc = temp2 ? 1 : 0; \
|
||||
temp2 = temp & 0x80; \
|
||||
temp = (temp << 1) | tempc; \
|
||||
c--; \
|
||||
} \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x18: /*RCR b,CL*/ \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
tempc = temp2 ? 0x80 : 0; \
|
||||
temp2 = temp & 1; \
|
||||
temp = (temp >> 1) | tempc; \
|
||||
c--; \
|
||||
} \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x20: case 0x30: /*SHL b,CL*/ \
|
||||
seteab(temp << c); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x28: /*SHR b,CL*/ \
|
||||
seteab(temp >> c); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x38: /*SAR b,CL*/ \
|
||||
temp = (int8_t)temp >> c; \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define OP_SHIFT_w(c, ea32) \
|
||||
{ \
|
||||
uint16_t temp_orig = temp; \
|
||||
if (!c) return 0; \
|
||||
flags_rebuild(); \
|
||||
switch (rmdat & 0x38) \
|
||||
{ \
|
||||
case 0x00: /*ROL w, c*/ \
|
||||
temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_rotate(FLAGS_ROL16, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x08: /*ROR w,CL*/ \
|
||||
temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_rotate(FLAGS_ROR16, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x10: /*RCL w, c*/ \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
tempc = temp2 ? 1 : 0; \
|
||||
temp2 = temp & 0x8000; \
|
||||
temp = (temp << 1) | tempc; \
|
||||
c--; \
|
||||
} \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x18: /*RCR w, c*/ \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
tempc = temp2 ? 0x8000 : 0; \
|
||||
temp2 = temp & 1; \
|
||||
temp = (temp >> 1) | tempc; \
|
||||
c--; \
|
||||
} \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x20: case 0x30: /*SHL w, c*/ \
|
||||
seteaw(temp << c); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x28: /*SHR w, c*/ \
|
||||
seteaw(temp >> c); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x38: /*SAR w, c*/ \
|
||||
temp = (int16_t)temp >> c; \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define OP_SHIFT_l(c, ea32) \
|
||||
{ \
|
||||
uint32_t temp_orig = temp; \
|
||||
if (!c) return 0; \
|
||||
flags_rebuild(); \
|
||||
switch (rmdat & 0x38) \
|
||||
{ \
|
||||
case 0x00: /*ROL l, c*/ \
|
||||
temp = (temp << c) | (temp >> (32-c)); \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_rotate(FLAGS_ROL32, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x08: /*ROR l,CL*/ \
|
||||
temp = (temp >> c) | (temp << (32-c)); \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_rotate(FLAGS_ROR32, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x10: /*RCL l, c*/ \
|
||||
temp2 = CF_SET(); \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
tempc = temp2 ? 1 : 0; \
|
||||
temp2 = temp & 0x80000000; \
|
||||
temp = (temp << 1) | tempc; \
|
||||
c--; \
|
||||
} \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
|
||||
break; \
|
||||
case 0x18: /*RCR l, c*/ \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
tempc = temp2 ? 0x80000000 : 0; \
|
||||
temp2 = temp & 1; \
|
||||
temp = (temp >> 1) | tempc; \
|
||||
c--; \
|
||||
} \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
|
||||
break; \
|
||||
case 0x20: case 0x30: /*SHL l, c*/ \
|
||||
seteal(temp << c); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
|
||||
break; \
|
||||
case 0x28: /*SHR l, c*/ \
|
||||
seteal(temp >> c); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
|
||||
break; \
|
||||
case 0x38: /*SAR l, c*/ \
|
||||
temp = (int32_t)temp >> c; \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define OP_SHIFT_b(c, ea32) \
|
||||
{ \
|
||||
uint8_t temp_orig = temp; \
|
||||
@@ -240,6 +472,7 @@
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opC0_a16(uint32_t fetchdat)
|
||||
{
|
||||
@@ -564,7 +797,7 @@ static int opD3_l_a32(uint32_t fetchdat)
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
count = getbyte() & 31; \
|
||||
operation() \
|
||||
operation(); \
|
||||
\
|
||||
CLOCK_CYCLES(3); \
|
||||
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \
|
||||
@@ -578,7 +811,7 @@ static int opD3_l_a32(uint32_t fetchdat)
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
count = CL & 31; \
|
||||
operation() \
|
||||
operation(); \
|
||||
\
|
||||
CLOCK_CYCLES(3); \
|
||||
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \
|
||||
@@ -592,7 +825,7 @@ static int opD3_l_a32(uint32_t fetchdat)
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
count = getbyte() & 31; \
|
||||
operation() \
|
||||
operation(); \
|
||||
\
|
||||
CLOCK_CYCLES(3); \
|
||||
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \
|
||||
@@ -606,7 +839,7 @@ static int opD3_l_a32(uint32_t fetchdat)
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
count = CL & 31; \
|
||||
operation() \
|
||||
operation(); \
|
||||
\
|
||||
CLOCK_CYCLES(3); \
|
||||
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \
|
@@ -106,11 +106,9 @@ static void seg_reset(x86seg *s)
|
||||
s->limit = 0xFFFF;
|
||||
s->limit_low = 0;
|
||||
s->limit_high = 0xffff;
|
||||
if(s == &cpu_state.seg_cs)
|
||||
if (s == &cpu_state.seg_cs)
|
||||
{
|
||||
// TODO - When the PC is reset, initialization of the CS descriptor must be like the annotated line below.
|
||||
s->base = AT ? (cpu_16bitbus ? 0xFF0000 : 0xFFFF0000) : 0xFFFF0;
|
||||
// s->base = AT ? 0xF0000 : 0xFFFF0;
|
||||
s->seg = AT ? 0xF000 : 0xFFFF;
|
||||
}
|
||||
else
|
||||
@@ -118,7 +116,6 @@ static void seg_reset(x86seg *s)
|
||||
s->base = 0;
|
||||
s->seg = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void x86seg_reset()
|
||||
@@ -133,7 +130,9 @@ void x86seg_reset()
|
||||
|
||||
void x86_doabrt(int x86_abrt)
|
||||
{
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
CS = oldcs;
|
||||
#endif
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
cpu_state.seg_cs.access = (oldcpl << 5) | 0x80;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
@@ -158,9 +157,11 @@ void x86_doabrt(int x86_abrt)
|
||||
SP-=6;
|
||||
}
|
||||
|
||||
cpu_state.flags&=~I_FLAG;
|
||||
cpu_state.flags&=~T_FLAG;
|
||||
oxpc=cpu_state.pc;
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oxpc=cpu_state.pc;
|
||||
#endif
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
return;
|
||||
@@ -249,7 +250,7 @@ void do_seg_load(x86seg *s, uint16_t *segdat)
|
||||
if (is386)
|
||||
s->base |= ((segdat[3] >> 8) << 24);
|
||||
s->access = segdat[2] >> 8;
|
||||
s->ar_high = segdat[3] & 0xff;
|
||||
s->ar_high = segdat[3] & 0xff;
|
||||
|
||||
if ((segdat[2] & 0x1800) != 0x1000 || !(segdat[2] & (1 << 10))) /*expand-down*/
|
||||
{
|
||||
@@ -331,7 +332,11 @@ static void check_seg_valid(x86seg *s)
|
||||
loadseg(0, s);
|
||||
}
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
int loadseg(uint16_t seg, x86seg *s)
|
||||
#else
|
||||
void loadseg(uint16_t seg, x86seg *s)
|
||||
#endif
|
||||
{
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr;
|
||||
@@ -344,7 +349,11 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
if (s==&cpu_state.seg_ss)
|
||||
{
|
||||
x86ss(NULL,0);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
s->seg = 0;
|
||||
s->access = 0x80;
|
||||
@@ -352,32 +361,36 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
s->base=-1;
|
||||
if (s == &cpu_state.seg_ds)
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 0;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
addr=seg&~7;
|
||||
if (seg&4)
|
||||
{
|
||||
#if 0
|
||||
if (addr>=ldt.limit)
|
||||
#else
|
||||
if ((addr+7)>ldt.limit)
|
||||
#endif
|
||||
{
|
||||
x86gpf("loadseg(): Bigger than LDT limit",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
addr+=ldt.base;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
if (addr>=gdt.limit)
|
||||
#else
|
||||
if ((addr+7)>gdt.limit)
|
||||
#endif
|
||||
{
|
||||
x86gpf("loadseg(): Bigger than GDT limit",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
addr+=gdt.base;
|
||||
}
|
||||
@@ -385,24 +398,40 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
segdat[0]=readmemw(0,addr);
|
||||
segdat[1]=readmemw(0,addr+2);
|
||||
segdat[2]=readmemw(0,addr+4);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return 1;
|
||||
#else
|
||||
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return;
|
||||
#endif
|
||||
dpl=(segdat[2]>>13)&3;
|
||||
if (s==&cpu_state.seg_ss)
|
||||
{
|
||||
if (!(seg&~3))
|
||||
{
|
||||
x86gpf("loadseg(): Stack segment is zero",seg&~3);
|
||||
x86gpf("loadseg(): Zero stack segment",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
if ((seg&3)!=CPL)
|
||||
{
|
||||
x86gpf("loadseg(): Stack segment RPL != CPL",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
if (dpl!=CPL)
|
||||
{
|
||||
x86gpf("loadseg(): Stack segment DPL != CPL",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
switch ((segdat[2]>>8)&0x1F)
|
||||
{
|
||||
@@ -410,12 +439,20 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
break;
|
||||
default:
|
||||
x86gpf("loadseg(): Unknown stack segment type",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
if (!(segdat[2]&0x8000))
|
||||
{
|
||||
x86ss(NULL,seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
set_stack32((segdat[3] & 0x40) ? 1 : 0);
|
||||
}
|
||||
@@ -430,33 +467,49 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
case 0x1A: case 0x1B: /*Readable non-conforming code*/
|
||||
if ((seg&3)>dpl)
|
||||
{
|
||||
x86gpf("loadseg(): Normal segment is zero",seg&~3);
|
||||
x86gpf("loadseg(): Normal segment RPL > DPL",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
if ((CPL)>dpl)
|
||||
{
|
||||
x86gpf("loadseg(): Normal segment DPL < CPL",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 0x1E: case 0x1F: /*Readable conforming code*/
|
||||
break;
|
||||
default:
|
||||
x86gpf("loadseg(): Unknown normal segment type",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!(segdat[2] & 0x8000))
|
||||
{
|
||||
x86np("Load data seg not present", seg & 0xfffc);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
s->seg = seg;
|
||||
do_seg_load(s, segdat);
|
||||
|
||||
#ifndef CS_ACCESSED
|
||||
if (s != &cpu_state.seg_cs)
|
||||
if (s != &_cs)
|
||||
{
|
||||
#endif
|
||||
#ifdef SEL_ACCESSED
|
||||
@@ -506,6 +559,10 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
else
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
|
||||
}
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return cpu_state.abrt;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define DPL ((segdat[2]>>13)&3)
|
||||
@@ -521,7 +578,7 @@ void loadcs(uint16_t seg)
|
||||
{
|
||||
if (!(seg&~3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
x86gpf("loadcs(): Protected mode selector is zero",0);
|
||||
return;
|
||||
}
|
||||
addr=seg&~7;
|
||||
@@ -578,7 +635,10 @@ void loadcs(uint16_t seg)
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
|
||||
#ifdef CS_ACCESSED
|
||||
cpl_override = 1;
|
||||
writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/
|
||||
@@ -589,7 +649,7 @@ void loadcs(uint16_t seg)
|
||||
{
|
||||
if (!(segdat[2]&0x8000))
|
||||
{
|
||||
x86np("Load CS system seg not present", seg & 0xfffc);
|
||||
x86np("Load CS system seg not present\n", seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
switch (segdat[2]&0xF00)
|
||||
@@ -609,8 +669,11 @@ void loadcs(uint16_t seg)
|
||||
CS=seg & 0xFFFF;
|
||||
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -690,6 +753,9 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
cycles -= timing_jmp_pm;
|
||||
}
|
||||
else /*System segment*/
|
||||
@@ -708,7 +774,9 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
case 0xC00:
|
||||
cgate32=(type&0x800);
|
||||
cgate16=!cgate32;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oldcs=CS;
|
||||
#endif
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
if (DPL < CPL)
|
||||
{
|
||||
@@ -720,16 +788,6 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
x86gpf("loadcsjmp(): Call gate DPL< RPL",seg&~3);
|
||||
return;
|
||||
}
|
||||
if (DPL < CPL)
|
||||
{
|
||||
x86gpf("loadcsjmp(): ex DPL < CPL",seg&~3);
|
||||
return;
|
||||
}
|
||||
if ((DPL < (seg&3)))
|
||||
{
|
||||
x86gpf("loadcsjmp(): ex (DPL < (seg&3))",seg&~3);
|
||||
return;
|
||||
}
|
||||
if (!(segdat[2]&0x8000))
|
||||
{
|
||||
x86np("Load CS JMP call gate not present\n", seg & 0xfffc);
|
||||
@@ -792,7 +850,9 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
CS=seg2;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3]&0x40);
|
||||
cpu_state.pc=newpc;
|
||||
|
||||
@@ -813,7 +873,7 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
|
||||
case 0x100: /*286 Task gate*/
|
||||
case 0x900: /*386 Task gate*/
|
||||
cpu_state.pc=old_pc;
|
||||
cpu_state.pc = old_pc;
|
||||
optype=JMP;
|
||||
cpl_override=1;
|
||||
taskswitch286(seg,segdat,segdat[2]&0x800);
|
||||
@@ -836,8 +896,11 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
CS=seg;
|
||||
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
cycles -= timing_jmp_rm;
|
||||
}
|
||||
}
|
||||
@@ -907,7 +970,11 @@ uint32_t POPL()
|
||||
return templ;
|
||||
}
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
void loadcscall(uint16_t seg, uint32_t old_pc)
|
||||
#else
|
||||
void loadcscall(uint16_t seg)
|
||||
#endif
|
||||
{
|
||||
uint16_t seg2;
|
||||
uint16_t segdat[4],segdat2[4],newss;
|
||||
@@ -917,7 +984,7 @@ void loadcscall(uint16_t seg)
|
||||
uint32_t oldss,oldsp,newsp, oldsp2;
|
||||
int type;
|
||||
uint16_t tempw;
|
||||
|
||||
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG))
|
||||
{
|
||||
x86seg_log("Protected mode CS load! %04X\n", seg);
|
||||
@@ -999,7 +1066,9 @@ void loadcscall(uint16_t seg)
|
||||
CS=seg;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
#ifdef ENABLE_X86SEG_LOG
|
||||
x86seg_log("Complete\n");
|
||||
#endif
|
||||
@@ -1013,10 +1082,12 @@ void loadcscall(uint16_t seg)
|
||||
{
|
||||
case 0x400: /*Call gate*/
|
||||
case 0xC00: /*386 Call gate*/
|
||||
x86seg_log("Callgate %08X\n", cpu_state.pc);
|
||||
x86seg_log("Callgate %08X\n", cpu_state.pc);
|
||||
cgate32=(type&0x800);
|
||||
cgate16=!cgate32;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oldcs=CS;
|
||||
#endif
|
||||
count=segdat[2]&31;
|
||||
if (DPL < CPL)
|
||||
{
|
||||
@@ -1030,7 +1101,6 @@ void loadcscall(uint16_t seg)
|
||||
}
|
||||
if (!(segdat[2]&0x8000))
|
||||
{
|
||||
x86seg_log("Call gate not present %04X\n",seg);
|
||||
x86np("Call gate not present\n", seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
@@ -1082,12 +1152,14 @@ void loadcscall(uint16_t seg)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch (segdat[2]&0x1F00)
|
||||
{
|
||||
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/
|
||||
if (DPL < CPL)
|
||||
{
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
uint16_t oldcs = CS;
|
||||
#endif
|
||||
oaddr = addr;
|
||||
/*Load new stack*/
|
||||
oldss=SS;
|
||||
@@ -1116,11 +1188,7 @@ void loadcscall(uint16_t seg)
|
||||
addr=newss&~7;
|
||||
if (newss&4)
|
||||
{
|
||||
#if 0
|
||||
if (addr>=ldt.limit)
|
||||
#else
|
||||
if ((addr+7)>ldt.limit)
|
||||
#endif
|
||||
{
|
||||
x86abort("Bigger than LDT limit %04X %08X %04X CSC SS\n",newss,addr,ldt.limit);
|
||||
x86ts(NULL,newss&~3);
|
||||
@@ -1130,11 +1198,7 @@ void loadcscall(uint16_t seg)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
if (addr>=gdt.limit)
|
||||
#else
|
||||
if ((addr+7)>gdt.limit)
|
||||
#endif
|
||||
{
|
||||
x86abort("Bigger than GDT limit %04X %04X CSC\n",newss,gdt.limit);
|
||||
x86ts(NULL,newss&~3);
|
||||
@@ -1143,12 +1207,12 @@ void loadcscall(uint16_t seg)
|
||||
addr+=gdt.base;
|
||||
}
|
||||
cpl_override=1;
|
||||
x86seg_log("Read stack seg\n");
|
||||
x86seg_log("Read stack seg\n");
|
||||
segdat2[0]=readmemw(0,addr);
|
||||
segdat2[1]=readmemw(0,addr+2);
|
||||
segdat2[2]=readmemw(0,addr+4);
|
||||
segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return;
|
||||
x86seg_log("Read stack seg done!\n");
|
||||
x86seg_log("Read stack seg done!\n");
|
||||
if (((newss & 3) != DPL) || (DPL2 != DPL))
|
||||
{
|
||||
x86ts(NULL,newss&~3);
|
||||
@@ -1172,7 +1236,7 @@ void loadcscall(uint16_t seg)
|
||||
|
||||
do_seg_load(&cpu_state.seg_ss, segdat2);
|
||||
|
||||
x86seg_log("Set access 1\n");
|
||||
x86seg_log("Set access 1\n");
|
||||
|
||||
#ifdef SEL_ACCESSED
|
||||
cpl_override = 1;
|
||||
@@ -1183,19 +1247,21 @@ void loadcscall(uint16_t seg)
|
||||
CS=seg2;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3]&0x40);
|
||||
cpu_state.pc=newpc;
|
||||
|
||||
x86seg_log("Set access 2\n");
|
||||
|
||||
x86seg_log("Set access 2\n");
|
||||
|
||||
#ifdef CS_ACCESSED
|
||||
cpl_override = 1;
|
||||
writememw(0, oaddr+4, segdat[2] | 0x100); /*Set accessed bit*/
|
||||
cpl_override = 0;
|
||||
#endif
|
||||
|
||||
x86seg_log("Type %04X\n",type);
|
||||
|
||||
x86seg_log("Type %04X\n",type);
|
||||
if (type==0xC00)
|
||||
{
|
||||
PUSHL(oldss);
|
||||
@@ -1204,6 +1270,9 @@ void loadcscall(uint16_t seg)
|
||||
{
|
||||
SS = oldss;
|
||||
ESP = oldsp2;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
CS = oldcs;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (count)
|
||||
@@ -1216,6 +1285,9 @@ void loadcscall(uint16_t seg)
|
||||
{
|
||||
SS = oldss;
|
||||
ESP = oldsp2;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
CS = oldcs;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1231,21 +1303,27 @@ void loadcscall(uint16_t seg)
|
||||
{
|
||||
SS = oldss;
|
||||
ESP = oldsp2;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
CS = oldcs;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
x86seg_log("Write SP to %04X:%04X\n",SS,SP);
|
||||
x86seg_log("Write SP to %04X:%04X\n",SS,SP);
|
||||
if (count)
|
||||
{
|
||||
while (count)
|
||||
{
|
||||
count--;
|
||||
tempw=readmemw(oldssbase,(oldsp&0xFFFF)+(count*2));
|
||||
x86seg_log("PUSH %04X\n",tempw);
|
||||
x86seg_log("PUSH %04X\n",tempw);
|
||||
PUSHW(tempw);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
SS = oldss;
|
||||
ESP = oldsp2;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
CS = oldcs;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1264,6 +1342,9 @@ void loadcscall(uint16_t seg)
|
||||
CS=seg2;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3]&0x40);
|
||||
cpu_state.pc=newpc;
|
||||
|
||||
@@ -1283,7 +1364,11 @@ void loadcscall(uint16_t seg)
|
||||
|
||||
case 0x100: /*286 Task gate*/
|
||||
case 0x900: /*386 Task gate*/
|
||||
cpu_state.pc=oxpc;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.pc = old_pc;
|
||||
#else
|
||||
cpu_state.pc = oxpc;
|
||||
#endif
|
||||
cpl_override=1;
|
||||
taskswitch286(seg,segdat,segdat[2]&0x800);
|
||||
cpl_override=0;
|
||||
@@ -1304,8 +1389,11 @@ void loadcscall(uint16_t seg)
|
||||
CS=seg;
|
||||
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1417,6 +1505,9 @@ void pmoderetf(int is32, uint16_t off)
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3] & 0x40);
|
||||
|
||||
cycles -= timing_retf_pm;
|
||||
@@ -1432,7 +1523,7 @@ void pmoderetf(int is32, uint16_t off)
|
||||
x86gpf("pmoderetf(): Non-conforming RPL != DPL",seg&~3);
|
||||
return;
|
||||
}
|
||||
x86seg_log("RETF non-conforming, %i %i\n",seg&3, DPL);
|
||||
x86seg_log("RETF non-conforming, %i %i\n",seg&3, DPL);
|
||||
break;
|
||||
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
||||
if ((seg&3) < DPL)
|
||||
@@ -1441,7 +1532,7 @@ void pmoderetf(int is32, uint16_t off)
|
||||
x86gpf("pmoderetf(): Conforming RPL < DPL",seg&~3);
|
||||
return;
|
||||
}
|
||||
x86seg_log("RETF conforming, %i %i\n",seg&3, DPL);
|
||||
x86seg_log("RETF conforming, %i %i\n",seg&3, DPL);
|
||||
break;
|
||||
default:
|
||||
ESP=oldsp;
|
||||
@@ -1499,7 +1590,7 @@ void pmoderetf(int is32, uint16_t off)
|
||||
segdat2[1]=readmemw(0,addr+2);
|
||||
segdat2[2]=readmemw(0,addr+4);
|
||||
segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP=oldsp; return; }
|
||||
x86seg_log("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]);
|
||||
x86seg_log("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]);
|
||||
if ((newss & 3) != (seg & 3))
|
||||
{
|
||||
ESP=oldsp;
|
||||
@@ -1539,14 +1630,17 @@ void pmoderetf(int is32, uint16_t off)
|
||||
#endif
|
||||
cpl_override = 0;
|
||||
#endif
|
||||
/*Conforming segments don't change CPL, so CPL = RPL*/
|
||||
if (segdat[2]&0x400)
|
||||
segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8));
|
||||
/*Conforming segments don't change CPL, so CPL = RPL*/
|
||||
if (segdat[2]&0x400)
|
||||
segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8));
|
||||
|
||||
cpu_state.pc=newpc;
|
||||
CS=seg;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3] & 0x40);
|
||||
|
||||
if (stack32) ESP+=off;
|
||||
@@ -1560,11 +1654,6 @@ void pmoderetf(int is32, uint16_t off)
|
||||
}
|
||||
}
|
||||
|
||||
void restore_stack()
|
||||
{
|
||||
ss=oldss; cpu_state.seg_ss.limit=oldsslimit;
|
||||
}
|
||||
|
||||
void pmodeint(int num, int soft)
|
||||
{
|
||||
uint16_t segdat[4],segdat2[4],segdat3[4];
|
||||
@@ -1575,10 +1664,10 @@ void pmodeint(int num, int soft)
|
||||
uint32_t newsp;
|
||||
uint16_t seg = 0;
|
||||
int new_cpl;
|
||||
|
||||
|
||||
if (cpu_state.eflags&VM_FLAG && IOPL!=3 && soft)
|
||||
{
|
||||
x86seg_log("V86 banned int\n");
|
||||
x86seg_log("V86 banned int\n");
|
||||
x86gpf("pmodeint(): V86 banned int",0);
|
||||
return;
|
||||
}
|
||||
@@ -1589,7 +1678,7 @@ void pmodeint(int num, int soft)
|
||||
{
|
||||
/*Triple fault - reset!*/
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
cpu_set_edx();
|
||||
}
|
||||
else if (num==0xD)
|
||||
{
|
||||
@@ -1607,7 +1696,11 @@ void pmodeint(int num, int soft)
|
||||
segdat[0]=readmemw(0,addr);
|
||||
segdat[1]=readmemw(2,addr);
|
||||
segdat[2]=readmemw(4,addr);
|
||||
segdat[3]=readmemw(6,addr); cpl_override=0; if (cpu_state.abrt) { /* x86seg_log("Abrt reading from %08X\n",addr); */ return; }
|
||||
segdat[3]=readmemw(6,addr); cpl_override=0;
|
||||
if (cpu_state.abrt) {
|
||||
x86seg_log("Abrt reading from %08X\n",addr);
|
||||
return;
|
||||
}
|
||||
oaddr = addr;
|
||||
|
||||
x86seg_log("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]);
|
||||
@@ -1675,7 +1768,7 @@ void pmodeint(int num, int soft)
|
||||
x86np("Int gate CS not present\n", segdat[1] & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if ((cpu_state.eflags&VM_FLAG) && DPL2)
|
||||
if ((cpu_state.eflags & VM_FLAG) && DPL2)
|
||||
{
|
||||
x86gpf("pmodeint(): Interrupt or trap gate non-zero DPL in V86 mode",segdat[1]&0xFFFC);
|
||||
return;
|
||||
@@ -1770,7 +1863,7 @@ void pmodeint(int num, int soft)
|
||||
}
|
||||
PUSHL(oldss);
|
||||
PUSHL(oldsp);
|
||||
PUSHL(cpu_state.flags|(cpu_state.eflags<<16));
|
||||
PUSHL(cpu_state.flags | (cpu_state.eflags << 16));
|
||||
PUSHL(CS);
|
||||
PUSHL(cpu_state.pc); if (cpu_state.abrt) return;
|
||||
}
|
||||
@@ -1806,7 +1899,7 @@ void pmodeint(int num, int soft)
|
||||
}
|
||||
if (type>0x800)
|
||||
{
|
||||
PUSHL(cpu_state.flags|(cpu_state.eflags<<16));
|
||||
PUSHL(cpu_state.flags | (cpu_state.eflags << 16));
|
||||
PUSHL(CS);
|
||||
PUSHL(cpu_state.pc); if (cpu_state.abrt) return;
|
||||
}
|
||||
@@ -1826,6 +1919,9 @@ void pmodeint(int num, int soft)
|
||||
CS = (seg & ~3) | new_cpl;
|
||||
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | (new_cpl << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
if (type>0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16);
|
||||
else cpu_state.pc=segdat[0];
|
||||
set_use32(segdat2[3]&0x40);
|
||||
@@ -1836,13 +1932,11 @@ void pmodeint(int num, int soft)
|
||||
cpl_override = 0;
|
||||
#endif
|
||||
|
||||
cpu_state.eflags&=~VM_FLAG;
|
||||
cpu_state.eflags &= ~VM_FLAG;
|
||||
cpu_cur_status &= ~CPU_STATUS_V86;
|
||||
if (!(type&0x100))
|
||||
{
|
||||
cpu_state.flags&=~I_FLAG;
|
||||
}
|
||||
cpu_state.flags&=~(T_FLAG|NT_FLAG);
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
cpu_state.flags &= ~(T_FLAG|NT_FLAG);
|
||||
cycles -= timing_int_pm;
|
||||
break;
|
||||
|
||||
@@ -1898,17 +1992,19 @@ void pmodeiret(int is32)
|
||||
uint32_t newpc;
|
||||
uint16_t segdat[4],segdat2[4];
|
||||
uint16_t segs[4];
|
||||
uint16_t seg;
|
||||
uint16_t seg = 0;
|
||||
uint32_t addr, oaddr;
|
||||
uint32_t oldsp=ESP;
|
||||
if (is386 && (cpu_state.eflags&VM_FLAG))
|
||||
if (is386 && (cpu_state.eflags & VM_FLAG))
|
||||
{
|
||||
if (IOPL!=3)
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return;
|
||||
}
|
||||
oxpc=cpu_state.pc;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oxpc=cpu_state.pc;
|
||||
#endif
|
||||
if (is32)
|
||||
{
|
||||
newpc=POPL();
|
||||
@@ -1926,15 +2022,15 @@ void pmodeiret(int is32)
|
||||
cpu_state.seg_cs.limit=0xFFFF;
|
||||
cpu_state.seg_cs.limit_low = 0;
|
||||
cpu_state.seg_cs.limit_high = 0xffff;
|
||||
cpu_state.seg_cs.access |= 0x80;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
cpu_state.seg_cs.access |= 0x80;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
CS=seg;
|
||||
cpu_state.flags=(cpu_state.flags&0x3000)|(tempflags&0xCFD5)|2;
|
||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempflags & 0xCFD5) | 2;
|
||||
cycles -= timing_iret_rm;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cpu_state.flags&NT_FLAG)
|
||||
if (cpu_state.flags & NT_FLAG)
|
||||
{
|
||||
seg=readmemw(tr.base,0);
|
||||
addr=seg&~7;
|
||||
@@ -1962,7 +2058,9 @@ void pmodeiret(int is32)
|
||||
cpl_override=0;
|
||||
return;
|
||||
}
|
||||
oxpc=cpu_state.pc;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oxpc=cpu_state.pc;
|
||||
#endif
|
||||
flagmask=0xFFFF;
|
||||
if (CPL) flagmask&=~0x3000;
|
||||
if (IOPL<CPL) flagmask&=~0x200;
|
||||
@@ -1979,7 +2077,7 @@ void pmodeiret(int is32)
|
||||
segs[1]=POPL();
|
||||
segs[2]=POPL();
|
||||
segs[3]=POPL(); if (cpu_state.abrt) { ESP = oldsp; return; }
|
||||
cpu_state.eflags=tempflags>>16;
|
||||
cpu_state.eflags = tempflags>>16;
|
||||
cpu_cur_status |= CPU_STATUS_V86;
|
||||
loadseg(segs[0],&cpu_state.seg_es);
|
||||
do_seg_v86_init(&cpu_state.seg_es);
|
||||
@@ -1989,25 +2087,28 @@ void pmodeiret(int is32)
|
||||
loadseg(segs[2],&cpu_state.seg_fs);
|
||||
do_seg_v86_init(&cpu_state.seg_fs);
|
||||
loadseg(segs[3],&cpu_state.seg_gs);
|
||||
do_seg_v86_init(&cpu_state.seg_gs);
|
||||
|
||||
cpu_state.pc=newpc;
|
||||
do_seg_v86_init(&cpu_state.seg_gs);
|
||||
|
||||
cpu_state.pc = newpc & 0xffff;
|
||||
cpu_state.seg_cs.base=seg<<4;
|
||||
cpu_state.seg_cs.limit=0xFFFF;
|
||||
cpu_state.seg_cs.limit_low = 0;
|
||||
cpu_state.seg_cs.limit_high = 0xffff;
|
||||
CS=seg;
|
||||
cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||
cpu_state.seg_cs.ar_high=0x10;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
|
||||
ESP=newsp;
|
||||
loadseg(newss,&cpu_state.seg_ss);
|
||||
do_seg_v86_init(&cpu_state.seg_ss);
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
|
||||
use32=0;
|
||||
cpu_cur_status &= ~CPU_STATUS_USE32;
|
||||
cpu_state.flags=(tempflags&0xFFD5)|2;
|
||||
cpu_state.flags = (tempflags&0xFFD5)|2;
|
||||
cycles -= timing_iret_v86;
|
||||
return;
|
||||
}
|
||||
@@ -2057,7 +2158,7 @@ void pmodeiret(int is32)
|
||||
segdat[1]=readmemw(0,addr+2);
|
||||
segdat[2]=readmemw(0,addr+4);
|
||||
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP = oldsp; return; }
|
||||
|
||||
|
||||
switch (segdat[2]&0x1F00)
|
||||
{
|
||||
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/
|
||||
@@ -2093,6 +2194,9 @@ void pmodeiret(int is32)
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3]&0x40);
|
||||
|
||||
#ifdef CS_ACCESSED
|
||||
@@ -2198,8 +2302,11 @@ void pmodeiret(int is32)
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3] & 0x40);
|
||||
|
||||
|
||||
check_seg_valid(&cpu_state.seg_ds);
|
||||
check_seg_valid(&cpu_state.seg_es);
|
||||
check_seg_valid(&cpu_state.seg_fs);
|
||||
@@ -2207,8 +2314,8 @@ void pmodeiret(int is32)
|
||||
cycles -= timing_iret_pm_outer;
|
||||
}
|
||||
cpu_state.pc=newpc;
|
||||
cpu_state.flags=(cpu_state.flags&~flagmask)|(tempflags&flagmask&0xFFD5)|2;
|
||||
if (is32) cpu_state.eflags=tempflags>>16;
|
||||
cpu_state.flags = (cpu_state.flags&~flagmask) | (tempflags&flagmask&0xFFD5)|2;
|
||||
if (is32) cpu_state.eflags = tempflags>>16;
|
||||
}
|
||||
|
||||
void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
@@ -2260,7 +2367,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
cpu_386_flags_rebuild();
|
||||
writememl(tr.base,0x1C,cr3);
|
||||
writememl(tr.base,0x20,cpu_state.pc);
|
||||
writememl(tr.base,0x24,cpu_state.flags|(cpu_state.eflags<<16));
|
||||
writememl(tr.base,0x24,cpu_state.flags | (cpu_state.eflags<<16));
|
||||
|
||||
writememl(tr.base,0x28,EAX);
|
||||
writememl(tr.base,0x2C,ECX);
|
||||
@@ -2326,8 +2433,8 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
flushmmucache();
|
||||
|
||||
cpu_state.pc=new_pc;
|
||||
cpu_state.flags=new_flags;
|
||||
cpu_state.eflags=new_flags>>16;
|
||||
cpu_state.flags = new_flags;
|
||||
cpu_state.eflags = new_flags>>16;
|
||||
cpu_386_flags_extract();
|
||||
|
||||
ldt.seg=new_ldt;
|
||||
@@ -2405,6 +2512,9 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
CS=new_cs;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat2);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat2[3] & 0x40);
|
||||
cpu_cur_status &= ~CPU_STATUS_V86;
|
||||
}
|
||||
@@ -2443,7 +2553,8 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
}
|
||||
if (cpu_state.abrt) return;
|
||||
|
||||
if (optype==IRET) cpu_state.flags&=~NT_FLAG;
|
||||
if (optype == IRET)
|
||||
cpu_state.flags &= ~NT_FLAG;
|
||||
|
||||
cpu_386_flags_rebuild();
|
||||
writememw(tr.base,0x0E,cpu_state.pc);
|
||||
@@ -2504,7 +2615,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
msw |= 8;
|
||||
|
||||
cpu_state.pc=new_pc;
|
||||
cpu_state.flags=new_flags;
|
||||
cpu_state.flags = new_flags;
|
||||
cpu_386_flags_extract();
|
||||
|
||||
ldt.seg=new_ldt;
|
||||
@@ -2578,6 +2689,9 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
CS=new_cs;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat2);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(0);
|
||||
|
||||
EAX=new_eax | 0xFFFF0000;
|
||||
@@ -2603,5 +2717,5 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
tr.base=base;
|
||||
tr.limit=limit;
|
||||
tr.access=segdat[2]>>8;
|
||||
tr.ar_high = segdat[3] & 0xff;
|
||||
tr.ar_high = segdat[3] & 0xff;
|
||||
}
|
@@ -157,8 +157,8 @@ sdl_stretch(int *w, int *h, int *x, int *y)
|
||||
}
|
||||
dx = (hw - dw) / 2.0;
|
||||
dy = (hh - dh) / 2.0;
|
||||
*w = (int) hw;
|
||||
*h = (int) hh;
|
||||
*w = (int) dw;
|
||||
*h = (int) dh;
|
||||
*x = (int) dx;
|
||||
*y = (int) dy;
|
||||
break;
|
||||
|
@@ -584,6 +584,8 @@ win_settings_machine_recalc_fpu(HWND hdlg)
|
||||
EnableWindow(h, TRUE);
|
||||
else
|
||||
EnableWindow(h, FALSE);
|
||||
|
||||
temp_fpu = fpu_get_type_from_index(temp_machine, temp_cpu_m, temp_cpu, SendMessage(h, CB_GETCURSEL, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user