Raw File
PAR.cpp
/****************************************************************************
 * PAR - PARITY GENERATION AND TEST subsystem
 *
 * AUTHOR: John Pultorak
 * DATE: 9/22/01
 * FILE: PAR.cpp
 *
 * NOTES: see header file.
 *
 *****************************************************************************
 */
#include "PAR.h"
#include "SEQ.h"
#include "BUS.h"
#include "MBF.h"
#include "ADR.h"
#include "MEM.h"
regP PAR::register_P;
regP2 PAR::register_P2;
regG15 PAR::register_G15; // memory buffer register bit 15
regPALM PAR::register_PALM; // PARITY ALARM FF
unsigned PAR::conv_WP[] =
  { BX, SG, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1 };
void
PAR::execRP_WE()
{
// Write parity into memory.
  MEM::MEM_PARITY_BUS = PAR::register_G15.read();
}
// IMPLEMENTATION NOTE: It has been empirically determined that the following
// control signals are mutually exclusive (there is never more than one of these
// generated at any time):
// GP, WGX, RP2, SBWG, CLG
// NOTE: WP clears register_P before writing into it. Strictly speaking, WPx isn't
// supposed to clear the register (should OR into the register), but in the counter
// sequences where WPx is used, register_P is always cleared in the previous TP by
// asserting WP with default zeroes on the write bus.
void
PAR::execWP_WP()
{
// set all bits except parity bit
  register_P.writeShift(BUS::glbl_WRITE_BUS, PAR::conv_WP);
// now set parity bit; in the actual AGC, this is
// a single operation.
  if (SEQ::isAsserted(RG))
    register_P.writeField(16, 16, register_G15.read());
  else
    register_P.writeField(16, 16, 0); // clear parity bit
}
void
PAR::execWP_WPx()
{
// set all bits except parity bit
  register_P.writeShift(BUS::glbl_WRITE_BUS, PAR::conv_WP);
// now set parity bit; in the actual AGC, this is
// a single operation.
  if (SEQ::isAsserted(RG))
    register_P.writeField(16, 16, register_G15.read());
  else
    register_P.writeField(16, 16, 0); // clear parity bit
}
void
PAR::execWP_WP2()
{
  register_P2.write(gen1_15Parity(register_P.read()));
}
void
PAR::execWP_RP2()
{
  register_G15.write(register_P2.read());
}
void
PAR::execWP_GP()
{
  register_G15.write(gen1_15Parity(register_P.read()));
}
void
PAR::execWP_SBWG()
{
  register_G15.write(MEM::MEM_PARITY_BUS); // load memory bit 16 (parity) into G15
}
void
PAR::execWP_WGx()
{
// This is only used in PINC, MINC, and SHINC. Does not clear G
// register; writes (ORs) into G from RWBus and writes into parity
// from 1-15 generator. All done in one operation, although I show
// it in two steps here. The sequence calls CLG in a previous TP.
  register_G15.write(PAR::gen1_15Parity(register_P.read()));
}
void
PAR::execWP_CLG()
{
  register_G15.write(0);
}
void
PAR::execWP_GENRST()
{
  register_PALM.write(0);
}
void
PAR::execWP_TP()
{
  if (ADR::GTR_27() && genP_15Parity(register_P.read()))
    register_PALM.write(genP_15Parity(register_P.read()));
}
void
PAR::CLR_PALM()
{
// asynchronous clear for PARITY ALARM (from MON)
  register_PALM.clear();
}

// RSB: All parity generation is turned off because: a) I don't care about it
// in a software sim; and b) it was giving me fits because the parity was
// showing up in my logs, fooling me into thinking weird stuff was happening
// and messing up my comparisons between yaAGCb1 and yaAGC-Block1.

unsigned
PAR::gen1_15Parity(unsigned r)
{
#if 0
//check the lower 15 bits of 'r' and return the odd parity;
//bit 16 is ignored.
  unsigned evenParity = (1 & (r >> 0)) ^ (1 & (r >> 1)) ^ (1 & (r >> 2))
      ^ (1 & (r >> 3)) ^ (1 & (r >> 4)) ^ (1 & (r >> 5)) ^ (1 & (r >> 6))
      ^ (1 & (r >> 7)) ^ (1 & (r >> 8)) ^ (1 & (r >> 9)) ^ (1 & (r >> 10))
      ^ (1 & (r >> 11)) ^ (1 & (r >> 12)) ^ (1 & (r >> 13)) ^ (1 & (r >> 14));
  return ~evenParity & 1; // odd parity
#else
  return 0;
#endif
}
unsigned
PAR::genP_15Parity(unsigned r)
{
#if 0
//check all 16 bits of 'r' and return the odd parity
  unsigned evenParity = (1 & (r >> 0)) ^ (1 & (r >> 1)) ^ (1 & (r >> 2))
      ^ (1 & (r >> 3)) ^ (1 & (r >> 4)) ^ (1 & (r >> 5)) ^ (1 & (r >> 6))
      ^ (1 & (r >> 7)) ^ (1 & (r >> 8)) ^ (1 & (r >> 9)) ^ (1 & (r >> 10))
      ^ (1 & (r >> 11)) ^ (1 & (r >> 12)) ^ (1 & (r >> 13)) ^ (1 & (r >> 14))
      ^ (1 & (r >> 15));
  return ~evenParity & 1; // odd parity
#else
  return 0;
#endif
}

back to top