Applied all mainline PCem commits;

Fixed behavior of the FDC RECALIBRATE command for FDC's on certain Super I/O chips;
Several 86F-related fixes;
Added the Intel Advanced/ML (430HX, Socket 7, currently with non-working Flash) and Intel Advanced/ATX (430FX, Socket 7, works perfectly) motherboards;
Fixed handling of DENSEL when the FDC is in National Semiconductors PC87306 mode;
Brought 440FX initialization PCI parameters in line with Bochs;
Brought PIIX3 initialization PCI parameters in line with QEMU.
This commit is contained in:
OBattler
2016-09-14 23:18:14 +02:00
parent 264859a574
commit cdfba37ea9
22 changed files with 1940 additions and 1081 deletions

View File

@@ -1348,6 +1348,13 @@ void exec386_dynarec(int cycs)
valid_block = 0;
}
}
if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP)
{
/*FPU top-of-stack does not match the value this block was compiled
with, re-compile using dynamic top-of-stack*/
block->flags &= ~CODEBLOCK_STATIC_TOP;
block->was_recompiled = 0;
}
}
if (valid_block && block->was_recompiled)

View File

@@ -56,10 +56,17 @@ typedef struct codeblock_t
uint64_t page_mask, page_mask2;
int was_recompiled;
uint32_t flags;
int TOP;
uint8_t data[2048];
} codeblock_t;
/*Code block uses FPU*/
#define CODEBLOCK_HAS_FPU 1
/*Code block is always entered with the same FPU top-of-stack*/
#define CODEBLOCK_STATIC_TOP 2
static inline codeblock_t *codeblock_tree_find(uint32_t phys)
{
codeblock_t *block = pages[phys >> 12].head;

View File

@@ -1837,6 +1837,41 @@ static void FP_ENTER()
}
static void FP_FLD(int reg)
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0xf3); /*MOVQ XMM0, ST[reg][EBP]*/
addbyte(0x0f);
addbyte(0x7e);
addbyte(0x45);
addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7]));
addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/
addbyte(0x45);
addbyte(cpu_state_offset(TOP));
addbyte((cpu_state.TOP - 1) & 7);
addbyte(0xf3); /*MOVQ XMM1, MM[reg][EBP]*/
addbyte(0x0f);
addbyte(0x7e);
addbyte(0x4d);
addbyte(cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q));
addbyte(0x66); /*MOVQ ST[-1][EBP], XMM0*/
addbyte(0x0f);
addbyte(0xd6);
addbyte(0x45);
addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]));
addbyte(0x8a); /*MOV AL, tag[reg][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(tag[(cpu_state.TOP + reg) & 7]));
addbyte(0x66); /*MOVQ MM[-1][EBP], XMM1*/
addbyte(0x0f);
addbyte(0xd6);
addbyte(0x4d);
addbyte(cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q));
addbyte(0x88); /*MOV tag[-1][EBP], AL*/
addbyte(0x45);
addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7]));
}
else
{
addbyte(0x8b); /*MOV EAX, [TOP]*/
addbyte(0x45);
@@ -1902,8 +1937,30 @@ static void FP_FLD(int reg)
addbyte(0x5d);
addbyte(cpu_state_offset(TOP));
}
}
static void FP_FST(int reg)
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/
addbyte(0x0f);
addbyte(0x7e);
addbyte(0x45);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
addbyte(0x8a); /*MOV AL, tag[0][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(tag[cpu_state.TOP]));
addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/
addbyte(0x0f);
addbyte(0xd6);
addbyte(0x45);
addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7]));
addbyte(0x88); /*MOV tag[reg][EBP], AL*/
addbyte(0x45);
addbyte(cpu_state_offset(tag[(cpu_state.TOP + reg) & 7]));
}
else
{
addbyte(0x8b); /*MOV EAX, [TOP]*/
addbyte(0x45);
@@ -1936,8 +1993,66 @@ static void FP_FST(int reg)
addbyte(0x05);
addbyte(cpu_state_offset(tag[0]));
}
}
static void FP_FXCH(int reg)
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/
addbyte(0x0f);
addbyte(0x7e);
addbyte(0x45);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
addbyte(0xf3); /*MOVQ XMM1, ST[reg][EBP]*/
addbyte(0x0f);
addbyte(0x7e);
addbyte(0x4d);
addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7]));
addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/
addbyte(0x0f);
addbyte(0xd6);
addbyte(0x45);
addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7]));
addbyte(0xf3); /*MOVQ XMM2, MM[0][EBP]*/
addbyte(0x0f);
addbyte(0x7e);
addbyte(0x55);
addbyte(cpu_state_offset(MM[cpu_state.TOP].q));
addbyte(0x66); /*MOVQ ST[0][EBP], XMM1*/
addbyte(0x0f);
addbyte(0xd6);
addbyte(0x4d);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
addbyte(0xf3); /*MOVQ XMM3, MM[reg][EBP]*/
addbyte(0x0f);
addbyte(0x7e);
addbyte(0x5d);
addbyte(cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q));
addbyte(0x66); /*MOVQ MM[reg][EBP], XMM2*/
addbyte(0x0f);
addbyte(0xd6);
addbyte(0x55);
addbyte(cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q));
addbyte(0x8a); /*MOV AL, tag[0][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(tag[cpu_state.TOP]));
addbyte(0x66); /*MOVQ MM[0][EBP], XMM3*/
addbyte(0x0f);
addbyte(0xd6);
addbyte(0x5d);
addbyte(cpu_state_offset(MM[cpu_state.TOP].q));
addbyte(0x8a); /*MOV AH, tag[reg][EBP]*/
addbyte(0x65);
addbyte(cpu_state_offset(tag[(cpu_state.TOP + reg) & 7]));
addbyte(0x88); /*MOV tag[reg][EBP], AL*/
addbyte(0x45);
addbyte(cpu_state_offset(tag[(cpu_state.TOP + reg) & 7]));
addbyte(0x88); /*MOV tag[0][EBP], AH*/
addbyte(0x65);
addbyte(cpu_state_offset(tag[cpu_state.TOP]));
}
else
{
addbyte(0x8b); /*MOV EAX, [TOP]*/
addbyte(0x45);
@@ -1947,7 +2062,7 @@ static void FP_FXCH(int reg)
addbyte(0x83); /*ADD EAX, reg*/
addbyte(0xc0);
addbyte(reg);
//#if 0
addbyte(0xdd); /*FLD [ST+EBX*8]*/
addbyte(0x44);
addbyte(0xdd);
@@ -1967,8 +2082,6 @@ static void FP_FXCH(int reg)
addbyte(0x5c);
addbyte(0xc5);
addbyte(cpu_state_offset(ST));
// addbyte(0xbe); /*MOVL ESI, tag*/
// addlong((uintptr_t)cpu_state.tag);
addbyte(0x8a); /*MOV CL, tag[EAX]*/
addbyte(0x4c);
addbyte(0x05);
@@ -2015,49 +2128,36 @@ static void FP_FXCH(int reg)
addbyte(0x54);
addbyte(0xc6);
addbyte(0x04);
reg = reg;
//#endif
#if 0
addbyte(0xbe); /*MOVL ESI, ST*/
addlong((uintptr_t)cpu_state.ST);
addbyte(0x8b); /*MOVL EDX, [ESI+EBX*8]*/
addbyte(0x14);
addbyte(0xde);
addbyte(0x83); /*AND EAX, 7*/
addbyte(0xe0);
addbyte(0x07);
addbyte(0x8b); /*MOVL ECX, [ESI+EAX*8]*/
addbyte(0x0c);
addbyte(0xc6);
addbyte(0x89); /*MOVL [ESI+EBX*8], ECX*/
addbyte(0x0c);
addbyte(0xde);
addbyte(0x89); /*MOVL [ESI+EAX*8], EDX*/
addbyte(0x14);
addbyte(0xc6);
addbyte(0x8b); /*MOVL ECX, [4+ESI+EAX*8]*/
addbyte(0x4c);
addbyte(0xc6);
addbyte(0x04);
addbyte(0x8b); /*MOVL EDX, [4+ESI+EBX*8]*/
addbyte(0x54);
addbyte(0xde);
addbyte(0x04);
addbyte(0x89); /*MOVL [4+ESI+EBX*8], ECX*/
addbyte(0x4c);
addbyte(0xde);
addbyte(0x04);
addbyte(0x89); /*MOVL [4+ESI+EAX*8], EDX*/
addbyte(0x54);
addbyte(0xc6);
addbyte(0x04);
#endif
}
}
static void FP_LOAD_S()
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x89); /*MOV [ESP], EAX*/
addbyte(0x04);
addbyte(0x24);
addbyte(0x85); /*TEST EAX, EAX*/
addbyte(0xc0);
addbyte(0xd9); /*FLD [ESP]*/
addbyte(0x04);
addbyte(0x24);
addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/
addbyte(0x45);
addbyte(cpu_state_offset(TOP));
addbyte((cpu_state.TOP - 1) & 7);
addbyte(0x0f); /*SETE tag[reg][EBP]*/
addbyte(0x94);
addbyte(0x45);
addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7]));
addbyte(0xdd); /*FSTP ST[reg][EBP]*/
addbyte(0x5d);
addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]));
block_current = block_current;
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2074,9 +2174,8 @@ static void FP_LOAD_S()
addbyte(0x83); /*AND EBX, 7*/
addbyte(0xe3);
addbyte(7);
addbyte(0x83); /*CMP EAX, 0*/
addbyte(0xf8);
addbyte(0);
addbyte(0x85); /*TEST EAX, EAX*/
addbyte(0xc0);
addbyte(0x89); /*MOV TOP, EBX*/
addbyte(0x5d);
addbyte(cpu_state_offset(TOP));
@@ -2090,7 +2189,29 @@ static void FP_LOAD_S()
addbyte(0x1d);
addbyte(cpu_state_offset(tag[0]));
}
}
static void FP_LOAD_D()
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x89); /*MOV ST[reg][EBP], EAX*/
addbyte(0x45);
addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]));
addbyte(0x09); /*OR EAX, EDX*/
addbyte(0xd0);
addbyte(0x89); /*MOV ST[reg][EBP]+4, EDX*/
addbyte(0x55);
addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4);
addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/
addbyte(0x45);
addbyte(cpu_state_offset(TOP));
addbyte((cpu_state.TOP - 1) & 7);
addbyte(0x0f); /*SETE tag[reg][EBP]*/
addbyte(0x94);
addbyte(0x45);
addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7]));
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2129,7 +2250,34 @@ static void FP_LOAD_D()
addbyte(0x1d);
addbyte(cpu_state_offset(tag[0]));
}
}
static void FP_LOAD_IW()
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x66); /*MOV [ESP], AX*/
addbyte(0x89);
addbyte(0x04);
addbyte(0x24);
addbyte(0x66); /*TEST AX, AX*/
addbyte(0x85);
addbyte(0xc0);
addbyte(0xdf); /*FILDw [ESP]*/
addbyte(0x04);
addbyte(0x24);
addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/
addbyte(0x45);
addbyte(cpu_state_offset(TOP));
addbyte((cpu_state.TOP - 1) & 7);
addbyte(0x0f); /*SETE tag[reg][EBP]*/
addbyte(0x94);
addbyte(0x45);
addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7]));
addbyte(0xdd); /*FSTP ST[reg][EBP]*/
addbyte(0x5d);
addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]));
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2162,7 +2310,32 @@ static void FP_LOAD_IW()
addbyte(0x1d);
addbyte(cpu_state_offset(tag[0]));
}
}
static void FP_LOAD_IL()
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x89); /*MOV [ESP], EAX*/
addbyte(0x04);
addbyte(0x24);
addbyte(0x85); /*TEST EAX, EAX*/
addbyte(0xc0);
addbyte(0xdb); /*FILDl [ESP]*/
addbyte(0x04);
addbyte(0x24);
addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/
addbyte(0x45);
addbyte(cpu_state_offset(TOP));
addbyte((cpu_state.TOP - 1) & 7);
addbyte(0x0f); /*SETE tag[reg][EBP]*/
addbyte(0x94);
addbyte(0x45);
addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7]));
addbyte(0xdd); /*FSTP ST[reg][EBP]*/
addbyte(0x5d);
addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]));
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2195,7 +2368,39 @@ static void FP_LOAD_IL()
addbyte(0x1d);
addbyte(cpu_state_offset(tag[0]));
}
}
static void FP_LOAD_IQ()
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x89); /*MOV MM[reg][EBP], EAX*/
addbyte(0x45);
addbyte(cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q));
addbyte(0x09); /*OR EAX, EDX*/
addbyte(0xd0);
addbyte(0x89); /*MOV MM[reg][EBP]+4, EDX*/
addbyte(0x55);
addbyte(cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q) + 4);
addbyte(0x0f); /*SETE AL*/
addbyte(0x94);
addbyte(0xc0);
addbyte(0xdf); /*FILDq MM[reg][EBP]*/
addbyte(0x6d);
addbyte(cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q));
addbyte(0x0c); /*OR AL, TAG_UINT64*/
addbyte(TAG_UINT64);
addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/
addbyte(0x45);
addbyte(cpu_state_offset(TOP));
addbyte((cpu_state.TOP - 1) & 7);
addbyte(0x88); /*MOV tag[reg][EBP], AL*/
addbyte(0x45);
addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7]));
addbyte(0xdd); /*FSTP ST[reg][EBP]*/
addbyte(0x5d);
addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]));
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2240,8 +2445,17 @@ static void FP_LOAD_IQ()
addbyte(0x1d);
addbyte(cpu_state_offset(tag[0]));
}
}
static int FP_LOAD_REG(int reg)
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0xdd); /*FLD ST[reg][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7]));
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2259,6 +2473,7 @@ static int FP_LOAD_REG(int reg)
addbyte(0x44);
addbyte(0xdd);
addbyte(cpu_state_offset(ST));
}
addbyte(0xd9); /*FSTP [ESP]*/
addbyte(0x1c);
addbyte(0x24);
@@ -2270,6 +2485,14 @@ static int FP_LOAD_REG(int reg)
}
static void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2)
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0xdd); /*FLD ST[reg][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7]));
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2287,6 +2510,7 @@ static void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2)
addbyte(0x44);
addbyte(0xdd);
addbyte(cpu_state_offset(ST));
}
addbyte(0xdd); /*FSTP [ESP]*/
addbyte(0x1c);
addbyte(0x24);
@@ -2541,6 +2765,19 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2)
}
static void FP_POP()
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0xc6); /*MOVB tag[0][EBP], 3*/
addbyte(0x45);
addbyte(cpu_state_offset(tag[cpu_state.TOP]));
addbyte(3);
addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/
addbyte(0x45);
addbyte(cpu_state_offset(TOP));
addbyte((cpu_state.TOP + 1) & 7);
}
else
{
addbyte(0x8b); /*MOV EAX, TOP*/
addbyte(0x45);
@@ -2558,6 +2795,7 @@ static void FP_POP()
addbyte(0x45);
addbyte(cpu_state_offset(TOP));
}
}
#define FPU_ADD 0x00
#define FPU_DIV 0x30
@@ -2567,6 +2805,27 @@ static void FP_POP()
#define FPU_SUBR 0x28
static void FP_OP_S(int op)
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x89); /*MOV [ESP], EAX*/
addbyte(0x04);
addbyte(0x24);
addbyte(0xdd); /*FLD ST[dst][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/
addbyte(0x65);
addbyte(cpu_state_offset(tag[cpu_state.TOP]));
addbyte(~TAG_UINT64);
addbyte(0xd8); /*FADD [ESP]*/
addbyte(0x04 | op);
addbyte(0x24);
addbyte(0xdd); /*FSTP ST[dst][EBP]*/
addbyte(0x5d);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2591,7 +2850,68 @@ static void FP_OP_S(int op)
addbyte(0xdd);
addbyte(cpu_state_offset(ST));
}
}
static void FP_OP_D(int op)
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x89); /*MOV [ESP], EAX*/
addbyte(0x04);
addbyte(0x24);
addbyte(0x89); /*MOV [ESP+4], EDX*/
addbyte(0x54);
addbyte(0x24);
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(0xdd); /*FLD ST[dst][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/
addbyte(0x65);
addbyte(cpu_state_offset(tag[cpu_state.TOP]));
addbyte(~TAG_UINT64);
addbyte(0xdc); /*FADD [ESP]*/
addbyte(0x04 | op);
addbyte(0x24);
addbyte(0xdd); /*FSTP ST[dst][EBP]*/
addbyte(0x5d);
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);
}
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2655,7 +2975,30 @@ static void FP_OP_D(int op)
addbyte(0x08);
}
}
}
static void FP_OP_IW(int op)
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x66); /*MOV [ESP], AX*/
addbyte(0x89);
addbyte(0x04);
addbyte(0x24);
addbyte(0xdd); /*FLD ST[0][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/
addbyte(0x65);
addbyte(cpu_state_offset(tag[cpu_state.TOP]));
addbyte(~TAG_UINT64);
addbyte(0xde); /*FADD [ESP]*/
addbyte(0x04 | op);
addbyte(0x24);
addbyte(0xdd); /*FSTP ST[0][EBP]*/
addbyte(0x5d);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2680,7 +3023,29 @@ static void FP_OP_IW(int op)
addbyte(0xdd);
addbyte(cpu_state_offset(ST));
}
}
static void FP_OP_IL(int op)
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x89); /*MOV [ESP], EAX*/
addbyte(0x04);
addbyte(0x24);
addbyte(0xdd); /*FLD ST[0][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/
addbyte(0x65);
addbyte(cpu_state_offset(tag[cpu_state.TOP]));
addbyte(~TAG_UINT64);
addbyte(0xda); /*FADD [ESP]*/
addbyte(0x04 | op);
addbyte(0x24);
addbyte(0xdd); /*FSTP ST[0][EBP]*/
addbyte(0x5d);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2705,7 +3070,33 @@ static void FP_OP_IL(int op)
addbyte(0xdd);
addbyte(cpu_state_offset(ST));
}
}
static void FP_OP_IQ(int op)
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x89); /*MOV [ESP], EAX*/
addbyte(0x04);
addbyte(0x24);
addbyte(0x89); /*MOV [ESP+4], EDX*/
addbyte(0x54);
addbyte(0x24);
addbyte(0x04);
addbyte(0xdd); /*FLD ST[0][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/
addbyte(0x65);
addbyte(cpu_state_offset(tag[cpu_state.TOP]));
addbyte(~TAG_UINT64);
addbyte(0xdc); /*FADD [ESP]*/
addbyte(0x04 | op);
addbyte(0x24);
addbyte(0xdd); /*FSTP ST[0][EBP]*/
addbyte(0x5d);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2734,6 +3125,7 @@ static void FP_OP_IQ(int op)
addbyte(0xdd);
addbyte(cpu_state_offset(ST));
}
}
#define C0 (1<<8)
#define C1 (1<<9)
@@ -2741,6 +3133,38 @@ static void FP_OP_IQ(int op)
#define C3 (1<<14)
static void FP_COMPARE_S()
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x89); /*MOV [ESP], EAX*/
addbyte(0x04);
addbyte(0x24);
addbyte(0xdd); /*FLD ST[0][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
addbyte(0x8a); /*MOV BL, [npxs+1]*/
addbyte(0x5d);
addbyte(cpu_state_offset(npxs) + 1);
addbyte(0xdb); /*FCLEX*/
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
addbyte((~(C0|C2|C3)) >> 8);
addbyte(0xd8); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
addbyte(0xdf); /*FSTSW AX*/
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
addbyte((C0|C2|C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
addbyte(0x5d);
addbyte(cpu_state_offset(npxs) + 1);
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2774,7 +3198,44 @@ static void FP_COMPARE_S()
addbyte(0x5d);
addbyte(cpu_state_offset(npxs) + 1);
}
}
static void FP_COMPARE_D()
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x89); /*MOV [ESP], EAX*/
addbyte(0x04);
addbyte(0x24);
addbyte(0x89); /*MOV [ESP+4], EDX*/
addbyte(0x54);
addbyte(0x24);
addbyte(0x04);
addbyte(0xdd); /*FLD ST[0][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
addbyte(0x8a); /*MOV BL, [npxs+1]*/
addbyte(0x5d);
addbyte(cpu_state_offset(npxs) + 1);
addbyte(0xdb); /*FCLEX*/
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
addbyte((~(C0|C2|C3)) >> 8);
addbyte(0xdc); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
addbyte(0xdf); /*FSTSW AX*/
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
addbyte((C0|C2|C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
addbyte(0x5d);
addbyte(cpu_state_offset(npxs) + 1);
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2812,7 +3273,41 @@ static void FP_COMPARE_D()
addbyte(0x5d);
addbyte(cpu_state_offset(npxs) + 1);
}
}
static void FP_COMPARE_IW()
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x66); /*MOV [ESP], AX*/
addbyte(0x89);
addbyte(0x04);
addbyte(0x24);
addbyte(0xdd); /*FLD ST[0][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
addbyte(0x8a); /*MOV BL, [npxs+1]*/
addbyte(0x5d);
addbyte(cpu_state_offset(npxs) + 1);
addbyte(0xdb); /*FCLEX*/
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
addbyte((~(C0|C2|C3)) >> 8);
addbyte(0xde); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
addbyte(0xdf); /*FSTSW AX*/
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
addbyte((C0|C2|C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
addbyte(0x5d);
addbyte(cpu_state_offset(npxs) + 1);
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2846,7 +3341,40 @@ static void FP_COMPARE_IW()
addbyte(0x5d);
addbyte(cpu_state_offset(npxs) + 1);
}
}
static void FP_COMPARE_IL()
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x89); /*MOV [ESP], EAX*/
addbyte(0x04);
addbyte(0x24);
addbyte(0xdd); /*FLD ST[0][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
addbyte(0x8a); /*MOV BL, [npxs+1]*/
addbyte(0x5d);
addbyte(cpu_state_offset(npxs) + 1);
addbyte(0xdb); /*FCLEX*/
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
addbyte((~(C0|C2|C3)) >> 8);
addbyte(0xda); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
addbyte(0xdf); /*FSTSW AX*/
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
addbyte((C0|C2|C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
addbyte(0x5d);
addbyte(cpu_state_offset(npxs) + 1);
}
else
{
addbyte(0x8b); /*MOV EBX, TOP*/
addbyte(0x5d);
@@ -2880,14 +3408,31 @@ static void FP_COMPARE_IL()
addbyte(0x5d);
addbyte(cpu_state_offset(npxs) + 1);
}
}
static void FP_OP_REG(int op, int dst, int src)
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0xdd); /*FLD ST[dst][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(ST[(cpu_state.TOP + dst) & 7]));
addbyte(0xdc); /*FADD ST[src][EBP]*/
addbyte(0x45 | op);
addbyte(cpu_state_offset(ST[(cpu_state.TOP + src) & 7]));
addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/
addbyte(0x65);
addbyte(cpu_state_offset(tag[(cpu_state.TOP + dst) & 7]));
addbyte(~TAG_UINT64);
addbyte(0xdd); /*FSTP ST[dst][EBP]*/
addbyte(0x5d);
addbyte(cpu_state_offset(ST[(cpu_state.TOP + dst) & 7]));
}
else
{
addbyte(0x8b); /*MOV EAX, TOP*/
addbyte(0x45);
addbyte(cpu_state_offset(TOP));
// addbyte(0xbe); /*MOVL ESI, ST*/
// addlong((uintptr_t)cpu_state.ST);
addbyte(0x89); /*MOV EBX, EAX*/
addbyte(0xc3);
if (src || dst)
@@ -2941,14 +3486,42 @@ static void FP_OP_REG(int op, int dst, int src)
addbyte(cpu_state_offset(ST));
}
}
}
static void FP_COMPARE_REG(int dst, int src)
{
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
{
addbyte(0x8a); /*MOV CL, [npxs+1]*/
addbyte(0x4d);
addbyte(cpu_state_offset(npxs) + 1);
addbyte(0xdb); /*FCLEX*/
addbyte(0xe2);
addbyte(0xdd); /*FLD ST[dst][EBP]*/
addbyte(0x45);
addbyte(cpu_state_offset(ST[(cpu_state.TOP + dst) & 7]));
addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/
addbyte(0xe1);
addbyte((~(C0|C2|C3)) >> 8);
addbyte(0xdc); /*FCOMP ST[src][EBP]*/
addbyte(0x5d);
addbyte(cpu_state_offset(ST[(cpu_state.TOP + src) & 7]));
addbyte(0xdf); /*FSTSW AX*/
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
addbyte((C0|C2|C3) >> 8);
addbyte(0x08); /*OR CL, AH*/
addbyte(0xe1);
addbyte(0x88); /*MOV [npxs+1], CL*/
addbyte(0x4d);
addbyte(cpu_state_offset(npxs) + 1);
}
else
{
addbyte(0x8b); /*MOV EAX, TOP*/
addbyte(0x45);
addbyte(cpu_state_offset(TOP));
// addbyte(0xbe); /*MOVL ESI, ST*/
// addlong((uintptr_t)cpu_state.ST);
addbyte(0x89); /*MOV EBX, EAX*/
addbyte(0xc3);
if (src || dst)
@@ -3004,6 +3577,7 @@ static void FP_COMPARE_REG(int dst, int src)
addbyte(0x4d);
addbyte(cpu_state_offset(npxs) + 1);
}
}
static int ZERO_EXTEND_W_B(int reg)
{

View File

@@ -281,6 +281,7 @@ void codegen_block_init(uint32_t phys_addr)
block->next = block->prev = NULL;
block->next_2 = block->prev_2 = NULL;
block->page_mask = 0;
block->flags = 0;
block->was_recompiled = 0;
@@ -1005,6 +1006,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xd9:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
@@ -1013,6 +1015,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xda:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
@@ -1021,6 +1024,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdb:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
@@ -1029,6 +1033,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdc:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
@@ -1038,6 +1043,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdd:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
@@ -1046,6 +1052,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xde:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
@@ -1054,6 +1061,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdf:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
@@ -1062,6 +1070,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xf0: /*LOCK*/

View File

@@ -281,6 +281,7 @@ void codegen_block_init(uint32_t phys_addr)
block->next = block->prev = NULL;
block->next_2 = block->prev_2 = NULL;
block->page_mask = 0;
block->flags = CODEBLOCK_STATIC_TOP;
block->was_recompiled = 0;
@@ -359,6 +360,7 @@ void codegen_block_start_recompile(codeblock_t *block)
_ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1;
block->TOP = cpu_state.TOP;
block->was_recompiled = 1;
}
@@ -484,6 +486,9 @@ void codegen_block_end_recompile(codeblock_t *block)
codegen_block_generate_end_mask();
add_to_block_list(block);
// pclog("End block %i\n", block_num);
if (!(block->flags & CODEBLOCK_HAS_FPU))
block->flags &= ~CODEBLOCK_STATIC_TOP;
}
void codegen_flush()
@@ -821,6 +826,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xd9:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
@@ -829,6 +835,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xda:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
@@ -837,6 +844,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdb:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
@@ -845,6 +853,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdc:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
@@ -854,6 +863,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdd:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
@@ -862,6 +872,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xde:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
@@ -870,6 +881,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdf:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
@@ -878,6 +890,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
over = 1;
pc_off = -1;
test_modrm = 0;
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xf0: /*LOCK*/

