Rewritten parts of the 86F handler to minimize false CRC errors and misidentification of sectors;

Replaced IMG handler with one that now proxies to the 86F handler;
Applies the remaining Mainline PCem speedup commit;
Fixed the National Semiconductors PC87306 Super I/O Chip's serial port IRQ assignment;
DMF images are now loaded with the correct sector interleave, improving read/write speed;
XDF images are now loaded in a way that emulates the real order of the sectors on the track, improving read/write speed;
Added 16-bit physical memory read/write routines (mem_phys_readw, mem_phys_writew) and modified the 16-bit DMA code to use them instead of two 8-bit reads/writes.
This commit is contained in:
OBattler
2016-09-22 21:22:56 +02:00
parent 0ae428b5f5
commit 6318e2bb17
24 changed files with 1688 additions and 513 deletions

View File

@@ -2173,82 +2173,6 @@ static void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2)
*host_reg2 = REG_ECX;
}
static double _fp_half = 0.5;
static void FP_LOAD_ROUNDING()
{
pclog("cpu_state.npxc %04x\n", cpu_state.npxc);
addbyte(0x8b); /*MOV EDX, npxc*/
addbyte(0x15);
addlong((uintptr_t)&cpu_state.npxc);
addbyte(0xd9); /*FSTCW [ESP+8]*/
addbyte(0x7c);
addbyte(0x24);
addbyte(0x08);
addbyte(0x89); /*MOV [ESP+12],EDX*/
addbyte(0x54);
addbyte(0x24);
addbyte(0x0c);
addbyte(0xd9); /*FLDCW [ESP+12]*/
addbyte(0x6c);
addbyte(0x24);
addbyte(0x0c);
}
static void FP_RESTORE_ROUNDING()
{
addbyte(0xd9); /*FLDCW [ESP+8]*/
addbyte(0x6c);
addbyte(0x24);
addbyte(0x08);
}
static int32_t x87_fround32(double b)
{
int64_t a, c;
switch ((cpu_state.npxc >> 10) & 3)
{
case 0: /*Nearest*/
a = (int64_t)floor(b);
c = (int64_t)floor(b + 1.0);
if ((b - a) < (c - b))
return a;
else if ((b - a) > (c - b))
return c;
else
return (a & 1) ? c : a;
case 1: /*Down*/
return (int32_t)floor(b);
case 2: /*Up*/
return (int32_t)ceil(b);
case 3: /*Chop*/
return (int32_t)b;
}
}
static int64_t x87_fround64(double b)
{
int64_t a, c;
switch ((cpu_state.npxc >> 10) & 3)
{
case 0: /*Nearest*/
a = (int64_t)floor(b);
c = (int64_t)floor(b + 1.0);
if ((b - a) < (c - b))
return a;
else if ((b - a) > (c - b))
return c;
else
return (a & 1) ? c : a;
case 1: /*Down*/
return (int64_t)floor(b);
case 2: /*Up*/
return (int64_t)ceil(b);
case 3: /*Chop*/
return (int64_t)b;
}
}
static int FP_LOAD_REG_INT_W(int reg)
{
addbyte(0x8b); /*MOV EBX, TOP*/
@@ -2268,25 +2192,19 @@ static int FP_LOAD_REG_INT_W(int reg)
addbyte(0xdd);
addbyte(cpu_state_offset(ST));
addbyte(0x89); /*MOV [ESP+8], EAX*/
addbyte(0x44);
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
addbyte(0x6d);
addbyte(cpu_state_offset(new_npxc));
addbyte(0xdb); /*FISTP [ESP]*/
addbyte(0x1c);
addbyte(0x24);
addbyte(0x08);
addbyte(0xdd); /*FSTP [ESP]*/
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
addbyte(0x6d);
addbyte(cpu_state_offset(old_npxc));
addbyte(0x8b); /*MOV EBX, [ESP]*/
addbyte(0x1c);
addbyte(0x24);
CALL_FUNC(x87_fround32);
addbyte(0x89); /*MOV EBX, EAX*/
addbyte(0xc3);
addbyte(0x8b); /*MOV EAX, [ESP+8]*/
addbyte(0x44);
addbyte(0x24);
addbyte(0x08);
return REG_EBX;
}
static int FP_LOAD_REG_INT(int reg)
@@ -2308,25 +2226,19 @@ static int FP_LOAD_REG_INT(int reg)
addbyte(0xdd);
addbyte(cpu_state_offset(ST));
addbyte(0x89); /*MOV [ESP+8], EAX*/
addbyte(0x44);
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
addbyte(0x6d);
addbyte(cpu_state_offset(new_npxc));
addbyte(0xdb); /*FISTP [ESP]*/
addbyte(0x1c);
addbyte(0x24);
addbyte(0x08);
addbyte(0xdd); /*FSTP [ESP]*/
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
addbyte(0x6d);
addbyte(cpu_state_offset(old_npxc));
addbyte(0x8b); /*MOV EBX, [ESP]*/
addbyte(0x1c);
addbyte(0x24);
CALL_FUNC(x87_fround32);
addbyte(0x89); /*MOV EBX, EAX*/
addbyte(0xc3);
addbyte(0x8b); /*MOV EAX, [ESP+8]*/
addbyte(0x44);
addbyte(0x24);
addbyte(0x08);
return REG_EBX;
}
static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2)
@@ -2378,34 +2290,29 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2)
addbyte(cpu_state_offset(MM));
addbyte(0xeb); /*JMP done*/
addbyte(4+4+3+5+2+2+4);
addbyte(4+3+3+3+3+4);
addbyte(0xdd); /*FLD ST[EBX*8]*/
addbyte(0x44);
addbyte(0xdd);
addbyte(cpu_state_offset(ST));
addbyte(0x89); /*MOV [ESP+8], EAX*/
addbyte(0x44);
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
addbyte(0x6d);
addbyte(cpu_state_offset(new_npxc));
addbyte(0xdf); /*FISTPQ [ESP]*/
addbyte(0x3c);
addbyte(0x24);
addbyte(0x08);
addbyte(0xdd); /*FSTP [ESP]*/
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
addbyte(0x6d);
addbyte(cpu_state_offset(old_npxc));
addbyte(0x8b); /*MOV EBX, [ESP]*/
addbyte(0x1c);
addbyte(0x24);
CALL_FUNC(x87_fround64);
addbyte(0x89); /*MOV EBX, EAX*/
addbyte(0xc3);
addbyte(0x89); /*MOV ECX, EDX*/
addbyte(0xd1);
addbyte(0x8b); /*MOV EAX, [ESP+8]*/
addbyte(0x44);
addbyte(0x8b); /*MOV ECX, 4[ESP]*/
addbyte(0x4c);
addbyte(0x24);
addbyte(0x08);
addbyte(4);
*host_reg1 = REG_EBX;
*host_reg2 = REG_ECX;
@@ -2511,31 +2418,9 @@ static void FP_OP_D(int op)
addbyte(0x04);
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
{
addbyte(0x9b); /*FSTCW [ESP+8]*/
addbyte(0xd9);
addbyte(0x7c);
addbyte(0x24);
addbyte(0x08);
addbyte(0x66); /*MOV AX, [ESP+8]*/
addbyte(0x8b);
addbyte(0x44);
addbyte(0x24);
addbyte(0x08);
addbyte(0x66); /*AND AX, ~(3 << 10)*/
addbyte(0x25);
addword(~(3 << 10));
addbyte(0x66); /*OR AX, npxc & (3 << 10)*/
addbyte(0x0d);
addword(cpu_state.npxc & (3 << 10));
addbyte(0x66); /*MOV [ESP+12], AX*/
addbyte(0x89);
addbyte(0x44);
addbyte(0x24);
addbyte(0x0c);
addbyte(0xd9); /*FLDCW [ESP+12]*/
addbyte(0x6c);
addbyte(0x24);
addbyte(0x0c);
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
addbyte(0x6d);
addbyte(cpu_state_offset(new_npxc));
}
addbyte(0xdd); /*FLD ST[dst][EBP]*/
addbyte(0x45);
@@ -2552,10 +2437,9 @@ static void FP_OP_D(int op)
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
{
addbyte(0xd9); /*FLDCW [ESP+8]*/
addbyte(0x6c);
addbyte(0x24);
addbyte(0x08);
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
addbyte(0x6d);
addbyte(cpu_state_offset(old_npxc));
}
}
else
@@ -2568,31 +2452,9 @@ static void FP_OP_D(int op)
addbyte(0x24);
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
{
addbyte(0x9b); /*FSTCW [ESP+8]*/
addbyte(0xd9);
addbyte(0x7c);
addbyte(0x24);
addbyte(0x08);
addbyte(0x66); /*MOV AX, [ESP+8]*/
addbyte(0x8b);
addbyte(0x44);
addbyte(0x24);
addbyte(0x08);
addbyte(0x66); /*AND AX, ~(3 << 10)*/
addbyte(0x25);
addword(~(3 << 10));
addbyte(0x66); /*OR AX, npxc & (3 << 10)*/
addbyte(0x0d);
addword(cpu_state.npxc & (3 << 10));
addbyte(0x66); /*MOV [ESP+12], AX*/
addbyte(0x89);
addbyte(0x44);
addbyte(0x24);
addbyte(0x0c);
addbyte(0xd9); /*FLDCW [ESP+12]*/
addbyte(0x6c);
addbyte(0x24);
addbyte(0x0c);
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
addbyte(0x6d);
addbyte(cpu_state_offset(new_npxc));
}
addbyte(0x89); /*MOV [ESP+4], EDX*/
addbyte(0x54);
@@ -2616,10 +2478,9 @@ static void FP_OP_D(int op)
addbyte(cpu_state_offset(ST));
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
{
addbyte(0xd9); /*FLDCW [ESP+8]*/
addbyte(0x6c);
addbyte(0x24);
addbyte(0x08);
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
addbyte(0x6d);
addbyte(cpu_state_offset(old_npxc));
}
}
}
@@ -3226,6 +3087,32 @@ static void FP_COMPARE_REG(int dst, int src)
}
}
static void UPDATE_NPXC(int reg)
{
addbyte(0x66); /*AND cpu_state.new_npxc, ~0xc00*/
addbyte(0x81);
addbyte(0x65);
addbyte(cpu_state_offset(new_npxc));
addword(~0xc00);
if (reg)
{
addbyte(0x66); /*AND reg, 0xc00*/
addbyte(0x81);
addbyte(0xe0 | reg);
addword(0xc00);
}
else
{
addbyte(0x66); /*AND AX, 0xc00*/
addbyte(0x25);
addword(0xc00);
}
addbyte(0x66); /*OR cpu_state.new_npxc, reg*/
addbyte(0x09);
addbyte(0x45 | (reg << 3));
addbyte(cpu_state_offset(new_npxc));
}
static int ZERO_EXTEND_W_B(int reg)
{
addbyte(0x0f); /*MOVZX regl, regb*/