Mano pdp8 ComputerMano.cc
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