Mano pdp8 BasicMano.cc

From Minor Miracle Software
Revision as of 16:49, 13 June 2016 by WikiSysop (talk | contribs) (Created page with " BasicMano.cc <PRE> // Basic Mano class // memory, registers and commands. #ifndef BASICMANO_CC #define BASICMANO_CC #ifndef INSTRUCTIONWORD_CC #include "InstructionWord...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search


BasicMano.cc

// Basic Mano class
// memory, registers and commands.

#ifndef BASICMANO_CC
#define BASICMANO_CC

#ifndef INSTRUCTIONWORD_CC
  #include "InstructionWord.cc"
#endif

#ifndef STACK_CC
  #include "stack.cc"
#endif

#ifndef RAM_CC
 #include "RAM.cc"
#endif

#ifndef COUNTER_CC
 #include "counter.cc"
#endif

class BasicMano;

ostream& operator << (ostream& OS, BasicMano &A);

class BasicMano {

// Main Memory
        RAM MainMemory;

// Nine registers:
        InstructionWord InstructionWord_AC;   // Accumulator
        InstructionWord InstructionWord_AR;   // Address Register
        InstructionWord InstructionWord_DR;   // Data Register
        InstructionWord InstructionWord_IR;   // Instruction Register
        char OUTR;                  // Output Register
        char INPR;                  // Input Register
        unsigned int          PC;   // Program Counter
        InstructionWord InstructionWord_TR;   // Temporary Register

        counter T_sequence_counter;  // Using T_sequence_counter as a 0-15 counter,
                                     // dropped SC and the 4x16 decoder.

// Seven flip-flops:
        short int I_flip_flop;
        short int S_flip_flop;
        short int E_flip_flop;
        short int R_flip_flop;
        short int IEN_flip_flop;
        short int FGI_flip_flop;
        short int FGO_flip_flop;

// Control states
        short int D_flip_flop;

// Indirection Control
        short int si_mIndirect;

friend ostream& operator << (ostream& OS, BasicMano &A)
{
if( DEBUG )
cout << "Basic Mano: << 0 " << endl;

        OS << "   Basic Mano Computer " << endl;
        OS << "   Nine Registers"   << endl;
        OS << "      AC   / Accumulator  " << A.InstructionWord_AC   << endl;
        OS << "      AR   / Address Register  " << A.InstructionWord_AR   << endl;
        OS << "      DR   / Data Register  " << A.InstructionWord_DR   << endl;
        OS << "      INPR / Input Register" << A.INPR << endl;
        OS << "      IR   / Instruction Register" << A.InstructionWord_IR   << endl;
        OS << "      OUTR / Output Register" << A.OUTR << endl;
        OS << "      PC   / Program Counter" << A.PC   << endl;
        OS << "      SC   / Sequence Counter" << A.T_sequence_counter    << endl;
        OS << "      TR   / Temporary Register" << A.InstructionWord_TR   << endl;
        OS << endl;
        OS << "   Seven Flip-Flops" << endl;
        OS << "      E   " << A.E_flip_flop   << endl;
        OS << "      FGI " << A.FGI_flip_flop << endl;
        OS << "      FGO " << A.FGO_flip_flop << endl;
        OS << "      I   " << A.I_flip_flop   << endl;
        OS << "      IEN " << A.IEN_flip_flop << endl;
        OS << "      R   " << A.R_flip_flop   << endl;
        OS << "      S   " << A.S_flip_flop   << endl;
        OS << endl;
        OS << "   Control States" << endl;
        OS << "      D  " << A.D_flip_flop  << endl;
        OS << endl;
        OS << "   Main Memory" << endl;
        OS << A.MainMemory << endl;
if( DEBUG )
cout << "Basic Mano: << 1 " << endl;
        return OS;
}


void Decode()
{
if( DEBUG )
cout << "Basic Mano: Decode 0 " << endl;

        D_flip_flop = InstructionWord_IR.getopcode();
}  // end decode


int Execute()
{
if( DEBUG )
cout << "Basic Mano: Execute 0 " << endl;

        T_sequence_counter++;
        if ( D_flip_flop == 7 )
           return ExecuteRegIo();
        else
           ExecuteMemRef();
        return 1;
}

int ExecuteRegIo()
{
if( DEBUG )
cout << "Basic Mano: ExecuteRegIo 0 " << endl;

     if ( I_flip_flop && (T_sequence_counter.getcount() == 3))
     {
           // execute I/O instruction
           switch ( InstructionWord_IR.getRcode() ) {
                  case 1: IEN_flip_flop = 0; // IOF
                          break;
                  case 2: IEN_flip_flop =1;  // ION
                          break;
                  case 4: if( FGO_flip_flop ) // SKO
                             PC++;
                          break;
                  case 8: if( FGI_flip_flop ) // SKI
                             PC++;
                          break;
                  case 16: OUTR = InstructionWord_AC.CellToDec(7);   // OUT
                           FGO_flip_flop = 0;
                           break;
                  case 32: InstructionWord_AC.DecToCell( (short) INPR );  // INP
                           FGI_flip_flop = 0;
                           break;
           default:
              ;
        }
     }

     if( (I_flip_flop == 0) && (T_sequence_counter.getcount() == 3))
     {
        // execute register-reference instruction
           switch( InstructionWord_AR.getopcode() ) {
                  case 0: S_flip_flop = 0;            // HLT
                          T_sequence_counter.clear();
                          return 0;
                          break;
                  case 1: if (E_flip_flop == 0)               // SZE
                             PC++;
                          break;
                  case 2: if( InstructionWord_AC.CellToDec() == 0) // SZA
                             PC++;
                          break;
                  case 3: if( InstructionWord_AC.getIcode() )        // SNA
                             PC++;
                          break;
                  case 4: if( InstructionWord_AC.getIcode() == 0 )   // SPA
                             PC++;
                          break;
                  case 5: InstructionWord_AC.increment();           // INC
                          break;
                  case 6: InstructionWord_AC.circulateleft( E_flip_flop );    // CIL
                          break;
                  case 7: InstructionWord_AC.circulateright( E_flip_flop );   // CIR
                          break;
                  case 8: ~E_flip_flop;                       // CME
                          break;
                  case 9: InstructionWord_AC.COMPLEMENT();          // CMA
                          break;
                  case 10: E_flip_flop = 0;                   // CLE
                           break;
                  case 11: InstructionWord_AC.clear();              // CLA
                           break;
           default:
              ;
        }
     }
     T_sequence_counter.clear();
     return 1;
}

void ExecuteMemRef()
{
if( DEBUG )
cout << "Basic Mano: ExecuteMemRef 0 " << endl;

     if ( I_flip_flop && (T_sequence_counter.getcount() == 3))
     {
           InstructionWord_AR = MainMemory.returncurrent(); // execute I/O
     }

     if ((I_flip_flop == 0) && (T_sequence_counter.getcount() == 3))
     {
           // execute memory-reference
           switch ( D_flip_flop ) {
                  case 0: {
                            InstructionWord mem_Temp = MainMemory.returncurrent( ); // AND
                            InstructionWord_AC.AND( mem_Temp );
                    }
                          break;
                  case 1: LoadDR();      // ADD
                          InstructionWord_AC.ADD( InstructionWord_DR , E_flip_flop );
                          T_sequence_counter.clear();
                          break;
                  case 2: LoadDR();      // LDA
                          InstructionWord_AC = InstructionWord_DR;
                          T_sequence_counter.clear();
                          break;
                  case 3: {
                            InstructionWord mem_Temp;     // STA
                            mem_Temp.setlocation( InstructionWord_AR.returndata() );
                            mem_Temp.setdata( InstructionWord_AC.returndata() );
                            MainMemory.LoadCell( mem_Temp );
                            T_sequence_counter.clear();
                          }
                          break;
                  case 4: PC = InstructionWord_AR.returndata(); // BUN
                          T_sequence_counter.clear();
                          break;
                  case 5:       // BSA
                          break;
                  case 6:       // ISZ
                          T_sequence_counter.clear();
                          break;
                  case 7:
                          break;
           default:
              ;
     }
  }
        T_sequence_counter.clear();
}

void Fetch()
{
if( DEBUG )
cout << "Basic Mano: Fetch 0 " << endl;

     if( LoadAR() && (T_sequence_counter.getcount() == 1) )
     {
if( DEBUG )
cout << "Basic Mano: Fetch 1 " << endl;
         MainMemory.locate( InstructionWord_AR );
         InstructionWord_IR = MainMemory.returncurrent();
cout << "Basic Mano: Fetch 2, InstructionWord_IR is " << InstructionWord_IR << endl;
         PC++;
         T_sequence_counter++;
     }
}

short LoadAR()
{
if( DEBUG ) cout << "Basic Mano: LoadAR 0 " << endl;

     if( T_sequence_counter.getcount() )
         return 0;
     InstructionWord_AR = PC;
     T_sequence_counter++;
     return 1;
}

void LoadDR()
{
if( DEBUG )
cout << "Basic Mano: LoadDR 0 " << endl;

        T_sequence_counter++;
        InstructionWord_DR = MainMemory.returncell( InstructionWord_AR );
}

public:

BasicMano()
{
       OUTR = '\0';
       INPR = '\0';
       D_flip_flop = 0;

       I_flip_flop = 0;
       S_flip_flop = 0;
       E_flip_flop = 0;
       R_flip_flop = 0;

       IEN_flip_flop = 0;
       FGI_flip_flop = 0;
       FGO_flip_flop = 0;

       PC = 0;
       si_mIndirect = 0;
}


BasicMano(const BasicMano &V)
{
       InstructionWord_AC = V.InstructionWord_AC;
       InstructionWord_AR = V.InstructionWord_AR;
       InstructionWord_DR = V.InstructionWord_DR;
       InstructionWord_IR = V.InstructionWord_IR;
       OUTR = V.OUTR;
       INPR = V.INPR;
       InstructionWord_TR = V.InstructionWord_TR;
       PC = V.PC;

       D_flip_flop = V.D_flip_flop;

       I_flip_flop = V.I_flip_flop;
       S_flip_flop = V.S_flip_flop;
       E_flip_flop = V.E_flip_flop;
       R_flip_flop = V.R_flip_flop;

       IEN_flip_flop = V.IEN_flip_flop;
       FGI_flip_flop = V.FGI_flip_flop;
       FGO_flip_flop = V.FGO_flip_flop;

       si_mIndirect = V.si_mIndirect;
       MainMemory = V.MainMemory;
}

~BasicMano(){}

int LoadMano( InstructionWord mem_NewCell )
{
if( DEBUG ) cout << "Basic Mano: LoadMano 0 " << endl;

     return MainMemory.LoadCell( mem_NewCell );
}

void reset()
{
if( DEBUG ) cout << "Basic Mano: Reset 0 " << endl;

        D_flip_flop = 0;
        I_flip_flop = 0;
        S_flip_flop = 0;
        E_flip_flop = 0;
        R_flip_flop = 0;
        IEN_flip_flop = 0;
        FGI_flip_flop = 0;
        FGO_flip_flop = 0;

        T_sequence_counter.clear();

        OUTR = '\0';
        INPR = '\0';

        MainMemory.erase();
}

void run()
{
if( DEBUG ) cout << "Basic Mano: Run 0 " << endl;

     do {
		cout << "Basic Mano: Run 1 " << endl;
         T_sequence_counter.clear();
         Fetch();             // Fetch instruction
         Decode();            // Decode instruction
         InstructionWord_AR = InstructionWord_IR.CellToDec(); // load raw address
         I_flip_flop = InstructionWord_IR.getIcode();   // get indirect flag
     }
     while( Execute() );   // Execute Instruction
}
};
#endif // BasicMano_CC


Internal Links

Parent Article: Mano PDP-8 Simulation Project Source Code