This commit is contained in:
@@ -25,10 +25,9 @@
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "emu.h"
|
||||
|
||||
#include "dosemu_debug.h"
|
||||
#include "ioselect.h"
|
||||
#include "emu.h"
|
||||
#include "pic.h"
|
||||
#include "port.h"
|
||||
#include "libpacket.h"
|
||||
@@ -124,7 +123,7 @@
|
||||
#define ENTSR_OWC 0x80 /* There was an out-of-window collision. */
|
||||
|
||||
#define NE2000_IRQ 10
|
||||
#define NE2000_IOBASE 0x310
|
||||
#define NE2000_IOBASE 0x300
|
||||
|
||||
#define NE2000_PMEM_SIZE (32 * 1024)
|
||||
#define NE2000_PMEM_START (16 * 1024)
|
||||
@@ -170,15 +169,14 @@ typedef struct NE2000State {
|
||||
static NE2000State ne2000state;
|
||||
|
||||
// For io_device
|
||||
Bit16u ne2000_io_read16(ioport_t port, void *arg);
|
||||
void ne2000_io_write16(ioport_t port, Bit16u value, void *arg);
|
||||
Bit8u ne2000_io_read8(ioport_t port, void *arg);
|
||||
void ne2000_io_write8(ioport_t port, Bit8u value, void *arg);
|
||||
Bit16u ne2000_io_read16(ioport_t port);
|
||||
void ne2000_io_write16(ioport_t port, Bit16u value);
|
||||
Bit8u ne2000_io_read8(ioport_t port);
|
||||
void ne2000_io_write8(ioport_t port, Bit8u value);
|
||||
static void ne2000_irq_activate(int);
|
||||
|
||||
static void ne2000_receive_req_async(int fd, void *arg);
|
||||
static void ne2000_receive_req_async(void *arg);
|
||||
static size_t ne2000_receive(NE2000State *s, const uint8_t *buf, size_t size_);
|
||||
static int ne2000_buffer_full(NE2000State *s);
|
||||
|
||||
#ifdef DEBUG_NE2000
|
||||
static void N_printhdr(uint8_t *buf);
|
||||
@@ -189,6 +187,13 @@ static void init_cbk(int fd, int mode)
|
||||
ne2000state.fdnet = fd;
|
||||
}
|
||||
|
||||
void ne2000_priv_init(void)
|
||||
{
|
||||
if (!config.ne2k)
|
||||
return;
|
||||
LibpacketInit();
|
||||
}
|
||||
|
||||
void ne2000_init(void)
|
||||
{
|
||||
NE2000State *s = &ne2000state;
|
||||
@@ -218,6 +223,8 @@ void ne2000_init(void)
|
||||
io_device.handler_name = "NE2000 Emulation";
|
||||
io_device.start_addr = /* config.ne2000_base */ NE2000_IOBASE;
|
||||
io_device.end_addr = /* config.ne2000_base */ NE2000_IOBASE + 0x1f;
|
||||
io_device.irq = /* config.ne2000_irq */ NE2000_IRQ;
|
||||
io_device.fd = -1;
|
||||
if (port_register_handler(io_device, 0) != 0) {
|
||||
N_printf("NE2000: Error registering NE2000 port handler\n");
|
||||
ne2000_done();
|
||||
@@ -225,7 +232,13 @@ void ne2000_init(void)
|
||||
}
|
||||
|
||||
/* init control defaults */
|
||||
s->irq = NE2000_IRQ;
|
||||
s->irq = pic_irq_list[NE2000_IRQ];
|
||||
|
||||
/* We let DOSEMU handle the interrupt */
|
||||
pic_seti(s->irq, NULL, 0, NULL);
|
||||
|
||||
/* Connect up the receiver */
|
||||
add_to_io_select(s->fdnet, ne2000_receive_req_async, NULL);
|
||||
|
||||
N_printf("NE2000: Initialisation - Base 0x%03x, IRQ %d\n", NE2000_IOBASE, NE2000_IRQ);
|
||||
}
|
||||
@@ -241,7 +254,6 @@ static void _ne2000_reset(NE2000State *s)
|
||||
N_printf("NE2000: ne2000_reset()\n");
|
||||
|
||||
s->isr = ENISR_RESET;
|
||||
s->cmd = E8390_STOP;
|
||||
s->mem[0] = NE2000_EADDR0;
|
||||
s->mem[1] = NE2000_EADDR1;
|
||||
s->mem[2] = NE2000_EADDR2;
|
||||
@@ -279,9 +291,7 @@ void ne2000_done(void)
|
||||
|
||||
N_printf("NE2000: ne2000_done()\n");
|
||||
|
||||
if (!(s->cmd & E8390_STOP))
|
||||
remove_from_io_select(s->fdnet);
|
||||
CloseNetworkLink(s->fdnet);
|
||||
close(s->fdnet);
|
||||
s->fdnet = -1;
|
||||
}
|
||||
|
||||
@@ -302,10 +312,29 @@ static void ne2000_ether_send(NE2000State *s, uint8_t *buf, int len)
|
||||
|
||||
static int ne2000_ether_recv(NE2000State *s, uint8_t *buf, int bufsiz)
|
||||
{
|
||||
struct timeval tv;
|
||||
fd_set readset;
|
||||
int ret;
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
/* anything ready? */
|
||||
FD_ZERO(&readset);
|
||||
FD_SET(s->fdnet, &readset);
|
||||
|
||||
/* anything ready? */
|
||||
if (select(s->fdnet + 1, &readset, NULL, NULL, &tv) <= 0) {
|
||||
N_printf("NE2000: ne2000_ether_recv() select failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!FD_ISSET(s->fdnet, &readset)) {
|
||||
N_printf("NE2000: ne2000_ether_recv() nothing to read\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = read(s->fdnet, buf, bufsiz);
|
||||
ioselect_complete(s->fdnet);
|
||||
if (ret < 0) {
|
||||
N_printf("NE2000: ne2000_ether_recv() read failed\n");
|
||||
return -1;
|
||||
@@ -316,17 +345,12 @@ static int ne2000_ether_recv(NE2000State *s, uint8_t *buf, int bufsiz)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ne2000_receive_req_async(int fd, void *arg)
|
||||
static void ne2000_receive_req_async(void *arg)
|
||||
{
|
||||
NE2000State *s = &ne2000state;
|
||||
uint8_t mybuf[MAX_ETH_FRAME_SIZE];
|
||||
int ret;
|
||||
|
||||
if (ne2000_buffer_full(s)) {
|
||||
N_printf("NE2000: ne2000_receive_req_async() called but buffer full\n");
|
||||
return;
|
||||
}
|
||||
|
||||
N_printf("NE2000: ne2000_receive_req_async() called\n");
|
||||
|
||||
ret = ne2000_ether_recv(s, mybuf, sizeof mybuf);
|
||||
@@ -470,7 +494,6 @@ static size_t ne2000_receive(NE2000State *s, const uint8_t *buf, size_t size_)
|
||||
static void ne2000_ioport_write(NE2000State *s, uint32_t addr, uint32_t val)
|
||||
{
|
||||
int offset, page, index;
|
||||
int old_full = ne2000_buffer_full(s);
|
||||
|
||||
N_printf("NE2000: ne2000_ioport_write()\n");
|
||||
|
||||
@@ -479,14 +502,9 @@ static void ne2000_ioport_write(NE2000State *s, uint32_t addr, uint32_t val)
|
||||
N_printf("NE2000: write addr=0x%x val=0x%02x\n", addr, val);
|
||||
#endif
|
||||
if (addr == E8390_CMD) {
|
||||
uint32_t old_cmd = s->cmd;
|
||||
/* control register */
|
||||
s->cmd = val;
|
||||
if (!(val & E8390_STOP)) { /* START bit makes no sense on RTL8029... */
|
||||
if (old_cmd & E8390_STOP) {
|
||||
N_printf("NE2000: enable receiver\n");
|
||||
add_to_io_select(s->fdnet, ne2000_receive_req_async, NULL);
|
||||
}
|
||||
s->isr &= ~ENISR_RESET;
|
||||
/* test specific case: zero length transfer */
|
||||
if ((val & (E8390_RREAD | E8390_RWRITE)) &&
|
||||
@@ -509,11 +527,6 @@ static void ne2000_ioport_write(NE2000State *s, uint32_t addr, uint32_t val)
|
||||
s->cmd &= ~E8390_TRANS;
|
||||
ne2000_update_irq(s);
|
||||
}
|
||||
} else {
|
||||
if (!(old_cmd & E8390_STOP)) {
|
||||
N_printf("NE2000: disable receiver\n");
|
||||
remove_from_io_select(s->fdnet);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
page = s->cmd >> 6;
|
||||
@@ -574,10 +587,6 @@ static void ne2000_ioport_write(NE2000State *s, uint32_t addr, uint32_t val)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* flush if buffer was full */
|
||||
if (old_full && !ne2000_buffer_full(s))
|
||||
ioselect_complete(s->fdnet);
|
||||
}
|
||||
|
||||
static uint32_t ne2000_ioport_read(NE2000State *s, uint32_t addr)
|
||||
@@ -869,7 +878,7 @@ static void ne2000_write(NE2000State *s, uint32_t addr, uint64_t data, unsigned
|
||||
/* --------------------------------- */
|
||||
/* 16 bit io functions - only on data port */
|
||||
|
||||
Bit16u ne2000_io_read16(ioport_t port, void *arg)
|
||||
Bit16u ne2000_io_read16(ioport_t port)
|
||||
{
|
||||
NE2000State *s = &ne2000state;
|
||||
ioport_t addr = port - NE2000_IOBASE;
|
||||
@@ -882,7 +891,7 @@ Bit16u ne2000_io_read16(ioport_t port, void *arg)
|
||||
return ne2000_read(s, addr, 1);
|
||||
}
|
||||
|
||||
void ne2000_io_write16(ioport_t port, Bit16u value, void *arg)
|
||||
void ne2000_io_write16(ioport_t port, Bit16u value)
|
||||
{
|
||||
NE2000State *s = &ne2000state;
|
||||
ioport_t addr = port - NE2000_IOBASE;
|
||||
@@ -899,7 +908,7 @@ void ne2000_io_write16(ioport_t port, Bit16u value, void *arg)
|
||||
|
||||
/* handle io reads from ne2000 */
|
||||
|
||||
Bit8u ne2000_io_read8(ioport_t port, void *arg)
|
||||
Bit8u ne2000_io_read8(ioport_t port)
|
||||
{
|
||||
NE2000State *s = &ne2000state;
|
||||
ioport_t addr = port - NE2000_IOBASE;
|
||||
@@ -912,7 +921,7 @@ Bit8u ne2000_io_read8(ioport_t port, void *arg)
|
||||
|
||||
/* handle io writes to ne2000 */
|
||||
|
||||
void ne2000_io_write8(ioport_t port, Bit8u value, void *arg)
|
||||
void ne2000_io_write8(ioport_t port, Bit8u value)
|
||||
{
|
||||
NE2000State *s = &ne2000state;
|
||||
ioport_t addr = port - NE2000_IOBASE;
|
||||
|
||||
Reference in New Issue
Block a user