From 6a097f78b496e9bc84a32e902e8d05fffa78e5d2 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 25 Nov 2020 19:10:15 -0300 Subject: [PATCH 01/22] Add high refresh rate and 1366x768 modes to DDC --- src/video/vid_ddc.c | 88 ++++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 28 deletions(-) diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index afe80b9ef..64483feec 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -25,10 +25,29 @@ #include <86box/i2c.h> -#define STD_TIMING(idx, width, aspect_ratio) do { \ - edid->standard_timings[idx].horiz_pixels = ((width) >> 3) - 31; \ - edid->standard_timings[idx].aspect_ratio_refresh_rate = (aspect_ratio) << 6; /* 60 Hz */ \ - } while (0) +#define PIXEL_MM(px) ((uint16_t) (((px) * 25.4) / 96)) +#define STANDARD_TIMING(slot, width, aspect_ratio, refresh) do { \ + edid->slot.horiz_pixels = ((width) >> 3) - 31; \ + edid->slot.aspect_ratio_refresh_rate = ((aspect_ratio) << 6) | ((refresh) - 60); \ + } while (0) +#define DETAILED_TIMING(slot, clk, width, height, hblank, vblank, hfp, hsp, vfp, vsp) do { \ + edid->slot.pixel_clock_lsb = ((clk) / 10) & 0xff; \ + edid->slot.pixel_clock_msb = ((clk) / 10) >> 8; \ + edid->slot.h_active_lsb = (width) & 0xff; \ + edid->slot.h_blank_lsb = (hblank) & 0xff; \ + edid->slot.h_active_blank_msb = (((width) >> 4) & 0xf0) | (((hblank) >> 8) & 0x0f); \ + edid->slot.v_active_lsb = (height) & 0xff; \ + edid->slot.v_blank_lsb = (vblank) & 0xff; \ + edid->slot.v_active_blank_msb = (((height) >> 4) & 0xf0) | (((vblank) >> 8) & 0x0f); \ + edid->slot.h_front_porch_lsb = (hfp) & 0xff; \ + edid->slot.h_sync_pulse_lsb = (hsp) & 0xff; \ + edid->slot.v_front_porch_sync_pulse_lsb = (((vfp) & 0x0f) << 4) | ((vsp) & 0x0f); \ + edid->slot.hv_front_porch_sync_pulse_msb = (((hfp) >> 2) & 0x03) | (((hsp) >> 4) & 0x03) | (((vfp) >> 6) & 0x03) | (((vsp) >> 8) & 0x03); \ + edid->slot.h_size_lsb = PIXEL_MM(width) & 0xff; \ + edid->slot.v_size_lsb = PIXEL_MM(height) & 0xff; \ + edid->slot.hv_size_msb = ((PIXEL_MM(width) >> 4) & 0xf0) | ((PIXEL_MM(height) >> 8) & 0x0f); \ + } while (0) + enum { STD_ASPECT_16_10 = 0x0, @@ -112,6 +131,7 @@ void * ddc_init(void *i2c) { edid_t *edid = malloc(sizeof(edid_t)); + uint8_t *edid_bytes = (uint8_t *) edid; memset(edid, 0, sizeof(edid_t)); memset(&edid->magic[1], 0xff, sizeof(edid->magic) - 2); @@ -140,34 +160,23 @@ ddc_init(void *i2c) memset(&edid->established_timings, 0xff, sizeof(edid->established_timings)); /* all enabled */ -#if 0 - memset(&edid->standard_timings, 0x01, sizeof(edid->standard_timings)); /* pad unused entries */ -#endif - STD_TIMING(0, 1280, STD_ASPECT_16_9); /* 1280x720 */ - STD_TIMING(1, 1280, STD_ASPECT_16_10); /* 1280x800 */ - STD_TIMING(2, 1366, STD_ASPECT_16_9); /* 1360x768 (closest to 1366x768) */ - STD_TIMING(3, 1440, STD_ASPECT_16_10); /* 1440x900 */ - STD_TIMING(4, 1600, STD_ASPECT_16_9); /* 1600x900 */ - STD_TIMING(5, 1680, STD_ASPECT_16_10); /* 1680x1050 */ - STD_TIMING(6, 1920, STD_ASPECT_16_9); /* 1920x1080 */ - STD_TIMING(7, 2048, STD_ASPECT_4_3); /* 2048x1536 */ + /* 60 Hz timings */ + STANDARD_TIMING(standard_timings[0], 1280, STD_ASPECT_16_9, 60); /* 1280x720 */ + STANDARD_TIMING(standard_timings[1], 1280, STD_ASPECT_16_10, 60); /* 1280x800 */ + STANDARD_TIMING(standard_timings[2], 1366, STD_ASPECT_16_9, 60); /* 1360x768 (closest to 1366x768) */ + STANDARD_TIMING(standard_timings[3], 1440, STD_ASPECT_16_10, 60); /* 1440x900 */ + STANDARD_TIMING(standard_timings[4], 1600, STD_ASPECT_16_9, 60); /* 1600x900 */ + STANDARD_TIMING(standard_timings[5], 1680, STD_ASPECT_16_10, 60); /* 1680x1050 */ + STANDARD_TIMING(standard_timings[6], 1920, STD_ASPECT_16_9, 60); /* 1920x1080 */ + STANDARD_TIMING(standard_timings[7], 2048, STD_ASPECT_4_3, 60); /* 2048x1536 */ - /* Detailed timings for the preferred mode of 800x600 @ 60 Hz */ - edid->detailed_timings[0].pixel_clock_lsb = 4000 & 0xff; /* 40.000 MHz */ - edid->detailed_timings[0].pixel_clock_msb = 4000 >> 8; - edid->detailed_timings[0].h_active_lsb = 800 & 0xff; - edid->detailed_timings[0].h_blank_lsb = 256 & 0xff; - edid->detailed_timings[0].h_active_blank_msb = ((800 >> 4) & 0xf0) | ((256 >> 8) & 0x0f); - edid->detailed_timings[0].v_active_lsb = 600 & 0xff; - edid->detailed_timings[0].v_blank_lsb = 28; - edid->detailed_timings[0].v_active_blank_msb = (600 >> 4) & 0xf0; - edid->detailed_timings[0].h_front_porch_lsb = 40; - edid->detailed_timings[0].h_sync_pulse_lsb = 128; - edid->detailed_timings[0].v_front_porch_sync_pulse_lsb = (1 << 4) | 4; + /* Detailed timing for the preferred mode of 800x600 @ 60 Hz */ + DETAILED_TIMING(detailed_timings[0], 40000, 800, 600, 256, 28, 40, 128, 1, 4); edid->descriptors[1].tag = 0xf7; /* established timings 3 */ edid->descriptors[1].established_timings3.version = 0x0a; memset(&edid->descriptors[1].established_timings3.timings, 0xff, sizeof(edid->descriptors[1].established_timings3.timings)); /* all enabled */ + edid->descriptors[1].established_timings3.timings[5] &= 0xf0; /* reserved bits */ edid->descriptors[2].tag = 0xfc; /* display name */ memcpy(&edid->descriptors[2].ascii, "86Box Monitor", 13); /* exactly 13 characters (would otherwise require LF termination and space padding) */ @@ -182,14 +191,37 @@ ddc_init(void *i2c) edid->descriptors[3].range_limits.padding[0] = 0x0a; memset(&edid->descriptors[3].range_limits.padding[1], 0x20, sizeof(edid->descriptors[3].range_limits.padding) - 1); - uint8_t *edid_bytes = (uint8_t *) edid; + edid->extensions = 1; for (uint8_t c = 0; c < 127; c++) edid->checksum += edid_bytes[c]; edid->checksum = 256 - edid->checksum; + + edid->ext_tag = 0x02; + edid->ext_rev = 0x03; + edid->ext_dtd_offset = 0x04; + + /* Detailed timing for 1366x768 */ + DETAILED_TIMING(ext_detailed_timings[0], 85500, 1366, 768, 426, 30, 70, 143, 3, 3); + + /* High refresh rate timings (VGA is limited to 85 Hz) */ + edid->ext_descriptors[1].tag = 0xfa; /* standard timing identifiers */ +#define ext_standard_timings0 ext_descriptors[1].ext_standard_timings.timings + STANDARD_TIMING(ext_standard_timings0[0], 640, STD_ASPECT_4_3, 90); /* 640x480 @ 90 Hz */ + STANDARD_TIMING(ext_standard_timings0[1], 640, STD_ASPECT_4_3, 120); /* 640x480 @ 120 Hz */ + STANDARD_TIMING(ext_standard_timings0[2], 800, STD_ASPECT_4_3, 90); /* 800x600 @ 90 Hz */ + STANDARD_TIMING(ext_standard_timings0[3], 800, STD_ASPECT_4_3, 120); /* 800x600 @ 120 Hz */ + STANDARD_TIMING(ext_standard_timings0[4], 1024, STD_ASPECT_4_3, 90); /* 1024x768 @ 90 Hz */ + STANDARD_TIMING(ext_standard_timings0[5], 1280, STD_ASPECT_5_4, 90); /* 1280x1024 @ 90 Hz */ + edid->ext_descriptors[1].ext_standard_timings.padding = 0x0a; + for (uint8_t c = 128; c < 255; c++) edid->checksum2 += edid_bytes[c]; edid->checksum2 = 256 - edid->checksum2; + FILE *f = fopen("C:\\Users\\Richard\\Desktop\\86boxedid.bin", "wb"); + fwrite(edid_bytes, 1, sizeof(edid_t), f); + fclose(f); + return i2c_eeprom_init(i2c, 0x50, edid_bytes, sizeof(edid_t), 0); } From b48eca1c611aeb1598cc9fb6e7df7253131103bd Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 25 Nov 2020 20:04:47 -0300 Subject: [PATCH 02/22] DDC EDID compliance fixes --- src/video/vid_ddc.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index 64483feec..7bab35c6a 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -42,10 +42,10 @@ edid->slot.h_front_porch_lsb = (hfp) & 0xff; \ edid->slot.h_sync_pulse_lsb = (hsp) & 0xff; \ edid->slot.v_front_porch_sync_pulse_lsb = (((vfp) & 0x0f) << 4) | ((vsp) & 0x0f); \ - edid->slot.hv_front_porch_sync_pulse_msb = (((hfp) >> 2) & 0x03) | (((hsp) >> 4) & 0x03) | (((vfp) >> 6) & 0x03) | (((vsp) >> 8) & 0x03); \ - edid->slot.h_size_lsb = PIXEL_MM(width) & 0xff; \ - edid->slot.v_size_lsb = PIXEL_MM(height) & 0xff; \ - edid->slot.hv_size_msb = ((PIXEL_MM(width) >> 4) & 0xf0) | ((PIXEL_MM(height) >> 8) & 0x0f); \ + edid->slot.hv_front_porch_sync_pulse_msb = (((hfp) >> 2) & 0xc0) | (((hsp) >> 4) & 0x30) | (((vfp) >> 2) & 0x0c) | (((vsp) >> 4) & 0x03); \ + edid->slot.h_size_lsb = horiz_mm & 0xff; \ + edid->slot.v_size_lsb = vert_mm & 0xff; \ + edid->slot.hv_size_msb = ((horiz_mm >> 4) & 0xf0) | ((vert_mm >> 8) & 0x0f); \ } while (0) @@ -131,9 +131,11 @@ void * ddc_init(void *i2c) { edid_t *edid = malloc(sizeof(edid_t)); - uint8_t *edid_bytes = (uint8_t *) edid; memset(edid, 0, sizeof(edid_t)); + uint8_t *edid_bytes = (uint8_t *) edid; + uint16_t horiz_mm = PIXEL_MM(1366), vert_mm = PIXEL_MM(768); + memset(&edid->magic[1], 0xff, sizeof(edid->magic) - 2); edid->mfg[0] = 0x09; /* manufacturer "BOX" (apparently unassigned by UEFI) */ @@ -141,11 +143,12 @@ ddc_init(void *i2c) edid->mfg_week = 48; edid->mfg_year = 2020 - 1990; edid->edid_version = 0x01; - edid->edid_rev = 0x04; /* EDID 1.4 */ + edid->edid_rev = 0x03; /* EDID 1.3 */ edid->input_params = 0x0e; /* analog input; separate sync; composite sync; sync on green */ - edid->horiz_size = ((4.0 / 3.0) * 100) - 99; /* landscape 4:3 */ - edid->features = 0x09; /* RGB color; GTF/CVT */ + edid->horiz_size = horiz_mm / 10; + edid->vert_size = vert_mm / 10; + edid->features = 0x0b; /* RGB color; first timing is preferred; GTF/CVT */ edid->red_green_lsb = 0x81; edid->blue_white_lsb = 0xf1; @@ -198,6 +201,7 @@ ddc_init(void *i2c) edid->ext_tag = 0x02; edid->ext_rev = 0x03; + edid->ext_native_dtds = 0x80; /* underscans IT; no native extended modes */ edid->ext_dtd_offset = 0x04; /* Detailed timing for 1366x768 */ From 460ebd15e9d7a08bfbda5f1fd59bf882bc6577b8 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 25 Nov 2020 20:09:15 -0300 Subject: [PATCH 03/22] That was not meant to ship --- src/video/vid_ddc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index 7bab35c6a..725578da2 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -222,10 +222,6 @@ ddc_init(void *i2c) edid->checksum2 += edid_bytes[c]; edid->checksum2 = 256 - edid->checksum2; - FILE *f = fopen("C:\\Users\\Richard\\Desktop\\86boxedid.bin", "wb"); - fwrite(edid_bytes, 1, sizeof(edid_t), f); - fclose(f); - return i2c_eeprom_init(i2c, 0x50, edid_bytes, sizeof(edid_t), 0); } From 426084bafba3adf14f2b2f0e100c3f051306e5c2 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 30 Nov 2020 20:07:13 -0300 Subject: [PATCH 04/22] NCR SCSI: check GPIO direction as well --- src/scsi/scsi_ncr53c8xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index ca0273cc8..e898e7d76 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -1529,7 +1529,7 @@ ncr53c8xx_reg_writeb(ncr53c8xx_t *dev, uint32_t offset, uint8_t val) case 0x07: /* GPREG */ ncr53c8xx_log("NCR 810: GPREG write %02X\n", val); dev->gpreg = val; - i2c_gpio_set(dev->i2c, !!(dev->gpreg & 0x02), !!(dev->gpreg & 0x01)); + i2c_gpio_set(dev->i2c, (dev->gpreg & 0x02) || ((dev->gpcntl & 0x82) == 0x02), (dev->gpreg & 0x01) || ((dev->gpcntl & 0x41) == 0x01)); break; case 0x08: /* SFBR */ /* The CPU is not allowed to write to this register. However the From f6be8931ff0f6c9867e72613e0c54d818340855c Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 30 Nov 2020 20:07:30 -0300 Subject: [PATCH 05/22] BusLogic SCSI: fix capitalization in device names --- src/scsi/scsi_buslogic.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index c023fb2f2..8ecbbe536 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -1846,7 +1846,7 @@ static const device_config_t BT958D_Config[] = { }; const device_t buslogic_542b_1991_device = { - "Buslogic BT-542B ISA", + "BusLogic BT-542B ISA", DEVICE_ISA | DEVICE_AT, CHIP_BUSLOGIC_ISA_542_1991, buslogic_init, x54x_close, NULL, @@ -1855,7 +1855,7 @@ const device_t buslogic_542b_1991_device = { }; const device_t buslogic_device = { - "Buslogic BT-542BH ISA", + "BusLogic BT-542BH ISA", DEVICE_ISA | DEVICE_AT, CHIP_BUSLOGIC_ISA_542, buslogic_init, x54x_close, NULL, @@ -1864,7 +1864,7 @@ const device_t buslogic_device = { }; const device_t buslogic_545s_device = { - "Buslogic BT-545S ISA", + "BusLogic BT-545S ISA", DEVICE_ISA | DEVICE_AT, CHIP_BUSLOGIC_ISA, buslogic_init, x54x_close, NULL, @@ -1873,7 +1873,7 @@ const device_t buslogic_545s_device = { }; const device_t buslogic_640a_device = { - "Buslogic BT-640A MCA", + "BusLogic BT-640A MCA", DEVICE_MCA, CHIP_BUSLOGIC_MCA, buslogic_init, x54x_close, NULL, @@ -1882,7 +1882,7 @@ const device_t buslogic_640a_device = { }; const device_t buslogic_445s_device = { - "Buslogic BT-445S VLB", + "BusLogic BT-445S VLB", DEVICE_VLB, CHIP_BUSLOGIC_VLB, buslogic_init, x54x_close, NULL, @@ -1891,7 +1891,7 @@ const device_t buslogic_445s_device = { }; const device_t buslogic_pci_device = { - "Buslogic BT-958D PCI", + "BusLogic BT-958D PCI", DEVICE_PCI, CHIP_BUSLOGIC_PCI, buslogic_init, x54x_close, NULL, From 2579f7fb837a8d87d12bf651373f70099bfd571e Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 30 Nov 2020 20:08:37 -0300 Subject: [PATCH 06/22] Move i2c_eeprom to mem/ directory --- src/{device => mem}/i2c_eeprom.c | 38 +++++++++++++++++++++++--------- src/win/Makefile.mingw | 4 ++-- 2 files changed, 29 insertions(+), 13 deletions(-) rename src/{device => mem}/i2c_eeprom.c (84%) diff --git a/src/device/i2c_eeprom.c b/src/mem/i2c_eeprom.c similarity index 84% rename from src/device/i2c_eeprom.c rename to src/mem/i2c_eeprom.c index a27403de8..68b5019cc 100644 --- a/src/device/i2c_eeprom.c +++ b/src/mem/i2c_eeprom.c @@ -33,7 +33,7 @@ typedef struct { uint8_t addr_len, addr_pos; } i2c_eeprom_t; - +#define ENABLE_I2C_EEPROM_LOG 1 #ifdef ENABLE_I2C_EEPROM_LOG int i2c_eeprom_do_log = ENABLE_I2C_EEPROM_LOG; @@ -54,35 +54,37 @@ i2c_eeprom_log(const char *fmt, ...) #endif -uint8_t +static uint8_t i2c_eeprom_start(void *bus, uint8_t addr, uint8_t read, void *priv) { i2c_eeprom_t *dev = (i2c_eeprom_t *) priv; i2c_eeprom_log("I2C EEPROM %s %02X: start()\n", i2c_getbusname(dev->i2c), dev->addr); - dev->addr_pos = 0; - dev->addr_register = (addr << dev->addr_len) & dev->addr_mask; + if (!read) { + dev->addr_pos = 0; + dev->addr_register = (addr << dev->addr_len) & dev->addr_mask; + } return 1; } -uint8_t +static uint8_t i2c_eeprom_read(void *bus, uint8_t addr, void *priv) { i2c_eeprom_t *dev = (i2c_eeprom_t *) priv; uint8_t ret = dev->data[dev->addr_register]; i2c_eeprom_log("I2C EEPROM %s %02X: read(%06X) = %02X\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, ret); - if (++dev->addr_register > dev->addr_mask) /* roll-over */ - dev->addr_register = 0; + dev->addr_register++; + dev->addr_register &= dev->addr_mask; /* roll-over */ return ret; } -uint8_t +static uint8_t i2c_eeprom_write(void *bus, uint8_t addr, uint8_t data, void *priv) { i2c_eeprom_t *dev = (i2c_eeprom_t *) priv; @@ -93,14 +95,14 @@ i2c_eeprom_write(void *bus, uint8_t addr, uint8_t data, void *priv) dev->addr_register &= (1 << dev->addr_len) - 1; dev->addr_register |= addr << dev->addr_len; dev->addr_register &= dev->addr_mask; - i2c_eeprom_log("I2C EEPROM %s %02X: write(address, %04X)\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register); + i2c_eeprom_log("I2C EEPROM %s %02X: write(address, %06X)\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register); dev->addr_pos += 8; } else { i2c_eeprom_log("I2C EEPROM %s %02X: write(%06X, %02X) = %d\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, data, !!dev->writable); if (dev->writable) dev->data[dev->addr_register] = data; - if (++dev->addr_register > dev->addr_mask) /* roll-over */ - dev->addr_register = 0; + dev->addr_register++; + dev->addr_register &= dev->addr_mask; /* roll-over */ return dev->writable; } @@ -108,12 +110,26 @@ i2c_eeprom_write(void *bus, uint8_t addr, uint8_t data, void *priv) } +uint8_t +log2i(uint32_t i) +{ + uint8_t ret = 0; + while ((i >>= 1)) + ret++; + return ret; +} + + void * i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t writable) { i2c_eeprom_t *dev = (i2c_eeprom_t *) malloc(sizeof(i2c_eeprom_t)); memset(dev, 0, sizeof(i2c_eeprom_t)); + /* Round size up to the next power of 2. */ + uint32_t pow_size = 1 << log2i(size); + if (pow_size < size) + size = pow_size << 1; size &= 0x7fffff; /* address space limit of 8 MB = 7 bits from I2C address + 16 bits */ i2c_eeprom_log("I2C EEPROM %s %02X: init(%d, %d)\n", i2c_getbusname(i2c), addr, size, writable); diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index da113c811..ff9cb73e3 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -622,7 +622,7 @@ MAINOBJ := pc.o config.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ usb.o device.o nvr.o nvr_at.o nvr_ps2.o \ $(VNCOBJ) -MEMOBJ := catalyst_flash.o intel_flash.o mem.o rom.o smram.o spd.o sst_flash.o +MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o smram.o spd.o sst_flash.o CPUOBJ := cpu.o cpu_table.o \ 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o $(CGTOBJ) \ @@ -654,7 +654,7 @@ MCHOBJ := machine.o machine_table.o \ DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o ibm_5161.o isamem.o isartc.o \ lpt.o pci_bridge.o postcard.o serial.o vpc2007.o \ - i2c.o i2c_eeprom.o i2c_gpio.o smbus_piix4.o \ + i2c.o i2c_gpio.o smbus_piix4.o \ keyboard.o \ keyboard_xt.o keyboard_at.o \ mouse.o \ From d9d592c3362cd6f7eae23326769bd51b6a58730d Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 30 Nov 2020 20:10:47 -0300 Subject: [PATCH 07/22] Change is_at checks to a new IS_AT macro which allows for ISA-less PCI machines --- src/include/86box/machine.h | 8 ++++---- src/machine/machine.c | 2 +- src/nvr.c | 2 +- src/pic.c | 8 ++++---- src/win/win_settings.c | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 9cb155f81..1191d5100 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -54,7 +54,6 @@ #define MACHINE_PCMCIA 0x00000400 /* sys is AT-compatible laptop with PCMCIA */ #define MACHINE_AGP 0x00000A0C /* sys is AT-compatible with AGP */ #define MACHINE_AGP98 0x00000A10 /* sys is NEC PC-98x1 series with AGP (did that even exist?) */ -#define MACHINE_IS_AT 0x00000FCC /* sys is AT-compatible (ISA + ISA16) */ /* Feature flags for miscellaneous internal devices. */ #define MACHINE_VIDEO 0x00001000 /* sys has int video */ #define MACHINE_VIDEO_ONLY 0x00002000 /* sys has fixed video */ @@ -83,7 +82,8 @@ #define MACHINE_SCSI 0x08000000 /* sys has int single SCSI - mark as pri SCSI */ #define MACHINE_SCSI_DUAL 0x18000000 /* sys has int dual SCSI - mark as both pri and sec SCSI */ -#define IS_ARCH(m, a) (machines[(m)].flags & (a)) ? 1 : 0; +#define IS_ARCH(m, a) (machines[m].flags & (a)) ? 1 : 0; +#define IS_AT(m) ((machines[m].flags & 0x00000FCC) && !(machines[m].flags & MACHINE_PC98)) ? 1 : 0; #define MACHINE_MULTIPLIER_FIXED -1, -1 @@ -492,8 +492,8 @@ extern int machine_at_apas3_init(const machine_t *); extern int machine_at_wcf681_init(const machine_t *); extern int machine_at_6via85x_init(const machine_t *); extern int machine_at_603tcf_init(const machine_t *); -extern int machine_at_trinity371_init(const machine_t *); -extern int machine_at_p6bap_init(const machine_t *); +extern int machine_at_trinity371_init(const machine_t *); +extern int machine_at_p6bap_init(const machine_t *); /* m_at_misc.c */ extern int machine_at_vpc2007_init(const machine_t *); diff --git a/src/machine/machine.c b/src/machine/machine.c index 4ff0993bd..19f821419 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -76,7 +76,7 @@ machine_init_ex(int m) is_vpc = 0; /* Set up the architecture flags. */ - AT = IS_ARCH(machine, (MACHINE_BUS_ISA16 | MACHINE_BUS_MCA | MACHINE_BUS_PCMCIA)); + AT = IS_AT(machine); PCI = IS_ARCH(machine, MACHINE_BUS_PCI); /* Reset the memory state. */ diff --git a/src/nvr.c b/src/nvr.c index fb7c3dfb8..d949c78bc 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -147,7 +147,7 @@ onesec_timer(void *priv) if (++nvr->onesec_cnt >= 100) { /* Update the internal clock. */ - is_at = IS_ARCH(machine, (MACHINE_BUS_ISA16 | MACHINE_BUS_MCA | MACHINE_BUS_PCMCIA)); + is_at = IS_AT(machine); if (!is_at) rtc_tick(); diff --git a/src/pic.c b/src/pic.c index ad2efc67e..8b0727070 100644 --- a/src/pic.c +++ b/src/pic.c @@ -176,7 +176,7 @@ find_best_interrupt(pic_t *dev) dev->interrupt = (ret == -1) ? 7 : ret; - is_at = IS_ARCH(machine, (MACHINE_BUS_ISA16 | MACHINE_BUS_MCA | MACHINE_BUS_PCMCIA)); + is_at = IS_AT(machine); if (is_at && (ret != -1) && (cpu_fast_off_flags & (1 << dev->interrupt))) cpu_fast_off_count = cpu_fast_off_val + 1; @@ -187,7 +187,7 @@ find_best_interrupt(pic_t *dev) void pic_update_pending(void) { - int is_at = IS_ARCH(machine, (MACHINE_BUS_ISA16 | MACHINE_BUS_MCA | MACHINE_BUS_PCMCIA)); + int is_at = IS_AT(machine); if (is_at) { pic2.int_pending = (find_best_interrupt(&pic2) != -1); @@ -227,7 +227,7 @@ pic_callback(void *priv) void pic_reset() { - int is_at = IS_ARCH(machine, (MACHINE_BUS_ISA16 | MACHINE_BUS_MCA | MACHINE_BUS_PCMCIA)); + int is_at = IS_AT(machine); memset(&pic, 0, sizeof(pic_t)); memset(&pic2, 0, sizeof(pic_t)); @@ -493,7 +493,7 @@ picint_common(uint16_t num, int level, int set) int is_at; uint8_t b, slaves = 0; - is_at = IS_ARCH(machine, (MACHINE_BUS_ISA16 | MACHINE_BUS_MCA | MACHINE_BUS_PCMCIA)); + is_at = IS_AT(machine); /* Make sure to ignore all slave IRQ's, and in case of AT+, translate IRQ 2 to IRQ 9. */ diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 1ca739b9d..ae674e328 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -783,7 +783,7 @@ win_settings_machine_recalc_machine(HWND hdlg) accel.nSec = 0; accel.nInc = machines[temp_machine].ram_granularity; SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); - is_at = IS_ARCH(temp_machine, (MACHINE_BUS_ISA16 | MACHINE_BUS_MCA | MACHINE_BUS_PCMCIA)); + is_at = IS_AT(temp_machine); if (!is_at || (machines[temp_machine].ram_granularity >= 128)) { SendMessage(h, UDM_SETPOS, 0, temp_mem_size); h = GetDlgItem(hdlg, IDC_TEXT_MB); @@ -990,7 +990,7 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) temp_mem_size = machines[temp_machine].min_ram; else if (temp_mem_size > machines[temp_machine].max_ram) temp_mem_size = machines[temp_machine].max_ram; - is_at = IS_ARCH(temp_machine, (MACHINE_BUS_ISA16 | MACHINE_BUS_MCA | MACHINE_BUS_PCMCIA)); + is_at = IS_AT(temp_machine); if (is_at && (machines[temp_machine].ram_granularity < 128)) temp_mem_size *= 1024; free(stransi); @@ -1609,7 +1609,7 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa settings_enable_window(hdlg, IDC_COMBO_SCSI, d); settings_enable_window(hdlg, IDC_CONFIGURE_SCSI, scsi_card_has_config(temp_scsi_card)); - is_at = IS_ARCH(temp_machine, (MACHINE_BUS_ISA16 | MACHINE_BUS_MCA | MACHINE_BUS_PCMCIA)); + is_at = IS_AT(temp_machine); settings_enable_window(hdlg, IDC_CHECK_IDE_TER, is_at); settings_enable_window(hdlg, IDC_BUTTON_IDE_TER, is_at && temp_ide_ter); settings_enable_window(hdlg, IDC_CHECK_IDE_QUA, is_at); From ee0d9f79f30b37e18f2ce044539aad70f46e15e4 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 30 Nov 2020 20:12:35 -0300 Subject: [PATCH 08/22] Make the ram(2) allocation failed fatals more user friendly --- src/mem/mem.c | 14 +++++++++----- src/win/win_settings.c | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/mem/mem.c b/src/mem/mem.c index ee92d995c..629325aad 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -25,6 +25,7 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> +#include <86box/version.h> #include "cpu.h" #include "x86_ops.h" #include "x86.h" @@ -2520,26 +2521,29 @@ mem_reset(void) } #endif if (mem_size > 2097152) - fatal("Attempting to use more than 2 GB of guest RAM\n"); + fatal("Attempting to use more than 2 GB of emulated RAM\n"); #if (!(defined __amd64__ || defined _M_X64)) if (mem_size > 1048576) { ram = (uint8_t *)malloc(1 << 30); /* allocate and clear the RAM block of the first 1 GB */ if (ram == NULL) { - fatal("X86 > 1 GB: Failed to malloc() ram\n"); + fatal("Failed to allocate primary RAM block. Make sure you have enough RAM available.\n"); return; } memset(ram, 0x00, (1 << 30)); ram2 = (uint8_t *)malloc(m - (1 << 30)); /* allocate and clear the RAM block above 1 GB */ if (ram2 == NULL) { - fatal("X86 > 1 GB: Failed to malloc() ram2\n"); + if (config_changed == 2) + fatal(EMU_NAME " must be restarted for the memory amount change to be applied.\n"); + else + fatal("Failed to allocate secondary RAM block. Make sure you have enough RAM available.\n"); return; } memset(ram2, 0x00, m - (1 << 30)); } else { ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ if (ram == NULL) { - fatal("X86 <= 1 GB: Failed to malloc() ram\n"); + fatal("Failed to allocate RAM block. Make sure you have enough RAM available.\n"); return; } memset(ram, 0x00, m); @@ -2547,7 +2551,7 @@ mem_reset(void) #else ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ if (ram == NULL) { - fatal("X64: Failed to malloc() ram\n"); + fatal("Failed to allocate RAM block. Make sure you have enough RAM available.\n"); return; } memset(ram, 0x00, m); diff --git a/src/win/win_settings.c b/src/win/win_settings.c index ae674e328..aad59192c 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -622,7 +622,7 @@ win_settings_save(void) } /* Mark configuration as changed. */ - config_changed = 1; + config_changed = 2; pc_reset_hard_init(); } From fa6d95db06bc9e695bf9bba9fddd4788f9a5b6fe Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 30 Nov 2020 20:14:10 -0300 Subject: [PATCH 09/22] Change Cyrix III CPU table according to the recently located Samuel 1 datasheet --- src/cpu/cpu_table.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 585f85831..93349437e 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -938,19 +938,24 @@ const cpu_family_t cpu_families[] = { .name = "Cyrix III", .internal_name = "c3_samuel", .cpus = { - {"66", CPU_CYRIX3S, fpus_internal, 66666666, 1.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 6, 6, 3, 3, 8}, /*66 MHz version*/ - {"233", CPU_CYRIX3S, fpus_internal, 233333333, 3.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 21, 21, 9, 9, 28}, - {"266", CPU_CYRIX3S, fpus_internal, 266666666, 4.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 24, 24, 12, 12, 32}, - {"300", CPU_CYRIX3S, fpus_internal, 300000000, 4.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 27, 27, 13, 13, 36}, - {"333", CPU_CYRIX3S, fpus_internal, 333333333, 5.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 30, 30, 15, 15, 40}, - {"350", CPU_CYRIX3S, fpus_internal, 350000000, 3.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 32, 32, 11, 11, 42}, - {"400", CPU_CYRIX3S, fpus_internal, 400000000, 4.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 36, 36, 12, 12, 48}, - {"450", CPU_CYRIX3S, fpus_internal, 450000000, 4.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 41, 41, 14, 14, 54}, /*^ is lower P2 speeds to allow emulation below 466 mhz*/ - {"500", CPU_CYRIX3S, fpus_internal, 500000000, 5.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 45, 45, 15, 15, 60}, - {"550", CPU_CYRIX3S, fpus_internal, 550000000, 5.5, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 50, 50, 17, 17, 66}, - {"600", CPU_CYRIX3S, fpus_internal, 600000000, 6.0, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 54, 54, 18, 18, 72}, - {"650", CPU_CYRIX3S, fpus_internal, 650000000, 6.5, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 58, 58, 20, 20, 78}, - {"700", CPU_CYRIX3S, fpus_internal, 700000000, 7.0, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 62, 62, 21, 21, 84}, + {"66", CPU_CYRIX3S, fpus_internal, 66666666, 1.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 6, 6, 3, 3, 8}, /* not in multiplier range */ + {"233", CPU_CYRIX3S, fpus_internal, 233333333, 3.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 21, 21, 9, 9, 28}, /* not in multiplier range */ + {"266", CPU_CYRIX3S, fpus_internal, 266666666, 4.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 24, 24, 12, 12, 32}, /* not in multiplier range */ + {"300", CPU_CYRIX3S, fpus_internal, 300000000, 4.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 27, 27, 13, 13, 36}, /* not specified */ + {"333", CPU_CYRIX3S, fpus_internal, 333333333, 5.0, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 30, 30, 15, 15, 40}, /* not specified */ + {"366", CPU_CYRIX3S, fpus_internal, 366666666, 5.5, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 33, 33, 16, 16, 44}, /* not specified */ + {"400", CPU_CYRIX3S, fpus_internal, 400000000, 6.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 36, 36, 17, 17, 48}, + {"433", CPU_CYRIX3S, fpus_internal, 433333333, 6.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 39, 39, 18, 18, 52}, /* not specified */ + {"450", CPU_CYRIX3S, fpus_internal, 450000000, 4.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 41, 41, 14, 14, 54}, + {"466", CPU_CYRIX3S, fpus_internal, 466666666, 6.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 42, 42, 14, 14, 56}, /* not specified */ + {"500", CPU_CYRIX3S, fpus_internal, 500000000, 5.0, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 45, 45, 15, 15, 60}, + {"533", CPU_CYRIX3S, fpus_internal, 533333333, 8.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 48, 48, 15, 15, 64}, /* not specified */ + {"550", CPU_CYRIX3S, fpus_internal, 550000000, 5.5, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 50, 50, 17, 17, 66}, + {"600/100", CPU_CYRIX3S, fpus_internal, 600000000, 6.0, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 54, 54, 18, 18, 72}, + {"600/133", CPU_CYRIX3S, fpus_internal, 600000000, 4.5, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 54, 54, 13, 13, 72}, + {"650", CPU_CYRIX3S, fpus_internal, 650000000, 6.5, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 58, 58, 20, 20, 78}, + {"667", CPU_CYRIX3S, fpus_internal, 666666667, 5.0, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 60, 60, 16, 16, 80}, + {"700", CPU_CYRIX3S, fpus_internal, 700000000, 7.0, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 63, 63, 21, 21, 84}, {"", 0} } }, { From 3fb42999b2536571a32efda3f22e51699eea6e4e Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 30 Nov 2020 20:16:04 -0300 Subject: [PATCH 10/22] Move SPD log() function to i2c_eeprom --- src/include/86box/i2c.h | 1 + src/mem/spd.c | 34 ++++++++++++---------------------- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/include/86box/i2c.h b/src/include/86box/i2c.h index e2135225c..58ef23bd1 100644 --- a/src/include/86box/i2c.h +++ b/src/include/86box/i2c.h @@ -55,6 +55,7 @@ extern uint8_t i2c_write(void *bus_handle, uint8_t addr, uint8_t data); extern void i2c_stop(void *bus_handle, uint8_t addr); /* i2c_eeprom.c */ +extern uint8_t log2i(uint32_t i); extern void *i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t writable); extern void i2c_eeprom_close(void *dev_handle); diff --git a/src/mem/spd.c b/src/mem/spd.c index 36aa5f34f..e3513d174 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -88,16 +88,6 @@ spd_init(const device_t *info) } -uint8_t -log2_ui16(uint16_t i) -{ - uint8_t ret = 0; - while ((i >>= 1)) - ret++; - return ret; -} - - int comp_ui16_rev(const void *elem1, const void *elem2) { @@ -117,7 +107,7 @@ spd_populate(uint16_t *rows, uint8_t slot_count, uint16_t total_size, uint16_t m memset(rows, 0, SPD_MAX_SLOTS << 1); for (row = 0; row < slot_count && total_size; row++) { /* populate slot */ - rows[row] = 1 << log2_ui16(MIN(total_size, max_module_size)); + rows[row] = 1 << log2i(MIN(total_size, max_module_size)); if (total_size >= rows[row]) { spd_log("SPD: Initial row %d = %d MB\n", row, rows[row]); total_size -= rows[row]; @@ -133,7 +123,7 @@ spd_populate(uint16_t *rows, uint8_t slot_count, uint16_t total_size, uint16_t m if (enable_asym) { row = slot_count - 1; do { - asym = (1 << log2_ui16(MIN(total_size, rows[row]))); + asym = (1 << log2i(MIN(total_size, rows[row]))); if (rows[row] + asym <= max_module_size) { rows[row] += asym; total_size -= asym; @@ -151,7 +141,7 @@ spd_populate(uint16_t *rows, uint8_t slot_count, uint16_t total_size, uint16_t m /* Look for a module to split. */ split = 0; for (row = 0; row < slot_count; row++) { - if ((rows[row] < (min_module_size << 1)) || (rows[row] != (1 << log2_ui16(rows[row])))) + if ((rows[row] < (min_module_size << 1)) || (rows[row] != (1 << log2i(rows[row])))) continue; /* no module here, module is too small to be split, or asymmetric module */ /* Find next empty row. */ @@ -224,7 +214,7 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) spd_modules[slot]->size = rows[row]; /* Determine the second row size, from which the first row size can be obtained. */ - asym = rows[row] - (1 << log2_ui16(rows[row])); /* separate the powers of 2 */ + asym = rows[row] - (1 << log2i(rows[row])); /* separate the powers of 2 */ if (!asym) /* is the module asymmetric? */ asym = rows[row] >> 1; /* symmetric, therefore divide by 2 */ @@ -245,10 +235,10 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) edo_data->bytes_used = 0x80; edo_data->spd_size = 0x08; edo_data->mem_type = ram_type; - edo_data->row_bits = SPD_ROLLUP(7 + log2_ui16(spd_modules[slot]->row1)); /* first row */ + edo_data->row_bits = SPD_ROLLUP(7 + log2i(spd_modules[slot]->row1)); /* first row */ edo_data->col_bits = 9; if (spd_modules[slot]->row1 != spd_modules[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */ - edo_data->row_bits |= SPD_ROLLUP(7 + log2_ui16(spd_modules[slot]->row2)) << 4; /* second row, if different from first */ + edo_data->row_bits |= SPD_ROLLUP(7 + log2i(spd_modules[slot]->row2)) << 4; /* second row, if different from first */ edo_data->col_bits |= 9 << 4; /* same as first row, but just in case */ } edo_data->banks = 2; @@ -281,10 +271,10 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) sdram_data->bytes_used = 0x80; sdram_data->spd_size = 0x08; sdram_data->mem_type = ram_type; - sdram_data->row_bits = SPD_ROLLUP(6 + log2_ui16(spd_modules[slot]->row1)); /* first row */ + sdram_data->row_bits = SPD_ROLLUP(6 + log2i(spd_modules[slot]->row1)); /* first row */ sdram_data->col_bits = 9; if (spd_modules[slot]->row1 != spd_modules[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */ - sdram_data->row_bits |= SPD_ROLLUP(6 + log2_ui16(spd_modules[slot]->row2)) << 4; /* second row, if different from first */ + sdram_data->row_bits |= SPD_ROLLUP(6 + log2i(spd_modules[slot]->row2)) << 4; /* second row, if different from first */ sdram_data->col_bits |= 9 << 4; /* same as first row, but just in case */ } sdram_data->rows = 2; @@ -306,10 +296,10 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) sdram_data->trp = sdram_data->trrd = sdram_data->trcd = sdram_data->tras = 1; if (spd_modules[slot]->row1 != spd_modules[slot]->row2) { /* Utilities interpret bank_density a bit differently on asymmetric modules. */ - sdram_data->bank_density = 1 << (log2_ui16(spd_modules[slot]->row1 >> 1) - 2); /* first row */ - sdram_data->bank_density |= 1 << (log2_ui16(spd_modules[slot]->row2 >> 1) - 2); /* second row */ + sdram_data->bank_density = 1 << (log2i(spd_modules[slot]->row1 >> 1) - 2); /* first row */ + sdram_data->bank_density |= 1 << (log2i(spd_modules[slot]->row2 >> 1) - 2); /* second row */ } else { - sdram_data->bank_density = 1 << (log2_ui16(spd_modules[slot]->row1 >> 1) - 1); /* symmetric module = only one bit is set */ + sdram_data->bank_density = 1 << (log2i(spd_modules[slot]->row1 >> 1) - 1); /* symmetric module = only one bit is set */ } sdram_data->ca_setup = sdram_data->data_setup = 0x15; sdram_data->ca_hold = sdram_data->data_hold = 0x08; @@ -355,7 +345,7 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit /* No SPD: split SIMMs into pairs as if they were "DIMM"s. */ if (!spd_present) { dimm = ((reg_max - reg_min) + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */ - spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2_ui16(machines[machine].max_ram / dimm)), 0); + spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2i(machines[machine].max_ram / dimm)), 0); } /* Write DRBs for each row. */ From fb0eb15f2b81f30441cfc745f3a0f96d57c390b6 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 30 Nov 2020 20:16:21 -0300 Subject: [PATCH 11/22] Disable LM75 logging --- src/device/hwm_lm75.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/hwm_lm75.c b/src/device/hwm_lm75.c index 19aefe314..086ae2bc1 100644 --- a/src/device/hwm_lm75.c +++ b/src/device/hwm_lm75.c @@ -35,7 +35,7 @@ static uint8_t lm75_i2c_read(void *bus, uint8_t addr, void *priv); static uint8_t lm75_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv); static void lm75_reset(lm75_t *dev); -#define ENABLE_LM75_LOG 1 + #ifdef ENABLE_LM75_LOG int lm75_do_log = ENABLE_LM75_LOG; From c536ea6ba5b78351f2bd5d142a0bc18396eee661 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 30 Nov 2020 20:17:28 -0300 Subject: [PATCH 12/22] Fix PIIX4 SMBus block reads --- src/device/smbus_piix4.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/device/smbus_piix4.c b/src/device/smbus_piix4.c index 8d457719f..dcb58131e 100644 --- a/src/device/smbus_piix4.c +++ b/src/device/smbus_piix4.c @@ -127,6 +127,9 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) smbus_addr = (dev->addr >> 1); read = dev->addr & 0x01; + cmd = (val >> 2) & 0xf; + smbus_piix4_log("SMBus PIIX4: addr=%02X read=%d protocol=%X cmd=%02X data0=%02X data1=%02X\n", smbus_addr, read, cmd, dev->cmd, dev->data0, dev->data1); + /* Raise DEV_ERR if no device is at this address, or if the device returned NAK when starting the transfer. */ if (!i2c_has_device(i2c_smbus, smbus_addr) || !i2c_start(i2c_smbus, smbus_addr, read)) { dev->next_stat = 0x04; @@ -137,8 +140,6 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) /* Decode the command protocol. VIA-specific modes (0x4 and [0x6:0xf]) are undocumented and required real hardware research. */ - cmd = (val >> 2) & 0xf; - smbus_piix4_log("SMBus PIIX4: protocol=%X cmd=%02X data0=%02X data1=%02X\n", cmd, dev->cmd, dev->data0, dev->data1); switch (cmd) { case 0x0: /* quick R/W */ break; @@ -217,15 +218,15 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) if (read) { /* block read [data0] (I2C) or [first byte] (SMBus) bytes */ - block_len = (cmd == 0x5) ? i2c_read(i2c_smbus, smbus_addr) : dev->data0; - for (i = 0; i < block_len; i++) + if (cmd == 0x5) + dev->data0 = i2c_read(i2c_smbus, smbus_addr); + for (i = 0; i < dev->data0; i++) dev->data[i & SMBUS_PIIX4_BLOCK_DATA_MASK] = i2c_read(i2c_smbus, smbus_addr); } else { - block_len = dev->data0; if (cmd == 0x5) /* send length [data0] as first byte on SMBus */ - i2c_write(i2c_smbus, smbus_addr, block_len); + i2c_write(i2c_smbus, smbus_addr, dev->data0); /* block write [data0] bytes */ - for (i = 0; i < block_len; i++) { + for (i = 0; i < dev->data0; i++) { if (!i2c_write(i2c_smbus, smbus_addr, dev->data[i & SMBUS_PIIX4_BLOCK_DATA_MASK])) break; } @@ -349,6 +350,8 @@ smbus_piix4_init(const device_t *info) memset(dev, 0, sizeof(smbus_piix4_t)); dev->local = info->local; + /* We save the I2C bus handle on dev but use i2c_smbus for all operations because + dev and therefore dev->i2c will be invalidated if a device triggers a hard reset. */ i2c_smbus = dev->i2c = i2c_addbus((dev->local == SMBUS_VIA) ? "smbus_vt82c686b" : "smbus_piix4"); timer_add(&dev->response_timer, smbus_piix4_response, dev, 0); From 750c721c5832c4d357c4f71e8c211fe7f317117a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 30 Nov 2020 20:18:50 -0300 Subject: [PATCH 13/22] Implement additional AS99127F reset register --- src/device/hwm_lm78.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/device/hwm_lm78.c b/src/device/hwm_lm78.c index ad4cb7425..db2b70bb0 100644 --- a/src/device/hwm_lm78.c +++ b/src/device/hwm_lm78.c @@ -24,6 +24,7 @@ #include <86box/86box.h> #include <86box/device.h> #include <86box/io.h> +#include <86box/timer.h> #include "cpu.h" #include <86box/i2c.h> #include <86box/hwm.h> @@ -50,6 +51,7 @@ typedef struct { uint32_t local; hwm_values_t *values; device_t *lm75[2]; + pc_timer_t hard_reset_timer; uint8_t regs[256]; uint8_t regs_782d[2][16]; @@ -369,10 +371,18 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) } break; + case 0x81: + /* CUV4X-LS performs a hard reset through this register. */ + if ((dev->local & LM78_AS99127F) && (val == 0xa9)) { + lm78_log("LM78: Hard reset requested through AS99127F\n"); + timer_set_delay_u64(&dev->hard_reset_timer, 1); /* hard reset on a timer to avoid issues caused by invalidation of the I2C bus */ + } + break; + case 0x87: - /* AS99127F boards perform a soft reset through this register */ + /* Other AS99127F boards perform a soft reset through this register. */ if ((dev->local & LM78_AS99127F) && (val == 0x01)) { - lm78_log("LM78: Reset requested through AS99127F\n"); + lm78_log("LM78: Soft reset requested through AS99127F\n"); resetx86(); } break; @@ -382,6 +392,13 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) } +static void +lm78_hard_reset_timer(void *priv) +{ + pc_reset_hard(); +} + + static void lm78_reset(lm78_t *dev, uint8_t initialization) { @@ -500,6 +517,8 @@ lm78_init(const device_t *info) if (dev->local & LM78_AS99127F) { /* AS99127: different -12V Rin value (bruteforced) */ defaults.voltages[5] = LM78_NEG_VOLTAGE(12000, 2400); + + timer_add(&dev->hard_reset_timer, lm78_hard_reset_timer, dev, 0); } else if (dev->local & LM78_W83782D) { /* W83782D: different negative voltage formula */ defaults.voltages[5] = LM78_NEG_VOLTAGE2(12000, 232); From 1e7bab8470ffe53bdf5b14f0a0cf29bc336b54df Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 30 Nov 2020 20:20:03 -0300 Subject: [PATCH 14/22] Make POST card PCjr detection a little more specific --- src/device/postcard.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/postcard.c b/src/device/postcard.c index 896f60b8b..b9f409589 100644 --- a/src/device/postcard.c +++ b/src/device/postcard.c @@ -94,7 +94,7 @@ postcard_reset(void) static void postcard_write(uint16_t port, uint8_t val, void *priv) { - if (postcard_written && val == postcard_code) + if (postcard_written && (val == postcard_code)) return; postcard_prev_code = postcard_code; @@ -117,7 +117,7 @@ postcard_init(const device_t *info) postcard_port = 0x190; /* ISA PS/2 machines */ else if (strstr(machines[machine].name, " IBM XT ")) postcard_port = 0x60; /* IBM XT */ - else if (strstr(machines[machine].name, "PCjr")) + else if (strstr(machines[machine].name, " IBM PCjr")) postcard_port = 0x10; /* IBM PCjr */ else if (strstr(machines[machine].name, " Compaq ") && !(machines[machine].flags & MACHINE_PCI)) postcard_port = 0x84; /* ISA Compaq machines */ From 73633abfca655e9589ed5ba28a061cd72731a828 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 30 Nov 2020 20:37:04 -0300 Subject: [PATCH 15/22] Rewrite I2C GPIO host controller --- src/device/i2c_gpio.c | 293 +++++++++--------------------------------- 1 file changed, 64 insertions(+), 229 deletions(-) diff --git a/src/device/i2c_gpio.c b/src/device/i2c_gpio.c index 08096123d..2b8cb9762 100644 --- a/src/device/i2c_gpio.c +++ b/src/device/i2c_gpio.c @@ -6,14 +6,12 @@ * * This file is part of the 86Box distribution. * - * Emulation of a GPIO-based I2C device. + * Emulation of a GPIO-based I2C host controller. * * * - * Authors: Sarah Walker, - * RichardG, + * Authors: RichardG, * - * Copyright 2008-2020 Sarah Walker. * Copyright 2020 RichardG. */ #include @@ -27,36 +25,11 @@ #include <86box/i2c.h> -enum { - TRANSMITTER_SLAVE = 1, - TRANSMITTER_MASTER = 2 -}; - -enum { - I2C_IDLE = 0, - I2C_RECEIVE, - I2C_RECEIVE_WAIT, - I2C_TRANSMIT_START, - I2C_TRANSMIT, - I2C_ACKNOWLEDGE, - I2C_NOTACKNOWLEDGE, - I2C_TRANSACKNOWLEDGE, - I2C_TRANSMIT_WAIT -}; - -enum { - SLAVE_IDLE = 0, - SLAVE_RECEIVEADDR, - SLAVE_RECEIVEDATA, - SLAVE_SENDDATA, - SLAVE_INVALID -}; - typedef struct { char *bus_name; void *i2c; - uint8_t scl, sda, receive_wait_sda, state, slave_state, slave_addr, - slave_read, last_sda, pos, transmit, byte; + uint8_t prev_scl, prev_sda, slave_sda, started, + slave_addr_received, slave_addr, slave_read, pos, byte; } i2c_gpio_t; @@ -90,7 +63,7 @@ i2c_gpio_init(char *bus_name) dev->bus_name = bus_name; dev->i2c = i2c_addbus(dev->bus_name); - dev->scl = dev->sda = 1; + dev->prev_scl = dev->prev_sda = dev->slave_sda = 1; dev->slave_addr = 0xff; return dev; @@ -110,206 +83,77 @@ i2c_gpio_close(void *dev_handle) } -void -i2c_gpio_next_byte(i2c_gpio_t *dev) -{ - dev->byte = i2c_read(dev->i2c, dev->slave_addr); - i2c_gpio_log(1, "I2C GPIO %s: Transmitting data %02X\n", dev->bus_name, dev->byte); -} - - -uint8_t -i2c_gpio_write(i2c_gpio_t *dev) -{ - uint8_t i; - - switch (dev->slave_state) { - case SLAVE_IDLE: - i = dev->slave_addr; - dev->slave_addr = dev->byte >> 1; - dev->slave_read = dev->byte & 1; - - i2c_gpio_log(1, "I2C GPIO %s: Initiating %s address %02X\n", dev->bus_name, dev->slave_read ? "read from" : "write to", dev->slave_addr); - - if (!i2c_has_device(dev->i2c, dev->slave_addr) || - ((i == 0xff) && !i2c_start(dev->i2c, dev->slave_addr, dev->slave_read))) { /* start only once per transfer */ - dev->slave_state = SLAVE_INVALID; - dev->slave_addr = 0xff; - return I2C_NOTACKNOWLEDGE; - } - - if (dev->slave_read) { - dev->slave_state = SLAVE_SENDDATA; - dev->transmit = TRANSMITTER_SLAVE; - dev->byte = i2c_read(dev->i2c, dev->slave_addr); - } else { - dev->slave_state = SLAVE_RECEIVEADDR; - dev->transmit = TRANSMITTER_MASTER; - } - break; - - case SLAVE_RECEIVEADDR: - i2c_gpio_log(1, "I2C GPIO %s: Receiving address %02X\n", dev->bus_name, dev->byte); - dev->slave_state = dev->slave_read ? SLAVE_SENDDATA : SLAVE_RECEIVEDATA; - if (!i2c_write(dev->i2c, dev->slave_addr, dev->byte)) - return I2C_NOTACKNOWLEDGE; - break; - - case SLAVE_RECEIVEDATA: - i2c_gpio_log(1, "I2C GPIO %s: Receiving data %02X\n", dev->bus_name, dev->byte); - if (!i2c_write(dev->i2c, dev->slave_addr, dev->byte)) - return I2C_NOTACKNOWLEDGE; - break; - - case SLAVE_INVALID: - return I2C_NOTACKNOWLEDGE; - } - - return I2C_ACKNOWLEDGE; -} - - -void -i2c_gpio_stop(i2c_gpio_t *dev) -{ - i2c_gpio_log(1, "I2C GPIO %s: Stopping transfer\n", dev->bus_name); - - if (dev->slave_addr != 0xff) /* don't stop if no transfer was in progress */ - i2c_stop(dev->i2c, dev->slave_addr); - - dev->slave_addr = 0xff; - dev->slave_state = SLAVE_IDLE; - dev->transmit = TRANSMITTER_MASTER; -} - - void i2c_gpio_set(void *dev_handle, uint8_t scl, uint8_t sda) { i2c_gpio_t *dev = (i2c_gpio_t *) dev_handle; - i2c_gpio_log(3, "I2C GPIO %s: scl=%d->%d sda=%d->%d last_valid_sda=%d state=%d\n", dev->bus_name, dev->scl, scl, dev->last_sda, sda, dev->sda, dev->state); + i2c_gpio_log(3, "I2C GPIO %s: write scl=%d->%d sda=%d->%d read=%d\n", dev->bus_name, dev->prev_scl, scl, dev->prev_sda, sda, dev->slave_read); - switch (dev->state) { - case I2C_IDLE: - if (scl && dev->last_sda && !sda) { /* start condition; dev->scl check breaks NCR SDMS */ - i2c_gpio_log(2, "I2C GPIO %s: Start condition received (from IDLE)\n", dev->bus_name); - dev->state = I2C_RECEIVE; - dev->pos = 0; - } - break; + if (dev->prev_scl && scl) { + if (dev->prev_sda && !sda) { + i2c_gpio_log(2, "I2C GPIO %s: Start condition\n", dev->bus_name); + dev->started = 1; + dev->pos = 0; + dev->slave_read = 2; /* start with address transfer */ + dev->slave_sda = 1; + } else if (!dev->prev_sda && sda) { + i2c_gpio_log(2, "I2C GPIO %s: Stop condition\n", dev->bus_name); + dev->started = 0; + dev->slave_sda = 1; + } + } else if (!dev->prev_scl && scl && dev->started) { + if (dev->pos++ < 8) { + if (dev->slave_read == 1) { + dev->slave_sda = !!(dev->byte & 0x80); + dev->byte <<= 1; + } else { + dev->byte <<= 1; + dev->byte |= sda; + } - case I2C_RECEIVE_WAIT: - if (!dev->scl && scl) - dev->state = I2C_RECEIVE; - else if (!dev->scl && !scl && dev->last_sda && sda) /* workaround for repeated start condition on Windows XP DDC */ - dev->receive_wait_sda = 1; - /* fall-through */ + i2c_gpio_log(2, "I2C GPIO %s: Bit %d = %d\n", dev->bus_name, 8 - dev->pos, (dev->slave_read == 1) ? dev->slave_sda : sda); + } - case I2C_RECEIVE: - if (!dev->scl && scl) { - dev->byte <<= 1; - if (sda) - dev->byte |= 1; - else - dev->byte &= 0xfe; - if (++dev->pos == 8) - dev->state = i2c_gpio_write(dev); - } else if (dev->scl && scl) { - if (sda && !dev->last_sda) { /* stop condition */ - i2c_gpio_log(2, "I2C GPIO %s: Stop condition received (from RECEIVE)\n", dev->bus_name); - dev->state = I2C_IDLE; - i2c_gpio_stop(dev); - } else if (!sda && dev->last_sda) { /* start condition */ - i2c_gpio_log(2, "I2C GPIO %s: Start condition received (from RECEIVE)\n", dev->bus_name); - dev->pos = 0; - dev->slave_state = SLAVE_IDLE; - } - } - break; + if (dev->pos == 8) { + i2c_gpio_log(2, "I2C GPIO %s: Byte = %02X\n", dev->bus_name, dev->byte); - case I2C_ACKNOWLEDGE: - if (!dev->scl && scl) { - i2c_gpio_log(2, "I2C GPIO %s: Acknowledging transfer to %02X\n", dev->bus_name, dev->slave_addr); - sda = 0; - dev->receive_wait_sda = 0; /* ack */ - dev->pos = 0; - dev->state = (dev->transmit == TRANSMITTER_MASTER) ? I2C_RECEIVE_WAIT : I2C_TRANSMIT; - } - break; + /* (N)ACKing here instead of at the 9th bit may sound odd, but is required by the Matrox Mystique Windows drivers. */ + switch (dev->slave_read) { + case 2: /* address transfer */ + dev->slave_addr = dev->byte >> 1; + dev->slave_read = (dev->byte & 1); - case I2C_NOTACKNOWLEDGE: - if (!dev->scl && scl) { - i2c_gpio_log(2, "I2C GPIO %s: Not acknowledging transfer\n", dev->bus_name); - sda = 1; - dev->pos = 0; - dev->state = I2C_IDLE; - dev->slave_state = SLAVE_IDLE; - } - break; + /* slave ACKs? */ + dev->slave_sda = !(i2c_has_device(dev->i2c, dev->slave_addr) && i2c_start(dev->i2c, dev->slave_addr, dev->slave_read)); + i2c_gpio_log(2, "I2C GPIO %s: Slave %02X %s %sACK\n", dev->bus_name, dev->slave_addr, dev->slave_read ? "read" : "write", dev->slave_sda ? "N" : ""); - case I2C_TRANSACKNOWLEDGE: - if (!dev->scl && scl) { - if (sda) { /* not acknowledged; must be end of transfer */ - i2c_gpio_log(2, "I2C GPIO %s: End of transfer\n", dev->bus_name); - dev->state = I2C_IDLE; - i2c_gpio_stop(dev); - } else { /* next byte to transfer */ - dev->state = I2C_TRANSMIT_START; - i2c_gpio_next_byte(dev); - dev->pos = 0; - i2c_gpio_log(2, "I2C GPIO %s: Next byte = %02X\n", dev->bus_name, dev->byte); - } - } - break; + if (!dev->slave_sda && dev->slave_read) /* read first byte on an ACKed read transfer */ + dev->byte = i2c_read(dev->i2c, dev->slave_addr); - case I2C_TRANSMIT_WAIT: - if (dev->scl && scl) { - if (dev->last_sda && !sda) { /* start condition */ - i2c_gpio_next_byte(dev); - dev->pos = 0; - i2c_gpio_log(2, "I2C GPIO %s: Next byte = %02X\n", dev->bus_name, dev->byte); - } - if (!dev->last_sda && sda) { /* stop condition */ - i2c_gpio_log(2, "I2C GPIO %s: Stop condition received (from TRANSMIT_WAIT)\n", dev->bus_name); - dev->state = I2C_IDLE; - i2c_gpio_stop(dev); - } - } - break; + dev->slave_read |= 0x80; /* slave_read was overwritten; stop the master ACK read logic from running at the 9th bit if we're reading */ + break; - case I2C_TRANSMIT_START: - if (!dev->scl && scl) - dev->state = I2C_TRANSMIT; - if (dev->scl && scl && !dev->last_sda && sda) { /* stop condition */ - i2c_gpio_log(2, "I2C GPIO %s: Stop condition received (from TRANSMIT_START)\n", dev->bus_name); - dev->state = I2C_IDLE; - i2c_gpio_stop(dev); - } - /* fall-through */ - - case I2C_TRANSMIT: - if (!dev->scl && scl) { - dev->scl = scl; - if (!dev->pos) - i2c_gpio_log(2, "I2C GPIO %s: Transmit byte %02X\n", dev->bus_name, dev->byte); - dev->sda = sda = dev->byte & 0x80; - i2c_gpio_log(2, "I2C GPIO %s: Transmit bit %02X %d\n", dev->bus_name, dev->byte, dev->pos); - dev->byte <<= 1; - dev->pos++; - return; - } - if (dev->scl && !scl && (dev->pos == 8)) { - dev->state = I2C_TRANSACKNOWLEDGE; - i2c_gpio_log(2, "I2C GPIO %s: Acknowledge mode\n", dev->bus_name); - } - break; + case 0: /* write transfer */ + dev->slave_sda = !i2c_write(dev->i2c, dev->slave_addr, dev->byte); + i2c_gpio_log(2, "I2C GPIO %s: Write %02X %sACK\n", dev->bus_name, dev->byte, dev->slave_sda ? "N" : ""); + break; + } + } else if (dev->pos == 9) { + if (dev->slave_read == 1) { /* read transfer (unless we're in an address transfer) */ + if (!sda) /* master ACKs? */ + dev->byte = i2c_read(dev->i2c, dev->slave_addr); + i2c_gpio_log(2, "I2C GPIO %s: Read %02X %sACK\n", dev->bus_name, dev->byte, sda ? "N" : ""); + } else + dev->slave_read &= 1; /* if we're in an address transfer, clear it */ + dev->pos = 0; /* start over */ + } + } else if (dev->prev_scl && !scl && (dev->pos != 8)) { /* keep (N)ACK computed at the 8th bit when transitioning to the 9th bit */ + dev->slave_sda = 1; } - if (!dev->scl && scl) - dev->sda = sda; - dev->last_sda = sda; - dev->scl = scl; + dev->prev_scl = scl; + dev->prev_sda = sda; } @@ -317,7 +161,7 @@ uint8_t i2c_gpio_get_scl(void *dev_handle) { i2c_gpio_t *dev = (i2c_gpio_t *) dev_handle; - return dev->scl; + return dev->prev_scl; } @@ -325,17 +169,8 @@ uint8_t i2c_gpio_get_sda(void *dev_handle) { i2c_gpio_t *dev = (i2c_gpio_t *) dev_handle; - switch (dev->state) { - case I2C_TRANSMIT: - case I2C_ACKNOWLEDGE: - return dev->sda; - - case I2C_RECEIVE_WAIT: - return dev->receive_wait_sda; - - default: - return 1; - } + i2c_gpio_log(3, "I2C GPIO %s: read myscl=%d mysda=%d slavesda=%d\n", dev->bus_name, dev->prev_scl, dev->prev_sda, dev->slave_sda); + return dev->prev_sda && dev->slave_sda; } From b895b096fb26abcdc201e8791f25572b42751bfe Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 30 Nov 2020 20:37:58 -0300 Subject: [PATCH 16/22] Fix VIA northbridge DRB and bus speed strap registers --- src/chipset/via_apollo.c | 141 ++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 62 deletions(-) diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index f1c468460..ccb2d4a59 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -25,6 +25,7 @@ #include #include #include <86box/86box.h> +#include "cpu.h" #include <86box/mem.h> #include <86box/smram.h> #include <86box/io.h> @@ -35,18 +36,19 @@ #include <86box/chipset.h> #include <86box/spd.h> -#define VIA_585 0x05850000 -#define VIA_595 0x05950000 -#define VIA_597 0x05970100 -#define VIA_598 0x05980000 -#define VIA_691 0x06910000 +#define VIA_585 0x05850000 +#define VIA_595 0x05950000 +#define VIA_597 0x05970100 +#define VIA_598 0x05980000 +#define VIA_691 0x06910000 #define VIA_693A 0x06914400 -#define VIA_694 0x0691c200 +#define VIA_694 0x0691c200 #define VIA_8601 0x86010500 typedef struct via_apollo_t { uint32_t id; + uint8_t drb_unit; uint8_t pci_conf[256]; smram_t *smram; @@ -98,10 +100,10 @@ via_apollo_setup(via_apollo_t *dev) dev->pci_conf[0x04] = 6; dev->pci_conf[0x05] = 0; - if ((dev->id >= VIA_585) || (dev->id < VIA_597)) + if ((dev->id >= VIA_585) || (dev->id < VIA_597)) dev->pci_conf[0x06] = 0xa0; - else - dev->pci_conf[0x06] = 0x90; + else + dev->pci_conf[0x06] = 0x90; dev->pci_conf[0x07] = 0x02; @@ -114,31 +116,30 @@ via_apollo_setup(via_apollo_t *dev) dev->pci_conf[0x0e] = 0; dev->pci_conf[0x0f] = 0; - if (dev->id >= VIA_597) - { - dev->pci_conf[0x10] = 0x08; - dev->pci_conf[0x34] = 0xa0; - } + if (dev->id >= VIA_597) { + dev->pci_conf[0x10] = 0x08; + dev->pci_conf[0x34] = 0xa0; + } - if ((dev->id >= VIA_585) || (dev->id < VIA_597)) + if ((dev->id >= VIA_585) || (dev->id < VIA_597)) dev->pci_conf[0x52] = 0x02; - else if (dev->id >= VIA_694) + else if (dev->id >= VIA_694) dev->pci_conf[0x52] = (dev->id == VIA_694) ? 0x90 : 0x10; - if(dev->id >= VIA_693A) + if (dev->id >= VIA_693A) dev->pci_conf[0x53] = 0x10; if (dev->id == VIA_691) { - dev->pci_conf[0x56] = 0x01; + dev->pci_conf[0x56] = 0x01; dev->pci_conf[0x57] = 0x01; } if (dev->id >= VIA_693A) - dev->pci_conf[0x58] = 0x40; - else if (dev->id >= VIA_585) + dev->pci_conf[0x58] = 0x40; + else if (dev->id >= VIA_585) dev->pci_conf[0x58] = 0x05; - if ((dev->id >= VIA_585) || (dev->id < VIA_597)) + if ((dev->id >= VIA_585) || (dev->id < VIA_597)) dev->pci_conf[0x59] = 0x02; dev->pci_conf[0x5a] = 0x01; @@ -149,33 +150,46 @@ via_apollo_setup(via_apollo_t *dev) dev->pci_conf[0x5f] = 0x01; dev->pci_conf[0x64] = ((dev->id >= VIA_585) || (dev->id < VIA_597)) ? 0xab : 0xec; - if (dev->id >= VIA_597) - { - dev->pci_conf[0x65] = 0xec; - dev->pci_conf[0x66] = 0xec; - } - if (dev->id >= VIA_691) - dev->pci_conf[0x67] = 0xec; /* DRAM Timing for Banks 6,7. */ + if (dev->id >= VIA_597) { + dev->pci_conf[0x65] = 0xec; + dev->pci_conf[0x66] = 0xec; + } + if (dev->id >= VIA_691) + dev->pci_conf[0x67] = 0xec; /* DRAM Timing for Banks 6, 7 */ + if (dev->id >= VIA_693A) { + if (cpu_busspeed < 95000000) + dev->pci_conf[0x68] |= 0x00; /* 66 MHz */ + else if (cpu_busspeed < 124000000) + dev->pci_conf[0x68] |= 0x01; /* 100 MHz */ + else + dev->pci_conf[0x68] |= (dev->id == VIA_8601) ? 0x03 : 0x02; /* 133 MHz */ + } else if (dev->id >= VIA_598) { + if (cpu_busspeed < 75000000) + dev->pci_conf[0x68] |= 0x00; /* 66 MHz */ + else if (cpu_busspeed < 100000000) + dev->pci_conf[0x68] |= (dev->id >= VIA_691) ? 0x00 : 0x03; /* 75/83 MHz (66 MHz on 691) */ + else + dev->pci_conf[0x68] |= 0x01; /* 100 MHz */ + } dev->pci_conf[0x6b] = 0x01; - if(dev->id >= VIA_597) - { - dev->pci_conf[0xa0] = 0x02; - dev->pci_conf[0xa2] = 0x10; - dev->pci_conf[0xa4] = 0x03; - dev->pci_conf[0xa5] = 0x02; - dev->pci_conf[0xa7] = 0x07; + if (dev->id >= VIA_597) { + dev->pci_conf[0xa0] = 0x02; + dev->pci_conf[0xa2] = 0x10; + dev->pci_conf[0xa4] = 0x03; + dev->pci_conf[0xa5] = 0x02; + dev->pci_conf[0xa7] = 0x07; - if(dev->id == VIA_693A) { - dev->pci_conf[0xac] = 0x08; - dev->pci_conf[0xad] = 0x02; + if (dev->id == VIA_693A) { + dev->pci_conf[0xac] = 0x08; + dev->pci_conf[0xad] = 0x02; } - if(dev->id == VIA_694) { - dev->pci_conf[0xb0] = 0x80; /* The datasheet refers it as 8xh */ - dev->pci_conf[0xb1] = 0x63; - } + if (dev->id == VIA_694) { + dev->pci_conf[0xb0] = 0x80; /* The datasheet refers it as 8xh */ + dev->pci_conf[0xb1] = 0x63; } + } } @@ -291,10 +305,10 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) break; case 0x56: case 0x57: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: /* DRAM Row Ending Address */ - if (dev->id >= VIA_691) - spd_write_drbs(dev->pci_conf, 0x5a, 0x56, 8); + if ((dev->id >= VIA_691) && (dev->id != VIA_8601)) + spd_write_drbs(dev->pci_conf, 0x5a, 0x56, dev->drb_unit); else if (addr >= 0x5a) - spd_write_drbs(dev->pci_conf, 0x5a, 0x5f, 8); + spd_write_drbs(dev->pci_conf, 0x5a, 0x5f, dev->drb_unit); break; case 0x58: @@ -427,25 +441,21 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[0x66] = val; break; case 0x68: - if(dev->id != VIA_595){ - if (dev->id == VIA_597) - dev->pci_conf[0x68] = (dev->pci_conf[0x6b] & ~0xfe) | (val & 0xfe); - else if ((dev->id == VIA_598) || (dev->id == VIA_693A) || (dev->id == VIA_8601)) - dev->pci_conf[0x68] = val; - else if (dev->id == VIA_694) - dev->pci_conf[0x68] = (dev->pci_conf[0x68] & ~0xdf) | (val & 0xdf); - else if (dev->id == VIA_585) - dev->pci_conf[0x68] = (dev->pci_conf[0x68] & ~0x08) | (val & 0x08); - else - dev->pci_conf[0x68] = (dev->pci_conf[0x6b] & ~0xfd) | (val & 0xfd); - break; + if (dev->id != VIA_595) { + if (dev->id == VIA_597) + dev->pci_conf[0x68] = (dev->pci_conf[0x68] & ~0xfe) | (val & 0xfe); + else if ((dev->id == VIA_693A) || (dev->id == VIA_694)) + dev->pci_conf[0x68] = (dev->pci_conf[0x68] & ~0xdc) | (val & 0xdc); + else + dev->pci_conf[0x68] = (dev->pci_conf[0x68] & ~0xfc) | (val & 0xfc); } + break; case 0x69: - if((dev->id != VIA_585) || (dev->id != VIA_595)){ - if ((dev->id == VIA_693A) || (dev->id < VIA_8601)) - dev->pci_conf[0x69] = (dev->pci_conf[0x69] & ~0xfe) | (val & 0xfe); - else - dev->pci_conf[0x69] = val; + if ((dev->id != VIA_585) || (dev->id != VIA_595)){ + if ((dev->id == VIA_693A) || (dev->id < VIA_8601)) + dev->pci_conf[0x69] = (dev->pci_conf[0x69] & ~0xfe) | (val & 0xfe); + else + dev->pci_conf[0x69] = val; } break; case 0x6b: @@ -684,6 +694,13 @@ via_apollo_init(const device_t *info) break; } + if ((dev->id >= VIA_694) && (dev->id != VIA_8601)) + dev->drb_unit = 16; + else if (dev->id >= VIA_597) + dev->drb_unit = 8; + else + dev->drb_unit = 4; + via_apollo_setup(dev); via_apollo_reset(dev); From 89d5a0f9116bec58242b46cefccda84433051b51 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 2 Dec 2020 18:24:07 -0300 Subject: [PATCH 17/22] Disable I2C EEPROM logging --- src/mem/i2c_eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mem/i2c_eeprom.c b/src/mem/i2c_eeprom.c index 68b5019cc..62615db34 100644 --- a/src/mem/i2c_eeprom.c +++ b/src/mem/i2c_eeprom.c @@ -33,7 +33,7 @@ typedef struct { uint8_t addr_len, addr_pos; } i2c_eeprom_t; -#define ENABLE_I2C_EEPROM_LOG 1 + #ifdef ENABLE_I2C_EEPROM_LOG int i2c_eeprom_do_log = ENABLE_I2C_EEPROM_LOG; From a90d8d1e65945b297cb7df7fff54b75e58e8bd19 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 2 Dec 2020 21:58:01 -0300 Subject: [PATCH 18/22] Implement VIA southbridge UDMA status bit, fixes UDMA on Windows --- src/chipset/via_pipc.c | 108 ++++++++++++++++++++++++++++++----------- src/disk/hdc_ide.c | 3 +- 2 files changed, 83 insertions(+), 28 deletions(-) diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index b11ac4548..8d95778a7 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -171,7 +171,7 @@ pipc_reset_hard(void *priv) if (dev->local <= VIA_PIPC_586B) dev->ide_regs[0x40] = 0x04; - dev->ide_regs[0x41] = 0x02; + dev->ide_regs[0x41] = (dev->local <= VIA_PIPC_686A) ? 0x06 : 0x02; dev->ide_regs[0x42] = 0x09; dev->ide_regs[0x43] = (dev->local >= VIA_PIPC_686A) ? 0x0a : 0x3a; dev->ide_regs[0x44] = 0x68; @@ -400,7 +400,7 @@ pipc_read(int func, int addr, void *priv) if (func > dev->max_func) return ret; else if (func == 0) { /* PCI-ISA bridge */ - if ((addr >= 0x60) && (addr <= 0x6f)) { + if ((addr >= 0x60) && (addr <= 0x6f)) { /* DMA shadow registers */ c = (addr & 0x0e) >> 1; if (addr & 0x01) ret = (dma[c].ab & 0x0000ff00) >> 8; @@ -411,19 +411,38 @@ pipc_read(int func, int addr, void *priv) } else ret = dev->pci_isa_regs[addr]; } - else if ((func == 1) && !(dev->pci_isa_regs[0x48] & 0x02)) /* IDE */ + else if ((func == 1) && !(dev->pci_isa_regs[0x48] & 0x02)) { /* IDE */ ret = dev->ide_regs[addr]; + if ((addr >= 0x50) && (addr <= 0x53)) { /* UDMA timing registers */ + /* Set or clear bit 5 according to UDMA mode. Documentation is unclear, but a real + 686B does set bit 5 when UDMA is enabled through the method specified in bit 7. */ + c = 0x53 - addr; + if (ret & 0x80) /* bit 7 set = use bit 6 */ + c = ret & 0x40; + else if (ide_drives[c]) /* bit 7 clear = use SET FEATURES mode */ + c = (ide_drives[c]->mdma_mode & 0xf00) == 0x300; + else /* no drive here */ + c = 0; + /* 586A/B datasheet claims bit 5 must be clear for UDMA, unlike later models where + it must be set, but the Windows driver doesn't care and always checks if it's set. */ + if (c) + ret |= 0x20; + else + ret &= ~0x20; + } + } else if ((func < pm_func) && !((func == 2) ? (dev->pci_isa_regs[0x48] & 0x04) : (dev->pci_isa_regs[0x85] & 0x10))) /* USB */ ret = dev->usb_regs[func - 2][addr]; else if (func == pm_func) { /* Power */ ret = dev->power_regs[addr]; if (addr == 0x42) { - ret &= ~0x10; if (dev->nvr->regs[0x0d] & 0x80) ret |= 0x10; + else + ret &= ~0x10; } } - else if ((func <= (pm_func + 2)) && !(dev->pci_isa_regs[0x85] & ((func == (pm_func + 1)) ? 0x04 : 0x08)) && 0) /* AC97 / MC97; temporarily disabled while unimplemented */ + else if ((func <= (pm_func + 2)) && !(dev->pci_isa_regs[0x85] & ((func == (pm_func + 1)) ? 0x04 : 0x08))) /* AC97 / MC97 */ ret = dev->ac97_regs[func - pm_func - 1][addr]; pipc_log("PIPC: read(%d, %02X) = %02X\n", func, addr, ret); @@ -667,31 +686,69 @@ pipc_write(int func, int addr, uint8_t val, void *priv) break; case 0x40: - if (dev->local <= VIA_PIPC_586B) { - dev->ide_regs[0x40] = val & 0x03; - dev->ide_regs[0x40] |= 0x04; - } else + if (dev->local <= VIA_PIPC_586B) + dev->ide_regs[0x40] = (val & 0x03) | 0x04; + else dev->ide_regs[0x40] = val & 0x0f; pipc_ide_handlers(dev); break; - case 0x50: case 0x52: - if (dev->local <= VIA_PIPC_586B) - dev->ide_regs[addr] = val & 0xe3; - else if (dev->local <= VIA_PIPC_596B) - dev->ide_regs[addr] = val & 0xeb; - else if (dev->local <= VIA_PIPC_686A) - dev->ide_regs[addr] = val & 0xef; + case 0x41: + if (dev->local <= VIA_PIPC_686A) + dev->ide_regs[0x41] = val; else - dev->ide_regs[addr] = val & 0xf7; + dev->ide_regs[0x41] = val & 0xf2; break; - case 0x51: case 0x53: - if (dev->local <= VIA_PIPC_596B) - dev->ide_regs[addr] = val & 0xe3; - else if (dev->local <= VIA_PIPC_686A) - dev->ide_regs[addr] = val & 0xe7; + + case 0x43: + if (dev->local <= VIA_PIPC_586A) + dev->ide_regs[0x43] = (val & 0x6f) | 0x10; + else if (dev->local <= VIA_PIPC_586B) + dev->ide_regs[0x43] = (val & 0xef) | 0x10; else - dev->ide_regs[addr] = val & 0xf7; + dev->ide_regs[0x43] = val & 0x0f; + break; + + case 0x44: + if (dev->local <= VIA_PIPC_586A) + dev->ide_regs[0x44] = val & 0x78; + else if (dev->local <= VIA_PIPC_586B) + dev->ide_regs[0x44] = val & 0x7b; + else if (dev->local <= VIA_PIPC_596B) + dev->ide_regs[0x44] = val & 0x7f; + else if (dev->local <= VIA_PIPC_686A) + dev->ide_regs[0x44] = val & 0x69; + else + dev->ide_regs[0x44] = val & 0x7d; + break; + + case 0x45: + if (dev->local <= VIA_PIPC_586B) + dev->ide_regs[0x45] = val & 0x40; + else if (dev->local <= VIA_PIPC_596B) + dev->ide_regs[0x45] = val & 0x4f; + else if (dev->local <= VIA_PIPC_686A) + dev->ide_regs[0x45] = val & 0x5f; + else + dev->ide_regs[0x45] = (val & 0x5c) | 0x20; + break; + + case 0x46: + if (dev->local <= VIA_PIPC_686A) + dev->ide_regs[0x46] = val & 0xf3; + else + dev->ide_regs[0x46] = val & 0xc0; + break; + + case 0x50: case 0x51: case 0x52: case 0x53: + if (dev->local <= VIA_PIPC_586B) + dev->ide_regs[addr] = val & 0xc3; + else if (dev->local <= VIA_PIPC_596B) + dev->ide_regs[addr] = val & ((addr & 1) ? 0xc3 : 0xcb); + else if (dev->local <= VIA_PIPC_686A) + dev->ide_regs[addr] = val & ((addr & 1) ? 0xc7 : 0xcf); + else + dev->ide_regs[addr] = val & 0xd7; break; case 0x61: case 0x69: @@ -805,9 +862,6 @@ pipc_write(int func, int addr, uint8_t val, void *priv) if ((func == (pm_func + 2)) && ((addr == 0x4a) || (addr == 0x4b) || (dev->pci_isa_regs[0x85] & 0x08))) return; - if (1) /* temporarily disabled while unimplemented */ - return; - switch (addr) { default: dev->ac97_regs[func - pm_func - 1][addr] = val; @@ -879,7 +933,7 @@ pipc_init(const device_t *info) if (dev->local >= VIA_PIPC_596A) dev->acpi = device_add(&acpi_via_596b_device); else if (dev->local >= VIA_PIPC_586B) - dev->acpi = device_add(&acpi_via_device); + dev->acpi = device_add(&acpi_via_device); dev->usb[0] = device_add_inst(&usb_device, 1); if (dev->local >= VIA_PIPC_686A) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index b2a708414..a47eb1654 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -573,7 +573,8 @@ ide_identify(ide_t *ide) ide->buffer[51] = ide_get_timings(ide, TIMINGS_PIO); ide->buffer[53] &= 0xfff9; ide->buffer[52] = ide->buffer[62] = ide->buffer[63] = ide->buffer[64] = 0x0000; - ide->buffer[65] = ide->buffer[66] = ide->buffer[67] = ide->buffer[68] = 0x0000; + ide->buffer[65] = ide->buffer[66] = ide_get_timings(ide, TIMINGS_DMA); + ide->buffer[67] = ide->buffer[68] = 0x0000; ide->buffer[88] = 0x0000; if (max_pio >= 3) { From 535e11d83797245e14a487b91bbcc1bf647b1be0 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 3 Dec 2020 00:40:13 -0300 Subject: [PATCH 19/22] Add ICS 9xxx clock generators --- src/device/clock_ics9xxx.c | 906 +++++++++++++++++++++++++++++++++++++ src/include/86box/clock.h | 42 ++ src/win/Makefile.mingw | 2 +- 3 files changed, 949 insertions(+), 1 deletion(-) create mode 100644 src/device/clock_ics9xxx.c create mode 100644 src/include/86box/clock.h diff --git a/src/device/clock_ics9xxx.c b/src/device/clock_ics9xxx.c new file mode 100644 index 000000000..620de9c7b --- /dev/null +++ b/src/device/clock_ics9xxx.c @@ -0,0 +1,906 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the ICS9xxx series of clock generators. + * + * + * + * Authors: RichardG, + * + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/i2c.h> +#include "cpu.h" + + +enum { + ICS9150_08 = 1, + ICS9248_39, + ICS9248_98, + ICS9250_08, + ICS9250_10, + ICS9250_13, + ICS9250_14, + ICS9250_16, + ICS9250_18, + ICS9250_19, + ICS9250_23, + ICS9250_25, + ICS9250_26, + ICS9250_27, + ICS9250_28, + ICS9250_29, + ICS9250_30, + ICS9250_32, + ICS9250_38, + ICS9250_50 +}; + +typedef struct { + uint16_t bus; + double ram_mult; + uint8_t pci_div; +} ics9xxx_frequency_t; + +typedef struct { + uint8_t model; + uint8_t max_reg: 3; + uint8_t regs[8]; + struct { + uint8_t normal_reg: 3; + uint8_t normal_bit: 3; + uint8_t inv_reg: 3; + uint8_t inv_bit: 3; + } fs_regs[5]; + uint8_t normal_bits_fixed: 1; + + uint8_t frequencies_ref; + ics9xxx_frequency_t frequencies[32]; + ics9xxx_frequency_t *frequencies_ptr; + + int8_t addr_register; + uint8_t bus_match: 5; +} ics9xxx_t; + + +static const ics9xxx_t ics9xxx_devices[] = { + [ICS9150_08] = { + .max_reg = 5, + .regs = {0x00, 0xff, 0xff, 0xff, 0x6f, 0xbf}, + .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, + .frequencies = { + {.bus = 5000, .pci_div = 2}, + {.bus = 7500, .pci_div = 2}, + {.bus = 8333, .pci_div = 2}, + {.bus = 6680, .pci_div = 2}, + {.bus = 10300, .pci_div = 3}, + {.bus = 11200, .pci_div = 3}, + {.bus = 13333, .pci_div = 4}, + {.bus = 10020, .pci_div = 3}, + } + }, + [ICS9248_39] = { + .max_reg = 5, + .regs = {0x00, 0x7f, 0xff, 0xbf, 0xf5, 0xff}, + .fs_regs = {{0, 4, 3, 6}, {0, 5, 4, 3}, {0, 6, 1, 7}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, + .frequencies = { + {.bus = 12400, .pci_div = 3}, + {.bus = 7500, .pci_div = 2}, + {.bus = 8333, .pci_div = 2}, + {.bus = 6680, .pci_div = 2}, + {.bus = 10300, .pci_div = 3}, + {.bus = 11200, .pci_div = 3}, + {.bus = 13300, .pci_div = 3}, + {.bus = 10030, .pci_div = 3}, + {.bus = 12000, .pci_div = 3}, + {.bus = 11500, .pci_div = 3}, + {.bus = 11000, .pci_div = 3}, + {.bus = 10500, .pci_div = 3}, + {.bus = 14000, .pci_div = 4}, + {.bus = 15000, .pci_div = 4}, + {.bus = 12400, .pci_div = 4}, + {.bus = 13300, .pci_div = 4} + } + }, + [ICS9248_98] = { + .max_reg = 6, + .regs = {0x00, 0x7f, 0xff, 0xbf, 0xf5, 0xff, 0x06}, + .fs_regs = {{0, 4, 3, 6}, {0, 5, 4, 3}, {0, 6, 1, 7}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, + .frequencies = { + {.bus = 8000, .pci_div = 2}, + {.bus = 7500, .pci_div = 2}, + {.bus = 8331, .pci_div = 2}, + {.bus = 6682, .pci_div = 2}, + {.bus = 10300, .pci_div = 3}, + {.bus = 11201, .pci_div = 3}, + {.bus = 6801, .pci_div = 2}, + {.bus = 10023, .pci_div = 3}, + {.bus = 12000, .pci_div = 3}, + {.bus = 11499, .pci_div = 3}, + {.bus = 10999, .pci_div = 3}, + {.bus = 10500, .pci_div = 3}, + {.bus = 14000, .pci_div = 4}, + {.bus = 15000, .pci_div = 4}, + {.bus = 12400, .pci_div = 4}, + {.bus = 13299, .pci_div = 4}, + {.bus = 13500, .pci_div = 4}, + {.bus = 12999, .pci_div = 4}, + {.bus = 12600, .pci_div = 4}, + {.bus = 11800, .pci_div = 3}, + {.bus = 11598, .pci_div = 3}, + {.bus = 9500, .pci_div = 3}, + {.bus = 9000, .pci_div = 3}, + {.bus = 8501, .pci_div = 3}, + {.bus = 16600, .pci_div = 4}, + {.bus = 16001, .pci_div = 4}, + {.bus = 15499, .pci_div = 4}, + {.bus = 14795, .pci_div = 4}, + {.bus = 14598, .pci_div = 4}, + {.bus = 14398, .pci_div = 4}, + {.bus = 14199, .pci_div = 4}, + {.bus = 13801, .pci_div = 4} + } + }, + [ICS9250_08] = { + .max_reg = 5, + .regs = {0x00, 0xff, 0xff, 0xff, 0x6d, 0xbf}, + .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, + .frequencies_ref = ICS9248_39 + }, + [ICS9250_10] = { + .max_reg = 5, + .regs = {0x1f, 0xff, 0xfe, 0x00, 0x00, 0x06}, + .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, + .frequencies = { + {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7067, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7466, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8266, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6350, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6867, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7267, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8866, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 10600, .ram_mult = 1, .pci_div = 3}, + {.bus = 11200, .ram_mult = 1, .pci_div = 3}, + {.bus = 12400, .ram_mult = 1, .pci_div = 3}, + {.bus = 9525, .ram_mult = 1, .pci_div = 3}, + {.bus = 10300, .ram_mult = 1, .pci_div = 3}, + {.bus = 10900, .ram_mult = 1, .pci_div = 3}, + {.bus = 13300, .ram_mult = 1, .pci_div = 3} + } + }, + [ICS9250_13] = { + .max_reg = 5, + .regs = {0x82, 0xcf, 0x7f, 0xff, 0xff, 0xf7}, + .fs_regs = {{0, 4, 1, 4}, {0, 5, 5, 7}, {0, 6, 1, 5}, {0, 2, 2, 7}, {-1, -1, -1, -1}}, + .frequencies = { + {.bus = 9000, .ram_mult = 1, .pci_div = 2}, + {.bus = 8901, .ram_mult = 1, .pci_div = 2}, + {.bus = 8800, .ram_mult = 1, .pci_div = 2}, + {.bus = 8699, .ram_mult = 1, .pci_div = 2}, + {.bus = 8591, .ram_mult = 1, .pci_div = 2}, + {.bus = 8501, .ram_mult = 1, .pci_div = 2}, + {.bus = 8400, .ram_mult = 1, .pci_div = 2}, + {.bus = 8200, .ram_mult = 1, .pci_div = 2}, + {.bus = 8101, .ram_mult = 1, .pci_div = 2}, + {.bus = 8000, .ram_mult = 1, .pci_div = 2}, + {.bus = 8331, .ram_mult = 1, .pci_div = 2}, + {.bus = 6849, .ram_mult = 1, .pci_div = 2}, + {.bus = 7800, .ram_mult = 1, .pci_div = 2}, + {.bus = 7500, .ram_mult = 1, .pci_div = 2}, + {.bus = 7199, .ram_mult = 1, .pci_div = 2}, + {.bus = 6682, .ram_mult = 1, .pci_div = 2} + } + }, + [ICS9250_14] = { + .max_reg = 5, + .regs = {0x02, 0x1f, 0xff, 0xff, 0xeb, 0xff}, + .fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}}, + .frequencies = { + {.bus = 6781, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7201, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7301, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7700, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7801, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8300, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8449, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 10000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8608, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8800, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 9000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 9500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 4990, .ram_mult = 1, .pci_div = 3}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 7485, .ram_mult = 1, .pci_div = 3}, + {.bus = 6658, .ram_mult = 1, .pci_div = 3}, + {.bus = 8284, .ram_mult = 1, .pci_div = 3}, + {.bus = 8981, .ram_mult = 1, .pci_div = 3}, + {.bus = 9480, .ram_mult = 1, .pci_div = 3}, + {.bus = 10050, .ram_mult = 1, .pci_div = 3}, + {.bus = 10478, .ram_mult = 1, .pci_div = 3}, + {.bus = 11177, .ram_mult = 1, .pci_div = 3}, + {.bus = 11477, .ram_mult = 1, .pci_div = 3}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 12375, .ram_mult = 1, .pci_div = 3}, + {.bus = 13274, .ram_mult = 1, .pci_div = 3}, + {.bus = 13975, .ram_mult = 1, .pci_div = 3}, + {.bus = 14969, .ram_mult = 1, .pci_div = 3} + } + }, + [ICS9250_16] = { + .max_reg = 5, + .regs = {0x1f, 0xff, 0xff, 0x00, 0x00, 0x06}, + .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, + .frequencies = { + {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7267, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7467, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 10500, .ram_mult = 1, .pci_div = 3}, + {.bus = 10900, .ram_mult = 1, .pci_div = 3}, + {.bus = 11201, .ram_mult = 1, .pci_div = 3}, + {.bus = 13334, .ram_mult = 1, .pci_div = 3}, + {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 12000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 12400, .ram_mult = 1, .pci_div = 3}, + {.bus = 13334, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 15000, .ram_mult = 1, .pci_div = 4}, + {.bus = 14000, .ram_mult = 1, .pci_div = 4}, + {.bus = 13299, .ram_mult = 1, .pci_div = 4} + } + }, + [ICS9250_18] = { + .max_reg = 5, + .regs = {0x02, 0xff, 0xff, 0xff, 0x6d, 0xbf}, + .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, + .frequencies = { + {.bus = 8000, .pci_div = 2}, + {.bus = 7500, .pci_div = 2}, + {.bus = 8331, .pci_div = 2}, + {.bus = 6690, .pci_div = 2}, + {.bus = 10300, .pci_div = 3}, + {.bus = 11201, .pci_div = 3}, + {.bus = 6801, .pci_div = 2}, + {.bus = 10070, .pci_div = 3}, + {.bus = 12000, .pci_div = 3}, + {.bus = 11499, .pci_div = 3}, + {.bus = 10999, .pci_div = 3}, + {.bus = 10500, .pci_div = 3}, + {.bus = 14000, .pci_div = 4}, + {.bus = 15000, .pci_div = 4}, + {.bus = 12400, .pci_div = 4}, + {.bus = 13390, .pci_div = 4}, + {.bus = 13500, .pci_div = 4}, + {.bus = 12999, .pci_div = 4}, + {.bus = 12600, .pci_div = 4}, + {.bus = 11800, .pci_div = 4}, + {.bus = 11598, .pci_div = 4}, + {.bus = 9500, .pci_div = 3}, + {.bus = 9000, .pci_div = 3}, + {.bus = 8501, .pci_div = 3}, + {.bus = 16600, .pci_div = 4}, + {.bus = 16001, .pci_div = 4}, + {.bus = 15499, .pci_div = 4}, + {.bus = 14795, .pci_div = 4}, + {.bus = 14598, .pci_div = 4}, + {.bus = 14398, .pci_div = 4}, + {.bus = 14199, .pci_div = 4}, + {.bus = 13801, .pci_div = 4} + } + }, + [ICS9250_19] = { + .max_reg = 5, + .regs = {0x02, 0xff, 0xff, 0xff, 0x6d, 0xbf}, + .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, + .frequencies_ref = ICS9250_08 + }, + [ICS9250_23] = { + .max_reg = 5, + .regs = {0x02, 0x1f, 0xff, 0xff, 0xeb, 0xff}, + .fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}}, + .frequencies = { + {.bus = 6900, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7100, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6690, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7200, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7660, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6800, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7400, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 14000, .ram_mult = 1, .pci_div = 4}, + {.bus = 13333, .ram_mult = 1, .pci_div = 4}, + {.bus = 15000, .ram_mult = 1, .pci_div = 4}, + {.bus = 15500, .ram_mult = 1, .pci_div = 4}, + {.bus = 16600, .ram_mult = 1, .pci_div = 4}, + {.bus = 16600, .ram_mult = 1, .pci_div = 3}, + {.bus = 11177, .ram_mult = 1, .pci_div = 3}, + {.bus = 10478, .ram_mult = 1, .pci_div = 3}, + {.bus = 10951, .ram_mult = 1, .pci_div = 3}, + {.bus = 10090, .ram_mult = 1, .pci_div = 3}, + {.bus = 11700, .ram_mult = 1, .pci_div = 3}, + {.bus = 12375, .ram_mult = 1, .pci_div = 3}, + {.bus = 13333, .ram_mult = 1, .pci_div = 3}, + {.bus = 14250, .ram_mult = 1, .pci_div = 3}, + {.bus = 13600, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14300, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13390, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14667, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14933, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 15330, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 16667, .ram_mult = 0.75, .pci_div = 4} + } + }, + [ICS9250_25] = { + .max_reg = 6, + .regs = {0x02, 0x1f, 0xff, 0xff, 0xeb, 0xff, 0x06}, + .fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}}, + .frequencies = { + {.bus = 5500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6680, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6833, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7200, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7700, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8330, .ram_mult = 1, .pci_div = 3}, + {.bus = 9000, .ram_mult = 1, .pci_div = 3}, + {.bus = 10030, .ram_mult = 1, .pci_div = 3}, + {.bus = 10300, .ram_mult = 1, .pci_div = 3}, + {.bus = 11250, .ram_mult = 1, .pci_div = 3}, + {.bus = 11500, .ram_mult = 1, .pci_div = 3}, + {.bus = 12000, .ram_mult = 1, .pci_div = 3}, + {.bus = 12500, .ram_mult = 1, .pci_div = 3}, + {.bus = 12800, .ram_mult = 1, .pci_div = 4}, + {.bus = 13000, .ram_mult = 1, .pci_div = 4}, + {.bus = 13370, .ram_mult = 1, .pci_div = 4}, + {.bus = 13700, .ram_mult = 1, .pci_div = 4}, + {.bus = 14000, .ram_mult = 1, .pci_div = 4}, + {.bus = 14500, .ram_mult = 1, .pci_div = 4}, + {.bus = 15000, .ram_mult = 1, .pci_div = 4}, + {.bus = 15333, .ram_mult = 1, .pci_div = 4}, + {.bus = 12500, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13370, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13700, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14500, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 15000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 15333, .ram_mult = 0.75, .pci_div = 4} + } + }, + [ICS9250_26] = { + .max_reg = 5, + .regs = {0x1e, 0xff, 0xff, 0x00, 0x00, 0x06}, + .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, + .frequencies_ref = ICS9250_16 + }, + [ICS9250_27] = { + .max_reg = 5, + .regs = {0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00}, + .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, + .frequencies = { + {.bus = 6666, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 13332, .ram_mult = 1, .pci_div = 4}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 13332, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 6666, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 13332, .ram_mult = 1, .pci_div = 4}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 13332, .ram_mult = 1, .pci_div = 4} + } + }, + [ICS9250_28] = { + .max_reg = 4, + .regs = {0x1e, 0xff, 0xfe, 0x00, 0x00}, + .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, + .frequencies_ref = ICS9250_27 + }, + [ICS9250_29] = { + .max_reg = 5, + .regs = {0x16, 0xff, 0xfe, 0x00, 0x00, 0x00}, + .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, + .frequencies_ref = ICS9250_27 + }, + [ICS9250_30] = { + .max_reg = 6, + .regs = {0x02, 0x0f, 0xff, 0xff, 0xeb, 0xff, 0x06}, + .fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}}, + .frequencies = { + {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6680, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6833, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8300, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 9000, .ram_mult = 1, .pci_div = 3}, + {.bus = 10030, .ram_mult = 1, .pci_div = 3}, + {.bus = 10300, .ram_mult = 1, .pci_div = 3}, + {.bus = 10500, .ram_mult = 1, .pci_div = 3}, + {.bus = 11000, .ram_mult = 1, .pci_div = 3}, + {.bus = 11500, .ram_mult = 1, .pci_div = 3}, + {.bus = 20000, .ram_mult = 1, .pci_div = 6}, + {.bus = 13333, .ram_mult = 1, .pci_div = 4}, + {.bus = 16667, .ram_mult = 1, .pci_div = 4}, + {.bus = 13370, .ram_mult = 1, .pci_div = 4}, + {.bus = 13700, .ram_mult = 1, .pci_div = 4}, + {.bus = 14000, .ram_mult = 1, .pci_div = 4}, + {.bus = 14500, .ram_mult = 1, .pci_div = 4}, + {.bus = 15000, .ram_mult = 1, .pci_div = 4}, + {.bus = 16000, .ram_mult = 1, .pci_div = 4}, + {.bus = 13333, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 16667, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13370, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13700, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14500, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 15000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 16000, .ram_mult = 0.75, .pci_div = 4} + } + }, + [ICS9250_32] = { + .max_reg = 4, + .regs = {0x07, 0xff, 0xff, 0x00, 0x00}, + .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}} + }, + [ICS9250_38] = { + .max_reg = 6, + .regs = {0x18, 0x07, 0xfe, 0xc7, 0xfc, 0x00, 0x80}, + .fs_regs = {{0, 0, -1, -1}, {0, 1, -1, -1}, {0, 2, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, + .normal_bits_fixed = 1, + .frequencies = { + {.bus = 6666, .ram_mult = 1, .pci_div = 1}, + {.bus = 10000, .ram_mult = 2.0/3.0, .pci_div = 3}, + {.bus = 20000, .ram_mult = 1.0/3.0, .pci_div = 6}, + {.bus = 13333, .ram_mult = 0.5, .pci_div = 2}, + {.bus = 6666, .ram_mult = 1, .pci_div = 1}, + {.bus = 10000, .ram_mult = 2.0/3.0, .pci_div = 3}, + {.bus = 20000, .ram_mult = 1.0/3.0, .pci_div = 6}, + {.bus = 13333, .ram_mult = 0.5, .pci_div = 2} + } + }, + [ICS9250_50] = { + .max_reg = 6, + .regs = {0x02, 0x6f, 0xff, 0xff, 0xef, 0xff, 0x06}, + .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {0, 7, 1, 7}, {0, 2, 4, 4}}, + .frequencies = { + {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 13333, .ram_mult = 1, .pci_div = 4}, + {.bus = 13333, .ram_mult = 0.75, .pci_div = 4} + } + } +}; + +#define ENABLE_ICS9xxx_LOG 1 +#ifdef ENABLE_ICS9xxx_LOG +int ics9xxx_do_log = ENABLE_ICS9xxx_LOG; + + +static void +ics9xxx_log(const char *fmt, ...) +{ + va_list ap; + + if (ics9xxx_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define ics9xxx_log(fmt, ...) +#endif + + +static uint8_t +ics9xxx_start(void *bus, uint8_t addr, uint8_t read, void *priv) +{ + ics9xxx_t *dev = (ics9xxx_t *) priv; + + ics9xxx_log("ICS9xxx: start()\n"); + + dev->addr_register = -2; /* -2 = command; -1 = SMBus block length; 0+ = registers */ + + return 1; +} + + +static uint8_t +ics9xxx_read(void *bus, uint8_t addr, void *priv) +{ + ics9xxx_t *dev = (ics9xxx_t *) priv; + uint8_t ret = 0xff; + + if (dev->addr_register < 0) { + dev->addr_register = -1; + ret = dev->max_reg + 1; + } else if ((dev->model == ICS9250_50) && (dev->addr_register == 0)) + ret = dev->regs[dev->addr_register] & 0x0b; /* -50 reads back revision ID instead */ + else + ret = dev->regs[dev->addr_register]; + + ics9xxx_log("ICS9xxx: read(%02X) = %02X\n", dev->addr_register, ret); + if (++dev->addr_register > dev->max_reg) + dev->addr_register = 0; /* roll-over */ + + return ret; +} + + +static void +ics9xxx_set(ics9xxx_t *dev, uint8_t val) +{ + /* Add register-defined frequency bits to the static frequency bits we were passed. */ + for (uint8_t i = 0; i < sizeof(dev->fs_regs) / sizeof(dev->fs_regs[0]); i++) { + if ((dev->fs_regs[i].normal_reg < 7) && (dev->regs[dev->fs_regs[i].normal_reg] & (1 << dev->fs_regs[i].normal_bit))) + val |= 1 << i; + } + + ics9xxx_log("ICS9xxx: set(%02X) = %d\n", val, ics9xxx_devices[dev->model].frequencies[val].bus); +} + + +static uint8_t +ics9xxx_write(void *bus, uint8_t addr, uint8_t data, void *priv) +{ + ics9xxx_t *dev = (ics9xxx_t *) priv; + + ics9xxx_log("ICS9xxx: write(%02X, %02X)\n", dev->addr_register, data); + + if (dev->addr_register >= 0) { + /* Preserve fixed bits. */ + for (uint8_t i = 0; i < sizeof(dev->fs_regs) / sizeof(dev->fs_regs[0]); i++) { + if (dev->normal_bits_fixed && (dev->fs_regs[i].normal_reg == dev->addr_register)) + data = (dev->regs[dev->addr_register] & (1 << dev->fs_regs[i].normal_bit)) | (data & ~(1 << dev->fs_regs[i].normal_bit)); + if (dev->fs_regs[i].inv_reg == dev->addr_register) + data = (dev->regs[dev->addr_register] & (1 << dev->fs_regs[i].inv_bit)) | (data & ~(1 << dev->fs_regs[i].inv_bit)); + } + + switch (dev->addr_register) { + case 0: + if (dev->model == ICS9250_38) + data = (dev->regs[dev->addr_register] & ~0xef) | (data & 0xef); + else if (dev->model == ICS9250_10) + ics9xxx_set(dev, (cpu_busspeed >= 100000000) * 0x08); + else if ((dev->model == ICS9250_16) || (dev->model == ICS9250_26)) + ics9xxx_set(dev, ((cpu_busspeed >= 120000000) * 0x08) | ((((cpu_busspeed >= 100000000) && (cpu_busspeed < 120000000)) || (cpu_busspeed == 150000000) || (cpu_busspeed == 132999999)) * 0x04)); + else if ((dev->model == ICS9250_27) || (dev->model == ICS9250_28) || (dev->model == ICS9250_29)) + ics9xxx_set(dev, ((cpu_busspeed == 100000000) * 0x02) | ((cpu_busspeed > 100000000) * 0x01)); + else + ics9xxx_set(dev, 0x00); + break; + + case 1: + if (dev->model == ICS9250_38) + data = (dev->regs[dev->addr_register] & ~0xfe) | (data & 0xfe); + break; + + case 3: + if (dev->model == ICS9250_32) + data ^= 0x70; + break; + + case 4: + if (dev->model == ICS9250_38) + data = (dev->regs[dev->addr_register] & ~0xfc) | (data & 0xfc); + break; + + case 6: + if (dev->model == ICS9250_38) + data = dev->regs[dev->addr_register]; + break; + } + dev->regs[dev->addr_register] = data; + } + + if (++dev->addr_register > dev->max_reg) + dev->addr_register = 0; /* roll-over */ + + return 1; +} + + +static uint8_t +find_bus_match(ics9xxx_t *dev, uint32_t bus, uint8_t preset_mask, uint8_t preset) { + uint8_t best_match = 0; + uint32_t delta, best_delta = -1; + + for (uint8_t i = 0; i < (sizeof(dev->frequencies) / sizeof(dev->frequencies[0])); i++) { + if (((i & preset_mask) != preset) || !dev->frequencies_ptr[i].bus) + continue; + + delta = ABS((int32_t) (bus - (dev->frequencies_ptr[i].bus * 10000))); + if (delta < best_delta) { + best_match = i; + best_delta = delta; + } + } + + ics9xxx_log("ICS9xxx: find_match(%02X, %d) = %d (%02X)\n", dev->model, bus, dev->frequencies_ptr[best_match].bus, best_match); + + return best_match; +} + + +static void * +ics9xxx_init(const device_t *info) +{ + ics9xxx_t *dev = (ics9xxx_t *) malloc(sizeof(ics9xxx_t)); + memcpy(dev, &ics9xxx_devices[info->local], sizeof(ics9xxx_t)); + + ics9xxx_log("ICS9xxx: init(%02X)\n", info->local); + + dev->model = info->local; + dev->frequencies_ptr = (ics9xxx_frequency_t *) ics9xxx_devices[dev->frequencies_ref ? dev->frequencies_ref : dev->model].frequencies; + if (!dev->frequencies_ptr) + fatal("ICS9xxx: NULL frequency table\n"); + + /* Determine which frequency bits cannot be strapped (register only). */ + uint8_t register_only_bits = 0x00; + uint8_t i; + for (i = 0; i < sizeof(dev->fs_regs) / sizeof(dev->fs_regs[0]); i++) { + if ((dev->fs_regs[i].normal_reg == 7) && (dev->fs_regs[i].inv_reg == 7)) + register_only_bits |= 1 << i; + } + + /* Find bus speed match and set default register bits accordingly. */ + dev->bus_match = find_bus_match(dev, cpu_busspeed, register_only_bits, 0x00); + for (i = 0; i < sizeof(dev->fs_regs) / sizeof(dev->fs_regs[0]); i++) { + if (dev->fs_regs[i].normal_reg < 7) { + if (dev->bus_match & (1 << i)) + dev->regs[dev->fs_regs[i].normal_reg] |= 1 << dev->fs_regs[i].normal_bit; + else + dev->regs[dev->fs_regs[i].normal_reg] &= ~(1 << dev->fs_regs[i].normal_bit); + } + if (dev->fs_regs[i].inv_reg < 7) { + if (dev->bus_match & (1 << i)) + dev->regs[dev->fs_regs[i].inv_reg] &= ~(1 << dev->fs_regs[i].inv_bit); + else + dev->regs[dev->fs_regs[i].inv_reg] |= 1 << dev->fs_regs[i].inv_bit; + } + } + + i2c_sethandler(i2c_smbus, 0x69, 1, ics9xxx_start, ics9xxx_read, ics9xxx_write, NULL, dev); + + return dev; +} + + +static void +ics9xxx_close(void *priv) +{ + ics9xxx_t *dev = (ics9xxx_t *) priv; + + ics9xxx_log("ICS9xxx: close()\n"); + + i2c_removehandler(i2c_smbus, 0x69, 1, ics9xxx_start, ics9xxx_read, ics9xxx_write, NULL, dev); + + free(dev); +} + + +const device_t ics9150_08_device = { + "ICS9150-08 Clock Generator", + DEVICE_ISA, + ICS9150_08, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9248_39_device = { + "ICS9248-39 Clock Generator", + DEVICE_ISA, + ICS9248_39, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9248_98_device = { + "ICS9248-98 Clock Generator", + DEVICE_ISA, + ICS9248_98, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_08_device = { + "ICS9250-08 Clock Generator", + DEVICE_ISA, + ICS9250_08, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_10_device = { + "ICS9250-10 Clock Generator", + DEVICE_ISA, + ICS9250_10, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_13_device = { + "ICS9250-13 Clock Generator", + DEVICE_ISA, + ICS9250_13, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_14_device = { + "ICS9250-14 Clock Generator", + DEVICE_ISA, + ICS9250_14, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_16_device = { + "ICS9250-16 Clock Generator", + DEVICE_ISA, + ICS9250_16, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_18_device = { + "ICS9250-18 Clock Generator", + DEVICE_ISA, + ICS9250_18, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_19_device = { + "ICS9250-19 Clock Generator", + DEVICE_ISA, + ICS9250_08, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_23_device = { + "ICS9250-23 Clock Generator", + DEVICE_ISA, + ICS9250_23, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_25_device = { + "ICS9250-25 Clock Generator", + DEVICE_ISA, + ICS9250_25, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_26_device = { + "ICS9250-26 Clock Generator", + DEVICE_ISA, + ICS9250_26, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_27_device = { + "ICS9250-27 Clock Generator", + DEVICE_ISA, + ICS9250_27, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_28_device = { + "ICS9250-28 Clock Generator", + DEVICE_ISA, + ICS9250_28, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_29_device = { + "ICS9250-29 Clock Generator", + DEVICE_ISA, + ICS9250_29, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_30_device = { + "ICS9250-30 Clock Generator", + DEVICE_ISA, + ICS9250_30, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_32_device = { + "ICS9250-32 Clock Generator", + DEVICE_ISA, + ICS9250_32, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_38_device = { + "ICS9250-38 Clock Generator", + DEVICE_ISA, + ICS9250_38, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t ics9250_50_device = { + "ICS9250-50 Clock Generator", + DEVICE_ISA, + ICS9250_50, + ics9xxx_init, ics9xxx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; diff --git a/src/include/86box/clock.h b/src/include/86box/clock.h new file mode 100644 index 000000000..da8ff9e2e --- /dev/null +++ b/src/include/86box/clock.h @@ -0,0 +1,42 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for clock generator chips. + * + * + * + * Authors: RichardG, + * + * Copyright 2020 RichardG. + */ +#ifndef EMU_CLOCK_H +# define EMU_CLOCK_H + +/* clock_ics9xxx.c */ +extern const device_t ics9150_08_device; +extern const device_t ics9248_39_device; +extern const device_t ics9248_98_device; +extern const device_t ics9250_08_device; +extern const device_t ics9250_10_device; +extern const device_t ics9250_13_device; +extern const device_t ics9250_14_device; +extern const device_t ics9250_16_device; +extern const device_t ics9250_18_device; +extern const device_t ics9250_19_device; +extern const device_t ics9250_23_device; +extern const device_t ics9250_25_device; +extern const device_t ics9250_26_device; +extern const device_t ics9250_27_device; +extern const device_t ics9250_28_device; +extern const device_t ics9250_29_device; +extern const device_t ics9250_30_device; +extern const device_t ics9250_32_device; +extern const device_t ics9250_38_device; +extern const device_t ics9250_50_device; + +#endif /*EMU_CLOCK_H*/ diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index ff9cb73e3..819f1092b 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -653,7 +653,7 @@ MCHOBJ := machine.o machine_table.o \ m_at_misc.o DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o ibm_5161.o isamem.o isartc.o \ - lpt.o pci_bridge.o postcard.o serial.o vpc2007.o \ + lpt.o pci_bridge.o postcard.o serial.o vpc2007.o clock_ics9xxx.o \ i2c.o i2c_gpio.o smbus_piix4.o \ keyboard.o \ keyboard_xt.o keyboard_at.o \ From 04617d506d7c8e491284b804f06f70f10566efc2 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 3 Dec 2020 00:40:45 -0300 Subject: [PATCH 20/22] Add newer ASUS VIA machines and replace the Acorp 6VIA85X --- src/acpi.c | 12 +++++-- src/include/86box/machine.h | 6 ++-- src/machine/m_at_slot1.c | 47 +++++++++++++++++++++++--- src/machine/m_at_socket370.c | 64 +++++++++++++++++++++++++++++------- src/machine/machine_table.c | 6 ++-- 5 files changed, 113 insertions(+), 22 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index 350021e00..19d52b9bf 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -1180,13 +1180,21 @@ acpi_reset(void *priv) - Bit 4: 80-conductor cable on primary IDE channel (active low) - Bit 3: 80-conductor cable on secondary IDE channel (active low) - Bit 2: password cleared (active low) + ASUS P3V4X: + - Bit 15: 80-conductor cable on secondary IDE channel (active low) + - Bit 5: 80-conductor cable on primary IDE channel (active low) AEWIN WCF-681: - Bit 3: 80-conductor cable on primary IDE channel (active low) - Bit 2: 80-conductor cable on secondary IDE channel (active low) - Acorp 6VIA85X: + ASUS CUV4X-LS: + - Bit 2: 80-conductor cable on secondary IDE channel (active low) + - Bit 1: 80-conductor cable on primary IDE channel (active low) + Acorp 6VIA90AP: - Bit 3: 80-conductor cable on secondary IDE channel (active low) - Bit 1: 80-conductor cable on primary IDE channel (active low) */ - dev->regs.gpi_val = !strcmp(machines[machine].internal_name, "wcf681") ? 0xffffffe3 : 0xffffffe5; + dev->regs.gpi_val = 0xffff7fc1; + if (!strcmp(machines[machine].internal_name, "ficva503a")) + dev->regs.gpi_val |= 0x00000004; } } diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 1191d5100..4f9bc5100 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -462,13 +462,14 @@ extern int machine_at_p3bf_init(const machine_t *); extern int machine_at_bf6_init(const machine_t *); extern int machine_at_ax6bc_init(const machine_t *); extern int machine_at_atc6310bxii_init(const machine_t *); -extern int machine_at_ga686bx_init(const machine_t *); +extern int machine_at_686bx_init(const machine_t *); extern int machine_at_tsunamiatx_init(const machine_t *); extern int machine_at_p6sba_init(const machine_t *); #if defined(DEV_BRANCH) && defined(NO_SIO) extern int machine_at_ergox365_init(const machine_t *); #endif extern int machine_at_ficka6130_init(const machine_t *); +extern int machine_at_p3v4x_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t *at_tsunamiatx_get_device(void); @@ -490,7 +491,8 @@ extern int machine_at_63a_init(const machine_t *); extern int machine_at_s370sba_init(const machine_t *); extern int machine_at_apas3_init(const machine_t *); extern int machine_at_wcf681_init(const machine_t *); -extern int machine_at_6via85x_init(const machine_t *); +extern int machine_at_cuv4xls_init(const machine_t *); +extern int machine_at_6via90ap_init(const machine_t *); extern int machine_at_603tcf_init(const machine_t *); extern int machine_at_trinity371_init(const machine_t *); extern int machine_at_p6bap_init(const machine_t *); diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 3fe6d5394..ff96c7dcc 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -37,6 +37,7 @@ #include "cpu.h" #include <86box/machine.h> #include <86box/sound.h> +#include <86box/clock.h> int machine_at_p65up5_cpknd_init(const machine_t *model) @@ -214,6 +215,7 @@ machine_at_p2bls_init(const machine_t *model) device_add(&piix4e_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&w83977ef_device); + device_add(&ics9150_08_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ @@ -251,6 +253,7 @@ machine_at_p3bf_init(const machine_t *model) device_add(&piix4e_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&w83977ef_device); + device_add(&ics9250_08_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ @@ -363,11 +366,11 @@ machine_at_atc6310bxii_init(const machine_t *model) int -machine_at_ga686bx_init(const machine_t *model) +machine_at_686bx_init(const machine_t *model) { int ret; - ret = bios_load_linear(L"roms/machines/ga686bx/6BX.F2a", + ret = bios_load_linear(L"roms/machines/686bx/6BX.F2a", 0x000c0000, 262144, 0); if (bios_only || !ret) @@ -507,8 +510,8 @@ machine_at_ergox365_init(const machine_t *model) device_add(&i440bx_device); device_add(&piix4e_device); device_add(&keyboard_ps2_ami_pci_device); - device_add(&fdc37c665_device); // Placeholder for the SM(S)C FDC37C675 - device_add(&sst_flash_39sf040_device); // Placeholder for the Intel 28F004 flash chip + device_add(&fdc37c665_device); /* Placeholder for the SM(S)C FDC37C675 */ + device_add(&sst_flash_39sf040_device); /* Placeholder for the Intel 28F004 flash chip */ spd_register(SPD_TYPE_SDRAM, 0xF, 256); return ret; @@ -545,3 +548,39 @@ machine_at_ficka6130_init(const machine_t *model) return ret; } + + +int +machine_at_p3v4x_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/p3v4x/1006.004", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&via_apro133a_device); + device_add(&via_vt82c596b_device); + device_add(&w83977ef_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&ics9250_18_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 512); + device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ + + return ret; +} diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 9a3e5f3c4..04453c5dd 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -36,6 +36,7 @@ #include <86box/video.h> #include "cpu.h" #include <86box/machine.h> +#include <86box/clock.h> int machine_at_s370slm_init(const machine_t *model) @@ -162,6 +163,7 @@ machine_at_cubx_init(const machine_t *model) device_add(&piix4e_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&w83977ef_device); + device_add(&ics9250_08_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ @@ -334,8 +336,8 @@ machine_at_wcf681_init(const machine_t *model) { int ret; - ret = bios_load_linear(L"roms/machines/wcf681/681osda2.bin", - 0x000c0000, 262144, 0); + ret = bios_load_linear(L"roms/machines/wcf681/p3tdde.bin", + 0x00080000, 524288, 0); if (bios_only || !ret) return ret; @@ -344,7 +346,8 @@ machine_at_wcf681_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x10, PCI_CARD_SOUTHBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x11, PCI_CARD_SOUTHBRIDGE, 1, 2, 0, 0); pci_register_slot(0x14, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x12, PCI_CARD_NORMAL, 4, 1, 2, 3); @@ -352,12 +355,12 @@ machine_at_wcf681_init(const machine_t *model) pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&via_apro133a_device); - device_add(&via_vt82c596b_device); - device_add(&w83977tf_device); + device_add(&via_vt82c686b_device); + device_add(&via_vt82c686_sio_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x3, 512); - device_add(&w83781d_device); /* fans: CPU, unused, unused; temperatures: System, unused, CPU */ + device_add(&via_vt82c686_hwm_device); /* fans: CPU, unused, unused; temperatures: System, unused, CPU */ hwm_values.voltages[1] = 2500; /* +2.5V */ hwm_values.fans[1] = 0; /* unused */ hwm_values.fans[2] = 0; /* unused */ @@ -367,11 +370,48 @@ machine_at_wcf681_init(const machine_t *model) } int -machine_at_6via85x_init(const machine_t *model) +machine_at_cuv4xls_init(const machine_t *model) { int ret; - ret = bios_load_linear(L"roms/machines/6via85x/6VIA85X_ver_1_1.bin", + ret = bios_load_linear(L"roms/machines/cuv4xls/1005LS.001", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 4, 1, 2, 3); + pci_register_slot(0x05, PCI_CARD_SOUND, 3, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x07, PCI_CARD_NORMAL, 2, 3, 0, 0); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&via_apro133a_device); + device_add(&via_vt82c686b_device); + device_add(&via_vt82c686_sio_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&ics9250_18_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 512); + device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ + + return ret; +} + +int +machine_at_6via90ap_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/6via90ap/90ap10.bin", 0x000c0000, 262144, 0); if (bios_only || !ret) @@ -407,7 +447,7 @@ machine_at_603tcf_init(const machine_t *model) { int ret; - ret = bios_load_linear(L"roms/machines/603tcf/603tcfA4.BIN", + ret = bios_load_linear(L"roms/machines/603tcf/6VX-4X.F8", 0x000c0000, 262144, 0); if (bios_only || !ret) @@ -423,11 +463,11 @@ machine_at_603tcf_init(const machine_t *model) pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&via_vt8601_device); - device_add(&via_vt82c686b_device); + device_add(&via_apro133a_device); + device_add(&via_vt82c686a_device); device_add(&via_vt82c686_sio_device); device_add(&keyboard_ps2_ami_pci_device); - device_add(&sst_flash_39sf020_device); + device_add(&sst_flash_29ee020_device); spd_register(SPD_TYPE_SDRAM, 0x3, 512); device_add(&via_vt82c686_hwm_device); /* fans: 1, 2; temperatures: CPU, System, unused */ hwm_values.temperatures[0] += 2; /* CPU offset */ diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 588b0430b..1aacf40b6 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -340,7 +340,7 @@ const machine_t machines[] = { { "[i440BX] ABIT BF6", "bf6", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 133333333, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_bf6_init, NULL }, { "[i440BX] AOpen AX6BC", "ax6bc", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 112121212, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_ax6bc_init, NULL }, { "[i440BX] A-Trend ATC6310BXII", "atc6310bxii", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 133333333, 1800, 3500, 3.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_atc6310bxii_init, NULL }, - { "[i440BX] Gigabyte GA-686BX", "ga686bx", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 3.0, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_ga686bx_init, NULL }, + { "[i440BX] Gigabyte GA-686BX", "686bx", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 3.0, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_686bx_init, NULL }, { "[i440BX] Tyan Tsunami ATX", "tsunamiatx", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 112121212, 1800, 3500, 3.5, 5.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_SOUND, 8, 1024, 8, 255, machine_at_tsunamiatx_init, at_tsunamiatx_get_device }, { "[i440BX] SuperMicro Super P6SBA", "p6sba", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 3.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_p6sba_init, NULL }, #if defined(DEV_BRANCH) && defined(NO_SIO) @@ -352,6 +352,7 @@ const machine_t machines[] = { /* VIA Apollo Pro */ { "[VIA Apollo Pro] FIC KA-6130", "ficka6130", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 3.5, 5.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 255, machine_at_ficka6130_init, NULL }, + { "[VIA Apollo Pro133A] ASUS P3V4X", "p3v4x", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 150000000, 1800, 3500, 2.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 2048, 8, 255, machine_at_p3v4x_init, NULL }, /* Slot 2 machines(Including Slot 1/2 Hybrids) */ /* 440GX */ @@ -376,7 +377,8 @@ const machine_t machines[] = { /* VIA Apollo Pro */ { "[VIA Apollo Pro] PC Partner APAS3", "apas3", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 100000000, 1800, 3500, 3.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_apas3_init, NULL }, { "[VIA Apollo Pro133A] AEWIN WCF-681", "wcf681", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1800, 3500, 0, 0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_wcf681_init, NULL }, - { "[VIA Apollo Pro133A] Acorp 6VIA85X", "6via85x", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1800, 3500, MACHINE_MULTIPLIER_FIXED, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1536, 8, 255, machine_at_6via85x_init, NULL }, + { "[VIA Apollo Pro133A] ASUS CUV4X-LS", "cuv4xls", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1800, 3500, 2.0, 8.0, (MACHINE_AGP & ~MACHINE_AT) | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16, 1536, 8, 255, machine_at_cuv4xls_init, NULL }, + { "[VIA Apollo Pro133A] Acorp 6VIA90AP", "6via90ap", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1800, 3500, MACHINE_MULTIPLIER_FIXED, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1536, 8, 255, machine_at_6via90ap_init, NULL }, { "[VIA Apollo Pro133A] ECS P6BAP", "p6bap", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1800, 3500, 2.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1536, 8, 255, machine_at_p6bap_init, NULL }, { "[VIA Apollo ProMedia] Jetway 603TCF", "603tcf", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1800, 3500, 2.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_603tcf_init, NULL }, From 6a1d0db3314e438a7adfaf3e7784a224fd552d6f Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 3 Dec 2020 00:41:00 -0300 Subject: [PATCH 21/22] Add undocumented P55T2P4 bus speed jumper --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 1aacf40b6..3a043e232 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -272,7 +272,7 @@ const machine_t machines[] = { { "[i430HX] SuperMicro Super P55T2S", "p55t2s", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3300, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 127, machine_at_p55t2s_init, NULL }, { "[i430HX] Acer V35N", "acerv35n", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 192, 8, 127, machine_at_acerv35n_init, NULL }, - { "[i430HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 75000000, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL }, + { "[i430HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 83333333, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL }, { "[i430HX] Micronics M7S-Hi", "m7shi", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 511, machine_at_m7shi_init, NULL }, { "[i430HX] Intel TC430HX", "tc430hx", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 255, machine_at_tc430hx_init, NULL }, { "[i430HX] Toshiba Equium 5200D", "equium5200", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 192, 8, 127, machine_at_equium5200_init, NULL }, From c1d9a95d55d02d6b07e086dd8366ab5e46fd81eb Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 3 Dec 2020 01:48:24 -0300 Subject: [PATCH 22/22] Fix ICS9250-19 device type --- src/device/clock_ics9xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/clock_ics9xxx.c b/src/device/clock_ics9xxx.c index 620de9c7b..e12c194e8 100644 --- a/src/device/clock_ics9xxx.c +++ b/src/device/clock_ics9xxx.c @@ -799,7 +799,7 @@ const device_t ics9250_18_device = { const device_t ics9250_19_device = { "ICS9250-19 Clock Generator", DEVICE_ISA, - ICS9250_08, + ICS9250_19, ics9xxx_init, ics9xxx_close, NULL, { NULL }, NULL, NULL, NULL