?? comm.c
字號:
// ****************************************************************************
//
// File Name: comm.c
//
// Description: Handheld program serial communication routines.
//
// ORIGINATOR: Mark C. Lampkin. Lampkin Software Works, (C)1994.
// 386 Merriweather
// Grosse Pointe Farms, MI. 48236
// (313) 884-8759
// Version 1.2A
//
// HISTORY
// who when what
// -------- --------- ----------------------------------------------------
// Geof 09-10-97 Took over. Added more baud rate settings and modem
// control register settings.
// Geof 04-06-98 Moved om_buf_clr(), com_rec_buf(), and SendStream()
// from hms800.c to this file.
// Geof 11-18-98 Dump debug information to a file, like ABx Fast and ASCII.
//
// ****************************************************************************
#include <dos.h>
#include <ctype.h>
#include <conio.h>
#include <bios.h>
#include <io.h>
#include <string.h>
#include <stdlib.h>
#include <graphics.h>
#include <time.h>
#include "typedef.h"
#include "handheld.h" // For device type.
#include "comm.h"
#if PRINT_CMDS
#include <stdio.h>
#endif
#define CBS 16384 /* RS-232 input buffer size (a guess) */
#define COM1 1 /* port number parameters for comm_open() */
#define COM2 2
#define MDMDAT1 0x03F8 /* Address of modem port 1 data */
#define MDMSTS1 0x03FD /* Address of modem port 1 status */
#define MDMCOM1 0x03FB /* Address of modem port 1 command */
#define MDMDAT2 0x02F8 /* Address of modem port 2 data */
#define MDMSTS2 0x02FD /* Address of modem port 2 status */
#define MDMCOM2 0x02FB /* Address of modem port 2 command */
#define MDMINTV 0x000C /* Com 1 interrupt vector */
#define MDINTV2 0x000B /* Com 2 interrupt vector */
#define MDMINTO 0x0EF /* Mask to enable IRQ3 for port 1 */
#define MDMINTC 0x010 /* Mask to Disable IRQ4 for port 1 */
#define MDINTC2 0x008 /* Mask to Disable IRQ3 for port 2 */
#define MDINTO2 0x0F7 /* Mask to enable IRQ4 for port 2 */
#define INTCONT 0x0021 /* 8259 interrupt controller ICW2-3 */
#define INTCON1 0x0020 /* Address of 8259 ICW1 */
#if TEST_MUX32
BYTE now_mux_addr = MUX_ADDR; // If using MUX32 then this is the MUX32 address.
#endif
#if PRINT_CMDS
static BYTE prt_fname[] = "debug.txt"; // Dump debug information.
static FILE *debug_file; // Point to debug file information, from the open.
#endif
static void interrupt (far *oldvec)();
static uint intv; /* interrupt number to usurp */
static int
dat8250, /* 8250 data register */
stat8250, /* 8250 line-status register */
com8250, /* 8250 line-control register */
c_in_buf = 0, /* count of characters received */
xoffpt, /* amount of buffer that forces XOFF */
xonpt, /* amount of buffer that unXOFFs */
xonxoff = FALSE, /* auto xon/xoff support flag */
xofsnt = FALSE; /* XOFF transmitted flag */
//xofrcv = 0; /* XOFF received flag */
static char
en8259, /* 8259 IRQ enable mask */
dis8259, /* 8259 IRQ disable mask */
buffer[CBS], /* Communications circular buffer */
*inptr = buffer, /* input address of circular buffer */
*outptr = buffer; /* output address of circular buffer */
work_buffer[256]; /* program 'in process' buffer */
*pointer = work_buffer; /* address of working buffer */
/* Function Prototypes */
static void dobaud(long unsigned int);
/* Functions */
void reset();
void start();
void stop();
// ****************************************************************************
// Serial interrupt routine, to actual receive data from the COM port.
//
// Input: NONE.
// Return: NONE.
// Side effects: Receive buffer and pointer are updated.
void interrupt serint(void)
{
*inptr++ = inportb(dat8250); /* Store character in buffer */
c_in_buf++; /* and increment count */
if (xonxoff) { /* if xon/xoff auto-support is on */
if ((c_in_buf > xoffpt) && !xofsnt) {
/* buffer nearly full */
comm_putc(XOFF); /* send an XOFF */
xofsnt = TRUE; /* and say so */
}
}
disable(); /* ints off for ptr change */
if (inptr == &buffer[CBS]) /* wrap buffer input pointer if end */
inptr = buffer;
enable();
outportb(0x20, 0x20); /* Generic EOI to 8259 */
}
/* installs comm interrupts */
// ****************************************************************************
// Set the UART's control register selection. What UART is open for this
// COM port? Setup to access it.
//
// Input: Port number.
// Return: BOOLEAN - TRUE of valid port number.
// - FALSE if not valid port number.
// Side effects: Global variables are setup for this COM port.
static unsigned char what_port(int port_number)
{
uint be = biosequip(); /* to get # installed serial ports */
be <<= 4; /* shift-wrap high bits off */
be >>= 13; /* shift down to low bits */
if (be >= port_number)
{
if (port_number == 1)
{
dat8250 = MDMDAT1;
stat8250 = MDMSTS1;
com8250 = MDMCOM1;
dis8259 = MDMINTC;
en8259 = MDMINTO;
intv = MDMINTV;
} else if (port_number == 2)
{
dat8250 = MDMDAT2;
stat8250 = MDMSTS2;
com8250 = MDMCOM2;
dis8259 = MDINTC2;
en8259 = MDINTO2;
intv = MDINTV2;
}
} else
return(FALSE);
return(TRUE);
}
// ****************************************************************************
// configure this PC's COM port to a new baud rate.
//
// Input: New baud rate value.
// Return: NONE.
// Side effects: NONE.
static void dobaud(long unsigned int baudrate)
{
uchar portval, blo, bhi;
switch (baudrate) { /* Baud rate LSB's and MSB's */
case 50: bhi = 0x9; blo = 0x00; break;
case 75: bhi = 0x6; blo = 0x00; break;
case 110: bhi = 0x4; blo = 0x17; break;
case 150: bhi = 0x3; blo = 0x00; break;
case 300: bhi = 0x1; blo = 0x80; break;
case 600: bhi = 0x0; blo = 0xC0; break;
case 1200: bhi = 0x0; blo = 0x60; break;
case 1800: bhi = 0x0; blo = 0x40; break;
case 2000: bhi = 0x0; blo = 0x3A; break;
case 2400: bhi = 0x0; blo = 0x30; break;
case 4800: bhi = 0x0; blo = 0x18; break;
case 9600: bhi = 0x0; blo = 0x0C; break;
case 19200: bhi = 0x0; blo = 0x06; break;
case 38400: bhi = 0x0; blo = 0x03; break;
case 57600: bhi = 0x0; blo = 0x02; break;
case 115200: bhi = 0x0; blo = 0x01; break;
default:
return;
}
portval = inportb(com8250); /* read Line-Control Reg val */
outportb(com8250, portval | 0x80); /* set high bit for baud init */
outportb(dat8250, blo); /* Send LSB for baud rate */
outportb(dat8250+1, bhi); /* Send MSB for baud rate */
outportb(com8250, portval); /* Reset initial value at LCR */
}
// ****************************************************************************
// data read (dread), read data from the circular buffer
//
// Input: Pointer to buffer to fill.
// Number of BYTEs wonted.
// Number of seconds to wait for the desired BYTEs.
// Return: NONE.
// Side effects: NONE.
static int dread(BYTE *buffer, WORD wanted, WORD seconds)
{
register int i;
long start;
int pending, elapsed;
start = time((long *)NULL);
for (;;)
{
pending = comm_avail();
if (pending >= wanted) // got enough in the buffer?
{
#if PRINT_CMDS
fprintf(debug_file, "Received: ");
#endif
for (i = 0; i < wanted; i++)
#if PRINT_CMDS
fprintf(debug_file, "%02x ", *buffer++ = comm_getc());
fprintf(debug_file, "\n");
#else
*buffer++ = comm_getc();
#endif
return TRUE;
} else
{
elapsed = time((long *)NULL) - start;
if (elapsed >= seconds)
return FALSE;
}
}
}
#if FALSE
// ****************************************************************************
// Put a srting out the COM port.
//
// Input: String pointer.
// Return: NONE.
// Side effects: NONE.
static void comm_puts(BYTE *s_message)
{
uchar x;
while(*s_message > 0)
{
x = *s_message++;
comm_putc(x);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -