Mano pdp8 ComputerMano.cc

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


ComputerMano.cc

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

#ifndef COMPUTERMANO_CC
#define COMPUTERMANO_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

#ifndef QUEUE_CC
  #include "queue.cc"
#endif

class ComputerMano;

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

class ComputerMano {

// 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, ComputerMano &A)
{
if( DEBUG )
cout << "Computer Mano: << 0 " << endl;

        OS << "   Computer 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 << "Computer Mano: << 1 " << endl;
        return OS;
}


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

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


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

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

int ExecuteRegIo()
{
if( DEBUG )
cout << "Computer 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 << "Computer 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 << "Computer Mano: Fetch 0 " << endl;

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

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

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

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

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

public:

ComputerMano()
{
       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;
}


ComputerMano(const ComputerMano &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;
}

~ComputerMano(){}

	// Load the assembly code
	void load( queue<InstructionWord> mem_NewCell )
	{
		if( DEBUG ) cout << "Computer Mano: load 0 " << endl;
		int i_test = 0;
		
		while( !mem_NewCell.isempty() )
		{
			i_test++;
			InstructionWord IW;
			mem_NewCell.dequeue( IW );

	        MainMemory.LoadCell( IW );
	     
	    } // while
		if( DEBUG ) cout << "Computer Mano: load 1. " << i_test << " cells loaded " << endl;
	} // void load( queue<InstructionWord> mem_NewCell )

void reset()
{
if( DEBUG ) cout << "Computer 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 << "Computer Mano: Run 0 " << endl;
		
		// Make sure there is something in memory
		if( MainMemory.census() )
		{
		if( DEBUG ) cout << "Computer Mano: Run 1 " << endl;

		     do {
				cout << "Computer 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
	     } // if
	} // run
};
#endif // ComputerMano_CC


Internal Links

Parent Article: Mano PDP-8 Simulation Project Source Code