Raw File
INT.cpp
/****************************************************************************
 * 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);
}
back to top