Skip to content

Commit

Permalink
NE2k PCMCIA card ready to be hooked up
Browse files Browse the repository at this point in the history
  • Loading branch information
Cacodemon345 committed Jun 13, 2024
1 parent a5a1aa0 commit 7f145d7
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 7 deletions.
3 changes: 2 additions & 1 deletion src/include/86box/pcmcia.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ typedef struct pcmcia_socket_t pcmcia_socket_t;

bool pcmcia_socket_is_free(pcmcia_socket_t* socket);
pcmcia_socket_t* pcmcia_search_for_slots(void);
void pcmcia_socket_insert_card(pcmcia_socket_t* socket);
/* Set up any relevant stuff to your card before calling this. */
void pcmcia_socket_insert_card(pcmcia_socket_t* socket, void* priv);
void pcmcia_reset(void);
void pcmcia_register_socket(pcmcia_socket_t *socket);
162 changes: 160 additions & 2 deletions src/network/net_ne2000.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
#include <86box/isapnp.h>
#include <86box/plat_fallthrough.h>
#include <86box/plat_unused.h>
#include <86box/pcmcia.h>

/* ROM BIOS file paths. */
#define ROM_PATH_NE1000 "roms/network/ne1000/ne1000.rom"
Expand All @@ -82,6 +83,48 @@
#define PCI_DEVID 0x8029 /* RTL8029AS */
#define PCI_REGSIZE 256 /* size of PCI space */

/* Copied over from NewtonOS emulator Einstein. */
const uint8_t cis_data[90] = {
// NE2000:
//
0x01, 3, // Tuple #1, code = 0x1 (Common memory descriptor), length = 3
0x00, 0x00, 0xff,
// Common memory device information:
// Device number 1, type No device, WPS = OFF
// Speed = No speed, Memory block size = 512b, 1 units
0x15, 51, // Tuple #2, code = 0x15 (Version 1 info), length = 51
0x04, 0x01, 0x45, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x41, 0x64, 0x61, 0x70, 0x74,
0x65, 0x72, 0x20, 0x45, 0x32, 0x30, 0x30, 0x30, 0x00, 0x50, 0x43, 0x4d, 0x43, 0x49, 0x41, 0x20,
0x45, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x00, 0x44, 0x00, 0x4e, 0x45, 0x32, 0x30, 0x30,
0x30, 0x00, 0xff,
// Version = 4.1, Manuf = [Ethernet Adapter], card vers = [E2000 PCMCIA Ethernet]
// Addit. info = [D],[NE2000]
0x1a, 5, // Tuple #3, code = 0x1a (Configuration map), length = 5
0x01, 0x20, 0xf8, 0x03, 0x03,
// Reg len = 2, config register addr = 0x3f8, last config = 0x20
// Registers: XX------
0x1b, 17, // Tuple #4, code = 0x1b (Configuration entry), length = 17
0xe0, 0x81, 0x1d, 0x3f, 0x55, 0x4d, 0x5d, 0x06, 0x86, 0x46, 0x26, 0xfc, 0x24, 0x65, 0x50, 0xff,
0xff,
// Config index = 0x20(default)
// Interface byte = 0x81 (I/O) wait signal supported
// Vcc pwr:
// Nominal operating supply voltage: 5 x 1V
// Minimum operating supply voltage: 4.5 x 1V
// Maximum operating supply voltage: 5.5 x 1V
// Continuous supply current: 1 x 100mA
// Max current average over 1 second: 1 x 100mA, ext = 0x46
// Max current average over 10 ms: 2 x 100mA
// Wait scale Speed = 1.5 x 10 us
// Card decodes 5 address lines, full 8/16 Bit I/O
// IRQ modes: Pulse
// IRQs: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0x21, 2, // Tuple #5, code = 0x21 (Functional ID), length = 2
0x06, 0x00,
// Network/LAN adapter
0xff, 0 // Tuple #6, code = 0xff (Terminator), length = 0
};

