/****************************************************************************
* INT - PRIORITY INTERRUPT subsystem
*
* AUTHOR: John Pultorak
* DATE: 9/22/01
* FILE: INT.cpp
*
* NOTES: see header file.
*
*****************************************************************************
*/
#include "INT.h"
#include "SEQ.h"
#include "BUS.h"
#define NUM_RUPTS 6 // 5
regRPCELL INT::register_RPCELL; // latches the selected priority interrupt vector (1-NUM_RUPTS)
regINHINT1 INT::register_INHINT1; // inhibits interrupts for 1 instruction (on WOVI)
regINHINT INT::register_INHINT; // inhibits interrupts on INHINT, reenables on RELINT
// NOTE: the priority cells (rupt[]) are indexed 0-4, but stored in the
// RPCELL register as 1-NUM_RUPTS; (0 in RPCELL means no interrupt)
unsigned INT::rupt[NUM_RUPTS];
bool
INT::IRQ()
{
if (INT::getPriorityRupt() // if interrupt requested
&& INT::register_RPCELL.read() == 0 // and interrupt not currently being serviced
&& INT::register_INHINT1.read() == 0 // and interrupt not inhibited for 1 instruction
&& INT::register_INHINT.read() == 0) // and interrupts enabled (RELINT)
{
return true;
}
return false;
}
void
INT::resetAllRupt()
{
for (int i = 0; i < NUM_RUPTS; i++)
{
rupt[i] = 0;
}
}
// interrupt vector; outputs 1-NUM_RUPTS (decimal) == vector; 0 == no interrupt
unsigned
INT::getPriorityRupt()
{
for (int i = 0; i < NUM_RUPTS; i++)
{
if (rupt[i])
return i + 1;
}
return 0;
}
void
INT::execRP_RRPA()
{
// RSB: John was mistaken about the interrupt-vector system for some
// reason. He had the program entry point at 02000, and the interrupt
// vectors at 4-word increments above that. In fact, the interrupt-vector
// table is at 02000 and the entry-point is elsewhere.
BUS::glbl_READ_BUS = 02000 + ((register_RPCELL.read() - 1) << 2);
}
// latches the selected priority interrupt vector (1-NUM_RUPTS)
// also inhibits additional interrupts while an interrupt is being processed
void
INT::execWP_GENRST()
{
register_RPCELL.write(0);
register_INHINT.write(1);
resetAllRupt();
}
void
INT::execWP_RPT()
{
register_RPCELL.write(INT::getPriorityRupt());
}
void
INT::execWP_KRPT()
{
INT::rupt[register_RPCELL.read() - 1] = 0;
}
void
INT::execWP_CLRP()
{
register_RPCELL.write(0);
}
// INHINT1: inhibits interrupts for 1 instruction (on WOVI)
void
INT::execWP_WOVI()
{
if (BUS::testOverflow(BUS::glbl_WRITE_BUS) != NO_OVF)
register_INHINT1.write(1);
}
void
INT::execWP_CLINH1()
{
register_INHINT1.write(0);
}
// INHINT: inhibits interrupts on INHINT, reenables on RELINT
void
INT::execWP_INH()
{
register_INHINT.write(1);
}
void
INT::execWP_CLINH()
{
register_INHINT.write(0);
}