From 5f065614694e6e2450a67e25ee110094d47f2c73 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 3 Sep 2025 00:49:27 +0200 Subject: [PATCH 1/3] EEPROM use changes and misc (September 3rd, 2025) 1.Move the 93cxx EEPROM implementation to the mem directory since it's used by cards which are not nics (e.g.: DC390 SCSI and S3 ELSA cards). 2. DC390 specific: remove the implementation used there and use the generic one from mem (used to be on the network directory) as well as fixing bus reset when interrupts are related. 3. S3: when the 64k size is selected in the LFB, use the SVGA 64k mapping as LFB (0xA0000). --- src/mem/CMakeLists.txt | 1 + .../net_eeprom_nmc93cxx.c => mem/nmc93cxx.c} | 9 +- src/network/CMakeLists.txt | 4 - src/network/net_rtl8139.c | 2 +- src/network/net_tulip.c | 2 +- src/scsi/scsi_pcscsi.c | 276 +++++------------- src/video/vid_s3.c | 9 +- 7 files changed, 90 insertions(+), 213 deletions(-) rename src/{network/net_eeprom_nmc93cxx.c => mem/nmc93cxx.c} (97%) 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..782672e98 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 @@ -71,9 +70,6 @@ if(NETSWITCH) endif() if (UNIX) - if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") - set_source_files_properties(net_slirp.c PROPERTIES COMPILE_FLAGS "-I/usr/local/include") - endif() find_path(HAS_VDE "libvdeplug.h" PATHS ${VDE_INCLUDE_DIR} "/usr/include /usr/local/include" "/opt/homebrew/include" ) if(HAS_VDE) find_library(VDE_LIB vdeplug) 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: From 7e490d53403c03f8ef0e2adaa474783bbb1a2b5c Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 3 Sep 2025 00:50:01 +0200 Subject: [PATCH 2/3] Forgot the header. --- src/include/86box/{net_eeprom_nmc93cxx.h => nmc93cxx.h} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/include/86box/{net_eeprom_nmc93cxx.h => nmc93cxx.h} (100%) 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 From 5618dba9d1a75c8f652111a63358c7427f42a2c0 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 3 Sep 2025 00:53:26 +0200 Subject: [PATCH 3/3] Restore FreeBSD stuff that was removed accidentally --- src/network/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 782672e98..0943a9258 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -70,6 +70,9 @@ if(NETSWITCH) endif() if (UNIX) + if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + set_source_files_properties(net_slirp.c PROPERTIES COMPILE_FLAGS "-I/usr/local/include") + endif() find_path(HAS_VDE "libvdeplug.h" PATHS ${VDE_INCLUDE_DIR} "/usr/include /usr/local/include" "/opt/homebrew/include" ) if(HAS_VDE) find_library(VDE_LIB vdeplug)