home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 9
/
MEDIASHARE_09.ISO
/
progmisc
/
djasy10d.zip
/
ASYNC.C
next >
Wrap
C/C++ Source or Header
|
1992-09-11
|
3KB
|
177 lines
/* async.c -- dj's async interface, modified for two ports and
pointer-bashing protection by j. alan eldridge 09/04/92
*/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include "djasync.h"
#define SIGNATURE 0x4154
#define VERSION 1
#define OFFSET 0x104
#ifdef __GNUC__
#define far
#define peek(a,b) (*(unsigned short *)(0xe0000000 + (a)*16 + (b)))
#define disable() asm("cli")
#define enable() asm("sti")
#endif
#ifdef __TURBOC__
#include <conio.h>
#endif
#define NO_INTR 1
#define RDY_CNT 1
typedef struct {
short jmp_op;
short signature;
short version;
short buffer_start;
short buffer_end;
short getp;
short putp;
short iov;
short count;
short overflow;
short buffer_size;
short ovflushes;
} ASYNC_STRUCT;
static ASYNC_STRUCT far *async[2];
static int iov[2];
#define com_rb(n) iov[n]
#define com_tb(n) iov[n]
#define com_ier(n) iov[n]+1
#define com_ifr(n) iov[n]+2
#define com_bfr(n) iov[n]+3
#define com_mcr(n) iov[n]+4
#define com_lsr(n) iov[n]+5
#define com_msr(n) iov[n]+6
static char far *aptr(int port, short p)
{
#ifdef __GNUC__
return (char *)((unsigned)async[port] - OFFSET + p);
#else
return (char far *)MK_FP(FP_SEG(async[port]), p);
#endif
}
static ASYNC_STRUCT far *getivec(int which)
{
ASYNC_STRUCT far *a;
if (peek(0, which*4) != OFFSET)
return 0;
#ifdef __GNUC__
a = (ASYNC_STRUCT *)(0xe0000000 + peek(0, which*4+2)*16 + peek(0, which*4));
#else
a = (ASYNC_STRUCT far *)MK_FP(peek(0,which*4+2),peek(0,which*4));
#endif
if (a->signature != SIGNATURE)
return 0;
if (a->version != VERSION)
return 0;
return a;
}
int async_init(int port)
{
async[port] = getivec(12-port);
if (!async[port])
{
fprintf(stderr, "No async driver.\n");
return 0;
}
iov[port] = async[port]->iov;
outportb(com_ier(port), 0x0f);
outportb(com_bfr(port), 0x03);
outportb(com_mcr(port), 0x0b);
return 1;
}
int async_cnt(int port)
{
return async[port]->count;
}
void async_flush(int port)
{
disable();
async[port]->count = async[port]->overflow = 0;
async[port]->getp = async[port]->putp = async[port]->buffer_start;
enable();
}
int async_overflow(int port)
{
int ret;
disable();
ret = async[port]->overflow;
async[port]->overflow = 0;
enable();
return ret;
}
int async_tx(int port, char c)
{
while (~inportb(com_lsr(port)) & 0x20);
outportb(com_tb(port), c);
return 0;
}
int async_ready(int port)
{
int ret;
disable();
#if RDY_CNT
ret = async[port]->count;
#else
ret = (async[port]->getp != async[port]->putp);
#endif
enable();
return ret;
}
int async_rx(int port)
{
char rv;
while (!async_ready(port))
/* spin wheels */;
disable();
rv = *aptr(port, async[port]->getp++);
async[port]->count--;
if (async[port]->getp >= async[port]->buffer_end)
async[port]->getp = async[port]->buffer_start;
enable();
return rv;
}
int kb_ready()
{
return (peek(0x40,0x1a) != peek(0x40,0x1c));
}
int kb_rx()
{
#ifdef __GNUC__
return getkey();
#else
return getch();
#endif
}