View File

@@ -88,8 +88,12 @@ static struct
crc_t track_crc;
uint8_t track_byte;
uint8_t track_index;
uint8_t track_fuzzy;
uint8_t track_data_byte;
uint8_t old_track_byte;
uint8_t old_track_index;
uint8_t old_track_fuzzy;
uint8_t old_track_data_byte;
uint8_t cur_track;
uint8_t side_flag_bytes;
} d86f[2];
@@ -857,6 +861,15 @@ int d86f_can_read_address(int drive)
return temp;
}
int d86f_should_write_am(int drive)
{
int temp;
temp = (d86f[drive].state == STATE_WRITE_FIND_SECTOR);
temp = temp && (d86f[drive].req_sector.dword == d86f[drive].last_sector.dword);
temp = temp && d86f_can_read_address(drive);
return temp;
}
int d86f_can_format(int drive)
{
int temp;
@@ -943,20 +956,19 @@ void d86f_poll_write_crc(int drive, int side)
{
if (d86f[drive].state != STATE_FORMAT) return;
d86f[drive].id_pos = d86f[drive].track_pos - d86f[drive].section_pos;
if (d86f[drive].id_pos)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].calc_crc.bytes[1];
}
else
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].calc_crc.bytes[0];
}
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = d86f[drive].calc_crc.bytes[d86f[drive].id_pos ^ 1];
}
void d86f_poll_advancebyte(int drive, int side)
{
d86f[drive].old_track_byte = d86f[drive].track_byte;
d86f[drive].old_track_index = d86f[drive].track_index;
d86f[drive].old_track_data_byte = d86f[drive].track_data_byte;
if (d86f[drive].version == 0x0114)
{
d86f[drive].old_track_fuzzy = d86f[drive].track_fuzzy;
}
d86f[drive].track_pos++;
d86f[drive].track_pos %= d86f_get_raw_size(drive);
@@ -965,11 +977,22 @@ void d86f_poll_advancebyte(int drive, int side)
{
d86f[drive].track_byte = d86f[drive].track_layout[side][d86f[drive].track_pos] & ~BYTE_INDEX_HOLE;
d86f[drive].track_index = d86f[drive].track_layout[side][d86f[drive].track_pos] & BYTE_INDEX_HOLE;
d86f[drive].track_data_byte = d86f[drive].track_data[side][d86f[drive].track_pos];
}
else if (d86f[drive].version == 0x0114)
{
d86f[drive].track_byte = d86f[drive].track_layout[side][d86f[drive].track_pos] & ~BYTE_IS_FUZZY;
d86f[drive].track_index = (d86f[drive].track_pos == d86f[drive].index_hole_pos[side]);
d86f[drive].track_fuzzy = d86f[drive].track_layout[side][d86f[drive].track_pos] & BYTE_IS_FUZZY;
if (d86f[drive].track_fuzzy)
{
d86f[drive].track_data_byte = disc_random_generate();
}
else
{
d86f[drive].track_data_byte = d86f[drive].track_data[side][d86f[drive].track_pos];
}
}
}
@@ -1006,16 +1029,6 @@ void d86f_poll_finish(int drive, int side)
d86f[drive].last_sector.dword = 0xFFFFFFFF;
}
uint8_t d86f_poll_data(int drive, int side)
{
uint8_t ret = d86f[drive].track_data[side][d86f[drive].track_pos];
if ((d86f[drive].version == 0x0114) && (d86f[drive].track_layout[side][d86f[drive].track_pos] & BYTE_IS_FUZZY))
{
ret = disc_random_generate();
}
return ret;
}
int d86f_mark_index_hole(int drive)
{
int temp = (d86f[drive].version == 0x0100);
@@ -1023,6 +1036,13 @@ int d86f_mark_index_hole(int drive)
return temp;
}
void d86f_poll_write(int drive, int side, uint8_t data, uint8_t type)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = data;
d86f[drive].track_layout[side][d86f[drive].track_pos] = type;
if (!d86f[drive].track_pos && d86f_mark_index_hole(drive)) d86f[drive].track_layout[side][d86f[drive].track_pos] |= BYTE_INDEX_HOLE;
}
void d86f_poll_readwrite(int drive, int side)
{
int data;
@@ -1031,7 +1051,7 @@ void d86f_poll_readwrite(int drive, int side)
if (d86f_read_state_data(drive))
{
max_len = d86f_data_size(drive);
data = d86f_poll_data(drive, side);
data = d86f[drive].track_data_byte;
if (d86f[drive].datac < d86f_get_data_len(drive))
{
fdc_data(data);
@@ -1055,25 +1075,21 @@ void d86f_poll_readwrite(int drive, int side)
}
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = data;
d86f[drive].track_layout[side][d86f[drive].track_pos] = BYTE_DATA;
if (!d86f[drive].track_pos && d86f_mark_index_hole(drive)) d86f[drive].track_layout[side][d86f[drive].track_pos] |= BYTE_INDEX_HOLE;
d86f_poll_write(drive, side, data, BYTE_DATA);
}
d86f_calccrc(drive, d86f[drive].track_data[side][d86f[drive].track_pos]);
d86f_calccrc(drive, d86f[drive].track_data_byte);
}
else if (d86f_read_state_crc(drive))
{
max_len = 2;
d86f[drive].track_crc.bytes[d86f[drive].datac] = d86f_poll_data(drive, side);
d86f[drive].track_crc.bytes[d86f[drive].datac ^ 1] = d86f[drive].track_data_byte;
}
else if (d86f[drive].state == STATE_WRITE_SECTOR_CRC)
{
max_len = 2;
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].calc_crc.bytes[d86f[drive].datac];
d86f[drive].track_layout[side][d86f[drive].track_pos] = BYTE_DATA_CRC;
if (!d86f[drive].track_pos) d86f[drive].track_layout[side][d86f[drive].track_pos] |= BYTE_INDEX_HOLE;
d86f_poll_write(drive, side, d86f[drive].calc_crc.bytes[d86f[drive].datac ^ 1], BYTE_DATA_CRC);
}
}
else if (d86f_read_state_gap3(drive))
@@ -1084,6 +1100,7 @@ void d86f_poll_readwrite(int drive, int side)
d86f_poll_finish(drive, side);
if (d86f[drive].track_crc.word != d86f[drive].calc_crc.word)
{
// pclog("d86f_poll(): Data CRC error (%i %i %i %i) (%04X %04X)\n", d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n, d86f[drive].track_crc.word, d86f[drive].calc_crc.word);
fdc_finishread();
fdc_datacrcerror();
}
@@ -1099,7 +1116,11 @@ void d86f_poll_readwrite(int drive, int side)
max_len = fdc_get_gap();
if (d86f[drive].datac == (fdc_get_gap() - 1))
{
if (!disable_write) d86f_writeback(drive);
if (!disable_write)
{
d86f_poll_write(drive, side, fdc_is_mfm() ? 0x4E : 0xFF, BYTE_GAP3);
d86f_writeback(drive);
}
d86f_poll_finish(drive, side);
fdc_sector_finishread(drive);
return;
@@ -1108,9 +1129,7 @@ void d86f_poll_readwrite(int drive, int side)
{
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = fdc_is_mfm() ? 0x4E : 0xFF;
d86f[drive].track_layout[side][d86f[drive].track_pos] = BYTE_GAP3;
if (!d86f[drive].track_pos) d86f[drive].track_layout[side][d86f[drive].track_pos] |= BYTE_INDEX_HOLE;
d86f_poll_write(drive, side, fdc_is_mfm() ? 0x4E : 0xFF, BYTE_GAP3);
}
}
}
@@ -1138,35 +1157,38 @@ void d86f_poll_find_nf(int drive, int side)
switch(d86f[drive].track_byte)
{
case BYTE_IDAM:
d86f[drive].calc_crc.word = fdc_is_mfm() ? 0xcdb4 : 0xffff;
// pclog("CRC reset: %02X\n", d86f[drive].track_byte);
d86f_calccrc(drive, d86f_poll_data(drive, side));
case BYTE_DATAAM_SYNC:
if (d86f_should_write_am(drive))
{
d86f_poll_write(drive, side, 0xA1, BYTE_DATAAM_SYNC);
}
case BYTE_IDAM_SYNC:
if (d86f_is_mfm(drive))
{
d86f_calccrc(drive, d86f[drive].track_data_byte);
}
break;
case BYTE_DATAAM:
d86f[drive].calc_crc.word = fdc_is_mfm() ? 0xcdb4 : 0xffff;
// pclog("CRC reset: %02X\n", d86f[drive].track_byte);
if (d86f_should_write_am(drive))
{
d86f_poll_write(drive, side, 0xFB, BYTE_DATAAM);
}
if ((d86f[drive].state == STATE_WRITE_FIND_SECTOR) && (d86f[drive].req_sector.dword == d86f[drive].last_sector.dword) && d86f_can_read_address(drive))
{
d86f[drive].track_data[side][d86f[drive].track_pos] = 0xFB;
if (d86f[drive].version == 0x0114)
{
d86f[drive].track_layout[side][d86f[drive].track_pos] &= ~BYTE_IS_FUZZY;
}
}
d86f_calccrc(drive, d86f_poll_data(drive, side));
case BYTE_IDAM:
d86f_calccrc(drive, d86f[drive].track_data_byte);
break;
case BYTE_ID:
d86f[drive].id_pos = d86f[drive].track_pos - d86f[drive].section_pos;
data = d86f_poll_data(drive, side);
data = d86f[drive].track_data_byte;
d86f[drive].rw_sector_id.byte_array[d86f[drive].id_pos] = data;
d86f_calccrc(drive, data);
break;
case BYTE_ID_CRC:
d86f[drive].id_pos = d86f[drive].track_pos - d86f[drive].section_pos;
d86f[drive].track_crc.bytes[d86f[drive].id_pos] = d86f_poll_data(drive, side);
d86f[drive].track_crc.bytes[d86f[drive].id_pos ^ 1] = d86f[drive].track_data_byte;
break;
}
@@ -1180,20 +1202,37 @@ void d86f_poll_find_nf(int drive, int side)
switch(d86f[drive].track_byte)
{
case BYTE_IDAM_SYNC:
case BYTE_DATAAM_SYNC:
if (d86f_is_mfm(drive))
{
d86f[drive].calc_crc.word = 0xffff;
}
break;
case BYTE_IDAM:
case BYTE_DATAAM:
if (!d86f_is_mfm(drive))
{
d86f[drive].calc_crc.word = 0xffff;
}
break;
case BYTE_GAP2:
if (d86f_can_read_address(drive))
{
if (((d86f[drive].req_sector.dword == d86f[drive].rw_sector_id.dword) || (d86f[drive].state == STATE_READ_FIND_ADDRESS)) && d86f_can_read_address(drive))
if ((d86f[drive].req_sector.dword == d86f[drive].rw_sector_id.dword) || (d86f[drive].state == STATE_READ_FIND_ADDRESS))
{
if (d86f[drive].track_crc.word != d86f[drive].calc_crc.word)
{
// pclog("d86f_poll(): Header CRC error (%i %i %i %i)\n", d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n);
if (d86f[drive].state != STATE_READ_FIND_ADDRESS)
{
// pclog("d86f_poll(): Header CRC error (%i %i %i %i) (%04X %04X)\n", d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n, d86f[drive].track_crc.word, d86f[drive].calc_crc.word);
fdc_finishread();
fdc_headercrcerror();
d86f[drive].state = STATE_IDLE;
d86f[drive].index_count = 0;
return;
}
}
else
{
d86f[drive].last_sector.dword = d86f[drive].rw_sector_id.dword;
@@ -1203,7 +1242,7 @@ void d86f_poll_find_nf(int drive, int side)
if ((d86f[drive].state == STATE_READ_FIND_ADDRESS) && (d86f[drive].last_sector.dword != 0xFFFFFFFF))
{
// pclog("Reading sector ID...\n");
// pclog("Reading sector ID (%i %i %i %i)...\n", d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n);
fdc_sectorid(d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n, 0, 0);
d86f[drive].state = STATE_IDLE;
d86f[drive].index_count = 0;
@@ -1240,49 +1279,29 @@ void d86f_poll_find_format(int drive, int side)
{
if (!(d86f_can_format(drive)))
{
if (d86f_can_read_address(drive))
{
// pclog("d86f_poll(): Disk is write protected or attempting to format wrong number of sectors per track\n");
fdc_writeprotect();
}
else
{
// pclog("d86f_poll(): Unable to format at the requested density or bitcell period\n");
fdc_notfound();
}
d86f_poll_reset(drive, side);
d86f_poll_advancebyte(drive, side);
return;
}
if (d86f[drive].track_index && d86f_can_read_address(drive))
{
// pclog("Index hole hit, formatting track...\n");
d86f[drive].state = STATE_FORMAT;
d86f_poll_advancebyte(drive, side);
return;
}
d86f_poll_advancebyte(drive, side);
if (d86f_poll_check_notfound(drive)) return;
if (d86f[drive].track_index)
{
// pclog("Index hole hit, formatting track...\n");
d86f[drive].state = STATE_FORMAT;
// d86f_poll_advancebyte(drive, side);
return;
}
}
void d86f_poll_format(int drive, int side)
{
int data;
if (d86f[drive].track_index)
{
// pclog("Index hole hit again, format finished\n");
d86f[drive].state = STATE_IDLE;
if (!disable_write) d86f_writeback(drive);
fdc_sector_finishread(drive);
d86f[drive].index_count = 0;
d86f_poll_advancebyte(drive, side);
return;
}
switch(d86f[drive].track_byte)
{
case BYTE_GAP0:
@@ -1290,74 +1309,103 @@ void d86f_poll_format(int drive, int side)
case BYTE_GAP2:
case BYTE_GAP3:
case BYTE_GAP4:
if (!disable_write) d86f[drive].track_data[side][d86f[drive].track_pos] = fdc_is_mfm() ? 0x4E : 0xFF;
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = fdc_is_mfm() ? 0x4E : 0xFF;
}
break;
case BYTE_IAM_SYNC:
if (!disable_write) d86f[drive].track_data[side][d86f[drive].track_pos] = 0xC2;
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = 0xC2;
}
break;
case BYTE_IAM:
if (!disable_write) d86f[drive].track_data[side][d86f[drive].track_pos] = 0xFC;
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = 0xFC;
}
break;
case BYTE_ID_SYNC:
d86f[drive].id_pos = d86f[drive].track_pos - d86f[drive].section_pos;
if (!disable_write) d86f[drive].track_data[side][d86f[drive].track_pos] = 0;
if (d86f[drive].id_pos > 3) break;
if (d86f[drive].id_pos > 3)
{
break;
}
data = fdc_getdata(0);
if ((data == -1) && (d86f[drive].id_pos < 3))
{
data = 0;
}
d86f[drive].format_sector_id.byte_array[d86f[drive].id_pos] = data & 0xff;
d86f_calccrc(drive, d86f[drive].format_sector_id.byte_array[d86f[drive].id_pos]);
// pclog("format_sector_id[%i] = %i\n", cur_id_pos, d86f[drive].format_sector_id.byte_array[d86f[drive].id_pos]);
if (d86f[drive].id_pos == 3)
{
fdc_stop_id_request();
// pclog("Formatting sector: %08X...\n", d86f[drive].format_sector_id.dword);
}
break;
case BYTE_I_SYNC:
case BYTE_DATA_SYNC:
if (!disable_write) d86f[drive].track_data[side][d86f[drive].track_pos] = 0;
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = 0;
}
break;
case BYTE_IDAM_SYNC:
case BYTE_DATAAM_SYNC:
if (!disable_write) d86f[drive].track_data[side][d86f[drive].track_pos] = 0xA1;
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = 0xA1;
}
if (d86f_is_mfm(drive))
{
d86f_calccrc(drive, d86f[drive].track_data_byte);
}
break;
case BYTE_IDAM:
case BYTE_DATAAM:
d86f[drive].calc_crc.word = fdc_is_mfm() ? 0xcdb4 : 0xffff;
// pclog("CRC reset: %02X\n", d86f[drive].track_byte);
if (!disable_write) d86f[drive].track_data[side][d86f[drive].track_pos] = (d86f[drive].track_byte == BYTE_IDAM) ? 0xFE : 0xFB;
d86f_calccrc(drive, d86f[drive].track_data[side][d86f[drive].track_pos]);
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = (d86f[drive].track_byte == BYTE_IDAM) ? 0xFE : 0xFB;
}
d86f_calccrc(drive, d86f[drive].track_data_byte);
break;
case BYTE_ID:
d86f[drive].id_pos = d86f[drive].track_pos - d86f[drive].section_pos;
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].format_sector_id.byte_array[d86f[drive].id_pos];
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = d86f[drive].format_sector_id.byte_array[d86f[drive].id_pos];
}
d86f_calccrc(drive, d86f[drive].track_data[side][d86f[drive].track_pos]);
d86f_calccrc(drive, d86f[drive].track_data_byte);
break;
case BYTE_DATA:
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].fill;
d86f_calccrc(drive, d86f[drive].fill);
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = d86f[drive].fill;
}
d86f_calccrc(drive, d86f[drive].track_data_byte);
break;
case BYTE_ID_CRC:
d86f_poll_write_crc(drive, side);
break;
case BYTE_DATA_CRC:
d86f[drive].id_pos = d86f[drive].track_pos - d86f[drive].section_pos;
d86f_poll_write_crc(drive, side);
break;
}
d86f_poll_advancebyte(drive, side);
if (d86f[drive].track_index)
{
// pclog("Index hole hit again, format finished\n");
d86f[drive].state = STATE_IDLE;
if (!disable_write) d86f_writeback(drive);
fdc_sector_finishread(drive);
d86f[drive].index_count = 0;
// d86f_poll_advancebyte(drive, side);
return;
}
if (d86f[drive].track_byte != d86f[drive].old_track_byte)
{
// pclog("Track byte: %02X, old: %02X\n", track_byte, old_track_byte);
@@ -1365,6 +1413,20 @@ void d86f_poll_format(int drive, int side)
switch(d86f[drive].track_byte & ~BYTE_INDEX_HOLE)
{
case BYTE_IDAM:
case BYTE_DATAAM:
if (!d86f_is_mfm(drive))
{
d86f[drive].calc_crc.word = 0xffff;
}
break;
case BYTE_IDAM_SYNC:
case BYTE_DATAAM_SYNC:
if (d86f_is_mfm(drive))
{
d86f[drive].calc_crc.word = 0xffff;
}
break;
case BYTE_ID_SYNC:
// pclog("Requesting next sector ID...\n");
fdc_request_next_sector_id();

202
src/fdc.c
View File

@@ -70,6 +70,8 @@ typedef struct FDC
int gap, dtl;
int format_sectors;
int max_track;
} FDC;
static FDC fdc;
@@ -248,12 +250,24 @@ static void fdc_watchdog_poll(void *p)
int bit_rate = 250;
static void fdc_rate(int drive);
void fdc_update_is_nsc(int is_nsc)
{
int old_is_nsc = fdc.is_nsc;
fdc.is_nsc = is_nsc;
if (old_is_nsc != is_nsc)
{
fdc.densel_force = fdc.densel_force ^ 3;
}
fdc_rate(0);
fdc_rate(1);
}
static void fdc_rate(int drive);
void fdc_update_max_track(int max_track)
{
fdc.max_track = max_track;
}
void fdc_update_enh_mode(int enh_mode)
{
@@ -291,6 +305,11 @@ void fdc_update_densel_polarity(int densel_polarity)
fdc_rate(1);
}
uint8_t fdc_get_densel_polarity()
{
return fdc.densel_polarity;
}
void fdc_update_densel_force(int densel_force)
{
fdc.densel_force = densel_force;
@@ -774,9 +793,14 @@ bad_command:
fdc_notfound();
else
{
fdc_seek(fdc.drive, -79);
fdc_seek(fdc.drive, -fdc.max_track);
}
disctime = fdc.max_track * 10 * TIMER_USEC;
fdc.st0 &= 0x30;
if (!fdd_track0(fdc.drive))
{
fdc.st0 |= 0x30;
}
disctime = 790 * TIMER_USEC;
break;
case 0x0d: /*Format*/
@@ -815,6 +839,7 @@ bad_command:
fdc_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
}
disctime = 790 * TIMER_USEC;
fdc.st0 &= 0x30;
break;
case 10: /*Read sector ID*/
@@ -952,6 +977,37 @@ uint8_t fdc_read(uint16_t addr, void *priv)
return temp;
}
void fdc_poll_readwrite_finish()
{
fdc.inread = 0;
discint=-2;
fdc_int();
fdc.stat=0xD0;
fdc.res[4]=(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=fdc.res[6]=0;
fdc.res[7]=fdc.rw_track;
fdc.res[8]=fdc.head;
fdc.res[9]=fdc.sector;
fdc.res[10]=fdc.params[4];
paramstogo=7;
}
void fdc_no_dma_end()
{
disctime = 0;
fdc_int();
fdc.stat=0xD0;
fdc.res[4]=0x40|(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=0x80; /*NDE (No DMA End)*/
fdc.res[6]=0;
fdc.res[7]=fdc.rw_track;
fdc.res[8]=fdc.head;
fdc.res[9]=fdc.sector;
fdc.res[10]=fdc.params[4];
paramstogo=7;
}
void fdc_callback()
{
int temp;
@@ -984,18 +1040,7 @@ void fdc_callback()
// pclog("Read a track callback, eot=%i\n", fdc.eot[fdc.drive]);
if (!fdc.eot[fdc.drive] || fdc.tc)
{
// pclog("Complete\n");
fdc.inread = 0;
discint=-2;
fdc_int();
fdc.stat=0xD0;
fdc.res[4]=(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=fdc.res[6]=0;
fdc.res[7]=fdc.rw_track;
fdc.res[8]=fdc.head;
fdc.res[9]=fdc.sector;
fdc.res[10]=fdc.params[4];
paramstogo=7;
fdc_poll_readwrite_finish();
return;
}
else
@@ -1018,95 +1063,54 @@ void fdc_callback()
disctime = 0;
return;
case 5: /*Write data*/
readflash = 1;
fdc.sector++;
if (fdc.sector > fdc.params[5])
{
fdc.sector = 1;
if (fdc.command & 0x80)
{
fdc.head ^= 1;
fdd_set_head(fdc.drive, fdd_get_head(fdc.drive ^ fdd_swap) ^ 1);
if (!fdc.head)
{
fdc.rw_track++;
// fdc.track[fdc.drive]++;
/* if (fdc.track[fdc.drive] >= 79)
{
fdc.track[fdc.drive] = 79;
fdc.tc = 1;
}*/
}
}
else
{
fdc.rw_track++;
// fdc.track[fdc.drive]++;
fdc.tc = 1;
}
}
if (fdc.tc)
{
discint=-2;
fdc_int();
fdc.stat=0xD0;
fdc.res[4]=(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=fdc.res[6]=0;
fdc.res[7]=fdc.rw_track;
fdc.res[8]=fdc.head;
fdc.res[9]=fdc.sector;
fdc.res[10]=fdc.params[4];
paramstogo=7;
return;
}
disc_writesector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
// ioc_fiq(IOC_FIQ_DISC_DATA);
return;
case 6: /*Read data*/
// rpclog("Read data %i\n", fdc.tc);
readflash = 1;
fdc.sector++;
if (fdc.sector > fdc.params[5])
{
fdc.sector = 1;
if (fdc.command & 0x80)
{
fdc.head ^= 1;
fdd_set_head(fdc.drive, fdd_get_head(fdc.drive ^ fdd_swap) ^ 1);
if (!fdc.head)
{
fdc.rw_track++;
// fdc.track[fdc.drive]++;
/* if (fdc.track[fdc.drive] >= 79)
{
fdc.track[fdc.drive] = 79;
fdc.tc = 1;
}*/
}
}
else
{
fdc.rw_track++;
// fdc.track[fdc.drive]++;
fdc.tc = 1;
}
}
if (fdc.tc)
{
fdc.inread = 0;
discint=-2;
fdc_int();
fdc.stat=0xD0;
fdc.res[4]=(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=fdc.res[6]=0;
fdc.res[7]=fdc.rw_track;
fdc.res[8]=fdc.head;
fdc.res[9]=fdc.sector;
fdc.res[10]=fdc.params[4];
paramstogo=7;
fdc_poll_readwrite_finish();
return;
}
readflash = 1;
if (fdc.sector == fdc.params[5])
{
/* Reached end of track, MT bit is clear */
if (!(fdc.command & 0x80))
{
fdc.rw_track++;
fdc.sector = 1;
fdc_no_dma_end();
return;
}
/* Reached end of track, MT bit is set, head is 1 */
if ((fdc.head & 1))
{
fdc.rw_track++;
fdc.sector = 1;
fdc.head &= 0xFE;
fdd_set_head(fdc.drive, 0);
fdc_no_dma_end();
return;
}
if ((fdc.command & 0x80) && (fdd_get_head(fdc.drive ^ fdd_swap) == 0))
{
fdc.sector = 1;
fdc.head |= 1;
fdd_set_head(fdc.drive, 1);
}
}
else if (fdc.sector < fdc.params[5])
{
fdc.sector++;
}
switch (discint)
{
case 5:
disc_writesector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
break;
case 6:
disc_readsector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
break;
}
fdc.inread = 1;
return;
@@ -1275,7 +1279,7 @@ void fdc_callback()
void fdc_overrun()
{
disc_sector_stop(fdc.drive ^ fdd_swap);
disc_stop(fdc.drive);
disctime = 0;
fdc_int();
@@ -1528,6 +1532,7 @@ void fdc_add()
io_sethandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL);
fdc.pcjr = 0;
fdc.ps1 = 0;
fdc.max_track = 79;
}
void fdc_add_for_superio()
@@ -1544,6 +1549,7 @@ void fdc_add_pcjr()
timer_add(fdc_watchdog_poll, &fdc.watchdog_timer, &fdc.watchdog_timer, &fdc);
fdc.pcjr = 1;
fdc.ps1 = 0;
fdc.max_track = 79;
}
void fdc_remove()

View File

@@ -19,12 +19,14 @@ int fdc_get_bitcell_period();
/* A few functions to communicate between Super I/O chips and the FDC. */
void fdc_update_is_nsc(int is_nsc);
void fdc_update_max_track(int max_track);
void fdc_update_enh_mode(int enh_mode);
int fdc_get_rwc(int drive);
void fdc_update_rwc(int drive, int rwc);
int fdc_get_boot_drive();
void fdc_update_boot_drive(int boot_drive);
void fdc_update_densel_polarity(int densel_polarity);
uint8_t fdc_get_densel_polarity();
void fdc_update_densel_force(int densel_force);
void fdc_update_drvrate(int drive, int drvrate);
void fdc_update_drv2en(int drv2en);

View File

@@ -39,11 +39,6 @@ static struct
#define FLAG_HOLE2 32
#define FLAG_DOUBLE_STEP 64
#define FLAGS_RPM_NONE 0
#define FLAGS_RPM_300_ONLY 1
#define FLAGS_RPM_360_ONLY 2
#define FLAGS_RPM_BOTH 3
static struct
{
int max_track;
@@ -81,10 +76,6 @@ static struct
{ /*3.5" ED*/
.max_track = 86,
.flags = FLAG_RPM_300 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2
},
{ /*3.5" ED 3-Mode*/
.max_track = 86,
.flags = FLAG_RPM_300| FLAG_RPM_360 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2
}
};
@@ -92,11 +83,12 @@ int fdd_swap = 0;
void fdd_seek(int drive, int track_diff)
{
int old_track;
drive ^= fdd_swap;
old_track = fdd[drive].track;
if (!track_diff)
{
return;
}
fdd[drive].track += track_diff;
@@ -127,36 +119,23 @@ void fdd_set_densel(int densel)
fdd[1].densel = densel;
}
int fdd_get_flags(int drive)
{
return drive_types[fdd[drive].type].flags;
}
int fdd_getrpm(int drive)
{
int hole = disc_hole(drive);
int flags = 0;
drive ^= fdd_swap;
flags = fdd_get_flags(drive);
if ((flags & 3) == FLAGS_RPM_300_ONLY)
{
return 300;
}
else if ((flags & 3) == FLAGS_RPM_360_ONLY)
{
return 360;
}
if (!(drive_types[fdd[drive].type].flags & FLAG_RPM_360)) return 300;
if (!(drive_types[fdd[drive].type].flags & FLAG_RPM_300)) return 360;
if (flags & FLAG_525)
if (drive_types[fdd[drive].type].flags & FLAG_525)
{
return fdd[drive].densel ? 360 : 300;
}
else
{
/* disc_hole(drive) returns 0 for double density media, 1 for high density, and 2 for extended density. */
if (hole >= 1)
if (hole == 1)
{
return fdd[drive].densel ? 300 : 360;
}
@@ -199,6 +178,11 @@ int fdd_get_type(int drive)
return fdd[drive].type;
}
int fdd_get_flags(int drive)
{
return drive_types[fdd[drive].type].flags;
}
int fdd_is_525(int drive)
{
return drive_types[fdd[drive].type].flags & FLAG_525;

View File

@@ -112,22 +112,25 @@ void i440fx_init()
card_i440fx[0x00] = 0x86; card_i440fx[0x01] = 0x80; /*Intel*/
card_i440fx[0x02] = 0x37; card_i440fx[0x03] = 0x12; /*82441FX*/
card_i440fx[0x04] = 0x03; card_i440fx[0x05] = 0x01;
card_i440fx[0x06] = 0x00; card_i440fx[0x07] = 0x00;
card_i440fx[0x06] = 0x80; card_i440fx[0x07] = 0x00;
card_i440fx[0x08] = 0x02; /*A0 stepping*/
card_i440fx[0x09] = 0x00; card_i440fx[0x0a] = 0x00; card_i440fx[0x0b] = 0x06;
card_i440fx[0x0d] = 0x00;
card_i440fx[0x0f] = 0x00;
card_i440fx[0x2c] = 0xf4;
card_i440fx[0x2d] = 0x1a;
card_i440fx[0x2e] = 0x00;
card_i440fx[0x2f] = 0x11;
// card_i440fx[0x53] = 0x80;
// card_i440fx[0x55] = 0x11;
card_i440fx[0x57] = 0x10;
card_i440fx[0x58] = 0x00;
card_i440fx[0x59] = 0x10;
card_i440fx[0x50] = 0x00;
card_i440fx[0x51] = 0x01;
card_i440fx[0x52] = card_i440fx[0x54] = card_i440fx[0x55] = card_i440fx[0x56] = 0x00;
card_i440fx[0x53] = 0x80;
card_i440fx[0x57] = 0x01;
card_i440fx[0x58] = 0x10;
card_i440fx[0x5a] = card_i440fx[0x5b] = card_i440fx[0x5c] = card_i440fx[0x5d] = card_i440fx[0x5e] = 0x11;
card_i440fx[0x5f] = 0x31;
// card_i440fx[0x60] = card_i440fx[0x61] = card_i440fx[0x62] = card_i440fx[0x63] = card_i440fx[0x64] = card_i440fx[0x65] = card_i440fx[0x66] = card_i440fx[0x67] = 0x02;
// card_i440fx[0x70] = 0x20;
// card_i440fx[0x71] = 0x10;
card_i440fx[0x72] = 0x0A;
card_i440fx[0x72] = 0x02;
}

View File

@@ -413,6 +413,9 @@ enum
ROM_440FX, /*Unknown / 440FX / Award BIOS / SMC FDC37C665*/
ROM_KN97, /*ASUS KN-97 / 440FX / Award BIOS / Winbond W8387F*/
ROM_MARL, /*Intel Advanced/ML / 430HX / AMI BIOS / National Semiconductors PC87306*/
ROM_THOR, /*Intel Advanced/ATX / 430FX / AMI BIOS / National Semiconductors PC87306*/
ROM_MAX
};

View File

@@ -6,6 +6,7 @@
#include "device.h"
#include "mem.h"
#define FLASH_ALLOW_16 4
#define FLASH_IS_BXB 2
#define FLASH_INVERT 1
@@ -23,7 +24,8 @@ enum
CMD_ERASE_SETUP = 0x20,
CMD_ERASE_CONFIRM = 0xd0,
CMD_ERASE_SUSPEND = 0xb0,
CMD_PROGRAM_SETUP = 0x40
CMD_PROGRAM_SETUP = 0x40,
CMD_PROGRAM_SETUP2 = 0x10
};
typedef struct flash_t
@@ -32,6 +34,7 @@ typedef struct flash_t
uint32_t flash_id;
uint8_t type; /* 0 = BXT, 1 = BXB */
uint8_t invert_high_pin; /* 0 = no, 1 = yes */
uint8_t allow_word_write; /* 0 = no, 1 = yes */
mem_mapping_t mapping[8], mapping_h[8];
uint32_t block_start[4], block_end[4], block_len[4];
uint8_t array[131072];
@@ -68,11 +71,36 @@ static uint8_t flash_read(uint32_t addr, void *p)
static uint16_t flash_readw(uint32_t addr, void *p)
{
// pclog("flash_readw(%08X)\n", addr);
flash_t *flash = (flash_t *)p;
if (!flash->allow_word_write)
{
addr &= 0x1ffff;
if (flash->invert_high_pin) addr ^= 0x10000;
return *(uint16_t *)&(flash->array[addr]);
}
if (flash->invert_high_pin)
{
addr ^= 0x10000;
if (addr & 0xfff00000) *(uint16_t *)&(flash->array[addr & 0x1ffff]);
}
addr &= 0x1ffff;
switch (flash->command)
{
case CMD_READ_ARRAY:
default:
return *(uint16_t *)&(flash->array[addr]);
case CMD_IID:
// pclog("Flash Read ID 16: %08X\n", addr);
if (addr & 1)
return 0x2274;
return 0x89;
case CMD_READ_STATUS:
return flash->status;
}
}
static uint32_t flash_readl(uint32_t addr, void *p)
{
@@ -100,7 +128,7 @@ static void flash_write(uint32_t addr, uint8_t val, void *p)
case CMD_ERASE_SETUP:
if (val == CMD_ERASE_CONFIRM)
{
pclog("flash_write: erase %05x\n", addr);
// pclog("flash_write: erase %05x\n", addr);
for (i = 0; i < 3; i++)
{
@@ -114,7 +142,8 @@ static void flash_write(uint32_t addr, uint8_t val, void *p)
break;
case CMD_PROGRAM_SETUP:
pclog("flash_write: program %05x %02x\n", addr, val);
case CMD_PROGRAM_SETUP2:
// pclog("flash_write: program %05x %02x\n", addr, val);
if ((addr & 0x1e000) != (flash->block_start[3] & 0x1e000))
flash->array[addr] = val;
flash->command = CMD_READ_STATUS;
@@ -132,16 +161,75 @@ static void flash_write(uint32_t addr, uint8_t val, void *p)
}
}
static void flash_writew(uint32_t addr, uint16_t val, void *p)
{
flash_t *flash = (flash_t *)p;
int i;
// pclog("flash_writew : addr=%08x val=%02x command=%02x %04x:%08x\n", addr, val, flash->command, CS, cpu_state.pc);
if (flash->invert_high_pin)
{
addr ^= 0x10000;
if (addr & 0xfff00000) return;
}
addr &= 0x1ffff;
switch (flash->command)
{
case CMD_ERASE_SETUP:
if (val == CMD_ERASE_CONFIRM)
{
// pclog("flash_writew: erase %05x\n", addr);
for (i = 0; i < 3; i++)
{
if ((addr >= flash->block_start[i]) && (addr <= flash->block_end[i]))
memset(&(flash->array[flash->block_start[i]]), 0xff, flash->block_len[i]);
}
flash->status = 0x80;
}
flash->command = CMD_READ_STATUS;
break;
case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP2:
// pclog("flash_writew: program %05x %02x\n", addr, val);
if ((addr & 0x1e000) != (flash->block_start[3] & 0x1e000))
*(uint16_t *)&(flash->array[addr]) = val;
flash->command = CMD_READ_STATUS;
flash->status = 0x80;
break;
default:
flash->command = val;
switch (val)
{
case CMD_CLEAR_STATUS:
flash->status = 0;
break;
}
}
}
void intel_flash_add_mappings(flash_t *flash)
{
int i = 0;
for (i = 0; i <= 7; i++)
{
if (flash->allow_word_write)
{
mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, flash_writew, mem_write_nulll, flash->array + ((i << 14) & 0x1ffff), MEM_MAPPING_EXTERNAL, (void *)flash);
mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, flash_writew, mem_write_nulll, flash->array + ((i << 14) & 0x1ffff), 0, (void *)flash);
}
else
{
mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + ((i << 14) & 0x1ffff), MEM_MAPPING_EXTERNAL, (void *)flash);
mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + ((i << 14) & 0x1ffff), 0, (void *)flash);
}
}
}
/* This is for boards which invert the high pin - the flash->array pointers need to pointer invertedly in order for INTERNAL writes to go to the right part of the array. */
void intel_flash_add_mappings_inverted(flash_t *flash)
@@ -149,11 +237,19 @@ void intel_flash_add_mappings_inverted(flash_t *flash)
int i = 0;
for (i = 0; i <= 7; i++)
{
if (flash->allow_word_write)
{
mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, flash_writew, mem_write_nulll, flash->array + (((i << 14) ^ 0x10000) & 0x1ffff), MEM_MAPPING_EXTERNAL, (void *)flash);
mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, flash_writew, mem_write_nulll, flash->array + (((i << 14) ^ 0x10000) & 0x1ffff), 0, (void *)flash);
}
else
{
mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + (((i << 14) ^ 0x10000) & 0x1ffff), MEM_MAPPING_EXTERNAL, (void *)flash);
mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + (((i << 14) ^ 0x10000) & 0x1ffff), 0, (void *)flash);
}
}
}
void *intel_flash_init(uint8_t type)
{
@@ -215,12 +311,19 @@ void *intel_flash_init(uint8_t type)
case ROM_KN97:
strcpy(flash_path, "roms/kn97/");
break;
case ROM_MARL:
strcpy(flash_path, "roms/marl/");
break;
case ROM_THOR:
strcpy(flash_path, "roms/thor/");
break;
}
// pclog("Flash init: Path is: %s\n", flash_path);
flash->type = (type & 2) ? 1 : 0;
flash->flash_id = (!flash->type) ? 0x94 : 0x95;
flash->invert_high_pin = (type & 1);
flash->allow_word_write = (type & 4) ? 1 : 0;
/* The block lengths are the same both flash types. */
flash->block_len[0] = 0x1c000;
@@ -321,6 +424,12 @@ void *intel_flash_bxt_ami_init()
return intel_flash_init(FLASH_INVERT);
}
/* For later AMI BIOS'es - Intel 28F100BXT with high address pin inverted and 16-bit write capability. */
void *intel_flash_100bxt_ami_init()
{
return intel_flash_init(FLASH_INVERT | FLASH_ALLOW_16);
}
/* For Award BIOS'es - Intel 28F001BXT with high address pin not inverted. */
void *intel_flash_bxt_init()
{
@@ -382,6 +491,19 @@ device_t intel_flash_bxt_ami_device =
NULL
};
device_t intel_flash_100bxt_ami_device =
{
"Intel 28F100BXT Flash BIOS",
0,
intel_flash_100bxt_ami_init,
intel_flash_close,
NULL,
NULL,
NULL,
NULL,
NULL
};
device_t intel_flash_bxt_device =
{
"Intel 28F001BXT Flash BIOS",

View File

@@ -2,5 +2,6 @@
see COPYING for more details
*/
extern device_t intel_flash_bxt_ami_device;
extern device_t intel_flash_100bxt_ami_device;
extern device_t intel_flash_bxt_device;
extern device_t intel_flash_bxb_device;

View File

@@ -727,6 +727,36 @@ int loadbios()
fclose(f);
biosmask = 0x1ffff;
return 1;
case ROM_MARL:
f = romfopen("roms/marl/1008DB0_.BIO", "rb");
if (!f) break;
fseek(f, 0x80, SEEK_SET);
fread(rom + 0x10000, 0x10000, 1, f);
fclose(f);
f = romfopen("roms/marl/1008DB0_.BI1", "rb");
if (!f) break;
fseek(f, 0x80, SEEK_SET);
fread(rom, 0xd000, 1, f);
fclose(f);
biosmask = 0x1ffff;
//is486=1;
return 1;
case ROM_THOR:
f = romfopen("roms/thor/1005CN0.BIO", "rb");
if (!f) break;
fseek(f, 0x80, SEEK_SET);
fread(rom + 0x10000, 0x10000, 1, f);
fclose(f);
f = romfopen("roms/thor/1005CN0.BI1", "rb");
if (!f) break;
fseek(f, 0x80, SEEK_SET);
fread(rom, 0x10000, 1, f);
fclose(f);
biosmask = 0x1ffff;
//is486=1;
return 1;
}
printf("Failed to load ROM!\n");
if (f) fclose(f);

