Raw File
SEQ.h
/****************************************************************************
 * SEQ - SEQUENCE GENERATOR subsystem
 *
 * AUTHOR: John Pultorak
 * DATE: 9/22/01
 * FILE: SEQ.h
 *
 * VERSIONS:
 *
 * DESCRIPTION:
 * Sequence Generator for the Block 1 Apollo Guidance Computer prototype (AGC4).
 *
 * SOURCES:
 * Mostly based on information from "Logical Description for the Apollo
 * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh
 * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963.
 *
 * NOTES:
 *
 *****************************************************************************
 */
#ifndef SEQ_H
#define SEQ_H
#include "reg.h"
#define MAXPULSES 15
#define MAX_IPULSES 5 // no more than 5 instruction-generated pulses active at any time
enum cpType
{ // **inferred; not defined in orignal R393 AGC4 spec.
  NO_PULSE = 0,
  // OUTPUTS FROM SUBSYSTEM A
  CI = 1, // Carry in
  CLG = 2, // Clear G
  CLCTR = 3, // Clear loop counter
  CTR = 4, // Loop counter
  GP = 5, // Generate Parity
  KRPT = 6, // Knock down Rupt priority
  NISQ = 7, // New instruction to the SQ register
  RA = 8, // Read A
  RB = 9, // Read B
  RB14 = 10, // Read bit 14
  RC = 11, // Read C
  RG = 12, // Read G
  RLP = 13, // Read LP
  RP2 = 14, // Read parity 2
  RQ = 15, // Read Q
  RRPA = 16, // Read RUPT address
  RSB = 17, // Read sign bit
  RSCT = 18, // Read selected counter address
  RU = 19, // Read sum
  RZ = 20, // Read Z
  R1 = 21, // Read 1
  R1C = 22, // Read 1 complimented
  R2 = 23, // Read 2
  R22 = 24, // Read 22
  R24 = 25, // Read 24
  ST1 = 26, // Stage 1
  ST2 = 27, // Stage 2
  TMZ = 28, // Test for minus zero
  TOV = 29, // Test for overflow
  TP = 30, // Test parity
  TRSM = 31, // Test for resume
  TSGN = 32, // Test sign
  TSGN2 = 33, // Test sign 2
  WA = 34, // Write A
  WALP = 35, // Write A and LP
  WB = 36, // Write B
  WGx = 37, // Write G (do not reset)
  WLP = 38, // Write LP
  WOVC = 39, // Write overflow counter
  WOVI = 40, // Write overflow RUPT inhibit
  WOVR = 41, // Write overflow
  WP = 42, // Write P
  WPx = 43, // Write P (do not reset)
  WP2 = 44, // Write P2
  WQ = 45, // Write Q
  WS = 46, // Write S
  WX = 47, // Write X
  WY = 48, // Write Y
  WYx = 49, // Write Y (do not reset)
  WZ = 50, // Write Z
  // OUTPUTS FROM SUBSYSTEM A; USED AS INPUTS TO SUBSYSTEM B ONLY;
  // NOT USED OUTSIDE CPM
  RSC = 51, // Read special and central (output to B only, not outside CPM)
  WSC = 52, // Write special and central (output to B only, not outside CPM)
  WG = 53, // Write G (output to B only, not outside CPM)
  // OUTPUTS FROM SUBSYSTEM A; USED AS INPUTS TO SUBSYSTEM C ONLY;
  // NOT USED OUTSIDE CPM
  SDV1 = 54, // Subsequence DV1 is currently active
  SMP1 = 55, // Subsequence MP1 is currently active
  SRSM3 = 56, // Subsequence RSM3 is currently active
  // EXTERNAL OUTPUTS FROM SUBSYSTEM B
  //
  RA0 = 57, // Read register at address 0 (A)
  RA1 = 58, // Read register at address 1 (Q)
  RA2 = 59, // Read register at address 2 (Z)
  RA3 = 60, // Read register at address 3 (LP)
  RA4 = 61, // Read register at address 4
  RA5 = 62, // Read register at address 5
  RA6 = 63, // Read register at address 6
  RA7 = 64, // Read register at address 7
  RA10 = 65, // Read register at address 10 (octal)
  RA11 = 66, // Read register at address 11 (octal)
  RA12 = 67, // Read register at address 12 (octal)
  RA13 = 68, // Read register at address 13 (octal)
  RA14 = 69, // Read register at address 14 (octal)
  RBK = 70, // Read BNK
  WA0 = 71, // Write register at address 0 (A)
  WA1 = 72, // Write register at address 1 (Q)
  WA2 = 73, // Write register at address 2 (Z)
  WA3 = 74, // Write register at address 3 (LP)
  WA10 = 75, // Write register at address 10 (octal)
  WA11 = 76, // Write register at address 11 (octal)
  WA12 = 77, // Write register at address 12 (octal)
  WA13 = 78, // Write register at address 13 (octal)
  WA14 = 79, // Write register at address 14 (octal)
  WBK = 80, // Write BNK
  WGn = 81, // Write G (normal gates)**
  W20 = 82, // Write into CYR
  W21 = 83, // Write into SR
  W22 = 84, // Write into CYL
  W23 = 85, // Write into SL
  // THESE ARE THE LEFTOVERS -- THEY'RE PROBABLY USED IN SUBSYSTEM C
  //
  GENRST = 86, // General Reset**
  CLINH = 87, // Clear INHINT**
  CLINH1 = 88, // Clear INHINT1**
  CLSTA = 89, // Clear state counter A (STA)**
  CLSTB = 90, // Clear state counter B (STB)**
  CLISQ = 91, // Clear SNI**
  CLRP = 92, // Clear RPCELL**
  INH = 93, // Set INHINT**
  RPT = 94, // Read RUPT opcode **
  SBWG = 95, // Write G from memory
  SETSTB = 96, // Set the ST1 bit of STB
  WE = 97, // Write E-MEM from G
  WPCTR = 98, // Write PCTR (latch priority counter sequence)**
  WSQ = 99, // Write SQ
  WSTB = 100, // Write stage counter B (STB)**
  R2000 = 101, // Read 2000 **
};
// INSTRUCTIONS
// Op Codes, as they appear in the SQ register.
enum instruction
{
  // The code in the SQ register is the same as the op code for these
  // four instructions.
  TC = 00, // 00 TC K Transfer Control 1 MCT
  CCS = 01, // 01 CCS K Count, Compare, and Skip 2 MCT
  INDEX = 02, // 02 INDEX K 2 MCT
  XCH = 03, // 03 XCH K Exchange 2 MCT
  // The SQ register code is the op code + 010 (octal). This happens because all
  // of these instructions have bit 15 set (the sign (SG) bit) while in memory. When the
  // instruction is copied from memory to the memory buffer register (G) to register
  // B, the SG bit moves from bit 15 to bit 16 and the sign is copied back into bit
  // 15 (US). Therefore, the CS op code (04) becomes (14), and so on.
  CS = 014, // 04 CS K Clear and Subtract 2 MCT
  TS = 015, // 05 TS K Transfer to Storage 2 MCT
  AD = 016, // 06 AD K Add 2 or 3 MCT
  MASK = 017, // 07 MASK K Bitwise AND 2 MCT
  // These are extended instructions. They are accessed by executing an INDEX 5777
  // before each instruction. By convention, address 5777 contains 47777. The INDEX
  // instruction adds 47777 to the extended instruction to form the SQ op code. For
  // example, the INDEX adds 4 to the 4 op code for MP to produce the 11 (octal; the
  // addition generates an end-around-carry). SQ register code (the 7777 part is a
  // negative zero).
  MP = 011, // 04 MP K Multiply 10 MCT
  DV = 012, // 05 DV K Divide 18 MCT
  SU = 013, // 06 SU K Subtract 4 or 5 MCT
};
enum subseq
{
  TC0 = 0,
  CCS0 = 1,
  CCS1 = 2,
  NDX0 = 3,
  NDX1 = 4,
  RSM3 = 5,
  XCH0 = 6,
  CS0 = 7,
  TS0 = 8,
  AD0 = 9,
  MASK0 = 10,
  MP0 = 11,
  MP1 = 12,
  MP3 = 13,
  DV0 = 14,
  DV1 = 15,
  SU0 = 16,
  RUPT1 = 17,
  RUPT3 = 18,
  STD2 = 19,
  PINC0 = 20,
  MINC0 = 21,
  SHINC0 = 22,
  NO_SEQ = 23
};
enum scType
{ // identifies subsequence for a given instruction
  SUB0 = 0, // ST2=0, ST1=0
  SUB1 = 1, // ST2=0, ST1=1
  SUB2 = 2, // ST2=1, ST1=0
  SUB3 = 3 // ST2=1, ST1=1
};
enum brType
{
  BR00 = 0, // BR1=0, BR2=0
  BR01 = 1, // BR1=0, BR2=1
  BR10 = 2, // BR1=1, BR2=0
  BR11 = 3, // BR1=1, BR2=1
  NO_BR = 4 // NO BRANCH
};
const int GOPROG = 02000; // bottom address of fixed memory
class regSQ : public reg
{
public:
  regSQ() :
      reg(4, "%02o")
  {
  }
};
class regSTA : public reg
{
public:
  regSTA() :
      reg(2, "%01o")
  {
  }
};
class regSTB : public reg
{
public:
  regSTB() :
      reg(2, "%01o")
  {
  }
};
class regBR1 : public reg
{
public:
  regBR1() :
      reg(1, "%01o")
  {
  }
};
class regBR2 : public reg
{
public:
  regBR2() :
      reg(1, "%01o")
  {
  }
};
class regCTR : public reg
{
public:
  regCTR() :
      reg(3, "%01o")
  {
  }
};
class regSNI : public reg
{
public:
  regSNI() :
      reg(1, "%01o")
  {
  }
};
class SEQ
{
public:
  static void
  execWP_GENRST();
  static void
  execWP_WSQ();
  static void
  execWP_NISQ();
  static void
  execWP_CLISQ();
  static void
  execWP_ST1();
  static void
  execWP_ST2();
  static void
  execWP_TRSM();
  static void
  execWP_CLSTA();
  static void
  execWP_WSTB();
  static void
  execWP_CLSTB();
  static void
  execWP_SETSTB();
  static void
  execWP_TSGN();
  static void
  execWP_TOV();
  static void
  execWP_TMZ();
  static void
  execWP_TSGN2();
  static void
  execWP_CTR();
  static void
  execWP_CLCTR();
  static regSNI register_SNI; // select next intruction flag
  static cpType glbl_cp[MAXPULSES]; // current set of asserted control pulses (MAXPULSES)
  static char* cpTypeString[];
  // Test the currently asserted control pulses; return true if the specified
  // control pulse is active.
  static bool
  isAsserted(cpType pulse);
  // Return a string containing the names of all asserted control pulses.
  static char*
  getControlPulses();
  static subseq glbl_subseq; // currently decoded instruction subsequence
  static regSQ register_SQ; // instruction register
  static regSTA register_STA; // stage counter A
  static regSTB register_STB; // stage counter B
  static regBR1 register_BR1; // branch register1
  static regBR2 register_BR2; // branch register2
  static regCTR register_LOOPCTR; // loop counter
  static char* instructionString[];
};
#endif
back to top