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); 
		} 
	}