View File

@@ -3,8 +3,10 @@
*/
#include "ibm.h"
#include "cpu.h"
#include "mem.h"
#include "model.h"
#include "io.h"
#include "rom.h"
#include "acer386sx.h"
#include "acerm3a.h"
@@ -96,9 +98,11 @@ void at_acerm3a_init();
void at_acerv35n_init();
// void at_p55t2p4_init();
void at_p55tvp4_init();
void at_marl_init();
void at_p55va_init();
void at_i440fx_init();
void at_kn97_init();
void at_deskpro2k_init();
int model;
@@ -152,13 +156,15 @@ MODEL models[] =
{"Intel Premiere/PCI II",ROM_PLATO, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, 1, 1, 128, 1, at_plato_init},
{"Intel Advanced/EV", ROM_ENDEAVOR, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, 1, 1, 128, 1, at_endeavor_init},
{"PC Partner MB500N", ROM_MB500N, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, 1, 1, 128, 1, at_mb500n_init},
{"Intel Advanced/ATX", ROM_THOR, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 256, 1, at_endeavor_init},
// {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, 1, 1, 512, 1, at_p54tp4xe_init},
{"Intel Advanced/ML", ROM_MARL, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 512, 1, at_marl_init},
{"Acer M3a", ROM_ACERM3A, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 512, 1, at_acerm3a_init},
{"Acer V35N", ROM_ACERV35N, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 512, 1, at_acerv35n_init},
// {"ASUS P/I-P55T2P4", ROM_P55T2P4, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 512, 1, at_p55t2p4_init},
{"Award 430VX PCI", ROM_430VX, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 256, 1, at_i430vx_init},
{"ASUS P/I-P55TVP4", ROM_P55TVP4, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 512, 1, at_p55tvp4_init},
{"Epox P55-VA", ROM_P55VA, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 256, 1, at_p55va_init},
{"ASUS P/I-P55TVP4", ROM_P55TVP4, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 256, 1, at_p55tvp4_init},
{"Award 440FX PCI", ROM_440FX, { "Intel", cpus_PentiumPro, "", NULL, "", NULL}, 0, 1, 1, 1024, 1, at_i440fx_init},
{"Award KN97 (440FX PCI)",ROM_KN97, { "Intel", cpus_PentiumPro, "", NULL, "", NULL}, 0, 1, 1, 1024, 1, at_kn97_init},
// {"Award 440FX PCI", ROM_440FX, { "Intel", cpus_PentiumPro,"Klamath", cpus_Pentium2, "Deschutes", cpus_Pentium2D}, 0, 1, 1, 1024, 1, at_i440fx_init},
@@ -476,7 +482,7 @@ void at_plato_init()
if (cdrom_channel >= 4) ide_ter_init();
}
void at_endeavor_init()
void at_advanced_common_init()
{
at_init();
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
@@ -485,10 +491,21 @@ void at_endeavor_init()
piix_init(7);
pc87306_init();
intel_endeavor_init();
device_add(&intel_flash_bxt_ami_device);
if (cdrom_channel >= 4) ide_ter_init();
}
void at_endeavor_init()
{
at_advanced_common_init();
device_add(&intel_flash_bxt_ami_device);
}
void at_marl_init()
{
at_advanced_common_init();
device_add(&intel_flash_100bxt_ami_device);
}
void at_mb500n_init()
{
at_init();
@@ -521,6 +538,7 @@ void at_p54tp4xe_init()
void at_acerm3a_init()
{
at_init();
memregs_init();
mouse_serial_init();
pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10);
i430hx_init();
@@ -534,6 +552,7 @@ void at_acerm3a_init()
void at_acerv35n_init()
{
at_init();
memregs_init();
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10);
i430hx_init();
@@ -562,6 +581,7 @@ void at_p55t2p4_init()
void at_i430vx_init()
{
at_init();
memregs_init();
mouse_serial_init();
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
i430vx_init();
@@ -571,6 +591,8 @@ void at_i430vx_init()
if (cdrom_channel >= 4) ide_ter_init();
}
// rom_t ami_ec_rom;
void at_p55tvp4_init()
{
at_init();
@@ -581,12 +603,19 @@ void at_p55tvp4_init()
piix3_init(7);
w83877f_init();
device_add(&intel_flash_bxt_device);
/* rom_init(&ami_ec_rom, "roms/AMIINT13.BIN", 0xd0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
pc87306_init();
intel_endeavor_init(); */
if (cdrom_channel >= 4) ide_ter_init();
}
void at_p55va_init()
{
at_init();
memregs_init();
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
i430vx_init();
@@ -599,7 +628,8 @@ void at_p55va_init()
void at_i440fx_init()
{
at_init();
mouse_ps2_init();
memregs_init();
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
i440fx_init();
piix3_init(7);
@@ -612,7 +642,7 @@ void at_kn97_init()
{
at_init();
memregs_init();
mouse_ps2_init();
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
i440fx_init();
piix3_init(7);

View File

@@ -241,6 +241,8 @@ void loadnvr()
case ROM_P55VA: f = romfopen("nvr/p55va.nvr", "rb"); nvrmask = 127; break;
case ROM_440FX: f = romfopen("nvr/440fx.nvr", "rb"); nvrmask = 127; break;
case ROM_KN97: f = romfopen("nvr/kn97.nvr", "rb"); nvrmask = 127; break;
case ROM_MARL: f = romfopen("nvr/marl.nvr", "rb"); nvrmask = 127; break;
case ROM_THOR: f = romfopen("nvr/thor.nvr", "rb"); nvrmask = 127; break;
default: return;
}
if (!f)
@@ -315,6 +317,8 @@ void savenvr()
case ROM_P55VA: f = romfopen("nvr/p55va.nvr", "wb"); break;
case ROM_440FX: f = romfopen("nvr/440fx.nvr", "wb"); break;
case ROM_KN97: f = romfopen("nvr/kn97.nvr", "wb"); break;
case ROM_MARL: f = romfopen("nvr/marl.nvr", "wb"); break;
case ROM_THOR: f = romfopen("nvr/thor.nvr", "wb"); break;
default: return;
}
fwrite(nvrram,128,1,f);

View File

@@ -178,7 +178,7 @@ process_value:
if (val & 2)
{
serial1_handler();
// mouse_serial_init();
if (mouse_always_serial) mouse_serial_init();
}
if (val & 4) serial2_handler();
@@ -218,7 +218,7 @@ process_value:
if (pc87306_regs[0] & 2)
{
serial1_handler();
// mouse_serial_init();
if (mouse_always_serial) mouse_serial_init();
}
if (pc87306_regs[0] & 4) serial2_handler();
break;
@@ -237,7 +237,7 @@ process_value:
if (pc87306_regs[0] & 2)
{
serial1_handler();
// mouse_serial_init();
if (mouse_always_serial) mouse_serial_init();
}
if (pc87306_regs[0] & 4) serial2_handler();
}
@@ -293,6 +293,7 @@ void pc87306_init()
*/
fdc_update_is_nsc(1);
fdc_update_densel_polarity(1);
fdc_update_max_track(85);
fdd_swap = 0;
io_sethandler(0x02e, 0x0002, pc87306_read, NULL, NULL, pc87306_write, NULL, NULL, NULL);
}

