/*
──────────────────────────────────────────────────────────────────────────────
ZyXEL communication port driver layer 1 function
──────────────────────────────────────────────────────────────────────────────
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include "typedef.h"
#include "zyascii.h"
#include "zyl1.h"
#include "zyvar1.h"
/*
────────────────────────────────────────────────────────────────────────────
int zyiopen(nComId, lSpeed, nParity, nStopBits, nWordLen)
int nComId; // the Communication port ID
long lSpeed; // the BaudRate of Comm port
int nParity; // the Parity format of Comm port
int nStopBits; // the StopBit length of Comm Port
int nWordLen; // the Data bits length of Comm Port
function:
Open a communication port and initialize the comm port
parameters:
nComId
the comm port number : COM1, COM2, COM3, COM4 ...
lSpeed
indicates the communicate baud rate.
nParity
to determine the parity bit
value Meaning
────────────────────────────────────────────────────────────
'N' none parity
────────────────────────────────────────────────────────────
'O' odd parity
────────────────────────────────────────────────────────────
'E' even parity
────────────────────────────────────────────────────────────
nStopBits
Stop bit for communications - 1 bit or 2 bits.
nWordLen
Word length for communications - 5, 6, 7, 8 bits.
return code:
return code >= 0 - the communication port number
return code <0 - the error code
────────────────────────────────────────────────────────────────────────────
*/
int FAR zyiopen(int nComId,
long lBaudRate, int nParity,
int nStopBits, int nWordLen)
{
/* local variable */
union REGS ireg, oreg;
ireg.x.dx = nComId;
ireg.x.bx = 0;
ireg.h.ah = 0x04;
int86(0x14, &ireg, &oreg);
if (oreg.x.ax != 0x1954)
return (IDR_INUSE);
/* setup comm port link option */
if (0 != zyiinit(nComId, lBaudRate, nParity, nStopBits, nWordLen))
{
zyiquit(nComId);
return(-1);
}
/* setup DTR */
zydtr(nComId, 1);
/* setup flow control */
zyiflow(nComId, ON);
return (nComId);
}
/*
────────────────────────────────────────────────────────────────────────────
int zyiinit(nComId, lSpeed, nParity, nStopBits, nWordLen)
int nComId; // the Communication port ID
long lSpeed; // the BaudRate of Comm port
int nParity; // the Parity format of Comm port
int nStopBits; // the StopBit length of Comm Port
int nWordLen; // the Data bits length of Comm Port
function:
Open a communication port and initialize the comm port
parameters:
nComId
the comm port number : COM1, COM2, COM3, COM4 ...
lSpeed
indicates the communicate baud rate.
nParity
to determine the parity bit
value Meaning
────────────────────────────────────────────────────────────
'N' none parity
────────────────────────────────────────────────────────────
'O' odd parity
────────────────────────────────────────────────────────────
'E' even parity
────────────────────────────────────────────────────────────
nStopBits
Stop bit for communications - 1 bit or 2 bits.
nWordLen
Word length for communications - 5, 6, 7, 8 bits.
return code:
return code >= 0 - the communication port initialize success
return code <0 - the error code
────────────────────────────────────────────────────────────────────────────
*/
int FAR zyiinit(int nComId, long lBaudRate,
int nParity, int nStopBits, int nWordLen)
{
union REGS ireg, oreg;
int nDataLen;
int nStopLen;
int nPbits;
int nBaud;
switch ( nStopBits)
{
case 1:
nStopLen = STOP1;
break;
case 2:
nStopLen = STOP2;
break;
default:
return (IDR_ILLEGALSTOPBITS);
}
switch ( nWordLen)
{
case 8:
nDataLen = DATA8;
break;
case 7:
nDataLen = DATA7;
break;
case 6:
nDataLen = DATA6;
break;
case 5:
nDataLen = DATA5;
break;
default:
return (IDR_ILLEGALWORDLENGTH);
}
switch (nParity)
{
case 'N':
case 'n':
nPbits = NOPAR;
break;
case 'O':
case 'o':
nPbits = ODDPAR;
break;
case 'E':
case 'e':
nPbits = EVENPAR;
break;
default:
return (IDR_ILLEGALPARITY);
}
switch((UINT)lBaudRate)
{
case 300L:
nBaud = BAUD300;
break;
case 600L:
nBaud = BAUD600;
break;
case 1200L:
nBaud = BAUD1200;
break;
case 2400L:
nBaud = BAUD2400;
break;
case 4800L:
nBaud = BAUD4800;
break;
case 9600L:
nBaud = BAUD9600;
break;
case 19200L:
nBaud = BAUD19200;
break;
case 38400L:
nBaud = BAUD38400;
break;
case 57600L:
nBaud = BAUD57K;
break;
case 115200L:
nBaud = BAUD115K;
break;
default:
return(IDR_ILLEGALBAUDRATE);
}
/*
─────────────────────────────────────────────────────────
use FOSSIL 00h function init comm port parameters
─────────────────────────────────────────────────────────
*/
ireg.x.dx = nComId;
ireg.h.al = (char)(nBaud | nPbits | nStopLen | nDataLen);
ireg.h.ah = 0x0;
int86(0x14, &ireg, &oreg);
return(IDR_SUCCESS);
}
/*
──────────────────────────────────────────────────────────────────────────
int zyiquit (nComId)
int nComId; // the communication port ID.
function:
Close a communication port and initialize the comm port
parameters:
nComId
the comm port number : COM1, COM2, COM3, COM4 ...
return code:
return code >= 0 - the close communication port success
return code <0 - the error code
────────────────────────────────────────────────────────────────────────────
*/
int FAR zyiquit(int nComId)
{
union REGS ireg, oreg;
/*
────────────────────────────────────
use FOSSIL 05h function close FOSSIL
────────────────────────────────────
*/
ireg.x.dx = nComId;
ireg.h.ah = 0x05;
int86(0x14, &ireg, &oreg);
return (IDR_SUCCESS);
}
/*
──────────────────────────────────────────────────────────────────────────
int zyiqutc (nComId, nCh)
int nComId; // the communication port ID.
int nCh; // the output data.
function:
send a character to the comm port without wait buffer empty.
parameters:
nComId
the comm port number : COM1, COM2, COM3, COM4 ...
nCh
the data want to be sent out
return code:
return code >= 0 - success
return code <0 - the error code
────────────────────────────────────────────────────────────────────────────
*/
int FAR zyiputc(int nComId, int nCh)
{
union REGS ireg, oreg;
/*
────────────────────────────────────
use FOSSIL 0Bh function
────────────────────────────────────
*/
ireg.h.al = (char) nCh;
ireg.h.ah = 0x0B;
ireg.x.dx = nComId;
int86(0x14, &ireg, &oreg);
if (oreg.x.ax == 0x01)
return (nCh);
return (IDR_GENERALERROR);
}
/*
──────────────────────────────────────────────────────────────────────────
int zyiputcabs (nComId, int nCh)
int nComId; // the communication port ID.
int nCh; // the output data
function:
send a character to comm port with waiting buffer empty
parameters:
nComId
the comm port number : COM1, COM2, COM3, COM4 ...
nCh
the data want to be sent out
return code:
return code = 0 - success
return code <0 - the error code
────────────────────────────────────────────────────────────────────────────
*/
int FAR zyiputcabs(int nComId, int nCh)
{
union REGS ireg, oreg;
/*
────────────────────────────────────
use FOSSIL 0Bh function
────────────────────────────────────
*/
ireg.h.al = (char) nCh;
ireg.h.ah = 0x01;
ireg.x.dx = nComId;
int86(0x14, &ireg, &oreg);
return (IDR_SUCCESS);
}
/*
──────────────────────────────────────────────────────────────────────────
int zyigetc (nComId)
int nComId; // the communication port ID.
function:
receive a character from comm port with waiting
parameters:
nComId
the comm port number : COM1, COM2, COM3, COM4 ...
return code:
return code - the char read from receive buffer
────────────────────────────────────────────────────────────────────────────
*/
int FAR zyigetc(int nComId)
{
union REGS ireg, oreg;
/*
────────────────────────────────────
use FOSSIL 02h function
────────────────────────────────────
*/
ireg.h.ah = 0x02;
ireg.x.dx = nComId;
int86(0x14, &ireg, &oreg);
return (oreg.x.ax);
}
/*
──────────────────────────────────────────────────────────────────────────
int zydtr (nComId, nControl)
int nComId; // the communication port ID.
int nControl; // the option selecting flag.
function:
receive a character from comm port with waiting
parameters:
nComId
the comm port number : COM1, COM2, COM3, COM4 ...
nControl
the set or reset control flag
ON - set dtr signal
OFF - reset dtr signal
return code:
return code = 0 success
────────────────────────────────────────────────────────────────────────────
*/
int FAR zydtr(int nComId, int nControl)
{
union REGS ireg, oreg;
/*
────────────────────────────────────
use FOSSIL 06h function
────────────────────────────────────
*/
ireg.h.ah = 0x06;
ireg.h.al = (char) nControl;
ireg.x.dx = nComId;
int86(0x14, &ireg, &oreg);
return (IDR_SUCCESS);
}
/*
──────────────────────────────────────────────────────────────────────────
int zyiclear (nComId, nFlag)
int nComId; // the communication port ID.
int nFlag; // the option selecting flag.
function:
clear the buffer
parameters:
nComId
the comm port number : COM1, COM2, COM3, COM4 ...
nFlag
the set or reset control flag
ASOUT - clear the tx buffer
ASIN - clear the rx buffer
ASINOUT - clear the tx and rx buffer
return code:
return code = 0 success
────────────────────────────────────────────────────────────────────────────
*/
int FAR zyiclear(int nComId, int nFlag)
{
union REGS ireg, oreg;
/*
────────────────────────────────────
use FOSSIL 09h and 0ah function
────────────────────────────────────
*/
switch(nFlag)
{
case ASINOUT:
case ASOUT:
ireg.h.ah = 0x09; /* clear tx_buffer */
ireg.x.dx = nComId;
int86(0x14, &ireg, &oreg);
if (nFlag == ASOUT) break;
case ASIN:
ireg.h.ah = 0x0A; /* clear rx_buffer */
ireg.x.dx = nComId;
int86(0x14, &ireg, &oreg);
break;
}
return (IDR_SUCCESS);
}
/*
──────────────────────────────────────────────────────────────────────────
int zyiclear (nComId)
int nComId; // the communication port ID.
function:
peek the rx buffer and detect the rx buffer has any data in it.
and the data is valid, the function will return the data.
if the rx buffer is empty the function will return IDR_BUFREMPTY
parameters:
nComId
the comm port number : COM1, COM2, COM3, COM4 ...
return code:
return code = 0 success
────────────────────────────────────────────────────────────────────────────
*/
int FAR zyipeek(int nComId)
{
union REGS ireg, oreg;
/*
────────────────────────────────────
use FOSSIL 0Ch function
────────────────────────────────────
*/
ireg.h.ah = 0x0C;
ireg.x.dx = nComId;
int86(0x14, &ireg, &oreg);
if (oreg.x.ax == 0xFFFF)
return (IDR_BUFREMPTY);
return (oreg.x.ax);
}
/*
──────────────────────────────────────────────────────────────────────────
int zyiflow (nComId, nFlag)
int nComId; // the communication port ID.
int nFlag; // the control flag.
function:
set or reset the hardware flow control.
parameters:
nComId
the comm port number : COM1, COM2, COM3, COM4 ...
nFlag
to determine the the hardware flow control ON or OFF
ON: set hardware flow control
OFF: reset hardware flow control
return code:
return code = 0 success
────────────────────────────────────────────────────────────────────────────
*/
int FAR zyiflow(int nComId, int nFlag)
{
union REGS ireg, oreg;
/*
────────────────────────────────────
use FOSSIL 0Fh function
────────────────────────────────────
*/
ireg.h.ah = 0x0F;
ireg.x.dx = nComId;
if (nFlag == ON)
ireg.h.al = 0xF2;
else
ireg.h.al = 0xF0;
int86(0x14, &ireg, &oreg);
return (IDR_SUCCESS);
}
/*
──────────────────────────────────────────────────────────────────────────
int zyiusexonxoff (nComId, nMask)
int nComId; // the communication port ID.
int nMask; // the control flag.
function:
set or reset the XON XOFF flow control.
parameters:
nComId
the comm port number : COM1, COM2, COM3, COM4 ...
nMask
to determine the the XON XOFF flow control
ASIN: set XON XOFF flow control in rx buffer
ASOUT: set XON XOFF flow control in tx buffer
ASINOUT: set XON XOFF flow control in rx and tx buffer
ASNOFL: reset the flow control in rx and tx buffer
return code:
return code = 0 success
────────────────────────────────────────────────────────────────────────────
*/
int FAR zyiusexonxoff(int nComId, int nMask)
{
union REGS ireg, oreg;
/*
────────────────────────────────────
use FOSSIL 0Fh function
────────────────────────────────────
*/
ireg.h.ah = 0x0F;
ireg.x.dx = nComId;
ireg.h.al = (char)nMask;
int86(0x14, &ireg, &oreg);
return (IDR_SUCCESS);
}
/*
──────────────────────────────────────────────
Ctrl-Break Interrupt survice routine variable
and const define
──────────────────────────────────────────────
*/
#define BreakVector 0x1B
static void interrupt (* oldBreakISR)(void);
static BOOL breakInstalled = FALSE;
static BOOL breakFlag;
/*
──────────────────────────────────────────────────────────────────────────
void breakISR (void)
function:
the Ctrl-Break interrupt survice routine to detect the Ctrl-Break
is pressed
parameters:
NONE
return code:
no return code
────────────────────────────────────────────────────────────────────────────
*/
void interrupt FAR breakISR (void)
{
breakFlag = ON;
}
/*
──────────────────────────────────────────────────────────────────────────
void breakInstall (void)
function:
To install the breakISR
parameters:
NONE
return code:
no return code
────────────────────────────────────────────────────────────────────────────
*/
void FAR breakInstall(void)
{
if (breakInstalled)
return;
breakFlag = OFF;
oldBreakISR = getvect(BreakVector);
setvect( BreakVector, breakISR);
breakInstalled = TRUE;
}
/*
──────────────────────────────────────────────────────────────────────────
void breakInstall (void)
function:
To release the breakISR
parameters:
NONE
return code:
no return code
────────────────────────────────────────────────────────────────────────────
*/
void FAR breakUnInstall (void)
{
if (!breakInstalled)
return;
setvect(BreakVector, oldBreakISR);
breakInstalled = FALSE;
}
/*
──────────────────────────────────────────────────────────────────────────
BOOL breakPressed (void)
function:
To determine the Ctrl-Break is pressed
parameters:
NONE
return code:
TRUE: Ctrl-Break was pressed
FALSE: Ctrl-Break was not pressed
────────────────────────────────────────────────────────────────────────────
*/
BOOL FAR breakPressed (void)
{
BOOL flag;
flag = breakFlag;
breakFlag = OFF;
return (flag);
}
/*
──────────────────────────────────────────────────────────────────────────
void breakReset (void)
function:
reset the breakFlag
parameters:
NONE
return code:
NONE
────────────────────────────────────────────────────────────────────────────
*/
void breakReset (void)
{
breakFlag = OFF;
}