www.pudn.com > pccp047.zip > PORT.C
/* Copyright (C) 1992 Peter Edward Cann, all rights reserved */ #include#include #include #include"port.h" int index, basereg; unsigned char diffintmask, irqnum; void (interrupt far *oldvect)(); unsigned char buf[TBUFSIZ]; void interrupt far inthndl(_es, _ds, _di, _si, _bp, _sp, _bx, _dx, _cx, _ax, _ip, _cs, _flags) unsigned _es, _ds, _di, _si, _bp, _sp; unsigned _bx, _dx, _cx, _ax, _ip, _cs, _flags; { if(inp(basereg+STATREG)&0x01) { buf[index++]=inp(basereg)&0xff; index=index%TBUFSIZ; } outp(INTBASE1, INTACK); outp(INTBASE2, INTACK); } unsigned char lctl; unsigned int speed, comnum; char databits, parity, stopbits; unsigned char newintmask, oldintmask, lctl, dlmsb, dllsb; unsigned intnum; unsigned char oldlctl, olddllsb, olddlmsb, oldintctl, oldmctl; setport() { newintmask=0; switch(comnum) { case 0: irqnum=4; diffintmask=0xff&~0x10; basereg=0x3f8; break; case 1: irqnum=3; diffintmask=0xff&~0x08; basereg=0x2f8; break; case 2: irqnum=4; diffintmask=0xff&~0x10; basereg=0x3e8; break; case 3: irqnum=3; diffintmask=0xff&~0x08; basereg=0x2e8; break; case 4: irqnum=2; diffintmask=0xff&~0x02; basereg=0x3e8; break; case 5: irqnum=2; diffintmask=0xff&~0x02; basereg=0x2e8; break; case 6: irqnum=5; diffintmask=0xff&~0x20; basereg=0x3e8; break; case 7: irqnum=5; diffintmask=0xff&~0x20; basereg=0x2e8; break; default: printf("Bad port choice.\n"); exit(4); } intnum=irqnum+8; switch(speed) { case 300: dlmsb=0; dllsb=0xc0; break; case 1200: dlmsb=0; dllsb=0x60; break; case 2400: dlmsb=0; dllsb=0x30; break; case 9600: dlmsb=0; dllsb=0x0c; break; case 19200: dlmsb=0; dllsb=0x06; break; case 38400: dlmsb=0; dllsb=0x03; break; case 57600: dlmsb=0; dllsb=0x02; break; default: printf("Bad speed %d.\n", speed); exit(5); } lctl=0; switch(parity) { case 'e': case 'E': lctl |= PARITYEN | PARITYEVEN; break; case 'o': case 'O': lctl|=PARITYEN; break; case 'n': case 'N': break; default: printf("Bad parity.\n"); exit(7); } switch(databits) { case '7': lctl|=DB7; break; case '8': lctl|=DB8; break; default: printf("Bad data bits.\n"); exit(8); } switch(stopbits) { case '1': break; case '2': lctl|=STOP2; break; default: printf("Bad stop bits.\n"); exit(9); } } readset() { oldlctl=inp(basereg+LCTLREG); outp(basereg+LCTLREG, DLAB); olddllsb=inp(basereg+DLLSBREG); olddlmsb=inp(basereg+DLMSBREG); outp(basereg+LCTLREG, oldlctl); oldvect=_dos_getvect(intnum); oldmctl=inp(basereg+MCTLREG); oldintmask=(intnum==10)?inp(INTMASK2):inp(INTMASK1); } setup() { outp(basereg+LCTLREG, DLAB); outp(basereg+DLLSBREG, dllsb); outp(basereg+DLMSBREG, dlmsb); outp(basereg+LCTLREG, lctl); _dos_setvect(intnum, inthndl); oldintctl=inp(basereg+INTCTLREG); outp(basereg+INTCTLREG, 0x01); inp(basereg); /* Clear interrupt */ outp(basereg+MCTLREG, 0x0b); newintmask=diffintmask; newintmask&=oldintmask; if(intnum==10) outp(INTMASK2, newintmask); else outp(INTMASK1, newintmask); outp(INTBASE1, INTACK); outp(INTBASE2, INTACK); } cleanup(flags) int flags; { if(!(flags&INHINT)) { if(intnum==10) outp(INTMASK2, oldintmask); else outp(INTMASK1, oldintmask); outp(basereg+INTCTLREG, oldintctl); _dos_setvect(intnum, oldvect); outp(basereg+MCTLREG, 0x03); } if(!(flags&INHCTL)) { outp(basereg+LCTLREG, DLAB); outp(basereg+DLLSBREG, olddllsb); outp(basereg+DLMSBREG, olddlmsb); outp(basereg+LCTLREG, oldlctl); outp(basereg+MCTLREG, oldmctl); } }