View File

@@ -546,6 +546,7 @@ void piix3_init(int card)
card_piix[0x70] = 0x80;
card_piix[0x76] = card_piix[0x77] = 0x0c;
card_piix[0x78] = 0x02; card_piix[0x79] = 0x00;
card_piix[0x80] = card_piix[0x82] = 0x00;
card_piix[0xa0] = 0x08;
card_piix[0xa2] = card_piix[0xa3] = 0x00;
card_piix[0xa4] = card_piix[0xa5] = card_piix[0xa6] = card_piix[0xa7] = 0x00;

View File

@@ -511,6 +511,7 @@ void w83877f_init()
fdc_update_drvrate(0, 0);
fdc_update_drvrate(1, 0);
fdc_update_enh_mode(0);
fdc_update_max_track(85);
swwp = 0;
disable_write = 0;
fdc_update_drv2en(1);

View File

@@ -614,6 +614,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE);
else SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE);
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX);
// pclog("Checking CD-ROM menu item...\n");
if (!cdrom_enabled)
CheckMenuItem(menu, IDM_CDROM_DISABLED, MF_CHECKED);
@@ -1032,6 +1034,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize)?MF_CHECKED:MF_UNCHECKED);
if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE);
else SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE);
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX);
GetWindowRect(hwnd,&rect);
SetWindowPos(hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED);
saveconfig();

