/*
/*              A Simple 16-bit Index Computer
/*
/*            This  computer program simulates the fetch,
/*            decode, and execute cycles of a simple 16-bit
/*            Index computer--SXC-16. 
/*
/*              SXC-16  has the following registers:
/*                  
/*                    
/*                  AC:   16 bits
/*                  MDR:  16 bits
/*                  MAR:  13 bits
/*                  IR:   16 bits
/*                  PC:   12 bits
/*                  IX:   12 bits
/*
/*          and its instruction repertoire consists of the 
/*          following instructions:
/*
/*     LDA: Load Accumulator:          Opcode: 00000+address   ---  AC = MEM[IR[5:15]]
/*     STA: Store Accumulator:         Opcode: 04096+address   ---  MEM[IR[5:16]] =AC
/*     ADD: Add Accumulator:           Opcode: 08192+address   ---  AC = AC + MEM[IR[5:15]] 
/*     SUB: Sub Accumulator:           Opcode: 12288+address   ---  AC = AC - MEM[IR[5:15]] 
/*     ORA: OR Accumulator:            Opcode: 16384+address   ---  AC = AC OR MEM[IR[5:15]] 
/*     ANA: AND Accumulator:           Opcode: 20480+address   ---  AC = AC AND MEM[IR[5:15]] 
/*     CMA: Comp Accumulator:          Opcode: 24576+address   ---  AC = ~AC + MEM[IR[5:15]] 
/*     CLA: Clear Accumulator:         Opcode: 28672+address   ---  AC = 0  
/*     SRA: Shift Right Accumulator:   Opcode: 32768+address   ---  AC = AC >> 1 
/*     SLA: Shift Left Accumulator:    Opcode: 36864+address   ---  AC = AC << 1 
/*     BRA: Branch Always:             Opcode: 40960+address   ---  PC  = IR[4:15] 
/*     BRZ: Branch if accumulator = 0: Opcode: 45056+address   ---  PC  = (AC=0) && IR[5:15] 
/*     BRN: Branch if accumulator < 0: Opcode: 49152+address   ---  PC  = (AC>0) && IR[5:15] 
/*     BRP: Branch if accumulator > 0: Opcode: 53248+address   ---  PC  = (AC<0) && IR[5:15] 
/*     INA: Increment AC:              Opcode: 57344           ---  AC  = AC + 1 
/*     HLT: Halt:                      Opcode: 61440           ---  reset =1 
/*     LDX: Indexed Load:              Opcode: 02048+address   ---  AC = MEM[IX];IX =IX+1
/*     STX  Indexed Store:             Opcode  06144+address   ---  MEM[IX] = AC;IX =IX+1
/*     ADX  Indexed Add:               Opcode  10240+address  ---  AC = AC + MEM[IX+IR[5:15]];IX=IX-1
/*     SUX  Indexed Sub:               Opcode  14336+address  ---  AC = AC - MEM[IX+IR[5:15]];IX=IX-1
/*     ORX  Indexed OR:                Opcode  18432+address  ---  AC = AC | MEM[IX+IR[5:15]];IX=IX-1
/*     ANX  Indexed AND:               Opcode  22528+address  ---  AC = AC & MEM[IX+IR[5:15]];IX=IX-1         
/*     INX  Initialize IX:             Opcode  26624+address  ---  IX = IR[5:15]
/*     ICX  Increment IX:              Opcode  30720          ---  IX = IX + 1
/*     DCX  Decrement IX:              Opcode  34816          ---  IX = IX - 1
/*     BZX  Branch if Index Reg. = 0:  Opcode  38912+address  ---  PC = (IX =0) && IR[5:15]
/*     BPX  Branch if Index Reg. > 0:  Opcode  43008+address  ---  PC = (IX >0) && IR[5:15]
/*                            
/*                              Please communicate all your questions
/*                                        and comments to 
/*          
/*                                         A. Yavuz Oruc
/*                                           Professor
/*                                       University of Maryland
/*                                      College Park, MD 20742
/*                                     E-mail: yavuz@eng.umd.edu
/*
/*                                         January 1997                       
*/



typedef struct 
{
   unsigned int   MDR;
   unsigned int   MAR;
   unsigned int   PC;
   unsigned int   IR;
   unsigned int   AC;
   unsigned int   IX;   
   unsigned int   MEMORY[8192];
   unsigned int  opcode;
   Boolean       S;
   Boolean       C;
   Boolean       V;
   Boolean       Z;
   Boolean       datavalid;
   Boolean       read;
   Boolean       write;
   Boolean      reset;
} CS228Global;



