/* Hardware interrupt dependent stuff for IBM-PC running MS-DOS */

#include "global.h"

/* This flag is set by setirq() if IRQ 8-15 is used, indicating
 * that the machine is a PC/AT with a second 8259 interrupt controller.
 * If this flag is set, the interrupt return code in pcgen.asm will
 * send an End of Interrupt command to the second 8259 as well as the
 * first.
 */
extern char isat;

/* Install hardware interrupt handler.
 * Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
 * Note that bus line IRQ2 maps to IRQ9 on the AT
 */
setirq(irq,handler)
unsigned irq;
void (*handler)();
{
	/* Set interrupt vector */
	if(irq < 8){
		setvect(8+irq,handler);
	} else if(irq < 16){
		isat = 1;
		setvect(0x70 + irq - 8,handler);
	} else {
		return -1;
	}
	return 0;
}
/* Return pointer to hardware interrupt handler.
 * Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
 */
void
(*getirq(irq))()
unsigned int irq;
{
	void (*getvect())();

	/* Set interrupt vector */
	if(irq < 8){
		return getvect(8+irq);
	} else if(irq < 16){
		return getvect(0x70 + irq - 8);
	} else {
		return NULLVFP;
	}
}
/* Disable hardware interrupt */
maskoff(irq)
unsigned irq;
{
	if(irq < 8){
		setbit(0x21,(char)(1<<irq));
	} else if(irq < 16){
		irq -= 8;
		setbit(0xa1,(char)(1<<irq));
	} else {
		return -1;
	}
	return 0;
}
/* Enable hardware interrupt */
maskon(irq)
unsigned irq;
{
	if(irq < 8){
		clrbit(0x21,(char)(1<<irq));
	} else if(irq < 16){
		irq -= 8;
		clrbit(0xa1,(char)(1<<irq));
	} else {
		return -1;
	}
	return 0;
}
/* Return 1 if specified interrupt is enabled, 0 if not, -1 if invalid */
getmask(irq)
unsigned irq;
{
	if(irq < 8)
		return (inportb(0x21) & (1 << irq)) ? 0 : 1;
	else if(irq < 16){
		irq -= 8;
		return (inportb(0xa1) & (1 << irq)) ? 0 : 1;
	} else
		return -1;
}

/* Set bit(s) in I/O port */

setbit(port,bits)
unsigned port;
char bits;
{
	outportb(port,(char)inportb(port)|bits);
}
/* Clear bit(s) in I/O port */
clrbit(port,bits)
unsigned port;
char bits;
{
	outportb(port,(char)(inportb(port) & ~bits));
}