View File

@@ -177,17 +177,14 @@ static inline void x87_st_fsave(int reg)
static inline void x87_ld_frstor(int reg)
{
uint16_t temp;
reg = (cpu_state.TOP + reg) & 7;
temp = readmemw(easeg, cpu_state.eaaddr + 8);
cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr);
cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8);
if (temp == 0x5555 && cpu_state.tag[reg] == 2)
if (cpu_state.MM_w4[reg] == 0x5555 && cpu_state.tag[reg] == 2)
{
cpu_state.tag[reg] = TAG_UINT64;
cpu_state.MM[reg].q = readmeml(easeg, cpu_state.eaaddr);
cpu_state.MM[reg].q |= ((uint64_t)readmeml(easeg, cpu_state.eaaddr + 4) << 32);
cpu_state.ST[reg] = (double)cpu_state.MM[reg].q;
}
else
@@ -290,7 +287,6 @@ typedef union
#define FP_ENTER() do \
{ \
flags_rebuild(); \
if (cr0 & 0xc) \
{ \
x86_int(7); \

View File

@@ -110,14 +110,14 @@ static int FSTOR()
cpu_state.eaaddr += 28;
break;
}
x87_ldmmx(&cpu_state.MM[0], &cpu_state.MM_w4[0]); x87_ld_frstor(0); cpu_state.eaaddr += 10;
x87_ldmmx(&cpu_state.MM[1], &cpu_state.MM_w4[1]); x87_ld_frstor(1); cpu_state.eaaddr += 10;
x87_ldmmx(&cpu_state.MM[2], &cpu_state.MM_w4[2]); x87_ld_frstor(2); cpu_state.eaaddr += 10;
x87_ldmmx(&cpu_state.MM[3], &cpu_state.MM_w4[3]); x87_ld_frstor(3); cpu_state.eaaddr += 10;
x87_ldmmx(&cpu_state.MM[4], &cpu_state.MM_w4[4]); x87_ld_frstor(4); cpu_state.eaaddr += 10;
x87_ldmmx(&cpu_state.MM[5], &cpu_state.MM_w4[5]); x87_ld_frstor(5); cpu_state.eaaddr += 10;
x87_ldmmx(&cpu_state.MM[6], &cpu_state.MM_w4[6]); x87_ld_frstor(6); cpu_state.eaaddr += 10;
x87_ldmmx(&cpu_state.MM[7], &cpu_state.MM_w4[7]); x87_ld_frstor(7);
x87_ld_frstor(0); cpu_state.eaaddr += 10;
x87_ld_frstor(1); cpu_state.eaaddr += 10;
x87_ld_frstor(2); cpu_state.eaaddr += 10;
x87_ld_frstor(3); cpu_state.eaaddr += 10;
x87_ld_frstor(4); cpu_state.eaaddr += 10;
x87_ld_frstor(5); cpu_state.eaaddr += 10;
x87_ld_frstor(6); cpu_state.eaaddr += 10;
x87_ld_frstor(7);
cpu_state.ismmx = 0;
/*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times