Merge pull request #6124 from 86Box/tc1995
EEPROM and misc changes (September 3rd, 2025)
This commit is contained in:
@@ -21,6 +21,7 @@ add_library(mem OBJECT
|
||||
intel_flash.c
|
||||
mem.c
|
||||
mmu_2386.c
|
||||
nmc93cxx.c
|
||||
rom.c
|
||||
row.c
|
||||
smram.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 *
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user