typedef struct nic_t {
dp8390_t *dp8390;

Expand All @@ -106,6 +149,13 @@ typedef struct nic_t {
/* POS registers, MCA boards only */
uint8_t pos_regs[8];

/* PCMCIA registers, PCMCIA cards only */
uint8_t pcmcia_config;
uint8_t pcmcia_status_reg;

/* PCMCIA socket instance. */
pcmcia_socket_t* pcmcia_socket;

int board;
int is_pci;
int is_mca;
Expand Down Expand Up @@ -148,6 +198,11 @@ nic_interrupt(void *priv, int set)
{
nic_t *dev = (nic_t *) priv;

if (dev->pcmcia_socket) {
dev->pcmcia_socket->interrupt(!!set, dev->pcmcia_socket);
return;
}

if (dev->is_pci) {
if (set)
pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
Expand Down Expand Up @@ -561,6 +616,8 @@ nic_pnp_write_vendor_reg(uint8_t ld, uint8_t reg, uint8_t val, void *priv)
static void
nic_ioset(nic_t *dev, uint16_t addr)
{
if (dev->pcmcia_socket)
return;
if (dev->is_pci) {
io_sethandler(addr, 32,
nic_readb, nic_readw, nic_readl,
Expand Down Expand Up @@ -907,6 +964,73 @@ nic_mca_feedb(void *priv)
return (dev->pos_regs[2] & 0x01);
}

static uint8_t
nic_pcmcia_read(uint32_t addr, int reg, void* priv)
{
nic_t *dev = (nic_t*)priv;
if (reg == 0)
addr &= ~1;
else
return 0xFF; /* There's no common memory space to access. */

addr &= 0x3FFFFFF;

if (addr == 0x3f8)
return dev->pcmcia_config;

if (addr == 0x3fa)
return dev->pcmcia_status_reg;

if ((addr >> 1) < 90)
return cis_data[(addr >> 1)];

return 0xFF;
}

static uint16_t
nic_pcmcia_readw(uint32_t addr, int reg, void* priv)
{
if ((addr & 1) && !reg)
return nic_pcmcia_read(addr + 1, reg, priv) << 8;

return nic_pcmcia_read(addr, reg, priv);
}

static void
nic_pcmcia_write(uint32_t addr, uint8_t val, int reg, void* priv)
{
nic_t *dev = (nic_t*)priv;
if (reg == 0)
addr &= ~1;
else
return; /* There's no common memory space to access. */

addr &= 0x3FFFFFF;

if (addr == 0x3f8) {
dev->pcmcia_config = val;

if (val & 0x80)
nic_reset(dev);
}

if (addr == 0x3fa) {
dev->pcmcia_status_reg = (val & 0x28);
}
}

static void
nic_pcmcia_writew(uint32_t addr, uint16_t val, int reg, void* priv)
{
nic_pcmcia_writew(addr, val, reg, priv);
}

static void
nic_pcmcia_ata_mode(bool ata, pcmcia_socket_t* socket)
{

}

static void *
nic_init(const device_t *info)
{
Expand All @@ -920,7 +1044,27 @@ nic_init(const device_t *info)
dev->board = info->local;
rom = NULL;

if (dev->board >= NE2K_RTL8019AS) {
if (info->flags & DEVICE_PCMCIA) {
pcmcia_socket_t* slot = pcmcia_search_for_slots();
if (!slot) {
free(dev);
return NULL;
}

slot->io_read = nic_readb;
slot->io_readw = nic_readw;
slot->io_write = nic_writeb;
slot->io_writew = nic_writew;
slot->mem_read = nic_pcmcia_read;
slot->mem_write = nic_pcmcia_write;
slot->mem_readw = nic_pcmcia_readw;
slot->mem_writew = nic_pcmcia_writew;
slot->reset = nic_reset;
slot->ata_mode = nic_pcmcia_ata_mode;
slot->mem_get_exec = NULL;
dev->pcmcia_socket = slot;
pcmcia_socket_insert_card(slot, dev);
} else if (dev->board >= NE2K_RTL8019AS) {
dev->base_address = 0x340;
dev->base_irq = 12;
if (dev->board == NE2K_RTL8029AS) {
Expand Down Expand Up @@ -1059,7 +1203,7 @@ nic_init(const device_t *info)
* Make this device known to the I/O system.
* PnP and PCI devices start with address spaces inactive.
*/
if ((dev->board < NE2K_RTL8019AS) && (dev->board != NE2K_ETHERNEXT_MC))
if ((dev->board < NE2K_RTL8019AS) && (dev->board != NE2K_ETHERNEXT_MC) && !(info->flags & DEVICE_PCMCIA))
nic_ioset(dev, dev->base_address);

/* Set up our BIOS ROM space, if any. */
Expand Down Expand Up @@ -1545,6 +1689,20 @@ const device_t ne2000_compat_device = {
.config = ne2000_compat_config
};

const device_t ne2000_compat_pcmcia_device = {
.name = "NE2000 Compatible",
.internal_name = "ne2k_pcmcia",
.flags = DEVICE_PCMCIA,
.local = NE2K_NE2000_COMPAT,
.init = nic_init,
.close = nic_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = rtl8019as_config
};

const device_t ethernext_mc_device = {
.name = "NetWorth EtherNext/MC",
.internal_name = "ethernextmc",
Expand Down
4 changes: 2 additions & 2 deletions src/pcmcia.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ pcmcia_search_for_slots(void)
}

void
pcmcia_socket_insert_card(pcmcia_socket_t *socket)
pcmcia_socket_insert_card(pcmcia_socket_t *socket, void* priv)
{
if (!socket->card_inserted)
fatal("No PCMCIA socket insertion function!\n");

socket->card_priv = socket->card_priv;
socket->card_priv = priv;
socket->card_inserted(true, socket);
}
4 changes: 2 additions & 2 deletions src/pcmcia/pcmcia_socket_pd6710.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ pd67xx_mgmt_interrupt(pcmcia_socket_pd67xx *pd67xx, int set)
return;
}

if (level) {
if (set && !!((pd67xx->management_interrupt_conf >> 4) & 0xF))
if (level && !!((pd67xx->management_interrupt_conf >> 4) & 0xF)) {
if (set)
picintlevel(1 << (pd67xx->management_interrupt_conf >> 4), &pd67xx->mgmt_irq_state);
else
picintclevel(1 << (pd67xx->management_interrupt_conf >> 4), &pd67xx->mgmt_irq_state);
Expand Down

0 comments on commit 7f145d7

Please sign in to comment.