diff --git a/src/include/86box/net_eeprom_nmc93cxx.h b/src/include/86box/nmc93cxx.h similarity index 100% rename from src/include/86box/net_eeprom_nmc93cxx.h rename to src/include/86box/nmc93cxx.h diff --git a/src/mem/CMakeLists.txt b/src/mem/CMakeLists.txt index 0e52beb4e..3984c2d02 100644 --- a/src/mem/CMakeLists.txt +++ b/src/mem/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(mem OBJECT intel_flash.c mem.c mmu_2386.c + nmc93cxx.c rom.c row.c smram.c diff --git a/src/network/net_eeprom_nmc93cxx.c b/src/mem/nmc93cxx.c similarity index 97% rename from src/network/net_eeprom_nmc93cxx.c rename to src/mem/nmc93cxx.c index 05fd43ed0..50905bae2 100644 --- a/src/network/net_eeprom_nmc93cxx.c +++ b/src/mem/nmc93cxx.c @@ -28,7 +28,7 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/nvr.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/plat_unused.h> #ifdef ENABLE_NMC93CXX_EEPROM_LOG @@ -256,7 +256,12 @@ static void nmc93cxx_eeprom_close(void *priv) { nmc93cxx_eeprom_t *eeprom = (nmc93cxx_eeprom_t *) priv; - free(eeprom); + FILE *fp = nvr_fopen(eeprom->filename, "wb"); + if (fp) { + fwrite(eeprom->dev.data, 2, eeprom->size, fp); + fclose(fp); + } + free(priv); } uint16_t * diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 3f7ba427c..0943a9258 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -28,7 +28,6 @@ list(APPEND net_sources net_plip.c net_event.c net_null.c - net_eeprom_nmc93cxx.c net_tulip.c net_rtl8139.c net_l80225.c diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index f1e531deb..41ce86f6b 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -43,7 +43,7 @@ #include <86box/device.h> #include <86box/thread.h> #include <86box/network.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/nvr.h> #include "cpu.h" #include <86box/plat_unused.h> diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 883ba53ad..cbf3b704e 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -31,7 +31,7 @@ #include <86box/device.h> #include <86box/thread.h> #include <86box/network.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> #include <86box/bswap.h> diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index f91eef683..04c188705 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -40,11 +40,11 @@ #include <86box/pci.h> #include <86box/device.h> #include <86box/nvr.h> +#include <86box/nmc93cxx.h> #include <86box/plat.h> #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/scsi_pcscsi.h> -#include <86box/vid_ati_eeprom.h> #include <86box/fifo8.h> #include "cpu.h" @@ -179,7 +179,6 @@ typedef struct esp_t { int BIOSBase; int MMIOBase; rom_t bios; - ati_eeprom_t eeprom; int PCIBase; uint8_t rregs[ESP_REGS]; @@ -223,9 +222,14 @@ typedef struct esp_t { uint8_t irq_state; uint8_t pos_regs[8]; + + uint8_t eeprom_inst; + uint8_t eeprom_data[128]; + + nmc93cxx_eeprom_t *eeprom; } esp_t; -static esp_t reset_state = { 0 }; +static esp_t *reset_state = NULL; #define READ_FROM_DEVICE 1 #define WRITE_TO_DEVICE 0 @@ -1534,19 +1538,19 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) break; case CMD_BUSRESET: esp_log("ESP Bus Reset val=%02x.\n", (dev->rregs[ESP_CFG1] & CFG1_RESREPT)); - if (dev->mca) { - esp_lower_irq(dev); - esp_hard_reset(dev); - } else - esp_pci_soft_reset(dev); - - for (uint8_t i = 0; i < 16; i++) { + for (uint8_t i = 0; i < 16; i++) scsi_device_reset(&scsi_devices[dev->bus][i]); - } + if (!(dev->rregs[ESP_CFG1] & CFG1_RESREPT)) { dev->rregs[ESP_RINTR] |= INTR_RST; esp_log("ESP Bus Reset with IRQ\n"); esp_raise_irq(dev); + } else { + if (dev->mca) { + esp_lower_irq(dev); + esp_hard_reset(dev); + } else + esp_pci_soft_reset(dev); } break; case CMD_TI: @@ -1994,180 +1998,6 @@ esp_bios_disable(esp_t *dev) #define EE_ADAPT_OPTION_INT13 0x04 #define EE_ADAPT_OPTION_SCAM_SUPPORT 0x08 -/*To do: make this separate from the SCSI card*/ -static void -dc390_save_eeprom(esp_t *dev) -{ - FILE *fp = nvr_fopen(dev->nvr_path, "wb"); - if (!fp) - return; - fwrite(dev->eeprom.data, 1, 128, fp); - fclose(fp); -} - -static void -dc390_write_eeprom(esp_t *dev, int ena, int clk, int dat) -{ - /*Actual EEPROM is the same as the one used by the ATI cards, the 93cxx series.*/ - ati_eeprom_t *eeprom = &dev->eeprom; - uint8_t tick = eeprom->count; - uint8_t eedo = eeprom->out; - uint16_t address = eeprom->address; - uint8_t command = eeprom->opcode; - - esp_log("EEPROM CS=%02x,SK=%02x,DI=%02x,DO=%02x,tick=%d\n", - ena, clk, dat, eedo, tick); - - if (!eeprom->oldena && ena) { - esp_log("EEPROM Start chip select cycle\n"); - tick = 0; - command = 0; - address = 0; - } else if (eeprom->oldena && !ena) { - if (!eeprom->wp) { - uint8_t subcommand = address >> 4; - if (command == 0 && subcommand == 2) { - esp_log("EEPROM Erase All\n"); - for (address = 0; address < 64; address++) - eeprom->data[address] = 0xffff; - dc390_save_eeprom(dev); - } else if (command == 3) { - esp_log("EEPROM Erase Word\n"); - eeprom->data[address] = 0xffff; - dc390_save_eeprom(dev); - } else if (tick >= 26) { - if (command == 1) { - esp_log("EEPROM Write Word\n"); - eeprom->data[address] &= eeprom->dat; - dc390_save_eeprom(dev); - } else if (command == 0 && subcommand == 1) { - esp_log("EEPROM Write All\n"); - for (address = 0; address < 64; address++) - eeprom->data[address] &= eeprom->dat; - dc390_save_eeprom(dev); - } - } - } - eedo = 1; - esp_log("EEPROM DO read\n"); - } else if (ena && !eeprom->oldclk && clk) { - if (tick == 0) { - if (dat == 0) { - esp_log("EEPROM Got correct 1st start bit, waiting for 2nd start bit (1)\n"); - tick++; - } else { - esp_log("EEPROM Wrong 1st start bit (is 1, should be 0)\n"); - tick = 2; - } - } else if (tick == 1) { - if (dat != 0) { - esp_log("EEPROM Got correct 2nd start bit, getting command + address\n"); - tick++; - } else { - esp_log("EEPROM 1st start bit is longer than needed\n"); - } - } else if (tick < 4) { - tick++; - command <<= 1; - if (dat) - command += 1; - } else if (tick < 10) { - tick++; - address = (address << 1) | dat; - if (tick == 10) { - esp_log("EEPROM command = %02x, address = %02x (val = %04x)\n", command, - address, eeprom->data[address]); - if (command == 2) - eedo = 0; - address = address % 64; - if (command == 0) { - switch (address >> 4) { - case 0: - esp_log("EEPROM Write disable command\n"); - eeprom->wp = 1; - break; - case 1: - esp_log("EEPROM Write all command\n"); - break; - case 2: - esp_log("EEPROM Erase all command\n"); - break; - case 3: - esp_log("EEPROM Write enable command\n"); - eeprom->wp = 0; - break; - - default: - break; - } - } else { - esp_log("EEPROM Read, write or erase word\n"); - eeprom->dat = eeprom->data[address]; - } - } - } else if (tick < 26) { - tick++; - if (command == 2) { - esp_log("EEPROM Read Word\n"); - eedo = ((eeprom->dat & 0x8000) != 0); - } - eeprom->dat <<= 1; - eeprom->dat += dat; - } else { - esp_log("EEPROM Additional unneeded tick, not processed\n"); - } - } - - eeprom->count = tick; - eeprom->oldena = ena; - eeprom->oldclk = clk; - eeprom->out = eedo; - eeprom->address = address; - eeprom->opcode = command; - esp_log("EEPROM EEDO = %d\n", eeprom->out); -} - -static void -dc390_load_eeprom(esp_t *dev) -{ - ati_eeprom_t *eeprom = &dev->eeprom; - uint8_t *nvr = (uint8_t *) eeprom->data; - int i; - uint16_t checksum = 0; - FILE *fp; - - eeprom->out = 1; - - fp = nvr_fopen(dev->nvr_path, "rb"); - if (fp) { - esp_log("EEPROM Load\n"); - if (fread(nvr, 1, 128, fp) != 128) - fatal("dc390_eeprom_load(): Error reading data\n"); - fclose(fp); - } else { - for (i = 0; i < 16; i++) { - nvr[i * 2] = 0x57; - nvr[i * 2 + 1] = 0x00; - } - - esp_log("EEPROM Defaults\n"); - - nvr[EE_ADAPT_SCSI_ID] = 7; - nvr[EE_MODE2] = 0x0f; - nvr[EE_TAG_CMD_NUM] = 0x04; - nvr[EE_ADAPT_OPTIONS] = EE_ADAPT_OPTION_F6_F8_AT_BOOT | EE_ADAPT_OPTION_BOOT_FROM_CDROM | EE_ADAPT_OPTION_INT13; - for (i = 0; i < EE_CHKSUM1; i += 2) { - checksum += ((nvr[i] & 0xff) | (nvr[i + 1] << 8)); - esp_log("Checksum calc = %04x, nvr = %02x\n", checksum, nvr[i]); - } - - checksum = 0x1234 - checksum; - nvr[EE_CHKSUM1] = checksum & 0xff; - nvr[EE_CHKSUM2] = checksum >> 8; - esp_log("EEPROM Checksum = %04x\n", checksum); - } -} - static uint8_t esp_pci_read(UNUSED(int func), int addr, void *priv) { @@ -2181,10 +2011,10 @@ esp_pci_read(UNUSED(int func), int addr, void *priv) if (!dev->has_bios || dev->local) return 0x22; else { - if (dev->eeprom.out) + if (nmc93cxx_eeprom_read(dev->eeprom)) return 0x22; else { - dev->eeprom.out = 1; + dev->eeprom->dev.out = 1; return 2; } } @@ -2270,9 +2100,9 @@ esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) if (addr == 0x80) { eesk = val & 0x80 ? 1 : 0; eedi = val & 0x40 ? 1 : 0; - dc390_write_eeprom(dev, 1, eesk, eedi); + nmc93cxx_eeprom_write(dev->eeprom, 1, eesk, eedi); } else if (addr == 0xc0) - dc390_write_eeprom(dev, 0, 0, 0); + nmc93cxx_eeprom_write(dev->eeprom, 0, 0, 0); // esp_log("ESP PCI: Write value %02X to register %02X\n", val, addr); return; } @@ -2371,26 +2201,35 @@ esp_pci_reset(void *priv) { esp_t *dev = (esp_t *) priv; - timer_disable(&dev->timer); + if (reset_state != NULL) { + esp_io_remove(dev, dev->PCIBase, 0x80); + esp_bios_disable(dev); + timer_stop(&dev->timer); - reset_state.bios.mapping = dev->bios.mapping; + reset_state->bios.mapping = dev->bios.mapping; + reset_state->timer = dev->timer; + reset_state->pci_slot = dev->pci_slot; - reset_state.timer = dev->timer; + *dev = *reset_state; - reset_state.pci_slot = dev->pci_slot; - - memcpy(dev, &reset_state, sizeof(esp_t)); - - esp_pci_soft_reset(dev); + esp_pci_soft_reset(dev); + esp_log("PCI Reset.\n"); + } } static void * dc390_init(const device_t *info) { esp_t *dev = calloc(1, sizeof(esp_t)); + reset_state = calloc(1, sizeof(esp_t)); const char *bios_rev = NULL; uint32_t mask = 0; uint32_t size = 0x8000; + nmc93cxx_eeprom_params_t params; + char eeprom_filename[1024] = { 0 }; + char filename[1024] = { 0 }; + uint16_t checksum = 0x0000; + uint8_t i; dev->bus = scsi_get_bus(); @@ -2434,10 +2273,40 @@ dc390_init(const device_t *info) esp_bios_disable(dev); if (!dev->local) { - sprintf(dev->nvr_path, "dc390_%i.nvr", device_get_instance()); + dev->eeprom_inst = device_get_instance(); + + snprintf(eeprom_filename, sizeof(eeprom_filename), "dc390_%d.nvr", dev->eeprom_inst); /* Load the serial EEPROM. */ - dc390_load_eeprom(dev); + for (i = 0; i < 16; i++) { + dev->eeprom_data[i * 2] = 0x57; + dev->eeprom_data[i * 2 + 1] = 0x00; + } + + esp_log("EEPROM Defaults\n"); + + dev->eeprom_data[EE_ADAPT_SCSI_ID] = 7; + dev->eeprom_data[EE_MODE2] = 0x0f; + dev->eeprom_data[EE_TAG_CMD_NUM] = 0x04; + dev->eeprom_data[EE_ADAPT_OPTIONS] = EE_ADAPT_OPTION_F6_F8_AT_BOOT | EE_ADAPT_OPTION_BOOT_FROM_CDROM | EE_ADAPT_OPTION_INT13; + for (i = 0; i < EE_CHKSUM1; i += 2) { + checksum += ((dev->eeprom_data[i] & 0xff) | (dev->eeprom_data[i + 1] << 8)); + esp_log("Checksum calc = %04x, nvr = %02x\n", checksum, dev->eeprom_data[i]); + } + + checksum = 0x1234 - checksum; + dev->eeprom_data[EE_CHKSUM1] = checksum & 0xff; + dev->eeprom_data[EE_CHKSUM2] = checksum >> 8; + + params.nwords = 64; + params.default_content = (uint16_t *) dev->eeprom_data; + params.filename = filename; + snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, dev->eeprom_inst); + dev->eeprom = device_add_inst_params(&nmc93cxx_device, dev->eeprom_inst, ¶ms); + if (dev->eeprom == NULL) { + free(dev); + return NULL; + } } esp_pci_hard_reset(dev); @@ -2449,7 +2318,7 @@ dc390_init(const device_t *info) scsi_bus_set_speed(dev->bus, 10000000.0); - memcpy(&reset_state, dev, sizeof(esp_t)); + *reset_state = *dev; return dev; } @@ -2622,7 +2491,7 @@ ncr53c9x_mca_init(const device_t *info) fifo8_create(&dev->fifo, ESP_FIFO_SZ); fifo8_create(&dev->cmdfifo, ESP_CMDFIFO_SZ); - dev->pos_regs[0] = 0x4f; /* MCA board ID */ + dev->pos_regs[0] = 0x4d; /* MCA board ID */ dev->pos_regs[1] = 0x7f; mca_add(ncr53c9x_mca_read, ncr53c9x_mca_write, ncr53c9x_mca_feedb, NULL, dev); @@ -2646,6 +2515,11 @@ esp_close(void *priv) fifo8_destroy(&dev->fifo); fifo8_destroy(&dev->cmdfifo); + if (reset_state != NULL) { + free(reset_state); + reset_state = NULL; + } + free(dev); dev = NULL; } diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 943441f1c..fbf329e84 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -33,7 +33,7 @@ #include <86box/mem.h> #include <86box/pci.h> #include <86box/rom.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/nvr.h> #include <86box/plat.h> #include <86box/thread.h> @@ -4807,10 +4807,10 @@ s3_updatemapping(s3_t *s3) break; } s3->linear_base &= ~(s3->linear_size - 1); - if (s3->linear_base == 0xa0000) { + if ((s3->linear_base == 0xa0000) || (s3->linear_size == 0x10000)) { mem_mapping_disable(&s3->linear_mapping); if (!(svga->crtc[0x53] & 0x10)) { - mem_mapping_set_addr(&svga->mapping, s3->linear_base, 0x10000); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; } } else { @@ -5071,6 +5071,7 @@ s3_accel_in(uint16_t port, void *priv) if (FIFO_FULL) temp = 0xff; } + s3_log("Read port=%04x, val=%02x.\n", port, temp); return temp; case 0x8119: case 0x9949: @@ -5127,7 +5128,7 @@ s3_accel_in(uint16_t port, void *priv) s3->data_available = 0; } } - s3_log("FIFO Status Temp=%02x.\n", temp); + s3_log("Read port=%04x, val=%02x.\n", port, temp); return temp; case 0x9d48: