Applied all relevant PCem commits;

Extensively cleaned up and changed the CD-ROM code;
Removed CD-ROM IOCTTL (it was causing performance and stability issues);
Turned a lot of things into device_t's;
Added the PS/1 Model 2011 XTA and standalone XTA hard disk controllers, ported from Varcem;
Numerous FDC fixes for the PS/1 Model 2121;
NVR changes ported from Varcem;
The PCap code no longer requires libpcap to be compiled;
Numerous fixes to various SCSI controllers;
Updated NukedOPL to 1.8;
Fixes to OpenAL initialization and closing, should give less Audio issues now;
Revorked parts of the common (S)VGA code (also based on code from QEMU);
Removed the Removable SCSI hard disks (they were a never finished experiment so there was no need to keep them there);
Cleaned up the SCSI hard disk and Iomega ZIP code (but more cleanups of that are coming in the future);
In some occasions (IDE hard disks in multiple sector mode and SCSI hard disks) the status bar icon is no longer updated, should improve performance a bit;
Redid the way the tertiary and quaternary IDE controllers are configured (and they are now device_t's);
Extensively reworked the IDE code and fixed quite a few bugs;
Fixes to XT MFM, AT MFM, and AT ESDI code;
Some changes to XTIDE and MCA ESDI code;
Some fixes to the CD-ROM image handler.
This commit is contained in:
OBattler
2018-04-25 23:51:13 +02:00
parent 2789adca0e
commit a412ceb4d9
151 changed files with 21026 additions and 21058 deletions

View File

@@ -18,7 +18,7 @@
* 2 clocks - fetch opcode 1 2 clocks - execute
* 2 clocks - fetch opcode 2 etc
*
* Version: @(#)808x.c 1.0.2 2018/03/09
* Version: @(#)808x.c 1.0.3 2018/04/19
*
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
* Miran Grca, <mgrca8@gmail.com>
@@ -58,9 +58,6 @@
#include "../nmi.h"
#include "../pic.h"
#include "../timer.h"
#include "../device.h" /* for scsi.h */
#include "../keyboard.h" /* its WRONG to have this in here!! --FvK */
#include "../scsi/scsi.h" /* its WRONG to have this in here!! --FvK */
#include "../plat.h"
@@ -648,7 +645,6 @@ void resetx86()
#endif
x86_was_reset = 1;
port_92_clear_reset();
scsi_card_reset();
}
void softresetx86()
@@ -658,7 +654,12 @@ void softresetx86()
cpu_cur_status = 0;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
msw=0;
cr0=0;
if (is486)
cr0 = 1 << 30;
else
cr0 = 0;
cpu_cache_int_enabled = 0;
cpu_update_waitstates();
cr4 = 0;
eflags=0;
cgate32=0;
@@ -680,7 +681,6 @@ void softresetx86()
x86seg_reset();
x86_was_reset = 1;
port_92_clear_reset();
scsi_card_reset();
}
static void setznp8(uint8_t val)

View File

@@ -634,5 +634,12 @@ opFLDimm(L2T, 3.3219280948873623)
opFLDimm(L2E, 1.4426950408889634);
opFLDimm(PI, 3.141592653589793);
opFLDimm(EG2, 0.3010299956639812);
opFLDimm(LN2, 0.693147180559945);
opFLDimm(Z, 0.0)
static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull);
return op_pc;
}

View File

@@ -59,6 +59,7 @@ static uint32_t prev_regmask;
static uint64_t *prev_deps;
static uint32_t prev_fetchdat;
static uint32_t last_regmask_modified;
static uint32_t regmask_modified;
static uint32_t opcode_timings[256] =
@@ -776,7 +777,7 @@ static inline int COUNT(uint32_t c, int op_32)
void codegen_timing_686_block_start()
{
prev_full = decode_delay = 0;
regmask_modified = 0;
regmask_modified = last_regmask_modified = 0;
}
void codegen_timing_686_start()
@@ -787,6 +788,18 @@ void codegen_timing_686_start()
void codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat)
{
if ((prefix & 0xf8) == 0xd8)
{
last_prefix = prefix;
return;
}
if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80)
{
/*0fh prefix is 'free' when used on conditional jumps*/
last_prefix = prefix;
return;
}
/*6x86 can decode 1 prefix per instruction per clock with no penalty. If
either instruction has more than one prefix then decode is delayed by
one cycle for each additional prefix*/
@@ -801,7 +814,16 @@ static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_3
if (addr_regmask & IMPL_ESP)
addr_regmask |= (1 << REG_ESP);
return regmask_modified & addr_regmask;
if (regmask_modified & addr_regmask)
{
regmask_modified = 0;
return 2;
}
if (last_regmask_modified & addr_regmask)
return 1;
return 0;
}
void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
@@ -914,6 +936,8 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
}
}
/*One prefix per instruction is free*/
decode_delay--;
if (decode_delay < 0)
decode_delay = 0;
@@ -925,8 +949,7 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
if (regmask & IMPL_ESP)
regmask |= SRCDEP_ESP | DSTDEP_ESP;
if (check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32))
agi_stall = 2;
agi_stall = check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32);
/*Second instruction in the pair*/
if ((timings[opcode] & PAIR_MASK) == PAIR_NP)
@@ -936,6 +959,7 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
prev_full = 0;
last_regmask_modified = regmask_modified;
regmask_modified = prev_regmask;
}
else if (((timings[opcode] & PAIR_MASK) == PAIR_X || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH)
@@ -946,6 +970,7 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
prev_full = 0;
last_regmask_modified = regmask_modified;
regmask_modified = prev_regmask;
}
else if (prev_regmask & regmask)
@@ -955,6 +980,7 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
prev_full = 0;
last_regmask_modified = regmask_modified;
regmask_modified = prev_regmask;
}
else
@@ -966,12 +992,12 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
if (!t_pair)
fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode);
if (check_agi(deps, opcode, fetchdat, op_32))
agi_stall = 2;
agi_stall = check_agi(deps, opcode, fetchdat, op_32);
codegen_block_cycles += t_pair + agi_stall;
decode_delay = (-t_pair) + 1 + agi_stall;
last_regmask_modified = regmask_modified;
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask;
prev_full = 0;
return;
@@ -985,12 +1011,12 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
{
/*Instruction not pairable*/
int agi_stall = 0;
if (check_agi(deps, opcode, fetchdat, op_32))
agi_stall = 2;
agi_stall = check_agi(deps, opcode, fetchdat, op_32);
codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(timings[opcode], op_32)) + 1 + agi_stall;
last_regmask_modified = regmask_modified;
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
}
else

