home *** CD-ROM | disk | FTP | other *** search
- /* 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
- }
-