aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/doscmd/int14.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/doscmd/int14.c')
-rw-r--r--usr.bin/doscmd/int14.c582
1 files changed, 372 insertions, 210 deletions
diff --git a/usr.bin/doscmd/int14.c b/usr.bin/doscmd/int14.c
index 56c9576776cb..a9c9a687bf6e 100644
--- a/usr.bin/doscmd/int14.c
+++ b/usr.bin/doscmd/int14.c
@@ -42,44 +42,221 @@
#include <unistd.h>
#include "doscmd.h"
+#include "AsyncIO.h"
#include "com.h"
-struct com_data_struct com_data[N_COMS_MAX];
-
-/* XXX where does struct queue come from? */
-static struct queue *create_queue(unsigned char);
-static int queue_not_empty(struct queue *);
-static int reset_irq_request(unsigned char);
-static int set_irq_request(unsigned char);
-static int test_irq_request(unsigned char);
-static int write_div_latches(struct com_data_struct *);
-
-static struct queue *
-create_queue(unsigned char irq) { return NULL; }
-
-static int
-queue_not_empty(struct queue *qp) {return 0;}
+#define N_BYTES 1024
+
+struct com_data_struct {
+ int fd; /* BSD/386 file descriptor */
+ char *path; /* BSD/386 pathname */
+ int addr; /* ISA I/O address */
+ unsigned char irq; /* ISA IRQ */
+ unsigned char inbuf[N_BYTES]; /* input buffer */
+ unsigned char outbuf[N_BYTES];/* output buffer */
+ int ids; /* input data size */
+ int ods; /* output data size */
+ int emptyint;
+ struct termios tty;
+ unsigned char div_latch[2]; /* mirror of 16550 R0':R1'
+ read/write */
+ unsigned char int_enable; /* mirror of 16550 R1 read/write */
+ unsigned char fifo_ctrl; /* mirror of 16550 R2 write only */
+ unsigned char line_ctrl; /* mirror of 16550 R3 read/write */
+ unsigned char modem_ctrl; /* mirror of 16550 R4 read/write */
+ unsigned char modem_stat; /* mirror of 16550 R6 read/write */
+ unsigned char uart_spare; /* mirror of 16550 R7 read/write */
+};
+
+#define DIV_LATCH_LOW 0
+#define DIV_LATCH_HIGH 1
-static int
-reset_irq_request(unsigned char irq) {return 0;}
+struct com_data_struct com_data[N_COMS_MAX];
+static unsigned char com_port_in(int port);
+static void com_port_out(int port, unsigned char val);
+static void com_set_line(struct com_data_struct *cdsp,
+ unsigned char port, unsigned char param);
+
+static void
+manage_int(struct com_data_struct *cdsp)
+{
+ if ((cdsp->int_enable & IE_RCV_DATA) && cdsp->ids > 0) {
+ hardint(cdsp->irq);
+ debug(D_PORT, "manage_int: hardint rd\n");
+ return;
+ }
+ if ((cdsp->int_enable & IE_TRANS_HLD) && cdsp->emptyint) {
+ hardint(cdsp->irq);
+ debug(D_PORT, "manage_int: hardint wr\n");
+ return;
+ }
+ unpend (cdsp->irq);
+}
+
static int
-set_irq_request(unsigned char irq) {return 0;}
-
+has_enough_data(struct com_data_struct *cdsp)
+{
+ switch (cdsp->fifo_ctrl & (FC_FIFO_EN | FC_FIFO_SZ_MASK)) {
+ case FC_FIFO_EN | FC_FIFO_4B:
+ return cdsp->ids >= 4;
+ case FC_FIFO_EN | FC_FIFO_8B:
+ return cdsp->ids >= 8;
+ case FC_FIFO_EN | FC_FIFO_14B:
+ return cdsp->ids >= 14;
+ }
+ return cdsp->ids;
+}
+
+static void
+input(struct com_data_struct *cdsp, int force_read)
+{
+ int nbytes;
+
+ if (cdsp->ids < N_BYTES && (force_read || !has_enough_data(cdsp))) {
+ nbytes = read(cdsp->fd, &cdsp->inbuf[cdsp->ids],
+ N_BYTES - cdsp->ids);
+ debug(D_PORT, "read of fd %d on '%s' returned %d (%s)\n",
+ cdsp->fd, cdsp->path, nbytes,
+ nbytes == -1 ? strerror(errno) : "");
+ if (nbytes != -1)
+ cdsp->ids += nbytes;
+ }
+}
+
+static void
+output(struct com_data_struct *cdsp)
+{
+ int nbytes;
+
+ if (cdsp->ods > 0) {
+ nbytes = write(cdsp->fd, &cdsp->outbuf[0], cdsp->ods);
+ debug(D_PORT, "write of fd %d on '%s' returned %d (%s)\n",
+ cdsp->fd, cdsp->path, nbytes,
+ nbytes == -1 ? strerror(errno) : "");
+ if (nbytes != -1) {
+ cdsp->ods -= nbytes;
+ memmove (&cdsp->outbuf[0],
+ &cdsp->outbuf[nbytes], cdsp->ods);
+ if ((cdsp->int_enable & IE_TRANS_HLD)
+ && cdsp->ods == 0)
+ cdsp->emptyint = 1;
+ }
+ }
+}
+
+static void
+flush_out(void* arg)
+{
+ struct com_data_struct *cdsp = (struct com_data_struct*)arg;
+ output(cdsp);
+ manage_int(cdsp);
+}
+
+/*
+ * We postponed flush till the end of interrupt processing
+ * (see int.c).
+ */
static int
-test_irq_request(unsigned char irq) {return 0;}
-
+write_char(struct com_data_struct *cdsp, char c)
+{
+ int r = 0;
+ cdsp->emptyint = 0;
+ if (cdsp->ods >= N_BYTES)
+ output(cdsp);
+ if (cdsp->ods < N_BYTES) {
+ cdsp->outbuf[cdsp->ods ++] = c;
+ if (!isinhardint(cdsp->irq))
+ output(cdsp);
+ r = 1;
+ }
+ manage_int(cdsp);
+ return r;
+}
+
static int
-write_div_latches(struct com_data_struct *cdsp) {return 0;}
+read_char(struct com_data_struct *cdsp)
+{
+ int c = -1;
+
+ input(cdsp, 0);
+
+ if (cdsp->ids > 0) {
+ c = cdsp->inbuf[0];
+ cdsp->ids --;
+ memmove(&cdsp->inbuf[0], &cdsp->inbuf[1], cdsp->ids);
+ }
+
+ manage_int(cdsp);
+
+ debug(D_PORT, "read_char: %x\n", c);
+ return c;
+}
+
+static void
+new_ii(struct com_data_struct *cdsp)
+{
+ if ((cdsp->int_enable & IE_TRANS_HLD) && cdsp->ods == 0)
+ cdsp->emptyint = 1;
+ manage_int(cdsp);
+}
+
+static unsigned char
+get_status(struct com_data_struct *cdsp)
+{
+ unsigned char s = (LS_X_DATA_E | LS_X_HOLD_E);
+ if (cdsp->ids > 0)
+ s |= LS_RCV_DATA_RD;
+ if (cdsp->ods > 0) {
+ s &= ~LS_X_DATA_E;
+ if (cdsp->ods >= N_BYTES)
+ s &= ~LS_X_HOLD_E;
+ }
+ debug(D_PORT, "get_status: %x\n", (unsigned)s);
+ return s;
+}
+
+static unsigned char
+get_int_id(struct com_data_struct *cdsp)
+{
+ unsigned char s = II_PEND_INT;
+ if (cdsp->fifo_ctrl & FC_FIFO_EN)
+ s |= II_FIFOS_EN;
+ if ((cdsp->int_enable & IE_RCV_DATA) && cdsp->ids > 0) {
+ if (has_enough_data(cdsp))
+ s = (s & ~II_PEND_INT) | II_RCV_DATA;
+ else
+ s = (s & ~II_PEND_INT) | II_TO;
+ } else
+ if ((cdsp->int_enable & IE_TRANS_HLD) && cdsp->emptyint) {
+ cdsp->emptyint = 0;
+ s = (s & ~II_PEND_INT) | II_TRANS_HLD;
+ }
+ debug(D_PORT, "get_int_id: %x\n", (unsigned)s);
+ return s;
+}
+
+static void
+com_async(int fd, int cond, void *arg, regcontext_t *REGS)
+{
+ struct com_data_struct *cdsp = (struct com_data_struct*) arg;
+
+ debug(D_PORT, "com_async: %X.\n", cond);
+
+ if (cond & AS_RD)
+ input(cdsp, 1);
+ if (cond & AS_WR)
+ output(cdsp);
+ manage_int(cdsp);
+}
void
int14(regcontext_t *REGS)
{
struct com_data_struct *cdsp;
- int nbytes;
- char c;
+ int i;
- debug (D_PORT, "int14: dl = 0x%02X, al = 0x%02X.\n", R_DL, R_AL);
+ debug(D_PORT, "int14: dl = 0x%02X, al = 0x%02X.\n", R_DL, R_AL);
if (R_DL >= N_COMS_MAX) {
if (vflag)
dump_regs(REGS);
@@ -89,39 +266,27 @@ int14(regcontext_t *REGS)
switch (R_AH) {
case 0x00: /* Initialize Serial Port */
-#if 0 /* hold off: try to defeat stupid DOS defaults */
com_set_line(cdsp, R_DL + 1, R_AL);
- R_AH = LS_X_SHFT_E | LS_X_HOLD_E;
+ R_AH = get_status(cdsp);
R_AL = 0;
-#endif 0
break;
case 0x01: /* Write Character */
- errno = 0;
- c = R_AL;
- nbytes = write(cdsp->fd, &c, 1);
- debug (D_PORT, "write of 0x%02x to fd %d on '%s' returned %d %s\n",
- R_AL, cdsp->fd, cdsp->path, nbytes, strerror(errno));
- if (nbytes == 1) {
- R_AH = LS_X_SHFT_E | LS_X_HOLD_E;
+ if (write_char(cdsp, R_AL)) {
+ R_AH = get_status(cdsp);
R_AL = 0;
} else {
- debug(D_PORT, "int14: lost output character 0x%02x\n",
- R_AL);
+ debug(D_PORT, "int14: lost output character 0x%02x\n", R_AL);
R_AH = LS_SW_TIME_OUT;
R_AL = 0;
}
break;
case 0x02: /* Read Character */
- errno = 0;
- nbytes = read(cdsp->fd, &c, 1);
- debug (D_PORT, "read of fd %d on '%s' returned %d byte 0x%02x %s\n",
- cdsp->fd, cdsp->path, nbytes, c,
- errno ? strerror(errno) : "");
- if (nbytes == 1) {
- R_AH = LS_X_SHFT_E | LS_X_HOLD_E;
- R_AL = c;
+ i = read_char(cdsp);
+ if (i != -1) {
+ R_AH = get_status(cdsp);
+ R_AL = (char)i;
} else {
R_AH = LS_SW_TIME_OUT;
R_AL = 0x60;
@@ -129,7 +294,8 @@ int14(regcontext_t *REGS)
break;
case 0x03: /* Status Request */
- R_AX = (LS_X_SHFT_E | LS_X_HOLD_E) << 8;
+ R_AH = get_status(cdsp);
+ R_AL = 0;
break;
case 0x04: /* Extended Initialization */
@@ -159,119 +325,181 @@ int14(regcontext_t *REGS)
/* called when doscmd initializes a single line */
-void
+static void
com_set_line(struct com_data_struct *cdsp, unsigned char port, unsigned char param)
{
struct stat stat_buf;
- int reg_num;
-
- debug (D_PORT, "com_set_line: cdsp = %8p, port = 0x%04x,"
+ int mode = 0; /* read | write */
+ int reg_num, ret_val, spd, speed;
+ u_int8_t div_hi, div_lo;
+
+ debug(D_PORT, "com_set_line: cdsp = %8p, port = 0x%04x,"
"param = 0x%04X.\n", cdsp, port, param);
if (cdsp->fd > 0) {
- debug (D_PORT, "Re-initialize serial port com%d\n", port);
- (void)close(cdsp->fd);
+ debug(D_PORT, "Re-initialize serial port com%d\n", port);
+ _RegisterIO(cdsp->fd, 0, 0, 0);
+ (void)close(cdsp->fd);
} else {
- debug (D_PORT, "Initialize serial port com%d\n", port);
+ debug(D_PORT, "Initialize serial port com%d\n", port);
}
-
+
stat(cdsp->path, &stat_buf);
if (!S_ISCHR(stat_buf.st_mode) ||
((cdsp->fd = open(cdsp->path, O_RDWR | O_NONBLOCK, 0666)) == -1)) {
-
- debug (D_PORT,
- "Could not initialize serial port com%d on path '%s'\n",
- port, cdsp->path);
+
+ debug(D_PORT,
+ "Could not initialize serial port com%d on path '%s'\n",
+ port, cdsp->path);
return;
}
-
- cdsp->flags = 0x00;
- cdsp->last_char_read = 0x00;
-#if 0
+
+ cdsp->ids = cdsp->ods = cdsp->emptyint = 0;
+ cdsp->int_enable = 0;
+ cdsp->fifo_ctrl = 0;
+ cdsp->modem_ctrl = 0;
+ cdsp->modem_stat = 0;
+ cdsp->uart_spare = 0;
+
if ((param & PARITY_EVEN) == PARITY_NONE)
- tty.c_iflag = IGNBRK | IGNPAR | IXON | IXOFF /* | IXANY */;
+ cdsp->tty.c_iflag = IGNBRK | IGNPAR /* | IXON | IXOFF | IXANY */;
else
- tty.c_iflag = IGNBRK | IXON | IXOFF /* | IXANY */;
- tty.c_oflag = 0;
- tty.c_lflag = 0;
- tty.c_cc[VTIME] = 0;
- tty.c_cc[VMIN] = 1;
- tty.c_cflag = CREAD | CLOCAL | HUPCL;
+ cdsp->tty.c_iflag = IGNBRK /* | IXON | IXOFF | IXANY */;
+ cdsp->tty.c_oflag = 0;
+ cdsp->tty.c_lflag = 0;
+ cdsp->tty.c_cc[VTIME] = 0;
+ cdsp->tty.c_cc[VMIN] = 0;
+ cdsp->tty.c_cflag = CREAD | CLOCAL | HUPCL;
/* MCL WHY CLOCAL ??????; but, gets errno EIO on writes, else */
- if ((param & TXLEN_8BITS) == TXLEN_8BITS)
- tty.c_cflag |= CS8;
- else
- tty.c_cflag |= CS7;
- if ((param & STOPBIT_2) == STOPBIT_2)
- tty.c_cflag |= CSTOPB;
+ if ((param & TXLEN_8BITS) == TXLEN_8BITS) {
+ cdsp->tty.c_cflag |= CS8;
+ cdsp->line_ctrl |= 3;
+ } else {
+ cdsp->tty.c_cflag |= CS7;
+ cdsp->line_ctrl |= 2;
+ }
+ if ((param & STOPBIT_2) == STOPBIT_2) {
+ cdsp->tty.c_cflag |= CSTOPB;
+ cdsp->line_ctrl |= LC_STOP_B;
+ } else {
+ cdsp->tty.c_cflag &= ~CSTOPB;
+ cdsp->line_ctrl &= ~LC_STOP_B;
+ }
switch (param & PARITY_EVEN) {
- case (PARITY_ODD):
- tty.c_cflag |= (PARENB | PARODD);
- break;
- case (PARITY_EVEN):
- tty.c_cflag |= PARENB;
- break;
- case (PARITY_NONE):
- default:
- break;
+ case PARITY_ODD:
+ cdsp->tty.c_cflag |= (PARENB | PARODD);
+ cdsp->line_ctrl &= ~LC_EVEN_P;
+ cdsp->line_ctrl |= LC_PAR_E;
+ break;
+ case PARITY_EVEN:
+ cdsp->tty.c_cflag |= PARENB;
+ cdsp->line_ctrl |= LC_EVEN_P | LC_PAR_E;
+ break;
+ case PARITY_NONE:
+ cdsp->line_ctrl &= ~LC_PAR_E;
+ default:
+ break;
}
switch (param & BITRATE_9600) {
- case (BITRATE_110):
+ case BITRATE_110:
speed = B110;
+ spd = 110;
break;
- case (BITRATE_150):
+ case BITRATE_150:
speed = B150;
+ spd = 150;
break;
- case (BITRATE_300):
+ case BITRATE_300:
speed = B300;
+ spd = 300;
break;
- case (BITRATE_600):
+ case BITRATE_600:
speed = B600;
+ spd = 600;
break;
- case (BITRATE_1200):
+ case BITRATE_1200:
speed = B1200;
+ spd = 1200;
break;
- case (BITRATE_2400):
+ case BITRATE_2400:
speed = B2400;
+ spd = 2400;
break;
- case (BITRATE_4800):
+ case BITRATE_4800:
speed = B4800;
+ spd = 4800;
break;
- case (BITRATE_9600):
+ case BITRATE_9600:
speed = B9600;
+ spd = 9600;
break;
}
- debug (D_PORT, "com_set_line: going with cflag 0x%X iflag 0x%X speed %d.\n",
- tty.c_cflag, tty.c_iflag, speed);
+ debug(D_PORT,
+ "com_set_line: going with cflag 0x%X iflag 0x%X speed %d.\n",
+ cdsp->tty.c_cflag, cdsp->tty.c_iflag, speed);
+ div_lo = (115200 / spd) & 0x00ff;
+ div_hi = (115200 / spd) & 0xff00;
+ cdsp->div_latch[DIV_LATCH_LOW] = div_lo;
+ cdsp->div_latch[DIV_LATCH_HIGH] = div_hi;
errno = 0;
- ret_val = cfsetispeed(&tty, speed);
- debug (D_PORT, "com_set_line: cfsetispeed returned 0x%X.\n", ret_val);
+ ret_val = cfsetispeed(&cdsp->tty, speed);
+ debug(D_PORT, "com_set_line: cfsetispeed returned 0x%X.\n", ret_val);
errno = 0;
- ret_val = cfsetospeed(&tty, speed);
- debug (D_PORT, "com_set_line: cfsetospeed returned 0x%X.\n", ret_val);
+ ret_val = cfsetospeed(&cdsp->tty, speed);
+ debug(D_PORT, "com_set_line: cfsetospeed returned 0x%X.\n", ret_val);
errno = 0;
- ret_val = tcsetattr(cdsp->fd, 0, &tty);
- debug (D_PORT, "com_set_line: tcsetattr returned 0x%X.\n", ret_val);
-
+ ret_val = tcsetattr(cdsp->fd, 0, &cdsp->tty);
+ debug(D_PORT, "com_set_line: tcsetattr returned 0x%X (%s).\n",
+ ret_val, ret_val == -1 ? strerror(errno) : "");
errno = 0;
ret_val = fcntl(cdsp->fd, F_SETFL, O_NDELAY);
- debug (D_PORT, "fcntl of 0x%X, 0x%X to fd %d returned %d errno %d\n",
- F_SETFL, O_NDELAY, cdsp->fd, ret_val, errno);
+ debug(D_PORT, "fcntl of 0x%X, 0x%X to fd %d returned %d errno %d\n",
+ F_SETFL, O_NDELAY, cdsp->fd, ret_val, errno);
errno = 0;
ret_val = ioctl(cdsp->fd, TIOCFLUSH, &mode);
- debug (D_PORT, "ioctl of 0x%02x to fd %d on 0x%X returned %d errno %d\n",
- TIOCFLUSH, cdsp->fd, mode, ret_val, errno);
-#endif
+ debug(D_PORT, "ioctl of 0x%02lx to fd %d on 0x%X returned %d errno %d\n",
+ TIOCFLUSH, cdsp->fd, mode, ret_val, errno);
for (reg_num = 0; reg_num < N_OF_COM_REGS; reg_num++) {
- define_input_port_handler(cdsp->addr + reg_num,
- com_port_in);
- define_output_port_handler(cdsp->addr + reg_num,
- com_port_out);
+ define_input_port_handler(cdsp->addr + reg_num, com_port_in);
+ define_output_port_handler(cdsp->addr + reg_num, com_port_out);
}
- cdsp->com_queue = create_queue(cdsp->irq);
debug(D_PORT, "com%d: attached '%s' at addr 0x%04x irq %d\n",
- port, cdsp->path, cdsp->addr, cdsp->irq);
+ port, cdsp->path, cdsp->addr, cdsp->irq);
+
+ set_eoir(cdsp->irq, flush_out, cdsp);
+ _RegisterIO(cdsp->fd, com_async, cdsp, 0);
}
+static void
+try_set_speed(struct com_data_struct *cdsp)
+{
+ unsigned divisor, speed;
+ int ret_val;
+
+ divisor = (unsigned) cdsp->div_latch[DIV_LATCH_HIGH] << 8
+ | (unsigned) cdsp->div_latch[DIV_LATCH_LOW];
+
+ debug(D_PORT, "try_set_speed: divisor = %u\n", divisor);
+
+ if (divisor == 0)
+ return;
+
+ speed = 115200 / divisor;
+ if (speed == 0)
+ return;
+
+ errno = 0;
+ ret_val = cfsetispeed(&cdsp->tty, speed);
+ debug(D_PORT, "try_set_speed: cfsetispeed returned 0x%X.\n", ret_val);
+
+ errno = 0;
+ ret_val = cfsetospeed(&cdsp->tty, speed);
+ debug(D_PORT, "try_set_speed: cfsetospeed returned 0x%X.\n", ret_val);
+
+ errno = 0;
+ ret_val = tcsetattr(cdsp->fd, 0, &cdsp->tty);
+ debug(D_PORT, "try_set_speed: tcsetattr returned 0x%X (%s).\n", ret_val,
+ ret_val == -1 ? strerror (errno) : "");
+}
/* called when config.c initializes a single line */
void
@@ -279,16 +507,19 @@ init_com(int port, char *path, int addr, unsigned char irq)
{
struct com_data_struct *cdsp;
- debug (D_PORT, "init_com: port = 0x%04x, addr = 0x%04X, irq = %d.\n",
- port, addr, irq);
+ debug(D_PORT, "init_com: port = 0x%04x, addr = 0x%04X, irq = %d.\n",
+ port, addr, irq);
cdsp = &(com_data[port]);
cdsp->path = path; /* XXX DEBUG strcpy? */
cdsp->addr = addr;
cdsp->irq = irq;
cdsp->fd = -1;
com_set_line(cdsp, port + 1, TXLEN_8BITS | BITRATE_9600);
-}
+ /* update BIOS variables */
+ nserial++;
+ *(u_int16_t *)&BIOSDATA[0x00 + 2 * port] = (u_int16_t)addr;
+}
/* called when DOS wants to read directly from a physical port */
unsigned char
@@ -297,7 +528,7 @@ com_port_in(int port)
struct com_data_struct *cdsp;
unsigned char rs;
unsigned char i;
- int nbytes;
+ int r;
/* search for a valid COM ???or MOUSE??? port */
for (i = 0; i < N_COMS_MAX; i++) {
@@ -307,7 +538,7 @@ com_port_in(int port)
}
}
if (i == N_COMS_MAX) {
- debug (D_PORT, "com port 0x%04x not found\n", port);
+ debug(D_PORT, "com port 0x%04x not found\n", port);
return 0xff;
}
@@ -317,45 +548,24 @@ com_port_in(int port)
if (cdsp->line_ctrl & LC_DIV_ACC)
rs = cdsp->div_latch[DIV_LATCH_LOW];
else {
-#if 0
- if (queue_not_empty(cdsp->com_queue)) {
- rs = get_char_q(cdsp->com_queue);
- cdsp->last_char_read = rs;
- if (queue_not_empty(cdsp->com_queue) &&
- (cdsp->int_enable & IE_RCV_DATA) != 0) {
- debug(D_PORT,
- "com_port_in: setting irq %d because bytes yet to be read.\n",
- cdsp->irq);
- set_irq_request(cdsp->irq);
- }
- } else
-#else
- errno = 0;
- nbytes = read(cdsp->fd, &rs, 1);
- debug (D_PORT, "read of fd %d on '%s' returned %d byte 0x%02x errno %d\n",
- cdsp->fd, cdsp->path, nbytes, rs, errno);
- if (nbytes != 1)
-#endif
- rs = cdsp->last_char_read;
+ rs = 0x60;
+ r = read_char(cdsp);
+ if (r != -1)
+ rs = (unsigned char)r;
}
break;
/* 0x03F9 - (interrupt enable) or (divisor latch HI) */
- case 1:
+ case 1:
if (cdsp->line_ctrl & LC_DIV_ACC)
rs = cdsp->div_latch[DIV_LATCH_HIGH];
else
rs = cdsp->int_enable;
-
+ break;
+
/* 0x03FA - interrupt identification register */
case 2:
- /* rs = cdsp->int_id; * XXX DEBUG not initialized */
- rs = 0;
- if ((queue_not_empty(cdsp->com_queue))
- && (test_irq_request(cdsp->irq) != 0))
- rs |= II_PEND_INT | II_RCV_DATA;
- if ((cdsp->fifo_ctrl & FC_FIFO_EN) == FC_FIFO_EN)
- rs |= II_FIFOS_EN;
+ rs = get_int_id(cdsp);
break;
/* 0x03FB - line control register */
@@ -370,11 +580,7 @@ com_port_in(int port)
/* 0x03FD - line status register */
case 5:
- rs = LS_X_SHFT_E | LS_X_HOLD_E;
- /* if (queue_not_empty(cdsp->com_queue)) */
- ioctl(cdsp->fd, FIONREAD, &nbytes);
- if (nbytes > 0)
- rs |= LS_RCV_DATA_RD;
+ rs = get_status(cdsp);
break;
/* 0x03FE - modem status register */
@@ -395,13 +601,11 @@ com_port_in(int port)
return rs;
}
-
/* called when DOS wants to write directly to a physical port */
void
com_port_out(int port, unsigned char val)
{
struct com_data_struct *cdsp;
- int nbytes;
int i;
/* search for a valid COM ???or MOUSE??? port */
@@ -412,7 +616,7 @@ com_port_out(int port, unsigned char val)
}
}
if (i == N_COMS_MAX) {
- debug (D_PORT, "com port 0x%04x not found\n", port);
+ debug(D_PORT, "com port 0x%04x not found\n", port);
return;
}
@@ -421,17 +625,9 @@ com_port_out(int port, unsigned char val)
case 0:
if (cdsp->line_ctrl & LC_DIV_ACC) {
cdsp->div_latch[DIV_LATCH_LOW] = val;
- cdsp->flags |= DIV_LATCH_LOW_WRITTEN;
- write_div_latches(cdsp);
+ try_set_speed(cdsp);
} else {
- errno = 0;
- nbytes = write(cdsp->fd, &val, 1);
- debug (D_PORT, "write of 0x%02x to fd %d on '%s' returned %d errno %d\n",
- val, cdsp->fd, cdsp->path, nbytes, errno);
- if (nbytes != 1)
- debug(D_PORT,
- "int14: lost output character 0x%02x\n",
- val);
+ write_char(cdsp, val);
}
break;
@@ -439,23 +635,24 @@ com_port_out(int port, unsigned char val)
case 1:
if (cdsp->line_ctrl & LC_DIV_ACC) {
cdsp->div_latch[DIV_LATCH_HIGH] = val;
- cdsp->flags |= DIV_LATCH_HIGH_WRITTEN;
- write_div_latches(cdsp);
+ try_set_speed(cdsp);
} else {
cdsp->int_enable = val;
- if ((val & IE_RCV_DATA) == 0) {
- reset_irq_request(cdsp->irq);
- } else {
- if (queue_not_empty(cdsp->com_queue)) {
- set_irq_request(cdsp->irq);
- }
- }
+ new_ii(cdsp);
}
break;
/* 0x03FA - FIFO control register */
case 2:
- cdsp->fifo_ctrl = val;
+ cdsp->fifo_ctrl = val & (FC_FIFO_EN | FC_FIFO_SZ_MASK);
+ if (val & FC_FIFO_CRV)
+ cdsp->ids = 0;
+ if (val & FC_FIFO_CTR) {
+ cdsp->ods = 0;
+ cdsp->emptyint = 1;
+ }
+ input(cdsp, 1);
+ manage_int(cdsp);
break;
/* 0x03FB - line control register */
@@ -470,7 +667,7 @@ com_port_out(int port, unsigned char val)
/* 0x03FD - line status register */
case 5:
- cdsp->line_stat = val;
+ /* read-only */
break;
/* 0x03FE - modem status register */
@@ -489,38 +686,3 @@ com_port_out(int port, unsigned char val)
break;
}
}
-
-#if 0
-/*
- * called when BSD has bytes ready (as discovered via select) for DOS
- */
-static void do_com_input(int fd)
-{
- struct com_data_struct *cdsp;
- unsigned char buffer[BUFSIZE];
- int i, nbytes;
-
- dp = search_com_device_by_fd(fd);
- if (dp == NULL)
- return;
- do {
- nbytes = read(cdsp->fd, buffer, BUFSIZE);
- if (nbytes > 0) {
- debug(D_PORT, "do_com_input: read %d bytes from fd %d (aka %d): ",
- nbytes, fd, cdsp->fd);
- for (i = 0; i < nbytes; i++) {
- put_char_q(cdsp->com_queue, buffer[i]);
- if (cdsp->int_enable & IE_RCV_DATA) {
- debug(D_PORT, "\n");
- debug(D_PORT, "do_com_input: setting irq %d because %d bytes read.\n",
- dp->irq, nbytes);
- debug(D_PORT, "do_com_input: ");
- set_irq_request(dp->irq);
- }
- debug(D_PORT, "%02x ", buffer[i]);
- }
- debug(D_PORT, "\n");
- }
- } while (nbytes == BUFSIZE);
-}
-#endif 0