View File

@@ -963,7 +963,7 @@ void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat)
last_prefix = prefix;
return;
}
if (prefix == 0x0f && (opcode & 0xf0) == 0x80)
if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80)
{
/*On Pentium 0fh prefix is 'free' when used on conditional jumps*/
last_prefix = prefix;

View File

@@ -8,7 +8,7 @@
*
* CPU type handler.
*
* Version: @(#)cpu.c 1.0.14 2018/03/11
* Version: @(#)cpu.c 1.0.15 2018/04/08
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei,
@@ -1313,7 +1313,7 @@ void cpu_CPUID()
EDX = CPUID_FPU; /*FPU*/
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_iDX4:
@@ -1331,7 +1331,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_VME;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_Am486SX:
@@ -1348,7 +1348,7 @@ void cpu_CPUID()
EBX = ECX = EDX = 0; /*No FPU*/
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_Am486DX:
@@ -1366,7 +1366,7 @@ void cpu_CPUID()
EDX = CPUID_FPU; /*FPU*/
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_WINCHIP:
@@ -1397,7 +1397,7 @@ void cpu_CPUID()
EDX |= CPUID_MMX;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_PENTIUM:
@@ -1415,7 +1415,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
#ifdef DEV_BRANCH
@@ -1435,7 +1435,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_5K86:
@@ -1487,7 +1487,7 @@ void cpu_CPUID()
EDX = 0x10040120;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_K6:
@@ -1549,7 +1549,7 @@ void cpu_CPUID()
EDX = 0x444D416E;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
#endif
#endif
@@ -1569,7 +1569,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
@@ -1588,7 +1588,7 @@ void cpu_CPUID()
EDX = CPUID_FPU;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
@@ -1607,7 +1607,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_CMPXCHG8B;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
@@ -1626,7 +1626,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
@@ -1646,7 +1646,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
#ifdef DEV_BRANCH
@@ -1669,7 +1669,7 @@ void cpu_CPUID()
{
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
/* case CPU_PENTIUM2:
@@ -1693,7 +1693,7 @@ void cpu_CPUID()
EDX = 0x0C040843;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break; */
case CPU_PENTIUM2D:
@@ -1717,7 +1717,7 @@ void cpu_CPUID()
EDX = 0x0C040844;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
#endif
#endif
@@ -2260,7 +2260,7 @@ void cpu_update_waitstates()
cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_write_cycles;
}
if (is486)
cpu_prefetch_cycles *= 4;
cpu_prefetch_cycles = (cpu_prefetch_cycles * 11) / 16;
cpu_mem_prefetch_cycles = cpu_prefetch_cycles;
if (cpu_s->rspeed <= 8000000)
cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles;

View File

@@ -8,7 +8,7 @@
*
* CPU type handler.
*
* Version: @(#)cpu.h 1.0.10 2018/03/11
* Version: @(#)cpu.h 1.0.11 2018/03/28
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei,
@@ -258,7 +258,11 @@ struct _cpustate_ {
#ifdef __MSC__
# define COMPILE_TIME_ASSERT(expr) /*nada*/
#else
# define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0];
# ifdef EXTREME_DEBUG
# define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0];
# else
# define COMPILE_TIME_ASSERT(expr) /*nada*/
# endif
#endif
COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128)

View File

@@ -8,18 +8,20 @@
*
* AMD SYSCALL and SYSRET CPU Instructions.
*
* Version: @(#)x86_ops_amd.h 1.0.1 2018/01/01
* Version: @(#)x86_ops_amd.h 1.0.2 2018/03/26
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016-2018 Miran Grca.
*/
#ifndef internal_illegal
static int internal_illegal(char *s)
{
cpu_state.pc = cpu_state.oldpc;
x86gpf(s, 0);
return cpu_state.abrt;
}
#endif
/* 0 = Limit 0-15
1 = Base 0-15

View File

@@ -8,12 +8,21 @@
*
* x86 i686 (Pentium Pro/Pentium II) CPU Instructions.
*
* Version: @(#)x86_ops_i686.h 1.0.2 2018/01/01
* Version: @(#)x86_ops_i686.h 1.0.3 2018/03/26
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016-2018 Miran Grca.
*/
#ifndef internal_illegal
static int internal_illegal(char *s)
{
cpu_state.pc = cpu_state.oldpc;
x86gpf(s, 0);
return cpu_state.abrt;
}
#endif
/* 0 = Limit 0-15
1 = Base 0-15
2 = Base 16-23 (bits 0-7), Access rights

View File

@@ -8,12 +8,12 @@
*
* Miscellaneous x86 CPU Instructions.
*
* Version: @(#)x86_ops_misc.h 1.0.0 2017/05/30
* Version: @(#)x86_ops_misc.h 1.0.1 2018/04/12
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
static int opCBW(uint32_t fetchdat)
@@ -70,6 +70,10 @@ static int opF6_a16(uint32_t fetchdat)
int8_t temps;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
{
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
}
dst = geteab(); if (cpu_state.abrt) return 1;
switch (rmdat & 0x38)
{
@@ -120,6 +124,7 @@ static int opF6_a16(uint32_t fetchdat)
{
flags_rebuild();
flags |= 0x8D5; /*Not a Cyrix*/
flags &= ~1;
}
}
else
@@ -127,8 +132,8 @@ static int opF6_a16(uint32_t fetchdat)
x86_int(0);
return 1;
}
CLOCK_CYCLES(is486 ? 16 : 14);
PREFETCH_RUN(is486 ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14);
PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
break;
case 0x38: /*IDIV AL,b*/
tempws = (int)(int16_t)AX;
@@ -142,6 +147,7 @@ static int opF6_a16(uint32_t fetchdat)
{
flags_rebuild();
flags|=0x8D5; /*Not a Cyrix*/
flags &= ~1;
}
}
else
@@ -217,6 +223,7 @@ static int opF6_a32(uint32_t fetchdat)
{
flags_rebuild();
flags |= 0x8D5; /*Not a Cyrix*/
flags &= ~1;
}
}
else
@@ -224,8 +231,8 @@ static int opF6_a32(uint32_t fetchdat)
x86_int(0);
return 1;
}
CLOCK_CYCLES(is486 ? 16 : 14);
PREFETCH_RUN(is486 ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14);
PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
break;
case 0x38: /*IDIV AL,b*/
tempws = (int)(int16_t)AX;
@@ -239,6 +246,7 @@ static int opF6_a32(uint32_t fetchdat)
{
flags_rebuild();
flags|=0x8D5; /*Not a Cyrix*/
flags &= ~1;
}
}
else
@@ -323,8 +331,8 @@ static int opF7_w_a16(uint32_t fetchdat)
x86_int(0);
return 1;
}
CLOCK_CYCLES(is486 ? 24 : 22);
PREFETCH_RUN(is486 ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22);
PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
break;
case 0x38: /*IDIV AX,w*/
tempws = (int)((DX << 16)|AX);
@@ -415,8 +423,8 @@ static int opF7_w_a32(uint32_t fetchdat)
x86_int(0);
return 1;
}
CLOCK_CYCLES(is486 ? 24 : 22);
PREFETCH_RUN(is486 ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22);
PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
break;
case 0x38: /*IDIV AX,w*/
tempws = (int)((DX << 16)|AX);

