User Tools

Site Tools


user:jr018429:portfolio:alu_api

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

  1. instructions involving A as an operand currently requires user to copy contents of A into the Temporary register before executing the instruction.
  2. 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 <cstdio>

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 <cstdio>
#include <ctype.h>
#include <stdlib.h>
#include "alu.h"
#include<string.h>
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$
user/jr018429/portfolio/alu_api.txt · Last modified: 2011/05/13 18:08 by jr018429