Add custom ISA/PCI/AGP clock facility, and fix PIT clock calculation oversight for CPU clocks ending in (but not equal to) 33 and 66 MHz

This commit is contained in:
RichardG867
2021-03-14 19:41:52 -03:00
parent 84c40909c7
commit dfee1165ea
4 changed files with 137 additions and 60 deletions

View File

@@ -167,7 +167,7 @@ int cpu_prefetch_cycles, cpu_prefetch_width,
cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles; cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles;
int cpu_waitstates; int cpu_waitstates;
int cpu_cache_int_enabled, cpu_cache_ext_enabled; int cpu_cache_int_enabled, cpu_cache_ext_enabled;
int cpu_pci_speed, cpu_alt_reset; int cpu_isa_speed, cpu_pci_speed, cpu_isa_pci_div, cpu_agp_speed, cpu_alt_reset;
uint16_t cpu_fast_off_count, cpu_fast_off_val; uint16_t cpu_fast_off_count, cpu_fast_off_val;
uint32_t cpu_fast_off_flags; uint32_t cpu_fast_off_flags;
int is_vpc; int is_vpc;
@@ -571,15 +571,9 @@ cpu_set(void)
else else
cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000; cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000;
if (cpu_busspeed < 42500000) cpu_set_isa_pci_div(0);
cpu_pci_speed = cpu_busspeed; cpu_set_pci_speed(0);
else if ((cpu_busspeed > 42500000) && (cpu_busspeed < 84000000)) cpu_set_agp_speed(0);
cpu_pci_speed = cpu_busspeed / 2;
else
cpu_pci_speed = cpu_busspeed / 3;
pci_burst_time = cpu_s->rspeed / cpu_pci_speed;
pci_nonburst_time = 4 * pci_burst_time;
if (cpu_iscyrix) if (cpu_iscyrix)
io_sethandler(0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); io_sethandler(0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL);
@@ -1879,6 +1873,82 @@ cpu_set(void)
x87_timings = x87_timings_486; x87_timings = x87_timings_486;
} }
} }
void
cpu_set_isa_speed(int speed)
{
if (speed) {
cpu_isa_speed = speed;
pc_speed_changed();
} else
cpu_isa_speed = 8000000;
cpu_log("cpu_set_isa_speed(%d) = %d\n", speed, cpu_isa_speed);
}
void
cpu_set_pci_speed(int speed)
{
if (speed)
cpu_pci_speed = speed;
else if (cpu_busspeed < 42500000)
cpu_pci_speed = cpu_busspeed;
else if (cpu_busspeed < 84000000)
cpu_pci_speed = cpu_busspeed / 2;
else if (cpu_busspeed < 120000000)
cpu_pci_speed = cpu_busspeed / 3;
else
cpu_pci_speed = cpu_busspeed / 4;
if (cpu_isa_pci_div)
cpu_set_isa_pci_div(cpu_isa_pci_div);
else if (speed)
pc_speed_changed();
pci_burst_time = cpu_s->rspeed / cpu_pci_speed;
pci_nonburst_time = 4 * pci_burst_time;
cpu_log("cpu_set_pci_speed(%d) = %d\n", speed, cpu_pci_speed);
}
void
cpu_set_isa_pci_div(int div)
{
cpu_isa_pci_div = div;
cpu_log("cpu_set_isa_pci_div(%d)\n", cpu_isa_pci_div);
if (cpu_isa_pci_div)
cpu_set_isa_speed(cpu_pci_speed / cpu_isa_pci_div);
else
cpu_set_isa_speed(0);
}
void
cpu_set_agp_speed(int speed)
{
if (speed) {
cpu_agp_speed = speed;
pc_speed_changed();
}
else if (cpu_busspeed < 84000000)
cpu_agp_speed = cpu_busspeed;
else if (cpu_busspeed < 120000000)
cpu_agp_speed = cpu_busspeed / 1.5;
else
cpu_agp_speed = cpu_busspeed / 2;
agp_burst_time = cpu_s->rspeed / cpu_agp_speed;
agp_nonburst_time = 4 * agp_burst_time;
cpu_log("cpu_set_agp_speed(%d) = %d\n", speed, cpu_agp_speed);
}
char * char *
cpu_current_pc(char *bufp) cpu_current_pc(char *bufp)
{ {

View File

@@ -433,7 +433,7 @@ extern uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw;
extern uint32_t pccache; extern uint32_t pccache;
extern uint8_t *pccache2; extern uint8_t *pccache2;
extern double bus_timing, pci_timing; extern double bus_timing, isa_timing, pci_timing, agp_timing;
extern uint64_t pmc[2]; extern uint64_t pmc[2];
extern uint16_t temp_seg_data[4]; extern uint16_t temp_seg_data[4];
extern uint16_t cs_msr; extern uint16_t cs_msr;
@@ -477,7 +477,7 @@ extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_writ
extern int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles; extern int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles;
extern int cpu_waitstates; extern int cpu_waitstates;
extern int cpu_cache_int_enabled, cpu_cache_ext_enabled; extern int cpu_cache_int_enabled, cpu_cache_ext_enabled;
extern int cpu_pci_speed; extern int cpu_isa_speed, cpu_pci_speed, cpu_agp_speed;
extern int timing_rr; extern int timing_rr;
extern int timing_mr, timing_mrl; extern int timing_mr, timing_mrl;
@@ -523,6 +523,10 @@ extern char *cpu_current_pc(char *bufp);
extern void cpu_update_waitstates(void); extern void cpu_update_waitstates(void);
extern void cpu_set(void); extern void cpu_set(void);
extern void cpu_set_isa_speed(int speed);
extern void cpu_set_pci_speed(int speed);
extern void cpu_set_isa_pci_div(int div);
extern void cpu_set_agp_speed(int speed);
extern void cpu_CPUID(void); extern void cpu_CPUID(void);
extern void cpu_RDMSR(void); extern void cpu_RDMSR(void);

View File

@@ -49,7 +49,7 @@ typedef struct PIT {
extern pit_t *pit, extern pit_t *pit,
*pit2; *pit2;
extern double SYSCLK, PCICLK; extern double SYSCLK, PCICLK, AGPCLK;
extern uint64_t PITCONST, ISACONST, extern uint64_t PITCONST, ISACONST,
CGACONST, CGACONST,

View File

@@ -44,8 +44,8 @@ pit_t *pit, *pit2;
double cpuclock, PITCONSTD, double cpuclock, PITCONSTD,
SYSCLK, SYSCLK,
isa_timing, isa_timing,
bus_timing, pci_timing, bus_timing, pci_timing, agp_timing,
PCICLK; PCICLK, AGPCLK;
uint64_t PITCONST, ISACONST, uint64_t PITCONST, ISACONST,
CGACONST, CGACONST,
@@ -961,17 +961,18 @@ pit_set_clock(int clock)
{ {
/* Set default CPU/crystal clock and xt_cpu_multi. */ /* Set default CPU/crystal clock and xt_cpu_multi. */
if (cpu_s->cpu_type >= CPU_286) { if (cpu_s->cpu_type >= CPU_286) {
if (clock == 66666666) int remainder = (clock % 100000000);
cpuclock = 200000000.0 / 3.0; if (remainder == 66666666)
else if (clock == 33333333) cpuclock = (double) (clock - remainder) + (200000000.0 / 3.0);
cpuclock = 100000000.0 / 3.0; else if (remainder == 33333333)
cpuclock = (double) (clock - remainder) + (100000000.0 / 3.0);
else else
cpuclock = (double) clock; cpuclock = (double) clock;
PITCONSTD = (cpuclock / 1193182.0); PITCONSTD = (cpuclock / 1193182.0);
PITCONST = (uint64_t) (PITCONSTD * (double)(1ull << 32)); PITCONST = (uint64_t) (PITCONSTD * (double)(1ull << 32));
CGACONST = (uint64_t) ((cpuclock / (19687503.0/11.0)) * (double)(1ull << 32)); CGACONST = (uint64_t) ((cpuclock / (19687503.0/11.0)) * (double)(1ull << 32));
ISACONST = (uint64_t) ((cpuclock / 8000000.0) * (double)(1ull << 32)); ISACONST = (uint64_t) ((cpuclock / (double)cpu_isa_speed) * (double)(1ull << 32));
xt_cpu_multi = 1ULL; xt_cpu_multi = 1ULL;
} else { } else {
cpuclock = 14318184.0; cpuclock = 14318184.0;
@@ -1039,15 +1040,17 @@ pit_set_clock(int clock)
TIMER_USEC = (uint64_t)((cpuclock / 1000000.0) * (double)(1ull << 32)); TIMER_USEC = (uint64_t)((cpuclock / 1000000.0) * (double)(1ull << 32));
isa_timing = (cpuclock / (double)8000000.0); isa_timing = (cpuclock / (double)cpu_isa_speed);
if (cpu_64bitbus) if (cpu_64bitbus)
bus_timing = (cpuclock / ((double)cpu_busspeed / 2)); bus_timing = (cpuclock / ((double)cpu_busspeed / 2));
else else
bus_timing = (cpuclock / (double)cpu_busspeed); bus_timing = (cpuclock / (double)cpu_busspeed);
pci_timing = (cpuclock / (double)cpu_pci_speed); pci_timing = (cpuclock / (double)cpu_pci_speed);
agp_timing = (cpuclock / (double)cpu_agp_speed);
/* PCICLK in us for use with timer_on_auto(). */ /* PCICLK in us for use with timer_on_auto(). */
PCICLK = pci_timing / (cpuclock / 1000000.0); PCICLK = pci_timing / (cpuclock / 1000000.0);
AGPCLK = agp_timing / (cpuclock / 1000000.0);
if (cpu_busspeed >= 30000000) if (cpu_busspeed >= 30000000)
SYSCLK = bus_timing * 4.0; SYSCLK = bus_timing * 4.0;