View File

@@ -24,6 +24,7 @@
#include <wchar.h>
#include "../86box.h"
#include "cpu.h"
#include "../device.h"
#include "../machine/machine.h"
#include "../mem.h"
#include "../nvr.h"

View File

@@ -8,15 +8,15 @@
*
* x87 FPU instructions core.
*
* Version: @(#)x87_ops.h 1.0.1 2017/10/28
* Version: @(#)x87_ops.h 1.0.2 2018/04/05
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 leilei.
* Copyright 2016,2017 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 leilei.
* Copyright 2016-2018 Miran Grca.
*/
#include <math.h>
#include <fenv.h>
@@ -80,6 +80,21 @@ static __inline void x87_push(double i)
cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? 1 : 0;
}
static inline void x87_push_u64(uint64_t i)
{
union
{
double d;
uint64_t ll;
} td;
td.ll = i;
cpu_state.TOP=(cpu_state.TOP-1)&7;
cpu_state.ST[cpu_state.TOP] = td.d;
cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? 1 : 0;
}
static __inline double x87_pop()
{
double t = cpu_state.ST[cpu_state.TOP];

View File

@@ -478,7 +478,7 @@ static int opFLDLN2(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
if (fplog) pclog("FLDLN2\n");
x87_push(0.693147180559945);
x87_push_u64(0x3fe62e42fefa39f0ull);
CLOCK_CYCLES(8);
return 0;
}