mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 09:35:32 -07:00
RTL8019AS and ISA PnP: More fixes.
This commit is contained in:
@@ -98,6 +98,8 @@ typedef struct _isapnp_card_ {
|
||||
uint8_t serial_read_pair;
|
||||
uint8_t serial_read_pos;
|
||||
uint8_t is_rt;
|
||||
uint8_t normal;
|
||||
uint8_t multiple_lds;
|
||||
uint8_t *rom;
|
||||
uint16_t rom_pos;
|
||||
uint16_t rom_size;
|
||||
@@ -449,15 +451,16 @@ isapnp_write_addr(UNUSED(uint16_t addr), uint8_t val, void *priv)
|
||||
if (!dev->key_pos) {
|
||||
isapnp_log("ISAPnP: Key unlocked, putting cards to SLEEP\n");
|
||||
while (card) {
|
||||
int is_rt = (!dev->using_key2 || card->is_rt);
|
||||
if (card->enable && is_rt && (card->enable != ISAPNP_CARD_NO_KEY) && (card->state == PNP_STATE_WAIT_FOR_KEY))
|
||||
int match_rt = (dev->using_key2 && card->is_rt);
|
||||
int match_normal = (!dev->using_key2 && card->normal);
|
||||
if (card->enable && (match_rt || match_normal) &&
|
||||
(card->enable != ISAPNP_CARD_NO_KEY) && (card->state == PNP_STATE_WAIT_FOR_KEY))
|
||||
card->state = PNP_STATE_SLEEP;
|
||||
card = card->next;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
dev->key_pos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,8 +530,22 @@ isapnp_write_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uin
|
||||
if (card->csn == val) {
|
||||
card->rom_pos = 0;
|
||||
card->id_checksum = isapnp_init_key[0];
|
||||
if (card->state == PNP_STATE_SLEEP)
|
||||
if (card->state == PNP_STATE_SLEEP) {
|
||||
card->state = (val == 0) ? PNP_STATE_ISOLATION : PNP_STATE_CONFIG;
|
||||
|
||||
if (!card->multiple_lds) {
|
||||
ld = card->first_ld;
|
||||
while (ld) {
|
||||
if (ld->number == 0x00) {
|
||||
isapnp_log("ISAPnP: Select CSN %02X device 00\n", card->csn);
|
||||
dev->current_ld_card = card;
|
||||
dev->current_ld = ld;
|
||||
break;
|
||||
}
|
||||
ld = ld->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
card->state = PNP_STATE_SLEEP;
|
||||
|
||||
@@ -549,27 +566,28 @@ isapnp_write_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uin
|
||||
break;
|
||||
|
||||
case 0x07: /* Logical Device Number */
|
||||
CHECK_CURRENT_CARD();
|
||||
if (card->multiple_lds) {
|
||||
CHECK_CURRENT_CARD();
|
||||
|
||||
card->ld = val;
|
||||
ld = card->first_ld;
|
||||
while (ld) {
|
||||
if (ld->number == val) {
|
||||
isapnp_log("ISAPnP: Select CSN %02X device %02X\n", card->csn, val);
|
||||
dev->current_ld_card = card;
|
||||
dev->current_ld = ld;
|
||||
break;
|
||||
card->ld = val;
|
||||
ld = card->first_ld;
|
||||
while (ld) {
|
||||
if (ld->number == val) {
|
||||
isapnp_log("ISAPnP: Select CSN %02X device %02X\n", card->csn, val);
|
||||
dev->current_ld_card = card;
|
||||
dev->current_ld = ld;
|
||||
break;
|
||||
}
|
||||
ld = ld->next;
|
||||
}
|
||||
ld = ld->next;
|
||||
}
|
||||
|
||||
if (!ld) {
|
||||
isapnp_log("ISAPnP: CSN %02X has no device %02X, creating one\n", card->csn, val);
|
||||
dev->current_ld_card = card;
|
||||
dev->current_ld = isapnp_create_ld(card);
|
||||
dev->current_ld->number = val;
|
||||
if (!ld) {
|
||||
isapnp_log("ISAPnP: CSN %02X has no device %02X, creating one\n", card->csn, val);
|
||||
dev->current_ld_card = card;
|
||||
dev->current_ld = isapnp_create_ld(card);
|
||||
dev->current_ld->number = val;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x30: /* Activate */
|
||||
@@ -759,11 +777,13 @@ isapnp_add_card(uint8_t *rom, uint16_t rom_size,
|
||||
isapnp_card_t *card = (isapnp_card_t *) calloc(1, sizeof(isapnp_card_t));
|
||||
|
||||
card->enable = 1;
|
||||
card->normal = 1;
|
||||
card->priv = priv;
|
||||
card->config_changed = config_changed;
|
||||
card->csn_changed = csn_changed;
|
||||
card->read_vendor_reg = read_vendor_reg;
|
||||
card->write_vendor_reg = write_vendor_reg;
|
||||
card->multiple_lds = 1;
|
||||
|
||||
if (!dev->first_card) {
|
||||
dev->first_card = card;
|
||||
@@ -1201,6 +1221,45 @@ isapnp_set_rt(void *priv, uint8_t is_rt)
|
||||
card->is_rt = is_rt;
|
||||
}
|
||||
|
||||
void
|
||||
isapnp_set_normal(void *priv, uint8_t normal)
|
||||
{
|
||||
isapnp_card_t *card = (isapnp_card_t *) priv;
|
||||
|
||||
card->normal = normal;
|
||||
}
|
||||
|
||||
void
|
||||
isapnp_activate(void *priv, uint16_t base, uint8_t irq)
|
||||
{
|
||||
isapnp_card_t *card = (isapnp_card_t *) priv;
|
||||
isapnp_device_t *ld = card->first_ld;
|
||||
|
||||
while (ld) {
|
||||
if (ld->number == 0x00)
|
||||
break;
|
||||
ld = ld->next;
|
||||
}
|
||||
|
||||
if (ld != NULL) {
|
||||
ld->regs[0x30] = 0x01;
|
||||
ld->regs[0x60] = base >> 4;
|
||||
if (!(ld->io_16bit & (1 << ((0x60 >> 1) & 0x07))))
|
||||
ld->regs[0x60] &= 0x03;
|
||||
ld->regs[0x61] = base & 0x0f;
|
||||
ld->regs[0x70] = irq;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isapnp_set_single_ld(void *priv)
|
||||
{
|
||||
isapnp_card_t *card = (isapnp_card_t *) priv;
|
||||
|
||||
card->multiple_lds = 0;
|
||||
card->ld = 0x00;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
isapnp_get_csnsav(void *priv)
|
||||
{
|
||||
|
||||
@@ -72,6 +72,9 @@ extern void isapnp_set_device_defaults(void *priv, uint8_t ldn, const isapnp
|
||||
extern void isapnp_reset_card(void *priv);
|
||||
extern void isapnp_reset_device(void *priv, uint8_t ld);
|
||||
extern void isapnp_set_rt(void *priv, uint8_t is_rt);
|
||||
extern void isapnp_set_normal(void *priv, uint8_t normal);
|
||||
extern void isapnp_activate(void *priv, uint16_t base, uint8_t irq);
|
||||
extern void isapnp_set_single_ld(void *priv);
|
||||
extern uint8_t *isapnp_get_csnsav(void *priv);
|
||||
|
||||
#endif /*EMU_ISAPNP_H*/
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
#include <86box/isapnp.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include "cpu.h"
|
||||
|
||||
/* ROM BIOS file paths. */
|
||||
#define ROM_PATH_NE1000 "roms/network/ne1000/ne1000.rom"
|
||||
@@ -340,7 +341,7 @@ page3_read(nic_t *dev, uint32_t off, UNUSED(unsigned int len))
|
||||
|
||||
case 0x3: /* CONFIG0 */
|
||||
if (dev->board == NE2K_RTL8019AS_PNP)
|
||||
ret = (dev->config0 & 0xc0) | 0x10; /* Cable not BNC */
|
||||
ret = dev->config0;
|
||||
else
|
||||
ret = 0x00; /* Cable not BNC */
|
||||
break;
|
||||
@@ -418,20 +419,20 @@ page3_write(nic_t *dev, uint32_t off, uint32_t val, UNUSED(unsigned len))
|
||||
if ((val & 0xc0) == 0x80)
|
||||
nmc93cxx_eeprom_write(dev->eeprom, !!(val & 0x08), !!(val & 0x04), !!(val & 0x02));
|
||||
else if ((val & 0xc0) == 0x40) {
|
||||
uint8_t *data = (uint8_t *) nmc93cxx_eeprom_data(dev->eeprom);
|
||||
uint8_t *data = (uint8_t *) nmc93cxx_eeprom_data(dev->eeprom);
|
||||
|
||||
data[0x00] = 0x80;
|
||||
data[0x01] = 0x00;
|
||||
data[0x02] = 0x80;
|
||||
data[0x03] = 0x00;
|
||||
dev->config1 = (data[0x00] & 0x7f) | 0x80;
|
||||
dev->config2 = (data[0x01] & 0xdf);
|
||||
dev->config3 = (data[0x02] & 0x77) | 0x80;
|
||||
dev->_9346cr = 0x21;
|
||||
|
||||
dev->_9346cr = 0x21;
|
||||
isapnp_set_normal(dev->pnp_card, !!(dev->config3 & 0x80));
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x03: /* CONFIG0 */
|
||||
if (cfg_write_enable && (dev->board == NE2K_RTL8019AS_PNP))
|
||||
dev->config0 = (val & 0xc0);
|
||||
dev->config0 = (dev->config0 & 0x3f) | (val & 0xc0);
|
||||
break;
|
||||
|
||||
case 0x04: /* CONFIG1 */
|
||||
@@ -442,7 +443,7 @@ page3_write(nic_t *dev, uint32_t off, uint32_t val, UNUSED(unsigned len))
|
||||
case 0x05: /* CONFIG2 */
|
||||
if (cfg_write_enable) {
|
||||
if (dev->board == NE2K_RTL8019AS_PNP)
|
||||
dev->config2 = val;
|
||||
dev->config2 = (dev->config2 & 0x1f) | (val & 0xe0);
|
||||
else
|
||||
dev->config2 = (val & 0xe0);
|
||||
}
|
||||
@@ -451,7 +452,7 @@ page3_write(nic_t *dev, uint32_t off, uint32_t val, UNUSED(unsigned len))
|
||||
case 0x06: /* CONFIG3 */
|
||||
if (cfg_write_enable) {
|
||||
if (dev->board == NE2K_RTL8019AS_PNP)
|
||||
dev->config3 = val;
|
||||
dev->config3 = (dev->config3 & 0xf9) | (val & 0x06);
|
||||
else
|
||||
dev->config3 = (val & 0x46);
|
||||
}
|
||||
@@ -582,9 +583,11 @@ static void nic_ioremove(nic_t *dev, uint16_t addr);
|
||||
static void
|
||||
nic_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv)
|
||||
{
|
||||
#if 0
|
||||
uint8_t irq_map[16] = { 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x40, 0x50, 0x60, 0x00, 0x00, 0x70 };
|
||||
uint8_t ios = 0x00;
|
||||
#endif
|
||||
|
||||
if (ld)
|
||||
return;
|
||||
@@ -600,18 +603,22 @@ nic_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv)
|
||||
|
||||
nic_interrupt(dev, 0);
|
||||
dev->base_irq = config->irq[0].irq;
|
||||
#if 0
|
||||
if ((dev->base_irq >= 0x00) && (dev->base_irq <= 0x0f))
|
||||
dev->config1 = (dev->config1 & 0x8f) | irq_map[dev->base_irq];
|
||||
else
|
||||
dev->config1 = (dev->config1 & 0x8f);
|
||||
#endif
|
||||
|
||||
if (config->activate && (dev->base_address != ISAPNP_IO_DISABLED)) {
|
||||
nic_ioset(dev, dev->base_address);
|
||||
#if 0
|
||||
ios |= (dev->base_address & 0x0100) ? 0x00 : 0x04;
|
||||
ios |= (dev->base_address & 0x0080) ? 0x08 : 0x00;
|
||||
ios |= (dev->base_address & 0x0040) ? 0x02 : 0x00;
|
||||
ios |= (dev->base_address & 0x0020) ? 0x01 : 0x00;
|
||||
dev->config1 = (dev->config1 & 0xf0) | ios;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,33 +633,38 @@ nic_pnp_csn_changed(uint8_t csn, void *priv)
|
||||
static uint8_t
|
||||
nic_pnp_read_vendor_reg(uint8_t ld, uint8_t reg, void *priv)
|
||||
{
|
||||
if (ld != 0)
|
||||
return 0x00;
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
const nic_t *dev = (nic_t *) priv;
|
||||
|
||||
switch (reg) {
|
||||
if (ld == 0) switch (reg) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0xf0: /* CONFIG0 */
|
||||
return 0x00; /* Cable not BNC */
|
||||
ret = dev->config0;
|
||||
break;
|
||||
|
||||
case 0xf1: /* CONFIG1 */
|
||||
return dev->config1;
|
||||
ret = dev->config1;
|
||||
break;
|
||||
|
||||
case 0xf2: /* CONFIG2 */
|
||||
return dev->config2;
|
||||
ret = dev->config2;
|
||||
break;
|
||||
|
||||
case 0xf3: /* CONFIG3 */
|
||||
return dev->config3;
|
||||
ret = dev->config3;
|
||||
break;
|
||||
|
||||
case 0xf5:
|
||||
return *dev->pnp_csnsav;
|
||||
|
||||
default:
|
||||
ret = *dev->pnp_csnsav;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
nelog(3, "[R] Vendor register: %02X (LD = %02X) = %02X\n", reg, ld, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -660,6 +672,8 @@ nic_pnp_write_vendor_reg(uint8_t ld, uint8_t reg, uint8_t val, void *priv)
|
||||
{
|
||||
nic_t *dev = (nic_t *) priv;
|
||||
|
||||
nelog(3, "[W] Vendor register: %02X (LD = %02X) = %02X\n", reg, ld, val);
|
||||
|
||||
if ((ld == 0) && (reg == 0xf6) && (val & 0x04)) {
|
||||
uint8_t csn = *dev->pnp_csnsav;
|
||||
isapnp_set_csn(dev->pnp_card, 0);
|
||||
@@ -1307,7 +1321,7 @@ nic_init(const device_t *info)
|
||||
nic_pnp_read_vendor_reg, nic_pnp_write_vendor_reg,
|
||||
dev);
|
||||
dev->pnp_csnsav = isapnp_get_csnsav(dev->pnp_card);
|
||||
dev->config0 = 0x00;
|
||||
dev->config0 = 0x10 /* Cable not BNC */;
|
||||
dev->config1 = 0x80;
|
||||
dev->config2 = 0x00;
|
||||
dev->config3 = 0x80;
|
||||
@@ -1315,7 +1329,7 @@ nic_init(const device_t *info)
|
||||
|
||||
dev->eeprom_data[0x00] = 0x80;
|
||||
dev->eeprom_data[0x01] = 0x00;
|
||||
dev->eeprom_data[0x02] = 0x80;
|
||||
dev->eeprom_data[0x02] = 0x81;
|
||||
dev->eeprom_data[0x03] = 0x01;
|
||||
memcpy(&dev->eeprom_data[0x04], dev->maclocal, 6);
|
||||
break;
|
||||
@@ -1340,6 +1354,32 @@ nic_init(const device_t *info)
|
||||
free(dev);
|
||||
return NULL;
|
||||
}
|
||||
if (info->local == NE2K_RTL8019AS_PNP) {
|
||||
uint8_t *data = (uint8_t *) nmc93cxx_eeprom_data(dev->eeprom);
|
||||
|
||||
dev->config1 = (data[0x00] & 0x7f) | 0x80;
|
||||
dev->config2 = (data[0x01] & 0xdf);
|
||||
dev->config3 = (data[0x02] & 0xf7);
|
||||
|
||||
isapnp_set_normal(dev->pnp_card, !!(dev->config3 & 0x80));
|
||||
isapnp_set_single_ld(dev->pnp_card);
|
||||
|
||||
if (!(dev->config3 & 0x01)) {
|
||||
uint8_t irq_map[8] = { 9, 3, 4, 5, 10, 11, 12, 15 };
|
||||
dev->base_address = 0x0000;
|
||||
|
||||
dev->base_irq = irq_map[(dev->config1 >> 4) & 0x07];
|
||||
|
||||
dev->base_address = (dev->config1 & 0x01) ? 0x0020 : 0x0000;
|
||||
dev->base_address |= (dev->config1 & 0x02) ? 0x0040 : 0x0000;
|
||||
dev->base_address |= (dev->config1 & 0x04) ? 0x0000 : 0x0100;
|
||||
dev->base_address |= (dev->config1 & 0x08) ? 0x0080 : 0x0000;
|
||||
|
||||
nic_ioset(dev, dev->base_address);
|
||||
|
||||
isapnp_activate(dev->pnp_card, dev->base_address, dev->base_irq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->pnp_csnsav == NULL)
|
||||
|
||||
Reference in New Issue
Block a user