This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
user:jr018429:portfolio:alu_api [2011/05/13 12:53] – [ALU-Arithmetic Logic Unit Class-alu.h] jr018429 | user:jr018429:portfolio:alu_api [2011/05/13 18:08] (current) – [ALU-Arithmetic Logic Unit Class-alu.h] jr018429 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ======ALU-Arithmetic Logic Unit Class-alu.h====== | ||
+ | The ALU class library is included before the main function like this:\\ | ||
+ | < | ||
+ | #include " | ||
+ | </ | ||
+ | **Object instantiation**\\ | ||
+ | An object of the type ALU is instatiated like this:\\ | ||
+ | < | ||
+ | // | ||
+ | ALU alu8085; | ||
+ | // | ||
+ | ALU *p = new ALU; | ||
+ | </ | ||
+ | **void ALU:: | ||
+ | The void ALU:: | ||
+ | < | ||
+ | //sets the accumulator value to fe hex or 254 decimal. | ||
+ | alu8085.setAccumu(0xfe); | ||
+ | </ | ||
+ | **void ALU:: | ||
+ | The void ALU:: | ||
+ | < | ||
+ | //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' | ||
+ | To use valid instructions, | ||
+ | Next, place the contents of the specific register or memory address, C for example, into the alu's temporary register using the ALU class' | ||
+ | < | ||
+ | Hex Code Mneumonic | ||
+ | ----------------------------------------------------------------------------------------------- | ||
+ | 0x07 | ||
+ | The carry flag is affected based on the value of bit D7. Flags S, Z, P,and AC are not affected. | ||
+ | |||
+ | |||
+ | 0x0f | ||
+ | position, D7. The carry flag is affected based on the value of bit D0. Flags S, Z, P,and AC are not affected. | ||
+ | |||
+ | |||
+ | 0x17 | ||
+ | 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 | ||
+ | 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 | ||
+ | No flags are modified. | ||
+ | |||
+ | |||
+ | 0x37 | ||
+ | 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 | ||
+ | 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 | ||
+ | The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set. | ||
+ | |||
+ | 0xa1 ANA C | ||
+ | The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set. | ||
+ | |||
+ | 0xa2 ANA D | ||
+ | The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set. | ||
+ | |||
+ | 0xa3 ANA E | ||
+ | The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set. | ||
+ | |||
+ | 0xa4 ANA H | ||
+ | The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set. | ||
+ | |||
+ | 0xa5 ANA L | ||
+ | The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set. | ||
+ | |||
+ | 0xa6 ANA M | ||
+ | The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set. | ||
+ | |||
+ | 0xa7 ANA A | ||
+ | The following flags are affected: S, Z, P; Carry (CY) is reset; AC is set. | ||
+ | |||
+ | |||
+ | 0xa8 XRA B | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | 0xa9 XRA C | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | 0xaa XRA D | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | 0xab XRA E | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | 0xac XRA H | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | 0xad XRA L | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | 0xae XRA M | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | 0xaf XRA A | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | |||
+ | 0xb0 ORA B | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | 0xb1 ORA C | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | 0xb2 ORA D | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | 0xb3 ORA E | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | 0xb4 ORA H | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | 0xb5 ORA L | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | 0xb6 ORA M | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | 0xb7 ORA A | ||
+ | The following flags are affected: S, Z, P; Carry (CY) and AC are reset. | ||
+ | |||
+ | |||
+ | 0xb8 CMP B | ||
+ | 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 | ||
+ | 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 | ||
+ | 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 | ||
+ | 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 | ||
+ | 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 | ||
+ | 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 | ||
+ | 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 | ||
+ | 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.\\ | ||
+ | - < | ||
+ | **void ALU:: | ||
+ | < | ||
+ | //sets the temporary register value to 0f hex or 15 decimal. | ||
+ | alu8085.setTempReg(0x0f); | ||
+ | </ | ||
+ | **void ALU:: | ||
+ | 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(); | ||
+ | </ | ||
+ | **DEPRICATED< | ||
+ | < | ||
+ | < | ||
+ | //prints the return value of getDataBus() | ||
+ | printf(" | ||
+ | </ | ||
+ | **unsigned char ALU:: | ||
+ | The member function unsigned char getFlags() gets or returns the value of the flag register.\\ | ||
+ | < | ||
+ | //prints the return value of getFlags() | ||
+ | printf(" | ||
+ | </ | ||
+ | **unsigned char ALU:: | ||
+ | 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(" | ||
+ | </ | ||
+ | **unsigned char ALU:: | ||
+ | The member function unsigned char getZeroFlag() returns the value of the zero flag.\\ | ||
+ | < | ||
+ | //prints the value of the zero flag | ||
+ | printf(" | ||
+ | </ | ||
+ | **unsigned char ALU:: | ||
+ | The member function unsigned char getCarryFlag() returns the value of the carry flag.\\ | ||
+ | < | ||
+ | //prints the value of the carry flag | ||
+ | printf(" | ||
+ | </ | ||
+ | **unsigned char ALU:: | ||
+ | The member function unsigned char getSignFlag() returns the value of the sign flag.\\ | ||
+ | < | ||
+ | //prints the value of the sign flag | ||
+ | printf(" | ||
+ | </ | ||
+ | **unsigned char ALU:: | ||
+ | The member function unsigned char getParityFlag() returns the value of the parity flag.\\ | ||
+ | < | ||
+ | //prints the value of the parity flag | ||
+ | printf(" | ||
+ | </ | ||
+ | **unsigned char ALU:: | ||
+ | The member function unsigned char getAuxCarryFlag()returns the value of the auxiliary carry flag.\\ | ||
+ | < | ||
+ | //prints the value of the auxiliary carry flag | ||
+ | printf(" | ||
+ | </ | ||
+ | \\ | ||
+ | \\ | ||
+ | **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; // | ||
+ | unsigned char tempreg; | ||
+ | unsigned char instructreg; | ||
+ | unsigned char databusout; | ||
+ | //flags | ||
+ | //D7 = S | ||
+ | //D6 = Z | ||
+ | //D5 | ||
+ | //D4 = AC | ||
+ | //D3 | ||
+ | //D2 = P | ||
+ | //D1 | ||
+ | //D0 = CY | ||
+ | unsigned char flags; | ||
+ | //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); | ||
+ | }; | ||
+ | # | ||
+ | </ | ||
+ | \\ | ||
+ | **alu.cc**\\ | ||
+ | < | ||
+ | #include " | ||
+ | #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:: | ||
+ | { | ||
+ | | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | A = accum; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | instructreg = instruction; | ||
+ | } | ||
+ | |||
+ | unsigned char ALU:: | ||
+ | { | ||
+ | return(databusout); | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | flags = flags | carryOrMask; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | flags = flags & carryAndMask; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | flags = flags | zeroOrMask; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | flags = flags & zeroAndMask; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | flags = flags | signOrMask; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | flags = flags & signAndMask; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | flags = flags | parityOrMask; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | flags = flags & parityAndMask; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | flags = flags | auxcarryOrMask; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | flags = flags & auxcarryAndMask; | ||
+ | } | ||
+ | |||
+ | unsigned char ALU:: | ||
+ | { | ||
+ | return(A); | ||
+ | } | ||
+ | |||
+ | unsigned char ALU:: | ||
+ | { | ||
+ | return(flags); | ||
+ | } | ||
+ | |||
+ | unsigned char ALU:: | ||
+ | { | ||
+ | unsigned char flag; | ||
+ | if(flags & 0x40) flag = 0x01; | ||
+ | else flag = 0x00; | ||
+ | return (flag); | ||
+ | } | ||
+ | |||
+ | unsigned char ALU:: | ||
+ | { | ||
+ | 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:: | ||
+ | { | ||
+ | unsigned char flag; | ||
+ | if(flags & 0x04) flag = 0x01; | ||
+ | else flag = 0x00; | ||
+ | return (flag); | ||
+ | } | ||
+ | |||
+ | unsigned char ALU:: | ||
+ | { | ||
+ | unsigned char flag; | ||
+ | if(flags & 0x10) flag = 0x01; | ||
+ | else flag = 0x00; | ||
+ | return (flag); | ||
+ | } | ||
+ | |||
+ | void ALU::add() | ||
+ | { | ||
+ | doAddAuxFlag(A, | ||
+ | if (doAddCarryFlag(A, | ||
+ | else resetCarryFlag(); | ||
+ | A = doAdd(A, tempreg); | ||
+ | doZeroFlag(A); | ||
+ | doSignFlag(A); | ||
+ | doParityFlag(A); | ||
+ | } | ||
+ | |||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | unsigned char temp = twosComplement(tempreg); | ||
+ | doAddAuxFlag(A, | ||
+ | if (doAddCarryFlag(A, | ||
+ | else setCarryFlag(); | ||
+ | A = doAdd(A, temp); | ||
+ | doZeroFlag(A); | ||
+ | doSignFlag(A); | ||
+ | doParityFlag(A); | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | setCarryFlag(); | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | A = ~A; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | 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:: | ||
+ | { | ||
+ | //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:: | ||
+ | { | ||
+ | //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:: | ||
+ | { | ||
+ | unsigned char tA = 0x00; | ||
+ | if(0x01 & A) | ||
+ | { | ||
+ | tA = 0x80; | ||
+ | setCarryFlag(); | ||
+ | } | ||
+ | else resetCarryFlag(); | ||
+ | A = A >> 1; | ||
+ | A = A | tA; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | unsigned char tA = 0x00; | ||
+ | if(0x80 & A) | ||
+ | { | ||
+ | tA = 0x01; | ||
+ | setCarryFlag(); | ||
+ | } | ||
+ | else resetCarryFlag(); | ||
+ | A = A << 1; | ||
+ | A = A | tA; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | unsigned char tA = 0x00; | ||
+ | if(getCarryFlag()) tA = 0x01; | ||
+ | if(0x01 & A) | ||
+ | { | ||
+ | setCarryFlag(); | ||
+ | } | ||
+ | else resetCarryFlag(); | ||
+ | A = A >> 1; | ||
+ | A = A | tA; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | unsigned char tA = 0x00; | ||
+ | if(getCarryFlag()) tA = 0x01; | ||
+ | if(0x80 & A) | ||
+ | { | ||
+ | setCarryFlag(); | ||
+ | } | ||
+ | else resetCarryFlag(); | ||
+ | A = A << 1; | ||
+ | A = A | tA; | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | unsigned char temp = twosComplement(tempreg); | ||
+ | unsigned temp2 = A; | ||
+ | doAddAuxFlag(temp2, | ||
+ | if (doAddCarryFlag(temp2, | ||
+ | else setCarryFlag(); | ||
+ | temp2 = doAdd(temp2, | ||
+ | doZeroFlag(temp2); | ||
+ | doSignFlag(temp2); | ||
+ | doParityFlag(temp2); | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | if(A == 0x00) setZeroFlag(); | ||
+ | else resetZeroFlag(); | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | if (A & 0x80) setSignFlag(); | ||
+ | else resetSignFlag(); | ||
+ | } | ||
+ | |||
+ | void ALU:: | ||
+ | { | ||
+ | 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:: | ||
+ | { | ||
+ | A = A & 0x0f; | ||
+ | B = B & 0x0f; | ||
+ | if(doAdd(A, B) & 0x10) setAuxCarryFlag(); | ||
+ | else resetAuxCarryFlag(); | ||
+ | } | ||
+ | |||
+ | unsigned char ALU:: | ||
+ | { | ||
+ | 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:: | ||
+ | { | ||
+ | A = ~A; | ||
+ | unsigned char B = 1; | ||
+ | return(doAdd(A, | ||
+ | } | ||
+ | |||
+ | 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(" | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | \\ | ||
+ | \\ | ||
+ | **alutest.cc**\\ | ||
+ | < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include " | ||
+ | # | ||
+ | unsigned char convert2CharStringTo2DigitHex(char * string); | ||
+ | void getAndPrintVal(char *printString, | ||
+ | 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(" | ||
+ | prompt(pQuit); | ||
+ | while(toupper(quit)!= ' | ||
+ | { | ||
+ | message = message1; | ||
+ | for (int i = 1; i <= 3; i++) | ||
+ | { | ||
+ | getAndPrintVal(message, | ||
+ | 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(" | ||
+ | printf(" | ||
+ | printf(" | ||
+ | printf(" | ||
+ | printf(" | ||
+ | printf(" | ||
+ | printf(" | ||
+ | printf(" | ||
+ | prompt(pQuit); | ||
+ | } | ||
+ | return(0); | ||
+ | } | ||
+ | |||
+ | unsigned char convert2CharStringTo2DigitHex(char * string) | ||
+ | { | ||
+ | for (int i = 0; i < 2; i++) | ||
+ | { | ||
+ | if(*(string + i) >= ' | ||
+ | else if (*(string + i) >= ' | ||
+ | } | ||
+ | *string = *string << 4; | ||
+ | *string = *(string + 1)|*string; | ||
+ | return(*string); | ||
+ | } | ||
+ | |||
+ | void getAndPrintVal(char *printString, | ||
+ | { | ||
+ | bool doneFlag = false; | ||
+ | while (!doneFlag) | ||
+ | { | ||
+ | printf(printString); | ||
+ | printf(" | ||
+ | printf(" | ||
+ | scanf(" | ||
+ | int check = (int) strnlen(valString, | ||
+ | if(check > 2) | ||
+ | { | ||
+ | printf(" | ||
+ | exit(0); | ||
+ | } | ||
+ | else if (check < 2) | ||
+ | { | ||
+ | printf(" | ||
+ | doneFlag = false; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | for (int i = 0; i < 2; i++) | ||
+ | { | ||
+ | | ||
+ | if((*(valString + i) >= ' | ||
+ | { | ||
+ | doneFlag = true; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | doneFlag = false; | ||
+ | printf(" | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | void prompt(char *quit) | ||
+ | { | ||
+ | printf(" | ||
+ | scanf(" | ||
+ | } | ||
+ | </ | ||
+ | \\ | ||
+ | **Makefile**\\ | ||
+ | < | ||
+ | CXX = g++ $(CXXFLAGS) $(INC) $(LIBS) | ||
+ | AR = ar | ||
+ | CXXFLAGS = -Wall | ||
+ | INC = -I ../ | ||
+ | LIBS = | ||
+ | SRC = alu.cc alutest.cc | ||
+ | OBJ = $(SRC: | ||
+ | BIN = alutest | ||
+ | all: $(SRC) $(BIN) | ||
+ | |||
+ | debug: CXX += -DDEBUG -g | ||
+ | debug: DEBUG = debug | ||
+ | debug: $(SRC) $(BIN) | ||
+ | |||
+ | $(BIN): $(OBJ) | ||
+ | ifneq ($(MAKECMDGOALS), | ||
+ | @printf " | ||
+ | @$(CXX) -o $(BIN) $(OBJ) && echo " | ||
+ | else | ||
+ | $(CXX) -o $(BIN) $(OBJ) | ||
+ | endif | ||
+ | |||
+ | .cc.o: | ||
+ | ifneq ($(MAKECMDGOALS), | ||
+ | @printf " | ||
+ | @$(CXX) -c $< && echo " | ||
+ | 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. | ||
+ | <cli> | ||
+ | lab46: | ||
+ | alu.cc | ||
+ | lab46: | ||
+ | Makefile | ||
+ | </ | ||
+ | \\ | ||
+ | The include file, alu.h should reside in its own directory.\\ | ||
+ | <cli> | ||
+ | lab46: | ||
+ | alu.h | ||
+ | </ | ||
+ | \\ | ||
+ | To compile the files, change the working directory to where the source files reside, and then type " | ||
+ | <cli> | ||
+ | lab46: | ||
+ | [B] | ||
+ | [B] | ||
+ | [CC] alutest | ||
+ | </ | ||
+ | \\ | ||
+ | To test the ALU API, execute alutest from the directory where the source and executable files reside.\\ | ||
+ | <cli> | ||
+ | lab46: | ||
+ | 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: | ||
+ | </ |