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;
int cpu_waitstates;
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;
uint32_t cpu_fast_off_flags;
int is_vpc;
@@ -571,15 +571,9 @@ cpu_set(void)
else
cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000;
if (cpu_busspeed < 42500000)
cpu_pci_speed = cpu_busspeed;
else if ((cpu_busspeed > 42500000) && (cpu_busspeed < 84000000))
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;
cpu_set_isa_pci_div(0);
cpu_set_pci_speed(0);
cpu_set_agp_speed(0);
if (cpu_iscyrix)
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;
}
}
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 *
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 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 uint16_t temp_seg_data[4];
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_waitstates;
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_mr, timing_mrl;
@@ -523,6 +523,10 @@ extern char *cpu_current_pc(char *bufp);
extern void cpu_update_waitstates(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_RDMSR(void);

View File

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

View File

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