#include <iostream.h>
#include <stdio.h>
#include <limits.h>


CS228Global     g;

void initialize (void);

void main(void)
{short address = 0, i = 0,  action = 0; 
 unsigned int location,location1,location2;
do
{
g.reset = 0;
initialize();
cout << "Type 0 to enter a program, 1 to display registers, 2 to display memory: ";
cin >> action;
cout << "\n";
if(action == 0)
{cout << "Enter your program's starting address: ";
cin >> g.PC;
address =g.PC;
do 
{cout << "Enter instruction  "   << address -g.PC << "\n";
cout << "Or type 0 to end your program: ";
 cin >>  g.MEMORY[address];
address = address + 1;
}
while (  (g.MEMORY[address-1] !=  0 ) && (address < 255));

if (address >= 255)
cout << "Memory overflow";

cout << "\nHere is your program: \n\n";
for (i = g.PC; i< address-1; i++)
 cout << "Location " << i << ": " << g.MEMORY[i] <<  "\n";
cout << "\nNow load your data  or type 0 to end your loading \n\n";
do 
{cout << "Location: ";
 cin >> location;
if ((location >= g.PC && location <= g.PC +address) && location != 0)
{cout << "Illegal location \n";}
else if (location != 0)
{
cout << "Data: ";
 cin >>  g.MEMORY[location];
 }
}
while ( location !=  0 );
cout << "\nHere is the flow of execution of your program:\n\n";
i=1;
while (g.reset == 0)
{       //Fetch Step
 cout << "Cycle " << i << ":  ";
 i= i+1;
 
        g.MAR =  g.PC;//Load next instruction's address into MAR
        g.PC =   g.PC +1; //Increment PC
        g.read = 1; //Fetch the next Instruction into MDR 
        g.MDR =  g.MEMORY[g.MAR]; 
        g.read = 0;
        g.IR = g.MDR;//Load the instruction into IR
        //Decode Step
        g.opcode =(g.IR >> 11) & 31;
    cout << "PC = " << g.PC << ", ";
    cout << "IR = " << g.IR << ",  ";
     switch(g.opcode) 
         {
          case  0://Load
          g.MAR =  g.IR & 0xFFF;//Load address into MAR
          g.read =1; 
          g.MDR =   g.MEMORY[ g.MAR];//Read
          g.read = 0;
          g.AC = g.MDR;   
          break;
          
          case  2://Store
          g.MDR = g.AC;   //Load operand into MDR
          g.MAR = g.IR  & 0x7FF; //Load address into MAR
          g.write =1; 
          g.MEMORY[g.MAR] =  g.MDR; //Write
          g.write = 0;    
          break;

          case  4://Add
          g.MAR = g.IR & 0x7FF;//Load address into MAR
          g.read =1; 
          g.MDR =  g.MEMORY[g.MAR];//Read
          g.read = 0;
          g.AC  =  g.MDR +  g.AC;         
          break;
          
          case  6://Subtract
          g.MAR = g.IR & 0x7FF;//Load address into MAR
          g.read =1; 
          g.MDR =  g.MEMORY[g.MAR];//Read
          g.read = 0;
          g.AC  =  g.AC - g.MDR;          
          break;  

          case  8://OR
          g.MAR = g.IR & 0x7FF;//Load address into MAR
          g.read =1; 
          g.MDR =   g.MEMORY[g.MAR];//Read
          g.read = 0;
          g.AC = g.MDR | g.AC;            
          break;
          
          case  10://AND
          g.MAR = g.IR & 0x7FF;//Load address into MAR
          g.read =1; 
          g.MDR =   g.MEMORY[g.MAR];//Read
          g.read = 0;
          g.AC = g.MDR & g.AC;            
          break;
         
          case  12://Complement
          g.AC = ~g.AC;                   
          break;
                  
          case  14://Clear
          g.AC = 0;                       
          break;
         
          case 16://Shift Right
          g.AC = g.AC >> 1;
          break;
          
          case 18: //Shift Left
          g.AC = g.AC << 1;
          break;
          
          case 20: //Branch
          g.PC = g.IR & 0x7FF;
          break;
          
          case 22: //Branch if AC =0
          if  (g.AC == 0)
          g.PC =g.IR & 0x7FF;
          break;
          
          case 24: //Branch if AC < 0
          if  ((signed int) g.AC < 0)
          g.PC =g.IR & 0x7FF;
          break;

          case 26: //Branch if AC > 0
          if  ((signed int) g.AC > 0)
          g.PC =g.IR & 0x7FF;
          break;


          case 28: //Increment
          g.AC = g.AC + 1;
          break;
                           
          case 30: //Halt
          g.reset =1;
      break;
      
      case 1: //Load with index
          g.MAR =  (g.IR +g.IX)  & 0x7FF;//Load address into MAR
          g.read =1; 
          g.MDR =   g.MEMORY[ g.MAR];//Read
          g.read = 0;
          g.AC = g.MDR;   
          g.IX = g.IX -1;
          break;
      
      case 3: //Store with index
          g.MDR = g.AC;   //Load operand into MDR
          g.MAR = (g.IR +g.IX)  & 0x7FF; //Load address into MAR
          g.write =1; 
          g.MEMORY[g.MAR] =  g.MDR; //Write
          g.write = 0;
          g.IX = g.IX -1;
          break;
          
          case  5://Indexed Add
          g.MAR = (g.IR +g.IX) & 0x7FF;//Load address into MAR
          g.read =1; 
          g.MDR =  g.MEMORY[g.MAR];//Read
          g.read = 0;
          g.AC  =  g.MDR +  g.AC;
          g.IX = g.IX -1;         
          break;
          
          case  7://Indexed Subtract
          g.MAR = (g.IR +g.IX) & 0x7FF;//Load address into MAR
          g.read =1; 
          g.MDR =  g.MEMORY[g.MAR];//Read
          g.read = 0;
          g.AC  =  g.AC - g.MDR;        
          g.IX = g.IX -1;  
          break;  

          case  9://Indexed OR
          g.MAR = (g.IR +g.IX) & 0x7FF;//Load address into MAR
          g.read =1; 
          g.MDR =   g.MEMORY[g.MAR];//Read
          g.read = 0;
          g.AC = g.MDR | g.AC;  
          g.IX = g.IX -1;         
          break;
          
          case  11://Indexed AND
          g.MAR = (g.IR +g.IX) & 0x7FF;//Load address into MAR
          g.read =1; 
          g.MDR =   g.MEMORY[g.MAR];//Read
          g.read = 0;
          g.AC = g.MDR & g.AC;
          g.IX = g.IX -1;                 
          break;
    
      case 13: //Set index register
      g.MAR = g.IR & 0x7FF;
      g.read =1; 
          g.MDR =   g.MEMORY[g.MAR];//Read
      g.IX = g.MDR & 0x7FF;
      g.read = 0;  
      break;
      
      case 15: //Increment index register
      g.IX = g.IX+1;
      break;
       
      case 17: //Decrement index register
      g.IX = g.IX-1;
      break;

          case 19: //Branch if IX =0
          if  (g.IX == 0)
          g.PC =g.IR & 0x7FF;
          break;

          case 21: //Branch if IXC > 0
          if  (g.IX > 0)
          g.PC = g.IR & 0x7FF;
          break;

      }
 cout << "AC = " <<  g.AC << ", ";
 cout << "MAR = " << g.MAR << ", ";
 cout << "MDR = " << g.MDR << ", ";
 cout << "IX = " <<  g.IX << ", "; 
 cout << "reset = " << (short) g.reset << "\n";
}
}
if (action == 1)
{
 cout << "AC = " << g.AC << ",  ";
 cout << "IX = " << g.IX << ",  ";
 cout << "MAR = " << g.MAR << ",  ";
 cout << "MDR = " << g.MDR << ",  \n";
 cout << "PC = " << g.PC << ", ";
 cout << "IR = " << g.IR << ",  ";
 cout << "reset = " << (short) g.reset << "\n\n";
}

if(action == 2)
{cout << "Enter the first address: ";
 cin >> location1;
 cout << "Enter the last address: ";
 cin >> location2;
 cout << "\n";
 for (i = location1; i <= location2; i++)
 cout <<  "Location" << i << ": " << g.MEMORY[i] << "\n";
 cout << "\n";
}
}
while (1);
}

void initialize(void)
{g.PC =   0;
 g.AC =   0;
 g.MAR =  0;
 g.MDR =   0;
 g.IR =   0;
 g.reset = 0;
 g.opcode =0;
 for(g.MAR = 0; g.MAR <= 255; g.MAR++)
 {g.MEMORY[g.MAR] = -1;}
}




Return to my home page

Return to software page