#include <iostream>
#include <iomanip>
#include "SML.h"
using namespace std;
SML::SML(int *Memory,int acc,int ins,int ope,int opd,int inr ):memory(Memory)
{
accumulator=acc;
instructionCounter=ins;
operationCode=ope;
operand=opd;
instructionRegister=inr;
}
void SML::load()
{
int instruction=0;
int i = 0;
cout<<"*** Welcome to Simpletron ***"<<endl;
cout<<"*** Please enter your program one instruction ***"<<endl;
cout<<"*** ( or data word ) at a time. I will type the ***"<<endl;
cout<<"*** location number and a question mark ( ? ). ***"<<endl;
cout<<"*** You then type the word for that location. ***"<<endl;
cout<<"*** Type the sentinel -99999 to stop entering ***"<<endl;
cout<<"*** your program. ***" <<endl;
cout<<"00"<<" "<<"?"<<" "<<":";
cin>>instruction;
while ( instruction != END )
{
if (!(instruction>=-99999 &&instruction <=99999) )
{
cout<< "Number out of range. Please enter again."<<endl;
}
else
{
memory[ i++ ] = instruction;
}
cout<<setw(2)<<setfill('0')<<i<<" "<<"?"<<" :";
cin>>instruction;
}
}
void SML::execute()
{
int fatal = FALSE;
int temp=0;
cout<<endl<<"************START************"<<endl<<endl;
instructionRegister = memory[ instructionCounter ];
operationCode = instructionRegister / 100;
operand = instructionRegister % 100;
while ( operationCode != HALT || !fatal )
{
switch ( operationCode )
{
case READ:
cout<<"Enter an integer: ";
cin>>temp;
while ( !(temp>=-9999 && temp <=9999) )
{
cout<< "Number out of range. Please enter again: " ;
cin>>temp;
}
memory[operand] = temp;
++instructionCounter;
break;
case WRITE:
cout<<"Contents of"<<setw(2)<<setfill('0')<<operand<<":"<<memory[operand];
++instructionCounter;
break;
case LOAD:
accumulator = memory[ operand ];
++instructionCounter;
break;
case STORE:
memory[operand ] =accumulator;
++instructionCounter;
break;
case ADD:
temp = accumulator + memory[ operand ];
if ( !(temp>=-9999 && temp<=9999) )
{
cout<<"*** FATAL ERROR: Accumulator overflow ***"<<endl;
cout<<"*** Simpletron execution abnormally terminated ***"<<endl;
fatal = TRUE;
}
else
{
accumulator = temp;
++instructionCounter;
}
break;
case SUBTRACT:
temp = accumulator - memory[ operand ];
if (!(temp>=-9999 && temp<=9999) )
{
cout<<"*** FATAL ERROR: Accumulator overflow ***"<<endl;
cout<<"*** Simpletron execution abnormally terminated ***"<<endl;
fatal = TRUE;
}
else
{
accumulator = temp;
++instructionCounter;
}
break;
case DIVIDE:
if ( memory[ operand] == 0 )
{
cout<<"*** FATAL ERROR: Attempt to divide by zero ***"<<endl;
cout<<"*** Simpletron execution abnormally terminated ***"<<endl;
fatal = TRUE;
}
else
{
accumulator /= memory[operand ];
++instructionCounter;
}
break;
case MULTIPLY:
temp = accumulator * memory[operand ];
if ( !(temp>=-9999 && temp<=9999 ))
{
cout<< "*** FATAL ERROR: Accumulator overflow ***"<<endl;
cout<< "*** Simpletron execution abnormally terminated ***"<<endl;
fatal = TRUE;
}
else
{
accumulator = temp;
++instructionCounter;
}
break;
case BRANCH:
instructionCounter = operand;
break;
case BRANCHNEG:
if ( accumulator < 0 )
{
instructionCounter = operand;
}
else
{
++instructionCounter;
}
break;
case BRANCHZERO:
if ( accumulator == 0 )
{
instructionCounter = operand;
}
else
{
++instructionCounter;
}
break;
default:
cout<<"*** FATAL ERROR: Invalid opcode detected ***"<<endl;
cout<<"*** Simpletron execution abnormally terminated ***"<<endl;
fatal = TRUE;
break;
}
instructionRegister = memory[ instructionCounter ];
operationCode = instructionRegister / 100;
operand = instructionRegister % 100;
}
cout<<"*************END*************"<<endl;
}
void SML::dump()
{
int i;
cout<<"REGISTERS:"<<endl<< "accumulator(累加器寄存器):"<<accumulator<<endl<<"instructioncounter(正在执行指令内存位子):"
<<instructionCounter<<endl<<"instructionregister(内存转移): "<< instructionRegister<<endl
<<"operationcode(最后执行操作):"<< operationCode<<endl<< "operand(内存位子): "<< operand<<endl;
cout<<endl<<endl<<"MEMORY:"<<endl;
for ( i = 0; i <= 9; i++ )
{
cout<<" "<<setw(4)<<setfill(' ')<<i;
}
for ( i = 0; i <SIZE; i++ )
{
if ( i % 10 == 0 )
{
cout<<endl<<setw(2)<<setfill('0')<<i/10;
}
cout<<"+"<<setw(4)<<setfill('0')<<memory[i]<<" ";
}
cout<<endl;
}