======ALU-Arithmetic Logic Unit Class-alu.h======
The ALU class library is included before the main function like this:\\
#include "alu.h"
**Object instantiation**\\
An object of the type ALU is instatiated like this:\\
//Instantiates an object of type ALU
ALU alu8085;
//Dynamically allocated, remember to "delete p;" when the dynamically allocated object is no longer used so that memory leaks will not occur
ALU *p = new ALU;
**void ALU::setAccumu(unsigned char)**\\
The void ALU::setAccumu(unsigned char) is used to set the accumulator's 8-bit value. Note that its sole parameter takes an unsigned char. This is because we are only dealing with hex numbers.\\
//sets the accumulator value to fe hex or 254 decimal.
alu8085.setAccumu(0xfe);
**void ALU::setInstruction(unsigned char)**\\
The void ALU::setInstruction(unsigned char) function is used to set the temporary register's 8-bit value. Note that its sole parameter takes an unsigned char. This is because we are only dealing with hex numbers.\\
//sets the ADD instruction
alu8085.setInstruction(0x80);
**Valid Instructions**\\
Before an instruction mathematical or logical operation is executed, it is assumed that the accumulator has been loaded with a value upon which a mathematical or logic operation will take place. Use the ALU class's setAccumu member function to do so.
To use valid instructions, next load the instruction register with a valid instruction using the ALU class's setInstruction member function.
Next, place the contents of the specific register or memory address, C for example, into the alu's temporary register using the ALU class's setTempReg. If, however, the operand is 8-bit rather than a register, using the setTempReg function, load the temporary register with the 8-bit value. Next, call the ALU class's doOp instruction to execute the instruction loaded in the instruction register.
Hex Code Mneumonic Description
-----------------------------------------------------------------------------------------------
0x07 RLC Rotate the contents of the Accumulator to the left one position; move the high order bit, D7, into the lowest order bit position, D0.
The carry flag is affected based on the value of bit D7. Flags S, Z, P,and AC are not affected.
0x0f RRC Rotate the contents of the Accumulator to the right one position; move the low order bit, D0, into the highest order bit
position, D7. The carry flag is affected based on the value of bit D0. Flags S, Z, P,and AC are not affected.
0x17 RAL Rotate the contents of the Accumulator to the left one position through the carry flag; move the contents of the carry flag
into the low order bit, D0; move the contents of the high order bit, D7, into the carry flag. Only the carry flag is affected.
0x1f RAR Rotate the contents of the Accumulator to the right one position through the carry flag; move the contents of the carry flag
into the high order bit, D7; move the contents of the low order bit, D0, into the carry flag. Only the carry flag is
affected.
0x2f CMA Complement the contents of the Accumulator
No flags are modified.
0x37 STC Set Carry
The Carry Flag is set to 1, no other flags are modified.
0x3c INR A Increment the contents of A by 1
The following flags are affected: S, Z, P, AC; Carry (CY) is not affected.
0x3d DCR A Decrement the contents of A by 1
The following flags are affected: S, Z, P and AC; Carry (CY) is not affected.
0x3f CMC Complement the Carry Flag
The carry flag is modified, none of the other flags are affected.
0x80 ADD B Add the contents of B to the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x81 ADD C Add the contents of C to the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x82 ADD D Add the contents of D to the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x83 ADD E Add the contents of E to the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x84 ADD H Add the contents of H to the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x85 ADD L Add the contents of L to the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x86 ADD M Add the contents of M to the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x87 ADD A Add the contents of A to the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x90 SUB B Subtract the contents of B from the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x91 SUB C Subtract the contents of C from the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x92 SUB D Subtract the contents of D from the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x93 SUB E Subtract the contents of E from the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x94 SUB H Subtract the contents of H from the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x95 SUB L Subtract the contents of L from the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x96 SUB M Subtract the contents of M from the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0x97 SUB A Subtract the contents of A from the contents of A and place the result in A
All flags are affected to reflect the result of this operation.
0xc6 ADI 8-bit Add immediate to the Accumulator
All flags are affected to reflect the result of this operation.
0xa0 ANA B Logical and the contents of B with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set.
0xa1 ANA C Logical and the contents of C with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set.
0xa2 ANA D Logical and the contents of D with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set.
0xa3 ANA E Logical and the contents of E with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set.
0xa4 ANA H Logical and the contents of H with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set.
0xa5 ANA L Logical and the contents of L with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set.
0xa6 ANA M Logical and the contents of M with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set.
0xa7 ANA A Logical and the contents of A with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set.
0xa8 XRA B Exclusive or the contents of B with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xa9 XRA C Exclusive or the contents of C with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xaa XRA D Exclusive or the contents of D with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xab XRA E Exclusive or the contents of E with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xac XRA H Exclusive or the contents of H with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xad XRA L Exclusive or the contents of L with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xae XRA M Exclusive or the contents of A with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xaf XRA A Exclusive or the contents of A with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xb0 ORA B Inclusive or the contents of B with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xb1 ORA C Inclusive or the contents of C with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xb2 ORA D Inclusive or the contents of D with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xb3 ORA E Inclusive or the contents of E with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xb4 ORA H Inclusive or the contents of H with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xb5 ORA L Inclusive or the contents of L with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xb6 ORA M Inclusive or the contents of M with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xb7 ORA A Inclusive or the contents of A with A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xb8 CMP B Compare the contents of the B with contents of A. A remains unchanged.
if A < register or memory, Carry flag is set and Zero flag is reset.
if A = register or memory, Zero flag is set and Carry flag is reset.
if A > register or memory, Carry and Zero flag are reset.
0xb9 CMP C Compare the contents of the C with contents of A. A remains unchanged.
if A < register or memory, Carry flag is set and Zero flag is reset.
if A = register or memory, Zero flag is set and Carry flag is reset.
if A > register or memory, Carry and Zero flag are reset.
0xba CMP D Compare the contents of the D with contents of A. A remains unchanged.
if A < register or memory, Carry flag is set and Zero flag is reset.
if A = register or memory, Zero flag is set and Carry flag is reset.
if A > register or memory, Carry and Zero flag are reset.
0xbb CMP E Compare the contents of the E with contents of A. A remains unchanged.
if A < register or memory, Carry flag is set and Zero flag is reset.
if A = register or memory, Zero flag is set and Carry flag is reset.
if A > register or memory, Carry and Zero flag are reset.
0xbc CMP H Compare the contents of the H with contents of A. A remains unchanged.
if A < register or memory, Carry flag is set and Zero flag is reset.
if A = register or memory, Zero flag is set and Carry flag is reset.
if A > register or memory, Carry and Zero flag are reset.
0xbd CMP L Compare the contents of the L with contents of A. A remains unchanged.
if A < register or memory, Carry flag is set and Zero flag is reset.
if A = register or memory, Zero flag is set and Carry flag is reset.
if A > register or memory, Carry and Zero flag are reset.
0xbe CMP M Compare the contents of the M with contents of A. A remains unchanged.
if A < register or memory, Carry flag is set and Zero flag is reset.
if A = register or memory, Zero flag is set and Carry flag is reset.
if A > register or memory, Carry and Zero flag are reset.
0xbf CMP A Compare the contents of the A with contents of A. A remains unchanged.
if A < register or memory, Carry flag is set and Zero flag is reset.
if A = register or memory, Zero flag is set and Carry flag is reset.
if A > register or memory, Carry and Zero flag are reset.
0xd6 SUI 8-bit Subtract an immediate value from the contents of A and place the result in A
All flags are affected to reflect the result of the subtraction.
0xe6 ANI 8-bit Logically and immediate value with the contents of A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) is reset; AC is reset.
0xee XRI 8-bit Logically exclusive or immediate value with the contents of A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xf6 ORI 8-bit Logically or immediate value with the contents of A and place the result in A
The following flags are affected: S, Z, P; Carry (CY) and AC are reset.
0xfe CPI 8-bit Compare the contents of the C with contents of A. A remains unchanged.
if A < register or memory, Carry flag is set and Zero flag is reset.
if A = register or memory, Zero flag is set and Carry flag is reset.
if A > register or memory, Carry and Zero flag are reset.
**Issues with instructions**\\
- instructions involving A as an operand currently requires user to copy contents of A into the Temporary register before executing the instruction.\\
- The Parity flag may not be working correctly if the result in A is 0. This bug has been fixed.\\
**void ALU::setTempReg(unsigned char)**\\
//sets the temporary register value to 0f hex or 15 decimal.
alu8085.setTempReg(0x0f);
**void ALU::doOp()**\\
The void ALU::doOp() member function tells an object of type ALU to execute the instruction loaded into the instruction register.\\
//execute the instruction loaded into the instruction register
alu8085.doOp();
**DEPRICATEDvoid ALU::getDataBus()**\\
The void ALU::getDataBus() member function returns the resulting value of the last operation.\\
//prints the return value of getDataBus()
printf("Result of the operation is %x\n", alu8085.getDataBus());
**unsigned char ALU::getFlags()**\\
The member function unsigned char getFlags() gets or returns the value of the flag register.\\
//prints the return value of getFlags()
printf("The flag register value is %x\n", alu8085.getFlags());
**unsigned char ALU::getAccumulator()**\\
The unsigned char getAccumulator() member function is used to get the value of the accumulator after an operation. The result of operations are placed into the accumulator. This function can also be used as a debugging tool to check the value in the accumulator at any time after an object of type ALU has been instantiated.\\
//prints the return value of getAccumulator()
printf("The value in the accumulator is %x\n", alu8085.getAccumulator());
**unsigned char ALU::getZeroFlag()**\\
The member function unsigned char getZeroFlag() returns the value of the zero flag.\\
//prints the value of the zero flag
printf("Zero flag is 0x%02x\n", alu8085.getZeroFlag());
**unsigned char ALU::getCarryFlag()**\\
The member function unsigned char getCarryFlag() returns the value of the carry flag.\\
//prints the value of the carry flag
printf("Carry flag is 0x%02x\n", alu8085.getCarryFlag());
**unsigned char ALU::getSignFlag()**\\
The member function unsigned char getSignFlag() returns the value of the sign flag.\\
//prints the value of the sign flag
printf("Sign flag is 0x%02x\n", alu8085.getSignFlag());
**unsigned char ALU::getParityFlag()**\\
The member function unsigned char getParityFlag() returns the value of the parity flag.\\
//prints the value of the parity flag
printf("Parity flag is 0x%02x\n", alu8085.getParityFlag());
**unsigned char ALU::getAuxCarryFlag()**\\
The member function unsigned char getAuxCarryFlag()returns the value of the auxiliary carry flag.\\
//prints the value of the auxiliary carry flag
printf("Auxiliary flag is 0x%02x\n", alu8085.getAuxCarryFlag());
\\
\\
**alu.h**\\
#ifndef _ALU_H
#define _ALU_H
class ALU
{
public:
ALU();
void setTempReg(unsigned char tempregister);
void setInstruction(unsigned char instruction);
void setAccumu(unsigned char accum);
unsigned char getDataBus();
void doOp();
unsigned char getAccumulator();
unsigned char getFlags();
unsigned char getZeroFlag();
unsigned char getCarryFlag();
unsigned char getSignFlag();
unsigned char getParityFlag();
unsigned char getAuxCarryFlag();
~ALU();
private:
unsigned char A; //accumulator
unsigned char tempreg; //temporary register
unsigned char instructreg; //instruction register
unsigned char databusout; //databus out
//flags
//D7 = S
//D6 = Z
//D5
//D4 = AC
//D3
//D2 = P
//D1
//D0 = CY
unsigned char flags; //the flag register
//functions
void add();
void subtract();
void complementA();
void complementCarry();
void andd();
void orr();
void xorr();
void decrementSource();
void incrementSource();
void rotateARight();
void rotateALeft();
void rotateARightThroughCarry();
void rotateALeftThroughCarry();
void compareWithAccumulator();
void setcarry();
void setCarryFlag();
void resetCarryFlag();
void setZeroFlag();
void resetZeroFlag();
void setSignFlag();
void resetSignFlag();
void setParityFlag();
void resetParityFlag();
void setAuxCarryFlag();
void resetAuxCarryFlag();
void doZeroFlag(unsigned char A);
void doSignFlag(unsigned char A);
void doParityFlag(unsigned char A);
void doAddAuxFlag(unsigned char A, unsigned char B);
unsigned char doAddCarryFlag(unsigned short A, unsigned short B);
unsigned char twosComplement(unsigned char A);
unsigned char doAdd(unsigned char A, unsigned char B);
};
#endif
\\
**alu.cc**\\
#include "alu.h"
#include
const unsigned char signAndMask = 0x7f; //to clear or reset the sign flag
const unsigned char signOrMask = 0x80; //to set the sign flag
const unsigned char zeroAndMask = 0xbf; //to clear or reset the zero flag
const unsigned char zeroOrMask = 0x40; //to set the zero flag
const unsigned char auxcarryAndMask = 0xef; //to clear or reset the aux carry flag
const unsigned char auxcarryOrMask = 0x10; //to set the aux carry flag
const unsigned char parityAndMask = 0xfb; //to clear or reset the parity flag
const unsigned char parityOrMask = 0x04; //to set the parity flag
const unsigned char carryAndMask = 0xfe; //to clear or reset the carry flag
const unsigned char carryOrMask = 0x01; //to set the carry flag
ALU::ALU()
{
flags = 0x00;
}
ALU::~ALU()
{
}
void ALU::setTempReg(unsigned char tempregister)
{
tempreg = tempregister;
}
void ALU::setAccumu(unsigned char accum)
{
A = accum;
}
void ALU::setInstruction(unsigned char instruction)
{
instructreg = instruction;
}
unsigned char ALU::getDataBus()
{
return(databusout);
}
void ALU::setCarryFlag()
{
flags = flags | carryOrMask;
}
void ALU::resetCarryFlag()
{
flags = flags & carryAndMask;
}
void ALU::setZeroFlag()
{
flags = flags | zeroOrMask;
}
void ALU::resetZeroFlag()
{
flags = flags & zeroAndMask;
}
void ALU::setSignFlag()
{
flags = flags | signOrMask;
}
void ALU::resetSignFlag()
{
flags = flags & signAndMask;
}
void ALU::setParityFlag()
{
flags = flags | parityOrMask;
}
void ALU::resetParityFlag()
{
flags = flags & parityAndMask;
}
void ALU::setAuxCarryFlag()
{
flags = flags | auxcarryOrMask;
}
void ALU::resetAuxCarryFlag()
{
flags = flags & auxcarryAndMask;
}
unsigned char ALU::getAccumulator()
{
return(A);
}
unsigned char ALU::getFlags()
{
return(flags);
}
unsigned char ALU::getZeroFlag()
{
unsigned char flag;
if(flags & 0x40) flag = 0x01;
else flag = 0x00;
return (flag);
}
unsigned char ALU::getCarryFlag()
{
unsigned char flag;
if(flags & 0x01) flag = 0x01;
else flag = 0x00;
return (flag);
}
unsigned char ALU:: getSignFlag()
{
unsigned char flag;
if(flags & 0x80) flag = 0x01;
else flag = 0x00;
return (flag);
}
unsigned char ALU::getParityFlag()
{
unsigned char flag;
if(flags & 0x04) flag = 0x01;
else flag = 0x00;
return (flag);
}
unsigned char ALU::getAuxCarryFlag()
{
unsigned char flag;
if(flags & 0x10) flag = 0x01;
else flag = 0x00;
return (flag);
}
void ALU::add()
{
doAddAuxFlag(A,tempreg);
if (doAddCarryFlag(A, tempreg)) setCarryFlag();
else resetCarryFlag();
A = doAdd(A, tempreg);
doZeroFlag(A);
doSignFlag(A);
doParityFlag(A);
}
void ALU::subtract()
{
unsigned char temp = twosComplement(tempreg);
doAddAuxFlag(A,temp);
if (doAddCarryFlag(A, temp)) resetCarryFlag();
else setCarryFlag();
A = doAdd(A, temp);
doZeroFlag(A);
doSignFlag(A);
doParityFlag(A);
}
void ALU::setcarry()
{
setCarryFlag();
}
void ALU::complementA()
{
A = ~A;
}
void ALU::complementCarry()
{
if(getCarryFlag()) resetCarryFlag();
else setCarryFlag();
}
void ALU::andd()
{
A = A & tempreg;
doSignFlag(A);
doZeroFlag(A);
doParityFlag(A);
resetCarryFlag();
setAuxCarryFlag();
}
void ALU::orr()
{
A = A | tempreg;
doSignFlag(A);
doZeroFlag(A);
doParityFlag(A);
resetCarryFlag();
resetAuxCarryFlag();
}
void ALU::xorr()
{
A = A ^ tempreg;
doSignFlag(A);
doZeroFlag(A);
doParityFlag(A);
resetCarryFlag();
resetAuxCarryFlag();
}
void ALU::decrementSource()
{
//only applies to A within the ALU class
unsigned char tA = A & 0x0f;
tA = tA + (~0x01 + 0x01);
if (tA & 0x10) setAuxCarryFlag();
else resetAuxCarryFlag();
A = A + (~0x01 + 0x01);
doSignFlag(A);
doZeroFlag(A);
doParityFlag(A);
}
void ALU::incrementSource()
{
//only applies to A within the ALU class
unsigned char tA = A & 0x0f;
tA = tA + 0x01;
if (tA & 0x10) setAuxCarryFlag();
else resetAuxCarryFlag();
A = A + 0x01;
doSignFlag(A);
doZeroFlag(A);
doParityFlag(A);
}
void ALU::rotateARight()
{
unsigned char tA = 0x00;
if(0x01 & A)
{
tA = 0x80;
setCarryFlag();
}
else resetCarryFlag();
A = A >> 1;
A = A | tA;
}
void ALU::rotateALeft()
{
unsigned char tA = 0x00;
if(0x80 & A)
{
tA = 0x01;
setCarryFlag();
}
else resetCarryFlag();
A = A << 1;
A = A | tA;
}
void ALU::rotateARightThroughCarry()
{
unsigned char tA = 0x00;
if(getCarryFlag()) tA = 0x01;
if(0x01 & A)
{
setCarryFlag();
}
else resetCarryFlag();
A = A >> 1;
A = A | tA;
}
void ALU::rotateALeftThroughCarry()
{
unsigned char tA = 0x00;
if(getCarryFlag()) tA = 0x01;
if(0x80 & A)
{
setCarryFlag();
}
else resetCarryFlag();
A = A << 1;
A = A | tA;
}
void ALU::compareWithAccumulator()
{
unsigned char temp = twosComplement(tempreg);
unsigned temp2 = A;
doAddAuxFlag(temp2,temp);
if (doAddCarryFlag(temp2, temp)) resetCarryFlag();
else setCarryFlag();
temp2 = doAdd(temp2, temp);
doZeroFlag(temp2);
doSignFlag(temp2);
doParityFlag(temp2);
}
void ALU::doZeroFlag(unsigned char A)
{
if(A == 0x00) setZeroFlag();
else resetZeroFlag();
}
void ALU::doSignFlag(unsigned char A)
{
if (A & 0x80) setSignFlag();
else resetSignFlag();
}
void ALU::doParityFlag(unsigned char A)
{
unsigned char accumParity = 0;
unsigned char tempAccum = A;
for (unsigned char i = 0; i <= 7; i++)
{
accumParity += (tempAccum & 0x01);
tempAccum = tempAccum >> 0x01;
}
if((accumParity % 2) == 0) setParityFlag();
else resetParityFlag();
}
void ALU::doAddAuxFlag(unsigned char A, unsigned char B)
{
A = A & 0x0f;
B = B & 0x0f;
if(doAdd(A, B) & 0x10) setAuxCarryFlag();
else resetAuxCarryFlag();
}
unsigned char ALU::doAddCarryFlag(unsigned short A, unsigned short B)
{
unsigned short sum;
unsigned short carry;
do
{
sum = A ^ B;
carry = A & B;
carry = carry << 1;
A = sum;
B = carry;
}
while(carry != 0);
unsigned char temp;
if (sum & 0x100) temp = 0x01;
else temp = 0x00;
return(temp);
}
unsigned char ALU::twosComplement(unsigned char A)
{
A = ~A;
unsigned char B = 1;
return(doAdd(A, B));
}
unsigned char ALU::doAdd (unsigned char A, unsigned char B)
{
unsigned char sum;
unsigned char carry;
do
{
sum = A ^ B;
carry = A & B;
carry = carry << 1;
A = sum;
B = carry;
}
while (carry != 0);
return(sum);
}
void ALU::doOp()
{
switch (instructreg)
{
case 0x00: // NOP operation, do nothing
break;
case 0x01: //LXI B, 16-bit
break;
case 0x02: //STX B
break;
case 0x03: //INX B
break;
case 0x04: //INR B
break;
case 0x05: //DCR B
break;
case 0x06: //MVI B, 8-Bit
break;
case 0x07: //RLC
rotateALeft();
break;
case 0x0f: //RRC
rotateARight();
break;
case 0x11: //LXI B, 16-Bit
break;
case 0x17: //RAL
rotateALeftThroughCarry();
break;
case 0x1f: //RAR
rotateARightThroughCarry();
break;
case 0x21: //LXI H, 16-Bit
break;
case 0x2f: //CMA
complementA();
break;
case 0x31: //LXI SP, 16-Bit
break;
case 0x37: //STC
setcarry();
break;
case 0x3c:
incrementSource();
break;
case 0x3d: //DCR
//alu class only affects A
decrementSource();
break;
case 0x3f:
complementCarry();
break;
case 0x40: //MOV B, B
break;
case 0x41: //MOV B, C
break;
case 0x42: //MOV B, D
break;
case 0x43: //MOV B, E
break;
case 0x44: //MOV B, H
break;
case 0x45: //MOV B, L
break;
case 0x46: //MOV B, M
break;
case 0x47: //MOV B, A
break;
case 0x48: //MOV C, B
break;
case 0x49: //MOV C, C
break;
case 0x4a: //MOV C, D
break;
case 0x4b: //MOV C, E
break;
case 0x4c: //MOV C, H
break;
case 0x4d: //MOV C, L
break;
case 0x4e: //MOV C, M
break;
case 0x4f: //MOV C, A
break;
case 0x50: //MOV D, B
break;
case 0x51: //MOV D, C
break;
case 0x52: //MOV D, D
break;
case 0x53: //MOV D, E
break;
case 0x54: //MOV D, H
break;
case 0x55: //MOV D, L
break;
case 0x56: //MOV D, M
break;
case 0x57: //MOV D, A
break;
case 0x58: //MOV E, B
break;
case 0x59: //MOV E, C
break;
case 0x5a: //MOV E, D
break;
case 0x5b: //MOV E, E
break;
case 0x5c: //MOV E, H
break;
case 0x5d: //MOV E, L
break;
case 0x5e: //MOV E, M
break;
case 0x5f: //MOV E, A
break;
case 0x60: //MOV H, B
break;
case 0x61: //MOV H, C
break;
case 0x62: //MOV H, D
break;
case 0x63: //MOV H, E
break;
case 0x64: //MOV H, H
break;
case 0x65: //MOV H, L
break;
case 0x66: //MOV H, M
break;
case 0x67: //MOV H, A
break;
case 0x68: //MOV L, B
break;
case 0x69: //MOV L, C
break;
case 0x6a: //MOV L, D
break;
case 0x6b: //MOV L, E
break;
case 0x6c: //MOV L, H
break;
case 0x6d: //MOV L, L
break;
case 0x6e: //MOV L, M
break;
case 0x6f: //MOV L, A
break;
case 0x78: //MOV A, B
break;
case 0x79: //MOV A, C
break;
case 0x7a: //MOV A, D
break;
case 0x7b: //MOV A, E
break;
case 0x7c: //MOV A, H
break;
case 0x7d: //MOV A, L
break;
case 0x7e: //MOV A, M
break;
case 0x7f: //MOV A, A
break;
case 0x80: //ADD B
case 0x81: //ADD C
case 0x82: //ADD D
case 0x83: //ADD E
case 0x84: //ADD H
case 0x85: //ADD L
case 0x86: //ADD M
case 0x87: //ADD A
add();
break;
case 0x88: //ADC B
break;
case 0x89: //ADC C
break;
case 0x8a: //ADC D
break;
case 0x8b: //ADC E
break;
case 0x8c: //ADC H
break;
case 0x8d: //ADC L
break;
case 0x8e: //ADC M
break;
case 0x8f: //ADC A
break;
case 0x90: //SUB B
case 0x91: //SUB C
case 0x92: //SUB D
case 0x93: //SUB E
case 0x94: //SUB H
case 0x95: //SUB L
case 0x96: //SUB M
case 0x97: //SUB A
subtract();
break;
case 0xa0: //ANA B
case 0xa1: //ANA C
case 0xa2: //ANA D
case 0xa3: //ANA E
case 0xa4: //ANA H
case 0xa5: //ANA L
case 0xa6: //ANA M
case 0xa7: //ANA A
andd();
break;
case 0xa8: //XRA B
case 0xa9: //XRA C
case 0xaa: //XRA D
case 0xab: //XRA E
case 0xac: //XRA H
case 0xad: //XRA L
case 0xae: //XRA M
case 0xaf: //XRA A
xorr();
break;
case 0xb0: //ORA B
case 0xb1: //ORA C
case 0xb2: //ORA D
case 0xb3: //ORA E
case 0xb4: //ORA H
case 0xb5: //ORA L
case 0xb6: //ORA M
case 0xb7: //ORA A
orr();
break;
case 0xb8: //CMP B
case 0xb9: //CMP C
case 0xba: //CMP D
case 0xbb: //CMP E
case 0xbc: //CMP H
case 0xbd: //CMP L
case 0xbe: //CMP M
case 0xbf: //CMP A
compareWithAccumulator();
break;
case 0xc6: //ADI 8-bit
add();
break;
case 0xcd: //CALL 16-bit
break;
case 0xce: //ACI 8-bit
break;
case 0xd6: //SUB 8-bit
subtract();
break;
case 0xdc: //CC 16-bit
break;
case 0xe6: //ANI 8-bit
andd();
break;
case 0xee:
xorr();
break;
case 0xf6:
orr();
break;
case 0xfc: //CM 16-bit
break;
case 0xfe:
compareWithAccumulator();
break;
default:
printf("Error %x is not an 8085 instruction\n", instructreg);
}
}
\\
\\
**alutest.cc**\\
#include
#include
#include
#include "alu.h"
#include
unsigned char convert2CharStringTo2DigitHex(char * string);
void getAndPrintVal(char *printString, char *valString);
void prompt(char *);
int main()
{
char *message;
char message1[18] = "Enter instruction";
char message2[24] = "Enter Accumulator value";
char message3[31] = "Enter Temporary Register value";
char hex2DigitString[3];
char quit;
char *pQuit;
pQuit = &quit;
ALU alu8085;
printf("Welcome to the 8085 alu simulator\n");
prompt(pQuit);
while(toupper(quit)!= 'Q')
{
message = message1;
for (int i = 1; i <= 3; i++)
{
getAndPrintVal(message, hex2DigitString);
switch(i)
{
case 1:
alu8085.setInstruction(convert2CharStringTo2DigitHex(hex2DigitString));
message = message2;
break;
case 2:
alu8085.setAccumu(convert2CharStringTo2DigitHex(hex2DigitString)); $
message = message3;
break;
case 3:
alu8085.setTempReg(convert2CharStringTo2DigitHex(hex2DigitString));
break;
}
}
alu8085.doOp();
printf("Result is 0x%02x\n", alu8085.getAccumulator());
printf("Flag Register = 0x%02x\n",alu8085.getFlags());
printf("Sign flag is %x\n", alu8085.getSignFlag());
printf("Carry flag is %x\n", alu8085.getCarryFlag());
printf("Zero flag is %x\n", alu8085.getZeroFlag());
printf("Parity flag is %x\n", alu8085.getParityFlag());
printf("Aux carry flag is %x\n", alu8085.getAuxCarryFlag());
printf("\n");
prompt(pQuit);
}
return(0);
}
unsigned char convert2CharStringTo2DigitHex(char * string)
{
for (int i = 0; i < 2; i++)
{
if(*(string + i) >= '0' && *(string + i) <= '9') *(string + i) = 0x0f & *(string + i);
else if (*(string + i) >= 'a' && *(string + i) <= 'f') *(string + i) = *(string + i) - 87;
}
*string = *string << 4;
*string = *(string + 1)|*string;
return(*string);
}
void getAndPrintVal(char *printString, char *valString)
{
bool doneFlag = false;
while (!doneFlag)
{
printf(printString);
printf("\n");
printf("0x");
scanf("%s", valString);
int check = (int) strnlen(valString, 10);
if(check > 2)
{
printf("Fatal error-hex value is greater than 2 digits\n");
exit(0);
}
else if (check < 2)
{
printf("Error-hex value is must be at least 2 digits\n");
doneFlag = false;
}
else
{
for (int i = 0; i < 2; i++)
{
*(valString + i) = tolower(*(valString + i));
if((*(valString + i) >= '0' && *(valString + i) <= '9') || (*(valString + i) >= 'a'$
{
doneFlag = true;
}
else
{
doneFlag = false;
printf("Error, digits must be 0-9 or a-f\n");
break;
}
}
}
}
}
void prompt(char *quit)
{
printf("Press c to continue, or q to quit\n");
scanf("%s", quit);
}
\\
**Makefile**\\
CXX = g++ $(CXXFLAGS) $(INC) $(LIBS)
AR = ar
CXXFLAGS = -Wall
INC = -I ../../include/
LIBS =
SRC = alu.cc alutest.cc
OBJ = $(SRC:.cc=.o)
BIN = alutest
all: $(SRC) $(BIN)
debug: CXX += -DDEBUG -g
debug: DEBUG = debug
debug: $(SRC) $(BIN)
$(BIN): $(OBJ)
ifneq ($(MAKECMDGOALS),debug)
@printf "[CC] %-20s ... " "$(BIN)"
@$(CXX) -o $(BIN) $(OBJ) && echo "SUCCESS" || echo "FAIL"
else
$(CXX) -o $(BIN) $(OBJ)
endif
.cc.o:
ifneq ($(MAKECMDGOALS),debug)
@printf "[B] %-20s ... " "$<"
@$(CXX) -c $< && echo "OK" || echo "FAIL"
else
$(CXX) -c $<
endif
clean:
rm -f *.o $(BIN) core
default: $(BIN)
\\
To use Makefile, all of the files other than alu.h should reside in the same directory.
lab46:~/src/cpu/8085/arithmeticlogicunit$ ls *.cc
alu.cc alutest.cc
lab46:~/src/cpu/8085/arithmeticlogicunit$ ls Makefile
Makefile
\\
The include file, alu.h should reside in its own directory.\\
lab46:~/src/cpu/include$ ls alu.h
alu.h
\\
To compile the files, change the working directory to where the source files reside, and then type "make" at the command prompt.\\
lab46:~/src/cpu/8085/arithmeticlogicunit$ make
[B] alu.cc ... OK
[B] alutest.cc ... OK
[CC] alutest ... SUCCESS
\\
To test the ALU API, execute alutest from the directory where the source and executable files reside.\\
lab46:~/src/cpu/8085/arithmeticlogicunit$ ./alutest
Welcome to the 8085 alu simulator
Press c to continue, or q to quit
c
Enter instruction
0x80
Enter Accumulator value
0x0f
Enter Temporary Register value
0x01
Result is 0x10
Flag Register = 0x10
Sign flag is 0
Carry flag is 0
Zero flag is 0
Parity flag is 0
Aux carry flag is 1
Press c to continue, or q to quit
q
lab46:~/src/cpu/8085/arithmeticlogicunit$