From f58cbb2856e69f76d14107e78580c92fe4c12caa Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Wed, 10 Aug 2022 17:38:54 -0400 Subject: [PATCH] Re-add the ASUS CUSL2-C Maybe we can fix it someday --- src/include/86box/machine.h | 7 +- src/include/86box/sio.h | 3 + src/machine/m_at_ich2.c | 56 ++++- src/machine/machine_table.c | 41 +++- src/sio/CMakeLists.txt | 1 + src/sio/sio_it8702.c | 445 ++++++++++++++++++++++++++++++++++++ src/win/Makefile.mingw | 1 + 7 files changed, 544 insertions(+), 10 deletions(-) create mode 100644 src/sio/sio_it8702.c diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index a7fe477ae..d5ce76a4c 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -706,9 +706,10 @@ extern int machine_at_p6bap_init(const machine_t *); extern int machine_at_vpc2007_init(const machine_t *); /* m_at_ich2.c */ -extern int machine_at_m6tsl_init(const machine_t *); -extern int machine_at_m6tss_init(const machine_t *); -extern int machine_at_s2080_init(const machine_t *); +extern int machine_at_cusl2c_init(const machine_t *); +extern int machine_at_m6tsl_init(const machine_t *); +extern int machine_at_m6tss_init(const machine_t *); +extern int machine_at_s2080_init(const machine_t *); /* m_at_t3100e.c */ extern int machine_at_t3100e_init(const machine_t *); diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index e872ace6c..c26e91dbf 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -46,6 +46,9 @@ extern const device_t i82091aa_398_device; extern const device_t i82091aa_ide_pri_device; extern const device_t i82091aa_ide_device; +/* ITE IT8702 */ +extern const device_t it8702_device; + /* National Semiconductor NSC366 (PC87366) */ extern const device_t nsc366_device; extern const device_t nsc366_4f_device; diff --git a/src/machine/m_at_ich2.c b/src/machine/m_at_ich2.c index df9aadcca..1dda0b623 100644 --- a/src/machine/m_at_ich2.c +++ b/src/machine/m_at_ich2.c @@ -26,6 +26,50 @@ #include "cpu.h" #include <86box/machine.h> +/* + * ASUS CUSL2-C + * + * North Bridge: Intel 815EP + * Super I/O: ITE IT8702 + * BIOS: Award Medallion 6.0 + * Notes: None +*/ +int +machine_at_cusl2c_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/cusl2c/1014c.001", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_bus_slot(0, 0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_bus_slot(0, 0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + pci_register_bus_slot(0, 0x1e, PCI_CARD_BRIDGE, 0, 0, 0, 0); + pci_register_bus_slot(0, 0x1f, PCI_CARD_SOUTHBRIDGE, 1, 2, 8, 4); + pci_register_bus_slot(1, 0x00, PCI_CARD_AGP, 1, 2, 0, 0); + pci_register_bus_slot(2, 0x0a, PCI_CARD_NORMAL, 7, 8, 5, 6); + pci_register_bus_slot(2, 0x0b, PCI_CARD_NORMAL, 8, 5, 6, 7); + pci_register_bus_slot(2, 0x0c, PCI_CARD_NORMAL, 5, 6, 7, 8); + pci_register_bus_slot(2, 0x0d, PCI_CARD_NORMAL, 6, 7, 8, 5); + pci_register_bus_slot(2, 0x0e, PCI_CARD_NORMAL, 3, 4, 1, 2); + + device_add(&intel_815ep_device); /* Intel 815EP MCH */ + device_add(&intel_ich2_device); /* Intel ICH2 */ + device_add(&it8702_device); /* ITE IT8702 */ + device_add(&sst_flash_49lf002_device); /* SST 2Mbit Firmware Hub */ + device_add(&as99127f_device); /* ASUS Hardware Monitor */ + ics9xxx_get(ICS9150_08); /* ICS Clock Chip */ + intel_815ep_spd_init(); /* SPD */ + + return ret; +} + /* * Biostar M6TSL * @@ -40,10 +84,10 @@ machine_at_m6tsl_init(const machine_t *model) int ret; ret = bios_load_linear("roms/machines/m6tsl/tsl0425b.bin", - 0x00080000, 524288, 0); + 0x00080000, 524288, 0); if (bios_only || !ret) - return ret; + return ret; machine_at_common_init_ex(model, 2); @@ -82,10 +126,10 @@ machine_at_m6tss_init(const machine_t *model) int ret; ret = bios_load_linear("roms/machines/m6tss/tss0518b.bin", - 0x00080000, 524288, 0); + 0x00080000, 524288, 0); if (bios_only || !ret) - return ret; + return ret; machine_at_common_init_ex(model, 2); @@ -125,10 +169,10 @@ machine_at_s2080_init(const machine_t *model) int ret; ret = bios_load_linear("roms/machines/s2080/2080V110.ROM", - 0x00080000, 524288, 0); + 0x00080000, 524288, 0); if (bios_only || !ret) - return ret; + return ret; machine_at_common_init_ex(model, 2); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3544c517c..32db5877b 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11714,7 +11714,43 @@ const machine_t machines[] = { }, /* Intel ICH2 */ - /* Has a NSC PC87366 LPC Super I/O with on-chip AMIKey-2 KBC firmware*/ + { + .name = "ASUS CUSL2-C", + .internal_name = "cusl2c", + .type = MACHINE_TYPE_ICH2, + .chipset = MACHINE_CHIPSET_INTEL_I815EP, + .init = machine_at_cusl2c_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET370, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 133333333, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0, + }, + .bus_flags = MACHINE_PS2_NOISA, + .flags = MACHINE_IDE_DUAL, + .ram = { + .min = 32768, + .max = 524288, + .step = 32768, + }, + .nvrmask = 255, + .kbc = KBC_UNKNOWN, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a NSC PC87366 LPC Super I/O with on-chip AMIKey-2 KBC firmware */ { .name = "[Intel i815E] Biostar M6TSL", .internal_name = "m6tsl", @@ -11743,6 +11779,9 @@ const machine_t machines[] = { .step = 32768 }, .nvrmask = 255, + .kbc = KBC_UNKNOWN, + .kbc_p1 = 0, + .gpio = 0, .device = NULL, .vid_device = NULL, .snd_device = NULL, diff --git a/src/sio/CMakeLists.txt b/src/sio/CMakeLists.txt index f492f5fcb..2d4814456 100644 --- a/src/sio/CMakeLists.txt +++ b/src/sio/CMakeLists.txt @@ -17,6 +17,7 @@ add_library(sio OBJECT sio_acc3221.c sio_ali5123.c sio_f82c710.c sio_82091aa.c sio_fdc37c6xx.c sio_fdc37c67x.c sio_fdc37c669.c sio_fdc37c93x.c sio_fdc37m60x.c sio_nsc366.c sio_it8661f.c + sio_it8702.c sio_pc87306.c sio_pc87307.c sio_pc87309.c sio_pc87310.c sio_pc87311.c sio_pc87332.c sio_prime3b.c sio_prime3c.c sio_w83627hf.c sio_w83787f.c sio_w83877f.c sio_w83977f.c sio_um8669f.c diff --git a/src/sio/sio_it8702.c b/src/sio/sio_it8702.c new file mode 100644 index 000000000..a96a99e04 --- /dev/null +++ b/src/sio/sio_it8702.c @@ -0,0 +1,445 @@ +/* + * ITE IT8702 + * + * Authors: Tiseno100, + * + * Copyright 2022 Tiseno100. + */ + +// NOTE: We don't really utilize fans because our emulated board doesn't use them. +// NOTE 2: LPT & Serial are aligned on a different way due to CUSL2-C not using them properly. + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/device.h> + +#include <86box/keyboard.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/fdd_common.h> +#include <86box/port_92.h> + +#include <86box/sio.h> + +typedef struct +{ + int ldn, unlock; + + uint8_t index, regs[15], sw_lock, + enable[11], + b_addr[4][11], + irq[11], + dma[11], + d_spec[15][11]; + + fdc_t *fdc; + serial_t *uart[2]; +} it8702_t; + +#ifdef ENABLE_IT8702_LOG +int it8702_do_log = ENABLE_IT8702_LOG; +static void +it8702_log(const char *fmt, ...) +{ + va_list ap; + + if (it8702_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define it8702_log(fmt, ...) +#endif + +static void it8702_reset(void *priv); + + +static void +it8702_unlock(uint8_t val, it8702_t *dev) +{ + if(val == 0x87) { /* The unlock mechanism of the CUSL2-C doesn't work as intended so we just unlock it with 87h only for now */ + it8702_log("IT8702 Unlock: Unlocking\n"); + dev->unlock = 1; + } +} + +static void +it8702_sw_lock(uint8_t val, it8702_t *dev) +{ + if(val & 0x80) + dev->sw_lock = val; + else + dev->sw_lock = 0; +} + +static void +it8702_fdc(it8702_t *dev) +{ + uint16_t base = ((dev->b_addr[0][0] & 0x0f) << 8) | (dev->b_addr[1][0] & 0xf8); + int irq = dev->irq[0]; + int dma = dev->dma[0]; + fdc_remove(dev->fdc); + + if(dev->enable[0] & 1) { + it8702_log("IT8702 FDC: Enabled with Base: 0x%x IRQ: %d and DMA: %d\n", base, irq, dma); + fdc_set_base(dev->fdc, base); + fdc_set_irq(dev->fdc, irq); + fdc_set_dma_ch(dev->fdc, dma); + + if(dev->d_spec[0][0] & 1) + fdc_writeprotect(dev->fdc); + + fdc_update_drvrate(dev->fdc, 0, dev->d_spec[1][0] & 3); + fdc_update_drvrate(dev->fdc, 1, (dev->d_spec[1][0] >> 2) & 3); + } +} + +static void +it8702_uart(int uart, it8702_t *dev) +{ + uint16_t base = ((dev->b_addr[0][2 + uart] & 0x0f) << 8) | (dev->b_addr[1][2 + uart] & 0xf8); + int irq = dev->irq[2 + uart]; + serial_remove(dev->uart[uart]); + + if(dev->enable[2 + uart]) + { + it8702_log("IT8702 Serial %c: Enabled with Base: 0x%x IRQ: %d\n", 'A' + uart, base, irq); + serial_setup(dev->uart[uart], base, irq); + serial_set_clock_src(dev->uart[uart], 24444444 / ((dev->d_spec[0][2 + uart] >> 1) ? 12 : 13)); + } +} + +static void +it8702_lpt(it8702_t *dev) +{ + uint16_t base = ((dev->b_addr[0][1] & 0x0f) << 8) | (dev->b_addr[1][1] & 0xf8); + int irq = dev->irq[1]; + lpt1_remove(); + lpt2_remove(); + + if(dev->enable[1] & 1) { + it8702_log("IT8702 LPT1: Enabled with Base: 0x%x IRQ: %d\n", base, irq); + lpt1_init(base); + lpt1_irq(irq); + lpt2_irq(irq); + } +} + +static void +it8702_ldn(it8702_t *dev) +{ + switch(dev->ldn) + { + case 0: + it8702_fdc(dev); + break; + + case 1: + it8702_lpt(dev); + break; + + case 2 ... 3: + it8702_uart((dev->ldn == 3), dev); + break; + + + } +} + +static void +it8702_write(uint16_t addr, uint8_t val, void *priv) +{ + it8702_t *dev = (it8702_t *) priv; + + if(addr == 0x2e) { + if(dev->unlock) + dev->index = val; + else + it8702_unlock(val, dev); + } + else if(addr == 0x2f) { + switch(dev->index) + { + /* Global Registers */ + case 0x02: /* Configure Control */ + if(val & 2) { + it8702_log("IT8702 Unlock: Locking\n"); + dev->unlock = 0; + } + + if(val & 1) { + it8702_log("IT8702: Resetting\n"); + it8702_reset(dev); + } + break; + + case 0x07: + dev->ldn = val; + break; + + case 0x23: + if(!(dev->sw_lock & 0x80)) + dev->regs[dev->index - 0x20] = val & 0xd9; + break; + + case 0x24: + dev->regs[dev->index - 0x20] = val & 0x00; + break; + + case 0x25 ... 0x28: + if(dev->ldn == 7) + dev->regs[dev->index - 0x20] = val; + break; + + case 0x29: + if(dev->ldn == 7) + dev->regs[dev->index - 0x20] = val & 0x3f; + break; + + case 0x2a: + if(dev->ldn == 7) + dev->regs[dev->index - 0x20] = val & 0x7f; + break; + + case 0x2b: + if(!(dev->sw_lock & 0x80)) { + dev->regs[dev->index - 0x20] = val; + it8702_sw_lock(val, dev); + } + break; + + case 0x2c: + dev->regs[dev->index - 0x20] = val & 0x1c; + break; + + case 0x30: + if(dev->ldn < 11) + dev->enable[dev->ldn] = val & 1; + + it8702_ldn(dev); + break; + + case 0x60 ... 0x63: + if(dev->ldn < 11) + dev->b_addr[dev->index & 3][dev->ldn] = val; + + it8702_ldn(dev); + break; + + case 0x70: + if(dev->ldn < 11) + dev->irq[dev->ldn] = val & 0x0f; + + it8702_ldn(dev); + break; + + case 0x74: + if(dev->ldn < 11) + dev->dma[dev->ldn] = val & 0x0f; + + it8702_ldn(dev); + break; + + case 0xf0 ... 0xf0: + if(dev->ldn < 11) + dev->d_spec[dev->index & 0x0f][dev->ldn] = val; + + it8702_ldn(dev); + break; + } + } +} + + +static uint8_t +it8702_read(uint16_t addr, void *priv) +{ + it8702_t *dev = (it8702_t *) priv; + + if(addr == 0x2e) + return dev->index; + else if(addr == 0x2f) { + if(dev->index == 0x02) /* The Configure Control register is Write Only */ + return 0xff; + else + switch(dev->index) + { + case 0x07: + return dev->ldn; + + case 0x20 ... 0x2f: + return dev->regs[dev->index - 0x20]; + + case 0x30: + if(dev->ldn < 11) + return dev->enable[dev->ldn]; + else + return 0xff; + + case 0x60 ... 0x63: + if(dev->ldn < 11) + return dev->b_addr[dev->index & 3][dev->ldn]; + else + return 0xff; + + case 0x70: + if(dev->ldn < 11) + return dev->irq[dev->ldn]; + else + return 0xff; + + case 0x74: + if(dev->ldn < 11) + return dev->dma[dev->ldn]; + else + return 0xff; + + case 0xf0 ... 0xff: + if(dev->ldn < 11) + return dev->d_spec[dev->index & 0x0f][dev->ldn]; + else + return 0xff; + + default: + return 0xff; + } + } +} + + +static void +it8702_reset(void *priv) +{ + it8702_t *dev = (it8702_t *) priv; + + dev->ldn = 0; + dev->sw_lock = 0; // Needs implementation + + dev->unlock = 0; /* Lock the chip */ + + /* Global Super I/O Registers */ + dev->regs[0x00] = 0x87; + dev->regs[0x01] = 0x02; + dev->regs[0x02] = 0x07; + + /* Floppy Disk Controller */ + dev->b_addr[0][0] = 0x03; + dev->b_addr[1][0] = 0xf0; + dev->irq[0] = 0x06; + dev->dma[0] = 0x02; + fdc_reset(dev->fdc); + it8702_fdc(dev); + + /* LPT */ + dev->b_addr[0][1] = 0x03; + dev->b_addr[1][1] = 0x78; + dev->irq[1] = 0x07; + dev->dma[1] = 0x03; + dev->d_spec[0][1] = 0x03; + it8702_lpt(dev); + + /* UART Serial A */ + dev->b_addr[0][2] = 0x02; + dev->b_addr[1][2] = 0xf8; + dev->irq[2] = 0x04; + dev->d_spec[1][2] = 0x50; + dev->d_spec[3][2] = 0x7f; + it8702_uart(0, dev); + + /* UART Serial B */ + dev->b_addr[0][3] = 0x02; + dev->b_addr[1][3] = 0x78; + dev->irq[3] = 0x04; + dev->d_spec[1][3] = 0x50; + dev->d_spec[3][3] = 0x7f; + it8702_uart(1, dev); + + /* FAN Handler */ + dev->b_addr[0][4] = 0x02; + dev->b_addr[1][4] = 0x90; + dev->b_addr[2][4] = 0x02; + dev->b_addr[3][4] = 0x30; + dev->irq[4] = 0x09; + + /* Keyboard Controller */ + dev->b_addr[3][5] = 0x64; + dev->irq[5] = 0x01; + + /* PS/2 Mouse */ + dev->irq[6] = 0x0c; + + /* MIDI */ + dev->b_addr[0][8] = 0x03; + dev->irq[8] = 0x0a; + + /* Gameport */ + dev->b_addr[0][9] = 0x02; + dev->b_addr[1][9] = 0x10; + + /* IR */ + dev->b_addr[0][10] = 0x03; + dev->b_addr[1][10] = 0x10; + dev->irq[10] = 0x0b; +} + + +static void +it8702_close(void *priv) +{ + it8702_t *dev = (it8702_t *) priv; + + free(dev); +} + + +static void * +it8702_init(const device_t *info) +{ + it8702_t *dev = (it8702_t *) malloc(sizeof(it8702_t)); + memset(dev, 0, sizeof(it8702_t)); + + /* FDC */ + dev->fdc = device_add(&fdc_at_smc_device); + + /* Keyboard Controller */ + device_add(&keyboard_ps2_ami_pci_device); + + /* Port 92h */ + device_add(&port_92_pci_device); + + /* Serial */ + dev->uart[0] = device_add_inst(&ns16650_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + io_sethandler(info->local, 2, it8702_read, NULL, NULL, it8702_write, NULL, NULL, dev); /* Ports 2Eh-2Fh: ITE IT8702 */ + + it8702_reset(dev); + + return dev; +} + +const device_t it8702_device = { + .name = "ITE IT8702", + .internal_name = "it8702", + .flags = 0, + .local = 0x2e, + .init = it8702_init, + .close = it8702_close, + .reset = it8702_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index f3ff2c7da..a19510828 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -612,6 +612,7 @@ SIOOBJ := sio_acc3221.o sio_ali5123.o \ sio_f82c710.o sio_82091aa.o sio_fdc37c6xx.o \ sio_fdc37c67x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \ sio_it8661f.o \ + sio_it8702.o \ sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87310.o sio_pc87311.o sio_pc87332.o \ sio_prime3b.o sio_prime3c.o \ sio_w83627hf.o sio_w83787f.o \