PROGRAM 1
/****************************************************************************/
/* program: myuart.c */
/* author: anthony f. ortiz */
/* class: cs3590 */
/* date: january 28, 1999 */
/* description: serial chat program */
/****************************************************************************/
#include
#include
#include "uart.h"
void main ()
{
int port = 1;
int return_value;
int key_hit;
byte_t mode = BAUD9600 | PARITY_NONE | STOP1 | WORD_8BIT;
char ch;
clrscr ();
printf ("computer 1, ready:\n\n");
/* initialize the uart. */
return_value = com_open (port, mode);
do
{
/* receive a byte from the port. */
return_value = com_in (port, &mode);
/* check for a current keystroke. */
key_hit = kbhit ();
/* if there is a new value in the uart register and
a key hasn't been hit, print value in uart register
to the screen else if a key has been hit, read character
from the keyboard and send it over the serial port. */
if (return_value >= 0 && key_hit == 0)
{
printf ("%c", mode);
}
else if (key_hit != 0)
{
ch = getch ();
mode = ch;
return_value = com_out (port, mode);
}
}
while (ch != 27);
/* close uart. */
return_value = com_close (port);
}
/* i didn't write uart.h or uart.c. */
/* -------------------------------------------- *
* uart.h *
* *
* cfh 1/7/94 *
* -------------------------------------------- */
/*
* modes for com port initialization
* mode is a bitwise or of a baud, parity, stop bit and word length
*/
/* baud rates */
#define BAUD110 (00<<5)
#define BAUD150 (01<<5)
#define BAUD300 (02<<5)
#define BAUD600 (03<<5)
#define BAUD1200 (04<<5)
#define BAUD2400 (05<<5)
#define BAUD4800 (06<<5)
#define BAUD9600 (07<<5)
/* parity */
#define PARITY_NONE (00<<3)
#define PARITY_ODD (01<<3)
#define PARITY_NONE2 (02<<3)
#define PARITY_EVEN (03<<3)
/* stop bit */
#define STOP0 (00<<2)
#define STOP1 (01<<2)
/* word length */
#define WORD_7BIT (02)
#define WORD_8BIT (03)
/* maximum port no. */
#define PORT_MAX 4
typedef unsigned char byte_t;
/* error code */
#define ERS_OK 0 /* no error */
#define ERS_TIMEOUT 1 /* timeout in i/o */
#define ERS_PORT 2 /* invaid port */
/*
* these functions return 0 if no error, -1 if error.
*/
int com_open (int port, byte_t mode); /* open com port. */
int com_close (int port); /* close a port. */
int com_in (int port, byte_t *c); /* get a byte. */
int com_out (int port, byte_t c); /* send a byte. */
int com_stat (int port, int *status); /* get the current status. */
/* -------------------------------------------- *
* uart.c *
* *
* cfh 1/7/94 *
* -------------------------------------------- */
#include "uart.h"
#define UART_VAR_SEG 40h
#define UART_RBR_OFFSET 0
#define UART_THR_OFFSET 0
#define UART_MCR_OFFSET 4
#define UART_LSR_OFFSET 5
#define UART_MSR_OFFSET 6
/* uart line commands */
#define CMD_DTR 0x1
#define CMD_RTS 0x2
#define PORT_CHECK(port) { \
if (port > 4 || port < 1) { \
ers_errno = ERS_PORT; \
return -1; \
} \
port--; /* we count from 0. */ \
}
int ers_errno;
int
com_open (int port, byte_t mode)
{
byte_t cmd;
int rc;
PORT_CHECK(port);
cmd = CMD_RTS|CMD_DTR;
asm {
push ds;
push dx;
push si;
push ax;
mov dx, port;
mov si, dx;
add si, si;
mov dx, UART_VAR_SEG;
mov ds, dx;
mov dx, [si];
add dx, UART_MCR_OFFSET;
mov al, cmd;
out dx, al;
pop ax;
pop si;
pop dx;
pop ds;
}
ers_errno = ERS_OK;
return 0;
}
int
com_close (int port)
{
byte_t cmd;
PORT_CHECK(port);
cmd = CMD_RTS;
asm {
push ds;
push dx;
push si;
push ax;
mov dx, port;
mov si, dx
add si, si;
mov dx, UART_VAR_SEG;
mov ds, dx;
mov dx, [si];
add dx, UART_MCR_OFFSET;
mov al, cmd;
out dx, al;
pop ax;
pop si;
pop dx;
pop ds;
}
ers_errno = ERS_OK;
return 0;
}
int
com_in (int port, byte_t *c)
{
int rc = -1;
PORT_CHECK(port);
asm {
push ds;
push dx;
push si;
push ax;
mov dx, port;
mov si, dx
add si, si;
mov dx, UART_VAR_SEG;
mov ds, dx;
mov dx, [si];
add dx, UART_LSR_OFFSET;
in al, dx; /* get the line status. */
test al, 1;
jz com_in_exit; /* no input. */
mov dx, [si];
in al, dx;
mov ah, 0;
mov rc, ax;
}
com_in_exit:
asm {
pop ax;
pop si;
pop dx;
pop ds;
}
if (rc < 0) {
ers_errno = ERS_TIMEOUT;
return -1;
}
*c = (byte_t) rc;
ers_errno = ERS_OK;
return 0;
}
int
com_out (int port, byte_t c)
{
int rc;
PORT_CHECK(port);
asm {
push ds;
push dx;
push si;
push ax;
mov dx, port;
mov si, dx
add si, si;
mov dx, UART_VAR_SEG;
mov ds, dx;
mov dx, [si];
add dx, UART_LSR_OFFSET;
}
com_out_loop:
asm {
in al, dx; /* get the line status. */
test al, 20h; /* is the buffer empty? */
jz com_out_loop;
mov dx, [si];
mov al, c;
out dx, al;
pop ax;
pop si;
pop dx;
pop ds;
}
ers_errno = ERS_OK;
return 0;
}
int
com_stat (int port, int *status)
{
int rc;
PORT_CHECK(port);
asm {
push ds;
push dx;
push si;
push ax;
mov dx, port;
mov si, dx
add si, si;
mov dx, UART_VAR_SEG;
mov ds, dx;
mov dx, [si];
add dx, UART_LSR_OFFSET;
in al, dx; /* get the line status. */
mov ah, al;
inc dx;
in al, dx; /* get the modem status. */
mov rc, ax;
pop ax;
pop si;
pop dx;
pop ds;
}
*status = rc;
ers_errno = ERS_OK;
return 0;
}
/* outfile: prog1.out */
/* after typing "hi, computer 2." on computer 1, computer 2 shows. */
computer 1, ready:
hi, computer 2.
/* after typing "hi, computer 1. " on computer 2, computer 1 shows. */
computer 2, ready:
hi, computer 1.
BACK TO CS3590 PAGE.