/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1987,1988
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */

#ifndef lint
static char    *rcsid = "$Header:ih.c 12.0$";
#endif


#include <dos.h>
#include <sys\types.h>
#include "pcparam.h"
#include "rb.h"
#include "vars.h"



extern void 
i_trap(), i_ign(), i_nmi(), i_tmp(), i_d0();
extern void 
sysirq(), irq1(), irq2(), irq3(), irq4(), irq5(), irq6(), irq7();
extern void 
irq8(), irq9(), irq10(), irq11(), irq12(), irq13(), irq14(), irq15();

/*
 * create an array of functions to make the processing simpler
 */
static u_long irqs[16] = {
(u_long) 0,	(u_long) irq1,	(u_long) irq2,	(u_long) irq3,	
(u_long) irq4,	(u_long) irq5,	(u_long) irq6,	(u_long) irq7,	
(u_long) irq8,	(u_long) irq9,	(u_long) irq10,	(u_long) irq11,	
(u_long) irq12,	(u_long) irq13,	(u_long) irq14,	(u_long) irq15 };


/* map the IRQ numbers into the PC vector number */
u_short vector_map[16] = {
	0x08,   0x09,   0x0a,   0x0b,   0x0c,   0x0d,   0x0e,   0x0f,
	0x70,   0x71,   0x72,   0x73,   0x74,   0x75,   0x76,   0x77 };

u_long          vec_save[8];	/* save of interrupt vectors */


void
setints()
{

#ifdef PROC_INTS
	register u_short s;
	int             i;
	long far       *p;


	s = spl();		/* turn off ints */

	for (i = 0; i < 8; i++)
	{
		TAKE_VECTOR(i, vec_save[i], i_trap);
	}

	splx(s);		/* interrupts back on */

#endif
}


void
resetints()
{

#ifdef PROC_INTS
	register u_short s;
	int             i;
	long far       *p;


	s = spl();		/* turn off ints */

	for (i = 0; i < 8; i++)
	{
		RESET_VECTOR(i, vec_save[i]);
	}

	splx(s);		/* interrupts back on */

#endif
}

u_long          save_irq[16];	/* save area for irq vectors */
u_long          biosint1c;	/* system clock save area */
u_short         master_mask;
u_short         slave_mask;
u_short         biosint1cseg;
u_short         biosint1coff;

/*
 * temp until we put interupt sharing in
 */
chain_int(irq,handler)
	int	irq;
	u_long	handler;
{
	if ((irq_bits & IRQBIT(irq)) == 0) {
		TAKE_VECTOR(irq,save_irq[irq],handler);
        } else {
		RESET_VECTOR(irq,handler);
	}
        irq_bits |= IRQBIT(irq);
}

void
setcbcbvec()
{

	register u_short s;
	register u_short mask;

	s = spl();
	master_mask = mask = IOIN(INTMAST + 1);
	mask &= ~(1 << 7);

	IOOUT(INTMAST + 1, mask);	/* unmask IRQ7 */
	TAKE_VECTOR(vector_map[7], save_irq[7], irq7);
	splx(s);
}

void
resetcbcbvec()
{

	register u_short s;
	register u_short mask;

	s = spl();
	RESET_VECTOR(vector_map[7], save_irq[7]);
	splx(s);
}

void
setirqs()
{


	register u_short s;
	register u_short mask;
	u_short         i;

	/*
	 * Foward interrupts that are handled by the ROMP. we do not forward
	 * those that are handled by the BIOS (such as disk and diskette) 
	 */



	s = spl();		/* No processor interrupts         */
	/*
	 * First do the master 8259 
	 */

	IOOUT(0x20, 0xc6);		/* make IRQ 7 highest priority     */

	mask = IOIN(INTMAST + 1);	/* Get the current 8259 mask       */

	/* process IRQ 0 ... IRQ 7 */
	for (i = 0; i < 8; ++i)
	{
		if ((irq_bits & IRQBIT(i)) == 0)
			continue;
		if ((long) irqs[i] == 0)
		{
			printf("warning: irq %d cannot be passed to ROMP\n", i);
			irq_bits &= ~ (IRQBIT(i));	/* kill the bit */
			continue;
		}
		mask &= ~(1 << i);	/* allow that interrupt             */
		TAKE_VECTOR(vector_map[i], save_irq[i], irqs[i]);
		cbcbptr->vec_map[i] = 1;	/* allow it to be passed	    */
	}


	if ((option_flag&OPTION_NOCLOCK) == 0) {
		TAKE_VECTOR(0x1c, biosint1c, sysirq);	/* 1c is the virtual sysclock */
		biosint1cseg = FP_SEG((int far *) biosint1c);
		biosint1coff = FP_OFF((int far *) biosint1c);
	}

	IOOUT(INTMAST + 1, mask);	/* Send it out to the 8259         */

	/*
	 * Now the slave 8259 
	 */

	mask = IOIN(INTSLAVE + 1);	/* Get the current 8259 mask       */
	slave_mask = mask;

	/* process IRQ 8 ... IRQ 15 */
	for (i = 8; i < 16; ++i)
	{
		if ((irq_bits & IRQBIT(i)) == 0)
			continue;
		if ((long) irqs[i] == 0)
		{
			printf("warning: irq %d cannot be passed to ROMP\n", i);
			irq_bits &= ~ (IRQBIT(i));	/* kill the bit */
			continue;
		}
		mask &= ~(1 << (i - 8));	/* allow that interrupt             */
		TAKE_VECTOR(vector_map[i], save_irq[i], irqs[i]);
		cbcbptr->vec_map[i] = 1;	/* allow it to be passed	    */
	}

	IOOUT(INTSLAVE + 1, mask);	/* Send it out to the 8259         */

	splx(s);

}

void
resetirqs()
{


	register u_short s;
	u_short         i;

	/*
	 * reset stolen interrupt vectors back to original state. 
	 */

	s = spl();		/* No processor interrupts         */
	/*
	 * First do the master 8259 
	 */

	/* process IRQ 0 ... IRQ 7 */
	for (i = 0; i < 8; ++i)
	{
		if ((irq_bits & IRQBIT(i)))
			RESET_VECTOR(vector_map[i], save_irq[i]);
	}

	RESET_VECTOR(0x1c, biosint1c);

	IOOUT(INTMAST + 1, master_mask | (1 << 4) | (1 << 7));

	/*
	 * Now the slave 8259 
	 */

	/* process IRQ 8 ... IRQ 15 */
	for (i = 8; i < 16; ++i)
		if ((irq_bits & IRQBIT(i)))
			RESET_VECTOR(vector_map[i], save_irq[i]);


	IOOUT(INTSLAVE + 1, slave_mask);	/* Send it out to the 8259         */

	splx(s);

}
