- support for serial port modes added. The mode defines what to do with the
data written to the port and where to get the data read from it. Available modes are 'null' (no input/output), 'file' (output to a file specified as the 'dev' parameter), 'term' (serial terminal) and 'raw' (use the real serial port - under construction for win32). - descriptions for serial and parallel options in bochsrc sample updated
This commit is contained in:
parent
158ba92f2e
commit
f1a0f56d55
@ -370,21 +370,29 @@ debug: action=ignore
|
||||
debugger_log: -
|
||||
|
||||
#=======================================================================
|
||||
# COM1:
|
||||
# This defines a serial port (UART type 16550A). You can specify a device
|
||||
# to use as com1. This can be a real serial line, or a pty. To use a pty
|
||||
# (under X/Unix), create two windows (xterms, usually). One of them will
|
||||
# COM1, COM2, COM3, COM4:
|
||||
# This defines a serial port (UART type 16550A). In the 'term' you can specify
|
||||
# a device to use as com1. This can be a real serial line, or a pty. To use
|
||||
# a pty (under X/Unix), create two windows (xterms, usually). One of them will
|
||||
# run bochs, and the other will act as com1. Find out the tty the com1
|
||||
# window using the `tty' command, and use that as the `dev' parameter.
|
||||
# Then do `sleep 1000000' in the com1 window to keep the shell from
|
||||
# messing with things, and run bochs in the other window. Serial I/O to
|
||||
# com1 (port 0x3f8) will all go to the other window.
|
||||
# Other serial modes are 'null' (no input/output), 'file' (output to a file
|
||||
# specified as the 'dev' parameter) and 'raw' (use the real serial port - under
|
||||
# construction for win32).
|
||||
#
|
||||
# Examples:
|
||||
# com1: enabled=1, mode=null
|
||||
# com2: enabled=1, mode=file, dev=serial.out
|
||||
# com3: enabled=1, mode=raw, dev=com1
|
||||
#=======================================================================
|
||||
#com1: enabled=1, dev=/dev/ttyp9
|
||||
#com1: enabled=1, mode=term, dev=/dev/ttyp9
|
||||
|
||||
|
||||
#=======================================================================
|
||||
# PARPORT1:
|
||||
# PARPORT1, PARPORT2:
|
||||
# This defines a parallel (printer) port. When turned on and an output file is
|
||||
# defined the emulated printer port sends characters printed by the guest OS
|
||||
# into the output file. On some platforms a device filename can be used to
|
||||
@ -393,7 +401,7 @@ debugger_log: -
|
||||
#
|
||||
# Examples:
|
||||
# parport1: enabled=1, file="parport.out"
|
||||
# parport1: enabled=1, file="/dev/lp0"
|
||||
# parport2: enabled=1, file="/dev/lp0"
|
||||
# parport1: enabled=0
|
||||
#=======================================================================
|
||||
parport1: enabled=1, file="parport.out"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: config.cc,v 1.7 2004-07-18 17:18:19 vruppert Exp $
|
||||
// $Id: config.cc,v 1.8 2004-07-28 19:36:42 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||
@ -843,6 +843,14 @@ void bx_init_options ()
|
||||
*par_ser_ptr++ = bx_options.par[i].Ooutfile;
|
||||
}
|
||||
|
||||
static char *serial_mode_list[] = {
|
||||
"null",
|
||||
"file",
|
||||
"term",
|
||||
"raw",
|
||||
NULL
|
||||
};
|
||||
|
||||
// serial ports
|
||||
for (i=0; i<BX_N_SERIAL_PORTS; i++) {
|
||||
// options for COM port
|
||||
@ -853,6 +861,15 @@ void bx_init_options ()
|
||||
strdup(name),
|
||||
strdup(descr),
|
||||
(i==0)?1 : 0); // only enable the first by default
|
||||
sprintf (name, "I/O mode of the serial device for COM%d", i+1);
|
||||
sprintf (descr, "The mode can be one these: 'null', 'file', 'term', 'raw'");
|
||||
bx_options.com[i].Omode = new bx_param_enum_c (
|
||||
BXP_COMx_MODE(i+1),
|
||||
strdup(name),
|
||||
strdup(descr),
|
||||
serial_mode_list,
|
||||
0,
|
||||
0);
|
||||
sprintf (name, "Pathname of the serial device for COM%d", i+1);
|
||||
sprintf (descr, "The path can be a real serial device or a pty (X/Unix only)");
|
||||
bx_options.com[i].Odev = new bx_param_filename_c (
|
||||
@ -860,11 +877,13 @@ void bx_init_options ()
|
||||
strdup(name),
|
||||
strdup(descr),
|
||||
"", BX_PATHNAME_LEN);
|
||||
deplist = new bx_list_c (BXP_NULL, 1);
|
||||
deplist = new bx_list_c (BXP_NULL, 2);
|
||||
deplist->add (bx_options.com[i].Omode);
|
||||
deplist->add (bx_options.com[i].Odev);
|
||||
bx_options.com[i].Oenabled->set_dependent_list (deplist);
|
||||
// add to menu
|
||||
*par_ser_ptr++ = bx_options.com[i].Oenabled;
|
||||
*par_ser_ptr++ = bx_options.com[i].Omode;
|
||||
*par_ser_ptr++ = bx_options.com[i].Odev;
|
||||
}
|
||||
|
||||
@ -1688,6 +1707,7 @@ void bx_reset_options ()
|
||||
// standard ports
|
||||
for (i=0; i<BX_N_SERIAL_PORTS; i++) {
|
||||
bx_options.com[i].Oenabled->reset();
|
||||
bx_options.com[i].Omode->reset();
|
||||
bx_options.com[i].Odev->reset();
|
||||
}
|
||||
for (i=0; i<BX_N_PARALLEL_PORTS; i++) {
|
||||
@ -2480,6 +2500,11 @@ parse_line_formatted(char *context, int num_params, char *params[])
|
||||
if (!strncmp(params[i], "enabled=", 8)) {
|
||||
bx_options.com[0].Oenabled->set (atol(¶ms[i][8]));
|
||||
}
|
||||
else if (!strncmp(params[i], "mode=", 5)) {
|
||||
if (!bx_options.com[0].Omode->set_by_name (strdup(¶ms[i][5])))
|
||||
PARSE_ERR(("%s: serial port mode '%s' not available", context, strdup(¶ms[i][5])));
|
||||
bx_options.com[0].Oenabled->set (1);
|
||||
}
|
||||
else if (!strncmp(params[i], "dev=", 4)) {
|
||||
bx_options.com[0].Odev->set (¶ms[i][4]);
|
||||
bx_options.com[0].Oenabled->set (1);
|
||||
@ -2494,6 +2519,11 @@ parse_line_formatted(char *context, int num_params, char *params[])
|
||||
if (!strncmp(params[i], "enabled=", 8)) {
|
||||
bx_options.com[1].Oenabled->set (atol(¶ms[i][8]));
|
||||
}
|
||||
else if (!strncmp(params[i], "mode=", 5)) {
|
||||
if (!bx_options.com[1].Omode->set_by_name (strdup(¶ms[i][5])))
|
||||
PARSE_ERR(("%s: serial port mode '%s' not available", context, strdup(¶ms[i][5])));
|
||||
bx_options.com[1].Oenabled->set (1);
|
||||
}
|
||||
else if (!strncmp(params[i], "dev=", 4)) {
|
||||
bx_options.com[1].Odev->set (¶ms[i][4]);
|
||||
bx_options.com[1].Oenabled->set (1);
|
||||
@ -2508,6 +2538,11 @@ parse_line_formatted(char *context, int num_params, char *params[])
|
||||
if (!strncmp(params[i], "enabled=", 8)) {
|
||||
bx_options.com[2].Oenabled->set (atol(¶ms[i][8]));
|
||||
}
|
||||
else if (!strncmp(params[i], "mode=", 5)) {
|
||||
if (!bx_options.com[2].Omode->set_by_name (strdup(¶ms[i][5])))
|
||||
PARSE_ERR(("%s: serial port mode '%s' not available", context, strdup(¶ms[i][5])));
|
||||
bx_options.com[2].Oenabled->set (1);
|
||||
}
|
||||
else if (!strncmp(params[i], "dev=", 4)) {
|
||||
bx_options.com[2].Odev->set (¶ms[i][4]);
|
||||
bx_options.com[2].Oenabled->set (1);
|
||||
@ -2522,6 +2557,11 @@ parse_line_formatted(char *context, int num_params, char *params[])
|
||||
if (!strncmp(params[i], "enabled=", 8)) {
|
||||
bx_options.com[3].Oenabled->set (atol(¶ms[i][8]));
|
||||
}
|
||||
else if (!strncmp(params[i], "mode=", 5)) {
|
||||
if (!bx_options.com[3].Omode->set_by_name (strdup(¶ms[i][5])))
|
||||
PARSE_ERR(("%s: serial port mode '%s' not available", context, strdup(¶ms[i][5])));
|
||||
bx_options.com[3].Oenabled->set (1);
|
||||
}
|
||||
else if (!strncmp(params[i], "dev=", 4)) {
|
||||
bx_options.com[3].Odev->set (¶ms[i][4]);
|
||||
bx_options.com[3].Oenabled->set (1);
|
||||
@ -3436,6 +3476,7 @@ bx_write_serial_options (FILE *fp, bx_serial_options *opt, int n)
|
||||
{
|
||||
fprintf (fp, "com%d: enabled=%d", n, opt->Oenabled->get ());
|
||||
if (opt->Oenabled->get ()) {
|
||||
fprintf (fp, ", mode=\"%s\"", opt->Omode->get_choice(opt->Omode->get()));
|
||||
fprintf (fp, ", dev=\"%s\"", opt->Odev->getptr ());
|
||||
}
|
||||
fprintf (fp, "\n");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: siminterface.h,v 1.122 2004-07-09 21:40:48 vruppert Exp $
|
||||
// $Id: siminterface.h,v 1.123 2004-07-28 19:36:42 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Before I can describe what this file is for, I have to make the
|
||||
@ -314,14 +314,18 @@ typedef enum {
|
||||
BXP_ATA3_SLAVE_JOURNAL,
|
||||
#define BXP_ATAx_DEVICE_JOURNAL(i, s) (BXP_ATA0_MASTER_JOURNAL + (2*(i)) + (s))
|
||||
|
||||
#define BXP_PARAMS_PER_SERIAL_PORT 2
|
||||
#define BXP_PARAMS_PER_SERIAL_PORT 3
|
||||
BXP_COM1_ENABLED,
|
||||
BXP_COM1_MODE,
|
||||
BXP_COM1_PATH,
|
||||
BXP_COM2_ENABLED,
|
||||
BXP_COM2_MODE,
|
||||
BXP_COM2_PATH,
|
||||
BXP_COM3_ENABLED,
|
||||
BXP_COM3_MODE,
|
||||
BXP_COM3_PATH,
|
||||
BXP_COM4_ENABLED,
|
||||
BXP_COM4_MODE,
|
||||
BXP_COM4_PATH,
|
||||
#define BXP_PARAMS_PER_USB_HUB 3
|
||||
BXP_USB1_ENABLED,
|
||||
@ -492,6 +496,8 @@ typedef enum {
|
||||
// use x=1,2,3,4
|
||||
#define BXP_COMx_ENABLED(x) \
|
||||
(bx_id)(BXP_COM1_ENABLED + (((x)-1)*BXP_PARAMS_PER_SERIAL_PORT))
|
||||
#define BXP_COMx_MODE(x) \
|
||||
(bx_id)(BXP_COM1_MODE + (((x)-1)*BXP_PARAMS_PER_SERIAL_PORT))
|
||||
#define BXP_COMx_PATH(x) \
|
||||
(bx_id)(BXP_COM1_PATH + (((x)-1)*BXP_PARAMS_PER_SERIAL_PORT))
|
||||
|
||||
@ -1310,6 +1316,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
bx_param_bool_c *Oenabled;
|
||||
bx_param_enum_c *Omode;
|
||||
bx_param_string_c *Odev;
|
||||
} bx_serial_options;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: serial.cc,v 1.54 2004-06-19 15:20:14 sshwarts Exp $
|
||||
// $Id: serial.cc,v 1.55 2004-07-28 19:36:42 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2004 MandrakeSoft S.A.
|
||||
@ -73,13 +73,24 @@ bx_serial_c::~bx_serial_c(void)
|
||||
{
|
||||
for (int i=0; i<BX_SERIAL_MAXDEV; i++) {
|
||||
if (bx_options.com[i].Oenabled->get ()) {
|
||||
#if USE_RAW_SERIAL
|
||||
delete [] BX_SER_THIS s[i].raw;
|
||||
#elif defined(SERIAL_ENABLE)
|
||||
if (s[i].tty_id >= 0) {
|
||||
tcsetattr(s[i].tty_id, TCSAFLUSH, &s[i].term_orig);
|
||||
}
|
||||
switch (BX_SER_THIS s[i].io_mode) {
|
||||
case BX_SER_MODE_FILE:
|
||||
if (BX_SER_THIS s[i].output != NULL)
|
||||
fclose(BX_SER_THIS s[i].output);
|
||||
break;
|
||||
case BX_SER_MODE_TERM:
|
||||
#if defined(SERIAL_ENABLE)
|
||||
if (s[i].tty_id >= 0) {
|
||||
tcsetattr(s[i].tty_id, TCSAFLUSH, &s[i].term_orig);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case BX_SER_MODE_RAW:
|
||||
#if USE_RAW_SERIAL
|
||||
delete [] BX_SER_THIS s[i].raw;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -194,38 +205,66 @@ bx_serial_c::init(void)
|
||||
DEV_register_ioread_handler(this, read_handler, addr, name, 1);
|
||||
DEV_register_iowrite_handler(this, write_handler, addr, name, 1);
|
||||
}
|
||||
#if USE_RAW_SERIAL
|
||||
BX_SER_THIS s[i].raw = new serial_raw(bx_options.com[i].Odev->getptr ());
|
||||
#elif defined(SERIAL_ENABLE)
|
||||
if (strlen(bx_options.com[i].Odev->getptr ()) > 0) {
|
||||
BX_SER_THIS s[i].tty_id = open(bx_options.com[i].Odev->getptr (), O_RDWR|O_NONBLOCK,600);
|
||||
if (BX_SER_THIS s[i].tty_id < 0)
|
||||
BX_PANIC(("open of com%d (%s) failed\n", i+1, bx_options.com[i].Odev->getptr ()));
|
||||
BX_DEBUG(("com%d tty_id: %d", i+1, BX_SER_THIS s[i].tty_id));
|
||||
tcgetattr(BX_SER_THIS s[i].tty_id, &BX_SER_THIS s[i].term_orig);
|
||||
bcopy((caddr_t) &BX_SER_THIS s[i].term_orig, (caddr_t) &BX_SER_THIS s[i].term_new, sizeof(struct termios));
|
||||
cfmakeraw(&BX_SER_THIS s[i].term_new);
|
||||
BX_SER_THIS s[i].term_new.c_oflag |= OPOST | ONLCR; // Enable NL to CR-NL translation
|
||||
|
||||
BX_SER_THIS s[i].io_mode = BX_SER_MODE_NULL;
|
||||
char *mode = bx_options.com[i].Omode->get_choice(bx_options.com[i].Omode->get());
|
||||
if (!strcmp(mode, "file")) {
|
||||
if (strlen(bx_options.com[i].Odev->getptr ()) > 0) {
|
||||
BX_SER_THIS s[i].output = fopen(bx_options.com[i].Odev->getptr (), "wb");
|
||||
if (BX_SER_THIS s[i].output)
|
||||
BX_SER_THIS s[i].io_mode = BX_SER_MODE_FILE;
|
||||
}
|
||||
} else if (!strcmp(mode, "term")) {
|
||||
#if defined(SERIAL_ENABLE)
|
||||
if (strlen(bx_options.com[i].Odev->getptr ()) > 0) {
|
||||
BX_SER_THIS s[i].tty_id = open(bx_options.com[i].Odev->getptr (), O_RDWR|O_NONBLOCK,600);
|
||||
if (BX_SER_THIS s[i].tty_id < 0) {
|
||||
BX_PANIC(("open of com%d (%s) failed\n", i+1, bx_options.com[i].Odev->getptr ()));
|
||||
} else {
|
||||
BX_SER_THIS s[i].io_mode = BX_SER_MODE_TERM;
|
||||
BX_DEBUG(("com%d tty_id: %d", i+1, BX_SER_THIS s[i].tty_id));
|
||||
tcgetattr(BX_SER_THIS s[i].tty_id, &BX_SER_THIS s[i].term_orig);
|
||||
bcopy((caddr_t) &BX_SER_THIS s[i].term_orig, (caddr_t) &BX_SER_THIS s[i].term_new, sizeof(struct termios));
|
||||
cfmakeraw(&BX_SER_THIS s[i].term_new);
|
||||
BX_SER_THIS s[i].term_new.c_oflag |= OPOST | ONLCR; // Enable NL to CR-NL translation
|
||||
#ifndef TRUE_CTLC
|
||||
// ctl-C will exit Bochs, or trap to the debugger
|
||||
BX_SER_THIS s[i].term_new.c_iflag &= ~IGNBRK;
|
||||
BX_SER_THIS s[i].term_new.c_iflag |= BRKINT;
|
||||
BX_SER_THIS s[i].term_new.c_lflag |= ISIG;
|
||||
// ctl-C will exit Bochs, or trap to the debugger
|
||||
BX_SER_THIS s[i].term_new.c_iflag &= ~IGNBRK;
|
||||
BX_SER_THIS s[i].term_new.c_iflag |= BRKINT;
|
||||
BX_SER_THIS s[i].term_new.c_lflag |= ISIG;
|
||||
#else
|
||||
// ctl-C will be delivered to the serial port
|
||||
BX_SER_THIS s[i].term_new.c_iflag |= IGNBRK;
|
||||
BX_SER_THIS s[i].term_new.c_iflag &= ~BRKINT;
|
||||
// ctl-C will be delivered to the serial port
|
||||
BX_SER_THIS s[i].term_new.c_iflag |= IGNBRK;
|
||||
BX_SER_THIS s[i].term_new.c_iflag &= ~BRKINT;
|
||||
#endif /* !def TRUE_CTLC */
|
||||
BX_SER_THIS s[i].term_new.c_iflag = 0;
|
||||
BX_SER_THIS s[i].term_new.c_oflag = 0;
|
||||
BX_SER_THIS s[i].term_new.c_cflag = CS8|CREAD|CLOCAL;
|
||||
BX_SER_THIS s[i].term_new.c_lflag = 0;
|
||||
BX_SER_THIS s[i].term_new.c_cc[VMIN] = 1;
|
||||
BX_SER_THIS s[i].term_new.c_cc[VTIME] = 0;
|
||||
//BX_SER_THIS s[i].term_new.c_iflag |= IXOFF;
|
||||
tcsetattr(BX_SER_THIS s[i].tty_id, TCSAFLUSH, &BX_SER_THIS s[i].term_new);
|
||||
}
|
||||
BX_SER_THIS s[i].term_new.c_iflag = 0;
|
||||
BX_SER_THIS s[i].term_new.c_oflag = 0;
|
||||
BX_SER_THIS s[i].term_new.c_cflag = CS8|CREAD|CLOCAL;
|
||||
BX_SER_THIS s[i].term_new.c_lflag = 0;
|
||||
BX_SER_THIS s[i].term_new.c_cc[VMIN] = 1;
|
||||
BX_SER_THIS s[i].term_new.c_cc[VTIME] = 0;
|
||||
//BX_SER_THIS s[i].term_new.c_iflag |= IXOFF;
|
||||
tcsetattr(BX_SER_THIS s[i].tty_id, TCSAFLUSH, &BX_SER_THIS s[i].term_new);
|
||||
}
|
||||
}
|
||||
#else
|
||||
BX_PANIC(("serial terminal support not available"));
|
||||
#endif /* def SERIAL_ENABLE */
|
||||
} else if (!strcmp(mode, "raw")) {
|
||||
#if USE_RAW_SERIAL
|
||||
BX_SER_THIS s[i].raw = new serial_raw(bx_options.com[i].Odev->getptr ());
|
||||
BX_SER_THIS s[i].io_mode = BX_SER_MODE_RAW;
|
||||
#else
|
||||
BX_PANIC(("raw serial support not present"));
|
||||
#endif
|
||||
} else if (strcmp(mode, "null")) {
|
||||
BX_PANIC(("unknown serial i/o mode"));
|
||||
}
|
||||
// simulate device connected
|
||||
if (BX_SER_THIS s[i].io_mode != BX_SER_MODE_RAW) {
|
||||
BX_SER_THIS s[i].modem_status.cts = 1;
|
||||
BX_SER_THIS s[i].modem_status.dsr = 1;
|
||||
}
|
||||
BX_INFO(("com%d at 0x%04x irq %d", i+1, ports[i], BX_SER_THIS s[i].IRQ));
|
||||
}
|
||||
}
|
||||
@ -446,24 +485,26 @@ bx_serial_c::read(Bit32u address, unsigned io_len)
|
||||
prev_dsr = BX_SER_THIS s[port].modem_status.dsr;
|
||||
prev_ri = BX_SER_THIS s[port].modem_status.ri;
|
||||
prev_dcd = BX_SER_THIS s[port].modem_status.dcd;
|
||||
if (BX_SER_THIS s[port].io_mode == BX_SER_MODE_RAW) {
|
||||
#if USE_RAW_SERIAL
|
||||
val = BX_SER_THIS s[port].raw->get_modem_status();
|
||||
BX_SER_THIS s[port].modem_status.cts = (val & 0x10) >> 4;
|
||||
BX_SER_THIS s[port].modem_status.dsr = (val & 0x20) >> 5;
|
||||
BX_SER_THIS s[port].modem_status.ri = (val & 0x40) >> 6;
|
||||
BX_SER_THIS s[port].modem_status.dcd = (val & 0x80) >> 7;
|
||||
if (BX_SER_THIS s[port].modem_status.cts != prev_cts) {
|
||||
BX_SER_THIS s[port].modem_status.delta_cts = 1;
|
||||
}
|
||||
if (BX_SER_THIS s[port].modem_status.dsr != prev_dsr) {
|
||||
BX_SER_THIS s[port].modem_status.delta_dsr = 1;
|
||||
}
|
||||
if ((BX_SER_THIS s[port].modem_status.ri == 0) && (prev_ri == 1))
|
||||
BX_SER_THIS s[port].modem_status.ri_trailedge = 1;
|
||||
if (BX_SER_THIS s[port].modem_status.dcd != prev_dcd) {
|
||||
BX_SER_THIS s[port].modem_status.delta_dcd = 1;
|
||||
}
|
||||
val = BX_SER_THIS s[port].raw->get_modem_status();
|
||||
BX_SER_THIS s[port].modem_status.cts = (val & 0x10) >> 4;
|
||||
BX_SER_THIS s[port].modem_status.dsr = (val & 0x20) >> 5;
|
||||
BX_SER_THIS s[port].modem_status.ri = (val & 0x40) >> 6;
|
||||
BX_SER_THIS s[port].modem_status.dcd = (val & 0x80) >> 7;
|
||||
if (BX_SER_THIS s[port].modem_status.cts != prev_cts) {
|
||||
BX_SER_THIS s[port].modem_status.delta_cts = 1;
|
||||
}
|
||||
if (BX_SER_THIS s[port].modem_status.dsr != prev_dsr) {
|
||||
BX_SER_THIS s[port].modem_status.delta_dsr = 1;
|
||||
}
|
||||
if ((BX_SER_THIS s[port].modem_status.ri == 0) && (prev_ri == 1))
|
||||
BX_SER_THIS s[port].modem_status.ri_trailedge = 1;
|
||||
if (BX_SER_THIS s[port].modem_status.dcd != prev_dcd) {
|
||||
BX_SER_THIS s[port].modem_status.delta_dcd = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
val = BX_SER_THIS s[port].modem_status.delta_cts |
|
||||
(BX_SER_THIS s[port].modem_status.delta_dsr << 1) |
|
||||
(BX_SER_THIS s[port].modem_status.ri_trailedge << 2) |
|
||||
@ -696,29 +737,30 @@ bx_serial_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
||||
|
||||
case BX_SER_LCR: /* Line control register */
|
||||
new_wordlen = value & 0x03;
|
||||
if (BX_SER_THIS s[port].io_mode == BX_SER_MODE_RAW) {
|
||||
#if USE_RAW_SERIAL
|
||||
if (BX_SER_THIS s[port].line_cntl.wordlen_sel != new_wordlen) {
|
||||
BX_SER_THIS s[port].raw->set_data_bits(new_wordlen + 5);
|
||||
}
|
||||
if (new_b2 != BX_SER_THIS s[port].line_cntl.stopbits) {
|
||||
BX_SER_THIS s[port].raw->set_stop_bits(new_b2 ? 2 : 1);
|
||||
}
|
||||
if ((new_b3 != BX_SER_THIS s[port].line_cntl.parity_enable) ||
|
||||
(new_b4 != BX_SER_THIS s[port].line_cntl.evenparity_sel) ||
|
||||
(new_b5 != BX_SER_THIS s[port].line_cntl.stick_parity)) {
|
||||
if (new_b3 == 0) {
|
||||
p_mode = P_NONE;
|
||||
} else {
|
||||
p_mode = ((value & 0x30) >> 4) + 1;
|
||||
if (BX_SER_THIS s[port].line_cntl.wordlen_sel != new_wordlen) {
|
||||
BX_SER_THIS s[port].raw->set_data_bits(new_wordlen + 5);
|
||||
}
|
||||
if (new_b2 != BX_SER_THIS s[port].line_cntl.stopbits) {
|
||||
BX_SER_THIS s[port].raw->set_stop_bits(new_b2 ? 2 : 1);
|
||||
}
|
||||
if ((new_b3 != BX_SER_THIS s[port].line_cntl.parity_enable) ||
|
||||
(new_b4 != BX_SER_THIS s[port].line_cntl.evenparity_sel) ||
|
||||
(new_b5 != BX_SER_THIS s[port].line_cntl.stick_parity)) {
|
||||
if (new_b3 == 0) {
|
||||
p_mode = P_NONE;
|
||||
} else {
|
||||
p_mode = ((value & 0x30) >> 4) + 1;
|
||||
}
|
||||
BX_SER_THIS s[port].raw->set_parity_mode(p_mode);
|
||||
}
|
||||
if ((new_b6 != BX_SER_THIS s[port].line_cntl.break_cntl) &&
|
||||
(!BX_SER_THIS s[port].modem_cntl.local_loopback)) {
|
||||
BX_SER_THIS s[port].raw->set_break(new_b6);
|
||||
}
|
||||
BX_SER_THIS s[port].raw->set_parity_mode(p_mode);
|
||||
}
|
||||
if ((new_b6 != BX_SER_THIS s[port].line_cntl.break_cntl) &&
|
||||
(!BX_SER_THIS s[port].modem_cntl.local_loopback)) {
|
||||
BX_SER_THIS s[port].raw->set_break(new_b6);
|
||||
}
|
||||
#endif // USE_RAW_SERIAL
|
||||
|
||||
}
|
||||
BX_SER_THIS s[port].line_cntl.wordlen_sel = new_wordlen;
|
||||
/* These are ignored, but set them up so they can be read back */
|
||||
BX_SER_THIS s[port].line_cntl.stopbits = new_b2;
|
||||
@ -744,19 +786,23 @@ bx_serial_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
||||
(BX_SER_THIS s[port].line_cntl.wordlen_sel + 5)),
|
||||
0); /* not continuous */
|
||||
}
|
||||
if (BX_SER_THIS s[port].io_mode == BX_SER_MODE_RAW) {
|
||||
#if USE_RAW_SERIAL
|
||||
BX_SER_THIS s[port].raw->set_baudrate(BX_SER_THIS s[port].baudrate);
|
||||
BX_SER_THIS s[port].raw->set_baudrate(BX_SER_THIS s[port].baudrate);
|
||||
#endif // USE_RAW_SERIAL
|
||||
}
|
||||
BX_DEBUG(("com%d: baud rate set - %d", port+1, BX_SER_THIS s[port].baudrate));
|
||||
}
|
||||
BX_SER_THIS s[port].line_cntl.dlab = new_b7;
|
||||
break;
|
||||
|
||||
case BX_SER_MCR: /* MODEM control register */
|
||||
if (BX_SER_THIS s[port].io_mode == BX_SER_MODE_RAW) {
|
||||
#if USE_RAW_SERIAL
|
||||
mcr_changed = (BX_SER_THIS s[port].modem_cntl.dtr != new_b0) |
|
||||
(BX_SER_THIS s[port].modem_cntl.rts != new_b1);
|
||||
mcr_changed = (BX_SER_THIS s[port].modem_cntl.dtr != new_b0) |
|
||||
(BX_SER_THIS s[port].modem_cntl.rts != new_b1);
|
||||
#endif
|
||||
}
|
||||
BX_SER_THIS s[port].modem_cntl.dtr = new_b0;
|
||||
BX_SER_THIS s[port].modem_cntl.rts = new_b1;
|
||||
BX_SER_THIS s[port].modem_cntl.out1 = new_b2;
|
||||
@ -766,28 +812,34 @@ bx_serial_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
||||
BX_SER_THIS s[port].modem_cntl.local_loopback = new_b4;
|
||||
if (BX_SER_THIS s[port].modem_cntl.local_loopback) {
|
||||
/* transition to loopback mode */
|
||||
if (BX_SER_THIS s[port].io_mode == BX_SER_MODE_RAW) {
|
||||
#if USE_RAW_SERIAL
|
||||
if (BX_SER_THIS s[port].modem_cntl.dtr ||
|
||||
BX_SER_THIS s[port].modem_cntl.rts) {
|
||||
BX_SER_THIS s[port].raw->set_modem_control(0);
|
||||
if (BX_SER_THIS s[port].modem_cntl.dtr ||
|
||||
BX_SER_THIS s[port].modem_cntl.rts) {
|
||||
BX_SER_THIS s[port].raw->set_modem_control(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
if (BX_SER_THIS s[port].line_cntl.break_cntl) {
|
||||
if (BX_SER_THIS s[port].io_mode == BX_SER_MODE_RAW) {
|
||||
#if USE_RAW_SERIAL
|
||||
BX_SER_THIS s[port].raw->set_break(0);
|
||||
BX_SER_THIS s[port].raw->set_break(0);
|
||||
#endif
|
||||
}
|
||||
BX_SER_THIS s[port].line_status.break_int = 1;
|
||||
BX_SER_THIS s[port].line_status.framing_error = 1;
|
||||
rx_fifo_enq(port, 0x00);
|
||||
}
|
||||
} else {
|
||||
/* transition to normal mode */
|
||||
if (BX_SER_THIS s[port].io_mode == BX_SER_MODE_RAW) {
|
||||
#if USE_RAW_SERIAL
|
||||
mcr_changed = 1;
|
||||
if (BX_SER_THIS s[port].line_cntl.break_cntl) {
|
||||
BX_SER_THIS s[port].raw->set_break(0);
|
||||
}
|
||||
mcr_changed = 1;
|
||||
if (BX_SER_THIS s[port].line_cntl.break_cntl) {
|
||||
BX_SER_THIS s[port].raw->set_break(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -818,17 +870,19 @@ bx_serial_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
||||
}
|
||||
raise_interrupt(port, BX_SER_INT_MODSTAT);
|
||||
} else {
|
||||
if (BX_SER_THIS s[port].io_mode == BX_SER_MODE_RAW) {
|
||||
#if USE_RAW_SERIAL
|
||||
if (mcr_changed) {
|
||||
BX_SER_THIS s[port].raw->set_modem_control(value & 0x03);
|
||||
}
|
||||
#else
|
||||
/* set these to 0 for the time being */
|
||||
BX_SER_THIS s[port].modem_status.cts = 0;
|
||||
BX_SER_THIS s[port].modem_status.dsr = 0;
|
||||
BX_SER_THIS s[port].modem_status.ri = 0;
|
||||
BX_SER_THIS s[port].modem_status.dcd = 0;
|
||||
if (mcr_changed) {
|
||||
BX_SER_THIS s[port].raw->set_modem_control(value & 0x03);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
/* simulate device connected */
|
||||
BX_SER_THIS s[port].modem_status.cts = 1;
|
||||
BX_SER_THIS s[port].modem_status.dsr = 1;
|
||||
BX_SER_THIS s[port].modem_status.ri = 0;
|
||||
BX_SER_THIS s[port].modem_status.dcd = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -930,16 +984,27 @@ bx_serial_c::tx_timer(void)
|
||||
if (BX_SER_THIS s[port].modem_cntl.local_loopback) {
|
||||
rx_fifo_enq(port, BX_SER_THIS s[port].tsrbuffer);
|
||||
} else {
|
||||
#if USE_RAW_SERIAL
|
||||
if (!BX_SER_THIS s[port].raw->ready_transmit())
|
||||
BX_PANIC(("com%d: not ready to transmit", port+1));
|
||||
BX_SER_THIS s[port].raw->transmit(BX_SER_THIS s[port].tsrbuffer);
|
||||
#elif defined(SERIAL_ENABLE)
|
||||
BX_DEBUG(("com%d: write: '%c'", port+1, BX_SER_THIS s[port].tsrbuffer));
|
||||
if (BX_SER_THIS s[port].tty_id >= 0) {
|
||||
write(BX_SER_THIS s[port].tty_id, (bx_ptr_t) & BX_SER_THIS s[port].tsrbuffer, 1);
|
||||
}
|
||||
switch (BX_SER_THIS s[port].io_mode) {
|
||||
case BX_SER_MODE_FILE:
|
||||
fputc(BX_SER_THIS s[port].tsrbuffer, BX_SER_THIS s[port].output);
|
||||
fflush(BX_SER_THIS s[port].output);
|
||||
break;
|
||||
case BX_SER_MODE_TERM:
|
||||
#if defined(SERIAL_ENABLE)
|
||||
BX_DEBUG(("com%d: write: '%c'", port+1, BX_SER_THIS s[port].tsrbuffer));
|
||||
if (BX_SER_THIS s[port].tty_id >= 0) {
|
||||
write(BX_SER_THIS s[port].tty_id, (bx_ptr_t) & BX_SER_THIS s[port].tsrbuffer, 1);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case BX_SER_MODE_RAW:
|
||||
#if USE_RAW_SERIAL
|
||||
if (!BX_SER_THIS s[port].raw->ready_transmit())
|
||||
BX_PANIC(("com%d: not ready to transmit", port+1));
|
||||
BX_SER_THIS s[port].raw->transmit(BX_SER_THIS s[port].tsrbuffer);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BX_SER_THIS s[port].line_status.tsr_empty = 1;
|
||||
@ -984,6 +1049,7 @@ bx_serial_c::rx_timer(void)
|
||||
#endif
|
||||
Bit8u port = 0;
|
||||
int timer_id;
|
||||
bx_bool data_ready = 0;
|
||||
|
||||
timer_id = bx_pc_system.triggeredTimerID();
|
||||
if (timer_id == BX_SER_THIS s[0].rx_timer_index) {
|
||||
@ -998,67 +1064,73 @@ bx_serial_c::rx_timer(void)
|
||||
int bdrate = BX_SER_THIS s[port].baudrate / (BX_SER_THIS s[port].line_cntl.wordlen_sel + 5);
|
||||
unsigned char chbuf = 0;
|
||||
|
||||
if (BX_SER_THIS s[port].io_mode == BX_SER_MODE_TERM) {
|
||||
#if BX_HAVE_SELECT && defined(SERIAL_ENABLE)
|
||||
tval.tv_sec = 0;
|
||||
tval.tv_usec = 0;
|
||||
tval.tv_sec = 0;
|
||||
tval.tv_usec = 0;
|
||||
|
||||
// MacOS: I'm not sure what to do with this, since I don't know
|
||||
// what an fd_set is or what FD_SET() or select() do. They aren't
|
||||
// declared in the CodeWarrior standard library headers. I'm just
|
||||
// leaving it commented out for the moment.
|
||||
|
||||
FD_ZERO(&fds);
|
||||
if (BX_SER_THIS s[port].tty_id >= 0) FD_SET(BX_SER_THIS s[port].tty_id, &fds);
|
||||
FD_ZERO(&fds);
|
||||
if (BX_SER_THIS s[port].tty_id >= 0) FD_SET(BX_SER_THIS s[port].tty_id, &fds);
|
||||
#endif
|
||||
|
||||
}
|
||||
if ((BX_SER_THIS s[port].line_status.rxdata_ready == 0) ||
|
||||
(BX_SER_THIS s[port].fifo_cntl.enable)) {
|
||||
if (BX_SER_THIS s[port].io_mode == BX_SER_MODE_RAW) {
|
||||
#if USE_RAW_SERIAL
|
||||
bx_bool rdy;
|
||||
int data;
|
||||
if ((rdy = BX_SER_THIS s[port].raw->ready_receive())) {
|
||||
data = BX_SER_THIS s[port].raw->receive();
|
||||
if (data < 0 ) {
|
||||
rdy = 0;
|
||||
switch (data) {
|
||||
case RAW_EVENT_BREAK:
|
||||
BX_SER_THIS s[port].line_status.break_int = 1;
|
||||
raise_interrupt(port, BX_SER_INT_RXLSTAT);
|
||||
break;
|
||||
case RAW_EVENT_FRAME:
|
||||
BX_SER_THIS s[port].line_status.framing_error = 1;
|
||||
raise_interrupt(port, BX_SER_INT_RXLSTAT);
|
||||
break;
|
||||
case RAW_EVENT_OVERRUN:
|
||||
BX_SER_THIS s[port].line_status.overrun_error = 1;
|
||||
raise_interrupt(port, BX_SER_INT_RXLSTAT);
|
||||
break;
|
||||
case RAW_EVENT_PARITY:
|
||||
BX_SER_THIS s[port].line_status.parity_error = 1;
|
||||
raise_interrupt(port, BX_SER_INT_RXLSTAT);
|
||||
break;
|
||||
case RAW_EVENT_CTS_ON:
|
||||
case RAW_EVENT_CTS_OFF:
|
||||
case RAW_EVENT_DSR_ON:
|
||||
case RAW_EVENT_DSR_OFF:
|
||||
case RAW_EVENT_RING_ON:
|
||||
case RAW_EVENT_RING_OFF:
|
||||
case RAW_EVENT_RLSD_ON:
|
||||
case RAW_EVENT_RLSD_OFF:
|
||||
raise_interrupt(port, BX_SER_INT_MODSTAT);
|
||||
break;
|
||||
int data;
|
||||
if ((data_ready = BX_SER_THIS s[port].raw->ready_receive())) {
|
||||
data = BX_SER_THIS s[port].raw->receive();
|
||||
if (data < 0 ) {
|
||||
data_ready = 0;
|
||||
switch (data) {
|
||||
case RAW_EVENT_BREAK:
|
||||
BX_SER_THIS s[port].line_status.break_int = 1;
|
||||
raise_interrupt(port, BX_SER_INT_RXLSTAT);
|
||||
break;
|
||||
case RAW_EVENT_FRAME:
|
||||
BX_SER_THIS s[port].line_status.framing_error = 1;
|
||||
raise_interrupt(port, BX_SER_INT_RXLSTAT);
|
||||
break;
|
||||
case RAW_EVENT_OVERRUN:
|
||||
BX_SER_THIS s[port].line_status.overrun_error = 1;
|
||||
raise_interrupt(port, BX_SER_INT_RXLSTAT);
|
||||
break;
|
||||
case RAW_EVENT_PARITY:
|
||||
BX_SER_THIS s[port].line_status.parity_error = 1;
|
||||
raise_interrupt(port, BX_SER_INT_RXLSTAT);
|
||||
break;
|
||||
case RAW_EVENT_CTS_ON:
|
||||
case RAW_EVENT_CTS_OFF:
|
||||
case RAW_EVENT_DSR_ON:
|
||||
case RAW_EVENT_DSR_OFF:
|
||||
case RAW_EVENT_RING_ON:
|
||||
case RAW_EVENT_RING_OFF:
|
||||
case RAW_EVENT_RLSD_ON:
|
||||
case RAW_EVENT_RLSD_OFF:
|
||||
raise_interrupt(port, BX_SER_INT_MODSTAT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rdy) {
|
||||
chbuf = data;
|
||||
#elif BX_HAVE_SELECT && defined(SERIAL_ENABLE)
|
||||
if ((BX_SER_THIS s[port].tty_id >= 0) && (select(BX_SER_THIS s[port].tty_id + 1, &fds, NULL, NULL, &tval) == 1)) {
|
||||
(void) read(BX_SER_THIS s[port].tty_id, &chbuf, 1);
|
||||
BX_DEBUG(("com%d: read: '%c'", port+1, chbuf));
|
||||
#else
|
||||
if (0) {
|
||||
if (data_ready) {
|
||||
chbuf = data;
|
||||
}
|
||||
#endif
|
||||
} else if (BX_SER_THIS s[port].io_mode == BX_SER_MODE_TERM) {
|
||||
#if BX_HAVE_SELECT && defined(SERIAL_ENABLE)
|
||||
if ((BX_SER_THIS s[port].tty_id >= 0) && (select(BX_SER_THIS s[port].tty_id + 1, &fds, NULL, NULL, &tval) == 1)) {
|
||||
(void) read(BX_SER_THIS s[port].tty_id, &chbuf, 1);
|
||||
BX_DEBUG(("com%d: read: '%c'", port+1, chbuf));
|
||||
data_ready = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (data_ready) {
|
||||
if (!BX_SER_THIS s[port].modem_cntl.local_loopback) {
|
||||
rx_fifo_enq(port, chbuf);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: serial.h,v 1.18 2004-01-18 11:58:07 vruppert Exp $
|
||||
// $Id: serial.h,v 1.19 2004-07-28 19:36:42 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2004 MandrakeSoft S.A.
|
||||
@ -66,6 +66,11 @@ extern "C" {
|
||||
#define BX_SER_MSR 6
|
||||
#define BX_SER_SCR 7
|
||||
|
||||
#define BX_SER_MODE_NULL 0
|
||||
#define BX_SER_MODE_FILE 1
|
||||
#define BX_SER_MODE_TERM 2
|
||||
#define BX_SER_MODE_RAW 3
|
||||
|
||||
enum {
|
||||
BX_SER_INT_IER,
|
||||
BX_SER_INT_RXDATA,
|
||||
@ -101,7 +106,9 @@ typedef struct {
|
||||
int rx_timer_index;
|
||||
int fifo_timer_index;
|
||||
|
||||
int io_mode;
|
||||
int tty_id;
|
||||
FILE *output;
|
||||
|
||||
#if USE_RAW_SERIAL
|
||||
serial_raw* raw;
|
||||
|
Loading…
Reference in New Issue
Block a user