/*
/* 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;}
}