Somewhat finish initial modem emulation
This commit is contained in:
@@ -589,8 +589,8 @@ serial_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
serial_do_irq(dev, 0);
|
serial_do_irq(dev, 0);
|
||||||
if ((val ^ dev->mctrl) & 0x10)
|
if ((val ^ dev->mctrl) & 0x10)
|
||||||
serial_reset_fifo(dev);
|
serial_reset_fifo(dev);
|
||||||
if (dev->sd && dev->sd->dtr_callback)
|
if (dev->sd && dev->sd->dtr_callback && (val ^ dev->mctrl) & 1)
|
||||||
dev->sd->dtr_callback(dev, val, dev->sd->priv);
|
dev->sd->dtr_callback(dev, val & 1, dev->sd->priv);
|
||||||
dev->mctrl = val;
|
dev->mctrl = val;
|
||||||
if (val & 0x10) {
|
if (val & 0x10) {
|
||||||
new_msr = (val & 0x0c) << 4;
|
new_msr = (val & 0x0c) << 4;
|
||||||
|
@@ -225,6 +225,9 @@ extern const device_t pcnet_am79c970a_device;
|
|||||||
extern const device_t pcnet_am79c973_device;
|
extern const device_t pcnet_am79c973_device;
|
||||||
extern const device_t pcnet_am79c973_onboard_device;
|
extern const device_t pcnet_am79c973_onboard_device;
|
||||||
|
|
||||||
|
/* Modem */
|
||||||
|
extern const device_t modem_device;
|
||||||
|
|
||||||
/* PLIP */
|
/* PLIP */
|
||||||
#ifdef EMU_LPT_H
|
#ifdef EMU_LPT_H
|
||||||
extern const lpt_device_t lpt_plip_device;
|
extern const lpt_device_t lpt_plip_device;
|
||||||
|
@@ -52,13 +52,14 @@ typedef struct modem_t
|
|||||||
{
|
{
|
||||||
uint8_t mac[6];
|
uint8_t mac[6];
|
||||||
serial_t *serial;
|
serial_t *serial;
|
||||||
double baudrate;
|
uint32_t baudrate;
|
||||||
|
|
||||||
modem_mode_t mode;
|
modem_mode_t mode;
|
||||||
|
|
||||||
uint8_t esc_character_expected;
|
uint8_t esc_character_expected;
|
||||||
pc_timer_t host_to_serial_timer;
|
pc_timer_t host_to_serial_timer;
|
||||||
pc_timer_t dtr_timer;
|
pc_timer_t dtr_timer;
|
||||||
|
pc_timer_t cmdpause_timer;
|
||||||
|
|
||||||
uint8_t tx_pkt_ser_line[0x10000]; /* SLIP-encoded. */
|
uint8_t tx_pkt_ser_line[0x10000]; /* SLIP-encoded. */
|
||||||
uint32_t tx_count;
|
uint32_t tx_count;
|
||||||
@@ -70,13 +71,25 @@ typedef struct modem_t
|
|||||||
|
|
||||||
char cmdbuf[512];
|
char cmdbuf[512];
|
||||||
uint32_t cmdpos;
|
uint32_t cmdpos;
|
||||||
|
uint32_t port;
|
||||||
int plusinc, flowcontrol;
|
int plusinc, flowcontrol;
|
||||||
int in_warmup;
|
int in_warmup, dtrmode;
|
||||||
|
|
||||||
bool connected, ringing;
|
bool connected, ringing;
|
||||||
bool echo, numericresponse;
|
bool echo, numericresponse;
|
||||||
|
|
||||||
int doresponse;
|
int doresponse;
|
||||||
|
int cmdpause;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool binary[2];
|
||||||
|
bool echo[2];
|
||||||
|
bool supressGA[2];
|
||||||
|
bool timingMark[2];
|
||||||
|
bool inIAC;
|
||||||
|
bool recCommand;
|
||||||
|
uint8_t command;
|
||||||
|
} telClient;
|
||||||
|
|
||||||
netcard_t *card;
|
netcard_t *card;
|
||||||
} modem_t;
|
} modem_t;
|
||||||
@@ -92,6 +105,14 @@ static modem_t *instance;
|
|||||||
#define MREG_GUARD_TIME 12
|
#define MREG_GUARD_TIME 12
|
||||||
#define MREG_DTR_DELAY 25
|
#define MREG_DTR_DELAY 25
|
||||||
|
|
||||||
|
static void modem_do_command(modem_t* modem);
|
||||||
|
|
||||||
|
static void
|
||||||
|
modem_echo(modem_t* modem, uint8_t c)
|
||||||
|
{
|
||||||
|
if (modem->echo && fifo8_num_free(&modem->data_pending)) fifo8_push(&modem->data_pending, c);
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
modem_scan_number(char **scan)
|
modem_scan_number(char **scan)
|
||||||
{
|
{
|
||||||
@@ -128,7 +149,7 @@ modem_speed_changed(void *priv)
|
|||||||
|
|
||||||
timer_stop(&dev->host_to_serial_timer);
|
timer_stop(&dev->host_to_serial_timer);
|
||||||
/* FIXME: do something to dev->baudrate */
|
/* FIXME: do something to dev->baudrate */
|
||||||
timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / dev->baudrate) * 9);
|
timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double)dev->baudrate) * 9);
|
||||||
#if 0
|
#if 0
|
||||||
serial_clear_fifo(dev->serial);
|
serial_clear_fifo(dev->serial);
|
||||||
#endif
|
#endif
|
||||||
@@ -210,16 +231,20 @@ static void
|
|||||||
modem_data_mode_process_byte(modem_t* modem, uint8_t data)
|
modem_data_mode_process_byte(modem_t* modem, uint8_t data)
|
||||||
{
|
{
|
||||||
if (modem->reg[MREG_ESCAPE_CHAR] <= 127) {
|
if (modem->reg[MREG_ESCAPE_CHAR] <= 127) {
|
||||||
if (modem->reg[MREG_ESCAPE_CHAR] == data) {
|
if (modem->plusinc >= 1 && modem->plusinc <= 3 && modem->reg[MREG_ESCAPE_CHAR] == data) {
|
||||||
return;
|
modem->plusinc++;
|
||||||
|
} else {
|
||||||
|
modem->plusinc = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data == END) {
|
if (modem->tx_count < 0x10000 && modem->connected) {
|
||||||
process_tx_packet(modem, modem->tx_pkt_ser_line, (uint32_t)modem->tx_count + 1ul);
|
|
||||||
}
|
|
||||||
else if (modem->tx_count < 0x10000)
|
|
||||||
modem->tx_pkt_ser_line[modem->tx_count++] = data;
|
modem->tx_pkt_ser_line[modem->tx_count++] = data;
|
||||||
|
if (data == END) {
|
||||||
|
process_tx_packet(modem, modem->tx_pkt_ser_line, (uint32_t)modem->tx_count);
|
||||||
|
modem->tx_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -237,6 +262,9 @@ host_to_modem_cb(void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!((modem->serial->mctrl & 2) || modem->flowcontrol != 3))
|
||||||
|
goto no_write_to_machine;
|
||||||
|
|
||||||
if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data)) {
|
if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data)) {
|
||||||
serial_write_fifo(modem->serial, fifo8_pop(&modem->rx_data));
|
serial_write_fifo(modem->serial, fifo8_pop(&modem->rx_data));
|
||||||
} else if (fifo8_num_used(&modem->data_pending)) {
|
} else if (fifo8_num_used(&modem->data_pending)) {
|
||||||
@@ -244,13 +272,55 @@ host_to_modem_cb(void *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
no_write_to_machine:
|
no_write_to_machine:
|
||||||
timer_on_auto(&modem->host_to_serial_timer, (1000000.0 / modem->baudrate) * (double)9);
|
timer_on_auto(&modem->host_to_serial_timer, (1000000.0 / (double)modem->baudrate) * (double)9);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
modem_write(UNUSED(serial_t *s), void *priv, uint8_t val)
|
modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval)
|
||||||
{
|
{
|
||||||
modem_t* modem = (modem_t*)priv;
|
modem_t* modem = (modem_t*)priv;
|
||||||
|
|
||||||
|
if (modem->mode == MODEM_MODE_COMMAND) {
|
||||||
|
if (modem->cmdpos < 2) {
|
||||||
|
// Ignore everything until we see "AT" sequence.
|
||||||
|
if (modem->cmdpos == 0 && toupper(txval) != 'A') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modem->cmdpos == 1 && toupper(txval) != 'T') {
|
||||||
|
modem_echo(modem, modem->reg[MREG_BACKSPACE_CHAR]);
|
||||||
|
modem->cmdpos = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Now entering command.
|
||||||
|
if (txval == modem->reg[MREG_BACKSPACE_CHAR]) {
|
||||||
|
if (modem->cmdpos > 2) {
|
||||||
|
modem_echo(modem, txval);
|
||||||
|
modem->cmdpos--;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txval == modem->reg[MREG_LF_CHAR]) {
|
||||||
|
return; // Real modem doesn't seem to skip this?
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txval == modem->reg[MREG_CR_CHAR]) {
|
||||||
|
modem_echo(modem, txval);
|
||||||
|
modem_do_command(modem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modem->cmdpos < 99) {
|
||||||
|
modem_echo(modem, txval);
|
||||||
|
modem->cmdbuf[modem->cmdpos] = txval;
|
||||||
|
modem->cmdpos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
modem_data_mode_process_byte(modem, txval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void modem_send_res(modem_t* modem, const ResTypes response) {
|
void modem_send_res(modem_t* modem, const ResTypes response) {
|
||||||
@@ -310,6 +380,7 @@ modem_enter_connected_state(modem_t* modem)
|
|||||||
modem->mode = MODEM_MODE_DATA;
|
modem->mode = MODEM_MODE_DATA;
|
||||||
modem->ringing = false;
|
modem->ringing = false;
|
||||||
modem->connected = true;
|
modem->connected = true;
|
||||||
|
memset(&modem->telClient, 0, sizeof(modem->telClient));
|
||||||
serial_set_dcd(modem->serial, 1);
|
serial_set_dcd(modem->serial, 1);
|
||||||
serial_set_ri(modem->serial, 0);
|
serial_set_ri(modem->serial, 0);
|
||||||
}
|
}
|
||||||
@@ -322,6 +393,7 @@ modem_reset(modem_t* modem)
|
|||||||
modem->cmdbuf[0] = 0;
|
modem->cmdbuf[0] = 0;
|
||||||
modem->flowcontrol = 0;
|
modem->flowcontrol = 0;
|
||||||
modem->plusinc = 0;
|
modem->plusinc = 0;
|
||||||
|
modem->dtrmode = 2;
|
||||||
|
|
||||||
memset(&modem->reg,0,sizeof(modem->reg));
|
memset(&modem->reg,0,sizeof(modem->reg));
|
||||||
modem->reg[MREG_AUTOANSWER_COUNT] = 0; // no autoanswer
|
modem->reg[MREG_AUTOANSWER_COUNT] = 0; // no autoanswer
|
||||||
@@ -560,6 +632,107 @@ modem_do_command(modem_t* modem)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'S': { // Registers
|
||||||
|
const uint32_t index = modem_scan_number(&scanbuf);
|
||||||
|
if (index >= 100) {
|
||||||
|
modem_send_res(modem, ResERROR);
|
||||||
|
return; //goto ret_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (scanbuf[0] == ' ')
|
||||||
|
scanbuf++; // skip spaces
|
||||||
|
|
||||||
|
if (scanbuf[0] == '=') { // set register
|
||||||
|
scanbuf++;
|
||||||
|
while (scanbuf[0] == ' ')
|
||||||
|
scanbuf++; // skip spaces
|
||||||
|
const uint32_t val = modem_scan_number(&scanbuf);
|
||||||
|
modem->reg[index] = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (scanbuf[0] == '?') { // get register
|
||||||
|
modem_send_number(modem, modem->reg[index]);
|
||||||
|
scanbuf++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// LOG_MSG("SERIAL: Port %" PRIu8 " print reg %" PRIu32
|
||||||
|
// " with %" PRIu8 ".",
|
||||||
|
// GetPortNumber(), index, reg[index]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '&': { // & escaped commands
|
||||||
|
char cmdchar = modem_fetch_character(&scanbuf);
|
||||||
|
switch(cmdchar) {
|
||||||
|
case 'K': {
|
||||||
|
const uint32_t val = modem_scan_number(&scanbuf);
|
||||||
|
if (val < 5)
|
||||||
|
modem->flowcontrol = val;
|
||||||
|
else {
|
||||||
|
modem_send_res(modem, ResERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'D': {
|
||||||
|
const uint32_t val = modem_scan_number(&scanbuf);
|
||||||
|
if (val < 4)
|
||||||
|
modem->dtrmode = val;
|
||||||
|
else {
|
||||||
|
modem_send_res(modem, ResERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '\0':
|
||||||
|
// end of string
|
||||||
|
modem_send_res(modem, ResERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '\\': { // \ escaped commands
|
||||||
|
char cmdchar = modem_fetch_character(&scanbuf);
|
||||||
|
switch (cmdchar) {
|
||||||
|
case 'N':
|
||||||
|
// error correction stuff - not emulated
|
||||||
|
if (modem_scan_number(&scanbuf) > 5) {
|
||||||
|
modem_send_res(modem, ResERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
// end of string
|
||||||
|
modem_send_res(modem, ResERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '\0':
|
||||||
|
modem_send_res(modem, ResOK);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
modem_dtr_callback_timer(void* priv)
|
||||||
|
{
|
||||||
|
modem_t *dev = (modem_t *) priv;
|
||||||
|
if (dev->connected) {
|
||||||
|
switch (dev->dtrmode) {
|
||||||
|
case 1:
|
||||||
|
dev->mode = MODEM_MODE_COMMAND;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
modem_send_res(dev, ResNOCARRIER);
|
||||||
|
modem_enter_idle_state(dev);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
modem_send_res(dev, ResNOCARRIER);
|
||||||
|
modem_reset(dev);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -571,7 +744,7 @@ modem_dtr_callback(serial_t* serial, int status, void *priv)
|
|||||||
if (status == 1)
|
if (status == 1)
|
||||||
timer_disable(&dev->dtr_timer);
|
timer_disable(&dev->dtr_timer);
|
||||||
else if (!timer_is_enabled(&dev->dtr_timer))
|
else if (!timer_is_enabled(&dev->dtr_timer))
|
||||||
timer_enable(&dev->dtr_timer);
|
timer_on_auto(&dev->dtr_timer, 1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -606,7 +779,12 @@ modem_rx(void *priv, uint8_t *buf, int io_len)
|
|||||||
uint8_t c = 0;
|
uint8_t c = 0;
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
|
||||||
if ((io_len) < (fifo8_num_free(&modem->rx_data) / 2)) {
|
if (!modem->connected) {
|
||||||
|
/* Drop packet. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((io_len) <= (fifo8_num_free(&modem->rx_data) / 2)) {
|
||||||
fifo8_resize_2x(&modem->rx_data);
|
fifo8_resize_2x(&modem->rx_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,12 +815,31 @@ modem_rcr_cb(UNUSED(struct serial_s *serial), void *priv)
|
|||||||
|
|
||||||
timer_stop(&dev->host_to_serial_timer);
|
timer_stop(&dev->host_to_serial_timer);
|
||||||
/* FIXME: do something to dev->baudrate */
|
/* FIXME: do something to dev->baudrate */
|
||||||
timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / dev->baudrate) * (double) 9);
|
timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double)dev->baudrate) * (double) 9);
|
||||||
#if 0
|
#if 0
|
||||||
serial_clear_fifo(dev->serial);
|
serial_clear_fifo(dev->serial);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
modem_cmdpause_timer_callback(void *priv)
|
||||||
|
{
|
||||||
|
modem_t *dev = (modem_t *) priv;
|
||||||
|
uint32_t guard_threashold = 0;
|
||||||
|
|
||||||
|
dev->cmdpause++;
|
||||||
|
guard_threashold = (uint32_t)(dev->reg[MREG_GUARD_TIME] * 20);
|
||||||
|
if (dev->cmdpause > guard_threashold) {
|
||||||
|
if (dev->plusinc == 0) {
|
||||||
|
dev->plusinc = 1;
|
||||||
|
} else if (dev->plusinc == 4) {
|
||||||
|
dev->mode = MODEM_MODE_COMMAND;
|
||||||
|
modem_send_res(dev, ResOK);
|
||||||
|
dev->plusinc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the device for use by the user. */
|
/* Initialize the device for use by the user. */
|
||||||
static void *
|
static void *
|
||||||
modem_init(const device_t *info)
|
modem_init(const device_t *info)
|
||||||
@@ -650,16 +847,50 @@ modem_init(const device_t *info)
|
|||||||
modem_t* modem = (modem_t*)calloc(1, sizeof(modem_t));
|
modem_t* modem = (modem_t*)calloc(1, sizeof(modem_t));
|
||||||
memset(modem->mac, 0xfc, 6);
|
memset(modem->mac, 0xfc, 6);
|
||||||
|
|
||||||
|
|
||||||
|
modem->port = device_get_config_int("port");
|
||||||
|
modem->baudrate = device_get_config_int("baudrate");
|
||||||
|
|
||||||
|
fifo8_create(&modem->data_pending, 0x10000);
|
||||||
|
fifo8_create(&modem->rx_data, 0x10000);
|
||||||
|
|
||||||
|
timer_add(&modem->dtr_timer, modem_dtr_callback_timer, modem, 0);
|
||||||
|
timer_add(&modem->host_to_serial_timer, host_to_modem_cb, modem, 0);
|
||||||
|
timer_add(&modem->cmdpause_timer, modem_cmdpause_timer_callback, modem, 0);
|
||||||
|
timer_on_auto(&modem->cmdpause_timer, 1000);
|
||||||
|
modem->serial = serial_attach_ex_2(modem->port, modem_rcr_cb, modem_write, modem_dtr_callback, modem);
|
||||||
|
|
||||||
|
modem_reset(modem);
|
||||||
modem->card = network_attach(instance, instance->mac, modem_rx, NULL);
|
modem->card = network_attach(instance, instance->mac, modem_rx, NULL);
|
||||||
return modem;
|
return modem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void modem_close(void *priv)
|
void modem_close(void *priv)
|
||||||
{
|
{
|
||||||
|
modem_t* modem = (modem_t*)priv;
|
||||||
|
fifo8_destroy(&modem->data_pending);
|
||||||
|
fifo8_destroy(&modem->rx_data);
|
||||||
|
netcard_close(modem->card);
|
||||||
free(priv);
|
free(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const device_config_t modem_config[] = {
|
static const device_config_t modem_config[] = {
|
||||||
|
{
|
||||||
|
.name = "port",
|
||||||
|
.description = "Serial Port",
|
||||||
|
.type = CONFIG_SELECTION,
|
||||||
|
.default_string = "",
|
||||||
|
.default_int = 0,
|
||||||
|
.file_filter = "",
|
||||||
|
.spinner = { 0 },
|
||||||
|
.selection = {
|
||||||
|
{ .description = "COM1", .value = 0 },
|
||||||
|
{ .description = "COM2", .value = 1 },
|
||||||
|
{ .description = "COM3", .value = 2 },
|
||||||
|
{ .description = "COM4", .value = 3 },
|
||||||
|
{ .description = "" }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = "baudrate",
|
.name = "baudrate",
|
||||||
.description = "Baud Rate",
|
.description = "Baud Rate",
|
||||||
@@ -669,10 +900,6 @@ static const device_config_t modem_config[] = {
|
|||||||
.file_filter = NULL,
|
.file_filter = NULL,
|
||||||
.spinner = { 0 },
|
.spinner = { 0 },
|
||||||
.selection = {
|
.selection = {
|
||||||
#if 0
|
|
||||||
{ .description = "256000", .value = 256000 },
|
|
||||||
{ .description = "128000", .value = 128000 },
|
|
||||||
#endif
|
|
||||||
{ .description = "115200", .value = 115200 },
|
{ .description = "115200", .value = 115200 },
|
||||||
{ .description = "57600", .value = 57600 },
|
{ .description = "57600", .value = 57600 },
|
||||||
{ .description = "56000", .value = 56000 },
|
{ .description = "56000", .value = 56000 },
|
||||||
@@ -694,7 +921,7 @@ static const device_config_t modem_config[] = {
|
|||||||
|
|
||||||
const device_t modem_device = {
|
const device_t modem_device = {
|
||||||
.name = "Standard Hayes-compliant Modem",
|
.name = "Standard Hayes-compliant Modem",
|
||||||
.flags = 0,
|
.flags = DEVICE_COM,
|
||||||
.local = 0,
|
.local = 0,
|
||||||
.init = modem_init,
|
.init = modem_init,
|
||||||
.close = modem_close,
|
.close = modem_close,
|
||||||
|
@@ -136,6 +136,7 @@ static const device_t *net_cards[] = {
|
|||||||
&dec_tulip_21140_vpc_device,
|
&dec_tulip_21140_vpc_device,
|
||||||
&dec_tulip_21040_device,
|
&dec_tulip_21040_device,
|
||||||
&pcnet_am79c960_vlb_device,
|
&pcnet_am79c960_vlb_device,
|
||||||
|
&modem_device,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user