//----------------------------------------------------------------------------- // Roman Lysecky, Tony Givargis, and Greg Stitt // Copyright 1999, All Rights Reserved. //----------------------------------------------------------------------------- // Version 1.1 //----------------------------------------------------------------------------- #include #include #include #include #include #include #include #include "i8051.h" //----------------------------------------------------------------------------- I8051::I8051() : InvalidData(11), LineLength(80), RecordTypeLength(3), ACC(0x0160), PSW(0x0150), B(0x0170), SP(0x0101), P0(0x0100), P1(0x0110), P2(0x0120), P3(0x0130), DPL(0x0102), DPH(0x0103), PC(0), instrCount(0), cycleCount(0), progEnd(false) { // no code } //----------------------------------------------------------------------------- I8051::~I8051() { // no code } //----------------------------------------------------------------------------- bool I8051::Simulate(char* inFile, char* outFile) { ofstream os; clock_t begin, end; unsigned short tempProduct = 0; unsigned short jumpAddr; short tempAdd; unsigned char directAddr = 0; unsigned char regNum; unsigned char rotateBit; unsigned char lowerNibble; unsigned char tempACC; char temp; bool carry3; bool carry6; bool carry7; bool borrow3; bool borrow6; bool borrow7; #ifdef PORTS char lastP0 = 0xFF; char lastP1 = 0xFF; char lastP2 = 0xFF; char lastP3 = 0xFF; #endif if( !LoadHex(inFile) ) { return false; } else { #ifdef DEBUG os.open(outFile); if( os.bad() ) { cerr << "Error: bad output file." << endl; return false; } #endif // initialize 8051 internal RAM Init8051(RAM); begin = clock(); // program Loaded emulate program while(!progEnd) { if( PC >= RomSize ) PC = 0; // get instruction IR = ROM[PC++]; // increment number of instructions executed instrCount++; switch(Decode(IR)) { //(A) <- (A) & (Rn) case ANL1: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "ANL1: " << endl; #endif regNum = IR & 0x07; RAM[ACC] &= RAM[GetRegisterBank()+regNum]; cycleCount += 12; break; //(A) <- (A) & (direct) case ANL2: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "ANL2: " << endl; #endif IR = ROM[PC++]; RAM[ACC] &= RAM[IR < 128 ? IR : (IR+128)]; cycleCount += 12; break; //(A) <- (A) & ((Ri)) case ANL3: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "ANL3: " << endl; #endif regNum = IR & 0x01; RAM[ACC] &= RAM[RAM[GetRegisterBank()+regNum]]; cycleCount += 12; break; //(A) <- (A) & (#data) case ANL4: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "ANL4: " << endl; #endif IR = ROM[PC++]; RAM[ACC] &= IR; cycleCount += 12; break; // (A)??(direct) <-> 1; if( rotateBit == 0x01 ) { SetBit(RAM[ACC], 7); } else { ClearBit(RAM[ACC], 7); } cycleCount += 12; break; // Rotate Right Thru Carry(A) case RRC: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "RRC: " << endl; #endif rotateBit = GetBit(RAM[ACC], 0); RAM[ACC] = (unsigned char)RAM[ACC] >> 1; if( GetBit(RAM[PSW], CY) == 0x01 ) { SetBit(RAM[ACC], 7); } if( rotateBit == 0x01 ) { SetBit(RAM[PSW], CY); } else { ClearBit(RAM[PSW], CY); } cycleCount += 12; break; // Swap nibbles(A) case SWAP: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "SWAP: " << endl; #endif lowerNibble = RAM[ACC] & 0x0F; RAM[ACC] = RAM[ACC] >> 4; RAM[ACC] |= (lowerNibble << 4); cycleCount += 12; break; // XCH (A), (Rn) case XCH1: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "XCH1: " << endl; #endif regNum = IR & 0x07; temp = RAM[ACC]; RAM[ACC] = RAM[GetRegisterBank()+regNum]; RAM[GetRegisterBank()+regNum] = temp; cycleCount += 12; break; // XCH (A), (direct) case XCH2: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "XCH2: " << endl; #endif IR = ROM[PC++]; temp = RAM[ACC]; RAM[ACC] = RAM[IR < 128 ? IR : (IR+128)]; RAM[IR < 128 ? IR : (IR+128)] = temp; cycleCount += 12; break; // XCH (A), ((Ri)) case XCH3: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "XCH3: " << endl; #endif regNum = IR & 0x01; temp = RAM[ACC]; RAM[ACC] = RAM[RAM[GetRegisterBank()+regNum]]; RAM[RAM[GetRegisterBank()+regNum]] = temp; cycleCount += 12; break; // XCHD (A), ((Ri)) case XCHD: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "XCHD: " << endl; #endif regNum = IR & 0x01; temp = RAM[ACC] & 0x0F; RAM[ACC] = (RAM[ACC] & 0xF0) | (RAM[RAM[GetRegisterBank()+regNum]] & 0x0F); RAM[RAM[GetRegisterBank()+regNum]] = (RAM[RAM[GetRegisterBank()+regNum]] & 0xF0 ) | temp; cycleCount += 12; break; // LCALL addr16 case LCALL: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "LCALL: " << endl; #endif ((unsigned char*)&jumpAddr)[1] = ROM[PC++]; ((unsigned char*)&jumpAddr)[0] = ROM[PC++]; RAM[SP] = (unsigned char)RAM[SP] + 1; RAM[(unsigned char)RAM[SP]] = ((unsigned char*)&PC)[0]; RAM[SP] = (unsigned char)RAM[SP] + 1; RAM[(unsigned char)RAM[SP]] = ((unsigned char*)&PC)[1]; PC = jumpAddr; cycleCount += 24; break; // ACALL addr11 case ACALL: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "ACALL: " << endl; #endif ((unsigned char*)&jumpAddr)[1] = ((IR & 0xE0) >> 1); ((unsigned char*)&jumpAddr)[0] = ROM[PC++]; RAM[SP] = (unsigned char)RAM[SP] + 1; RAM[RAM[SP]] = ((unsigned char*)&PC)[0]; RAM[SP] = (unsigned char)RAM[SP] + 1; RAM[RAM[SP]] = ((unsigned char*)&PC)[1]; PC = jumpAddr; cycleCount += 24; break; // DA (A) case DA: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "DA: " << endl; #endif if( (RAM[ACC] & 0x0F) > 9 || GetBit(RAM[PSW], AC) == 0x01 ) { tempAdd = RAM[ACC] + 0x06; RAM[ACC] = (char)tempAdd; if( ((unsigned char*)&tempAdd)[1] != 0 ) { SetBit(RAM[PSW], CY); } } if( ((RAM[ACC] & 0x0F) >> 4) > 9 || GetBit(RAM[PSW], CY) == 0x01 ) { tempAdd = RAM[ACC] + 0x60; if( ((unsigned char*)&tempAdd)[1] != 0 ) { SetBit(RAM[PSW], CY); } } cycleCount += 12; break; // CJNE (A), (direct), (rel) case CJNE1: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "CJNE1: " << endl; #endif IR = ROM[PC++]; if( RAM[ACC] != RAM[IR < 128 ? IR : (IR+128)] ) { directAddr = IR; IR = ROM[PC++]; PC += (char)IR; } else { PC++; } if( (unsigned char)RAM[ACC] < (unsigned char)RAM[directAddr < 128 ? directAddr: (directAddr+128)] ) { SetBit(RAM[PSW], CY); } else { ClearBit(RAM[PSW], CY); } cycleCount += 24; break; // CJNE (A), (#data), (rel) case CJNE2: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "CJNE2: " << endl; #endif IR = ROM[PC++]; if( RAM[ACC] != (char)IR ) { directAddr = IR; IR = ROM[PC++]; PC += (char)IR; } else { PC++; } if( (unsigned char)RAM[ACC] < (unsigned char)directAddr ) { SetBit(RAM[PSW], CY); } else { ClearBit(RAM[PSW], CY); } cycleCount += 24; break; // CJNE (Rn), (#data), (rel) case CJNE3: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "CJNE3: " << endl; #endif regNum = IR & 0x07; IR = ROM[PC++]; if( RAM[GetRegisterBank()+regNum] != (char)IR ) { directAddr = IR; IR = ROM[PC++]; PC += (char)IR; } else { PC++; } if( (unsigned char)RAM[GetRegisterBank()+regNum] < (unsigned char)directAddr ) { SetBit(RAM[PSW], CY); } else { ClearBit(RAM[PSW], CY); } cycleCount += 24; break; // CJNE ((Ri)), (#data), (rel) case CJNE4: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "CJNE4: " << endl; #endif regNum = IR & 0x01; IR = ROM[PC++]; if( RAM[RAM[GetRegisterBank()+regNum]] != (char)IR ) { directAddr = IR; IR = ROM[PC++]; PC += (char)IR; } else { PC++; } if( (unsigned char)RAM[RAM[GetRegisterBank()+regNum]] < (unsigned char)directAddr ) { SetBit(RAM[PSW], CY); } else { ClearBit(RAM[PSW], CY); } cycleCount += 24; break; // DEC (A) case DEC1: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "DEC1: " << endl; #endif RAM[ACC]--; cycleCount += 12; break; // DEC (Rn) case DEC2: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "DEC2: " << endl; #endif regNum = IR & 0x07; RAM[GetRegisterBank()+regNum]--; cycleCount += 12; break; // DEC (direct) case DEC3: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "DEC2: " << endl; #endif IR = ROM[PC++]; RAM[IR < 128 ? IR : (IR+128)]--; cycleCount += 12; break; // DEC ((Ri)) case DEC4: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "DEC4: " << endl; #endif regNum = IR & 0x01; RAM[RAM[GetRegisterBank()+regNum]]--; cycleCount += 12; break; // DIV (A)/(B) case DIV: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "DIV: " << endl; #endif if( RAM[B] == 0x00 ) { SetBit(RAM[PSW], OV); } else { ClearBit(RAM[PSW], OV); tempACC = RAM[ACC]; RAM[ACC] = tempACC/RAM[B]; RAM[B] = tempACC%RAM[B]; } ClearBit(RAM[PSW], CY); cycleCount += 48; break; // INC (A) case INC1: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "INC1: " << endl; #endif RAM[ACC] = (unsigned char)RAM[ACC] + 1; cycleCount += 12; break; // INC (Rn) case INC2: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "INC2: " << endl; #endif regNum = IR & 0x07; RAM[GetRegisterBank()+regNum] = (unsigned char)RAM[GetRegisterBank()+regNum] + 1; cycleCount += 12; break; // INC (direct) case INC3: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "INC3: " << endl; #endif IR = ROM[PC++]; RAM[IR < 128 ? IR : (IR+128)]++; cycleCount += 12; break; // INC ((Ri)) case INC4: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "INC4: " << endl; #endif regNum = IR & 0x01; RAM[RAM[GetRegisterBank()+regNum]]++; cycleCount += 12; break; // INC (DPTR) case INC5: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "INC5: " << endl; #endif ((unsigned char*)&tempDPTR)[1] = RAM[DPH]; ((unsigned char*)&tempDPTR)[0] = RAM[DPL]; tempDPTR++; RAM[DPH] = ((unsigned char*)&tempDPTR)[1]; RAM[DPL] = ((unsigned char*)&tempDPTR)[0]; cycleCount += 24; break; // NOP case NOP: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "NOP: " << endl; #endif // no code cycleCount += 12; break; // DJNZ (Rn), (rel) case DJNZ1: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "DJNZ1: " << endl; #endif regNum = IR & 0x07; if( --RAM[GetRegisterBank()+regNum] != 0x00 ) { IR = ROM[PC++]; PC += (char)IR; } else { PC++; } cycleCount += 24; break; // DJNZ (direct), (rel) case DJNZ2: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "DJNZ2: " << endl; #endif regNum = IR & 0x07; IR = ROM[PC++]; if( --RAM[IR < 128 ? IR : (IR+128)] != 0x00 ) { IR = ROM[PC++]; PC += (char)IR; } else { PC++; } cycleCount += 24; break; // MUL (A), (B) case MUL: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MUL: " << endl; #endif tempProduct = (unsigned char)RAM[ACC] * (unsigned char)RAM[B]; if( tempProduct > 255 ) { SetBit(RAM[PSW], OV); } else { ClearBit(RAM[PSW], OV); } ClearBit(RAM[PSW], CY); RAM[ACC] = ((unsigned char*)&tempProduct)[0]; RAM[B] = ((unsigned char*)&tempProduct)[1]; cycleCount += 48; break; // POP (direct) case POP: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "POP: " << endl; #endif IR = ROM[PC++]; RAM[IR < 128 ? IR : (IR+128)] = RAM[(unsigned char)RAM[SP]]; RAM[SP] = (unsigned char)RAM[SP] - 1; cycleCount += 24; break; // PUSH (direct) case PUSH: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "PUSH: " << endl; #endif IR = ROM[PC++]; RAM[SP] = (unsigned char)RAM[SP] + 1; RAM[(unsigned char)RAM[SP]] = RAM[IR < 128 ? IR : (IR+128)]; cycleCount += 24; break; // JB (bit), (rel) case JB: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "JB: " << endl; #endif IR = ROM[PC++]; if( GetBit(RAM[((IR & 0xF8) < 128) ? (IR & 0xF8) : (128 + (IR & 0xF8))], (IR & 0x07)) == 0x01 ) { IR = ROM[PC++]; PC += (char)IR; } else { PC++; } cycleCount += 24; break; // JBC (bit), (rel) case JBC: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "JB: " << endl; #endif IR = ROM[PC++]; if( GetBit(RAM[((IR & 0xF8) < 128) ? (IR & 0xF8) : (128 + (IR & 0xF8))], (IR & 0x07)) == 0x01 ) { ClearBit(RAM[((IR & 0xF8) < 128) ? (IR & 0xF8) : (128 + (IR & 0xF8))], (IR & 0x07)); IR = ROM[PC++]; PC += (char)IR; } else { PC++; } cycleCount += 24; break; // JC (rel) case JC: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "JC: " << endl; #endif if( GetBit(RAM[PSW], CY) == 0x01 ) { IR = ROM[PC++]; PC += (char)IR; } else { PC++; } cycleCount += 24; break; // JMP @A+DPTR case JMP: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "JMP: " << endl; #endif ((unsigned char*)&tempDPTR)[1] = RAM[DPH]; ((unsigned char*)&tempDPTR)[0] = RAM[DPL]; tempDPTR += (unsigned char)RAM[ACC]; PC = (unsigned short)tempDPTR; cycleCount += 24; break; // JNB (bit), (rel) case JNB: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "JNB: " << endl; #endif IR = ROM[PC++]; if( GetBit(RAM[((IR & 0xF8) < 128) ? (IR & 0xF8) : (128 + (IR & 0xF8))], (IR & 0x07)) == 0x00 ) { IR = ROM[PC++]; PC += (char)IR; } else { PC++; } cycleCount += 24; break; // JNC (rel) case JNC: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "JNC: " << endl; #endif if( GetBit(RAM[PSW], CY) == 0x00 ) { IR = ROM[PC++]; PC += (char)IR; } else { PC++; } cycleCount += 24; break; // JNZ (rel) case JNZ: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "JNZ: " << endl; #endif if( RAM[ACC] != 0x00 ) { IR = ROM[PC++]; PC += (char)IR; } else { PC++; } cycleCount += 24; break; // JZ (rel) case JZ: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "JZ: " << endl; #endif if( RAM[ACC] == 0x00 ) { IR = ROM[PC++]; PC += (char)IR; } else { PC++; } cycleCount += 24; break; // AJMP addr11 case AJMP: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "AJMP: " << endl; #endif ((unsigned char*)&jumpAddr)[1] = ((IR & 0xE0) >> 1); ((unsigned char*)&jumpAddr)[0] = ROM[PC++]; PC = jumpAddr; cycleCount += 24; break; // LJMP addr16 case LJMP: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "LJMP: " << endl; #endif ((unsigned char*)&jumpAddr)[1] = ROM[PC++]; ((unsigned char*)&jumpAddr)[0] = ROM[PC++]; PC = jumpAddr; cycleCount += 24; break; // SJMP (rel) case SJMP: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "SJMP: " << endl; #endif PC += (char)ROM[PC++]; cycleCount += 24; break; // A <- Rn case MOV1: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV1: " << endl; #endif regNum = IR & 0x07; RAM[ACC] = RAM[GetRegisterBank()+regNum]; cycleCount += 12; break; // A <- direct case MOV2: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV2: " << endl; #endif IR = ROM[PC++]; RAM[ACC] = RAM[IR < 128 ? IR : (IR + 128)]; cycleCount += 12; break; // A <- @Ri case MOV3: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV3: " << endl; #endif regNum = IR & 0x01; RAM[ACC] = RAM[RAM[GetRegisterBank()+regNum]]; cycleCount += 12; break; // A <- #data case MOV4: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV4: " << endl; #endif IR = ROM[PC++]; RAM[ACC] = IR; cycleCount += 12; break; // Rn <- A case MOV5: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV5: " << endl; #endif regNum = IR & 0x07; RAM[GetRegisterBank()+regNum] = RAM[ACC]; cycleCount += 12; break; // Rn <- direct case MOV6: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV6: " << endl; #endif regNum = IR & 0x07; IR = ROM[PC++]; RAM[GetRegisterBank()+regNum] = RAM[ IR < 128 ? IR : (IR + 128)]; cycleCount += 24; break; // Rn <- #data case MOV7: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV7: " << endl; #endif regNum = IR & 0x07; RAM[GetRegisterBank()+regNum] = ROM[PC++]; cycleCount += 12; break; // direct <- A case MOV8: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV8: " << endl; #endif IR = ROM[PC++]; RAM[IR < 128 ? IR : (IR+128)] = RAM[ACC]; cycleCount += 12; break; // direct <- Rn case MOV9: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV9: " << endl; #endif regNum = IR & 0x07; IR = ROM[PC++]; RAM[IR<128 ? IR : (IR+128)] = RAM[GetRegisterBank()+regNum]; cycleCount += 24; break; // direct <- direct case MOV10: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV10: " << endl; #endif directAddr = ROM[PC++]; IR = ROM[PC++]; RAM[IR<128 ? IR : (IR+128)] = RAM[directAddr < 128 ? directAddr : (directAddr+128)]; cycleCount += 24; break; // direct <- Ri case MOV11: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV11: " << endl; #endif regNum = IR & 0x01; IR = ROM[PC++]; RAM[IR <128 ? IR : (IR+128)] = RAM[RAM[GetRegisterBank()+regNum]]; cycleCount += 24; break; // direct <- #data case MOV12: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV12: " << endl; #endif directAddr = ROM[PC++]; RAM[directAddr<128 ? directAddr : (directAddr+128)] = ROM[PC++]; cycleCount += 24; break; // Ri <- A case MOV13: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV13: " << endl; #endif regNum = IR & 0x01; RAM[RAM[GetRegisterBank()+regNum]] = RAM[ACC]; cycleCount += 12; break; // Ri <- direct case MOV14: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV14: " << endl; #endif regNum = IR & 0x01; IR = ROM[PC++]; RAM[RAM[GetRegisterBank()+regNum]] = RAM[IR<128 ? IR : (IR+128)]; cycleCount += 24; break; // @Ri, #data case MOV15: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV15: " << endl; #endif regNum = IR & 0x01; IR = ROM[PC++];; RAM[RAM[GetRegisterBank()+regNum]] = IR; cycleCount += 12; break; // MOV (C), bit case MOV16: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV16: " << endl; #endif IR = ROM[PC++]; if( GetBit(RAM[((IR & 0xF8) < 128) ? (IR & 0xF8) : (128 + (IR & 0xF8))], (IR & 0x07)) == 0x01 ) { SetBit(RAM[PSW], CY); } else { ClearBit(RAM[PSW], CY); } cycleCount += 12; break; // MOV bit, (C) case MOV17: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV17: " << endl; #endif IR = ROM[PC++]; if( GetBit(RAM[PSW], CY) == 0x01 ) { SetBit(RAM[((IR & 0xF8) < 128) ? (IR & 0xF8) : (128 + (IR & 0xF8))], (IR & 0x07)); } else { ClearBit(RAM[((IR & 0xF8) < 128) ? (IR & 0xF8) : (128 + (IR & 0xF8))], (IR & 0x07)); } cycleCount += 24; break; // MOV DPTR, data16 case MOV18: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOV18: " << endl; #endif RAM[DPH] = ROM[PC++]; RAM[DPL] = ROM[PC++]; cycleCount += 24; break; // MOVC (A), @A+DPTR case MOVC1: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOVC1: " << endl; #endif ((unsigned char*)&tempDPTR)[1] = RAM[DPH]; ((unsigned char*)&tempDPTR)[0] = RAM[DPL]; RAM[ACC] = ROM[(unsigned char)RAM[ACC]+tempDPTR]; cycleCount += 24; break; // MOVC (A), @A+PC case MOVC2: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "MOVC2: " << endl; #endif RAM[ACC] = ROM[(unsigned char)RAM[ACC]+PC]; cycleCount += 24; break; // ADD A, (Rn) case ADD1: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "ADD1: " << endl; #endif carry3 = false; carry6 = false; carry7 = false; regNum = IR & 0x07; PrintHex(RAM[GetRegisterBank()+regNum], &os); tempAdd = (RAM[ACC] & 0x0F) + (RAM[GetRegisterBank()+regNum] & 0x0F); if( (tempAdd & 0x0010) == 0x0010 ) carry3 = true; tempAdd += (RAM[ACC] & 0x70) + (RAM[GetRegisterBank()+regNum] & 0x70); if( (tempAdd & 0x0080) == 0x0080 ) carry6 = true; tempAdd += (RAM[ACC] & 0x80) + (RAM[GetRegisterBank()+regNum] & 0x80); if( (tempAdd & 0x0100) == 0x0100 ) carry7 = true; RAM[ACC] = tempAdd; if( carry3 ) SetBit(RAM[PSW], AC); else ClearBit(RAM[PSW], AC); if( carry7 ) { SetBit(RAM[PSW], CY); } else ClearBit(RAM[PSW], CY); if( (carry6 && !carry7) || (!carry6 && carry7) ) SetBit(RAM[PSW], OV); else ClearBit(RAM[PSW], OV); cycleCount += 12; break; // ADD A, (direct) case ADD2: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "ADD2: " << endl; #endif carry3 = false; carry6 = false; carry7 = false; IR = ROM[PC++]; tempAdd = (RAM[ACC] & 0x0F) + (RAM[IR <128 ? IR : (IR+128)] & 0x0F); if( (tempAdd & 0x0010) == 0x0010 ) carry3 = true; tempAdd += (RAM[ACC] & 0x70) + (RAM[IR <128 ? IR : (IR+128)] & 0x70); if( (tempAdd & 0x0080) == 0x0080 ) carry6 = true; tempAdd += (RAM[ACC] & 0x80) + (RAM[IR <128 ? IR : (IR+128)] & 0x80); if( (tempAdd & 0x0100) == 0x0100 ) carry7 = true; RAM[ACC] = tempAdd; if( carry3 ) SetBit(RAM[PSW], AC); else ClearBit(RAM[PSW], AC); if( carry7 ) SetBit(RAM[PSW], CY); else ClearBit(RAM[PSW], CY); if( (carry6 && !carry7) || (!carry6 && carry7) ) SetBit(RAM[PSW], OV); else ClearBit(RAM[PSW], OV); cycleCount += 12; break; // ADD A, ((Ri)) case ADD3: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "ADD3: " << endl; #endif carry3 = false; carry6 = false; carry7 = false; regNum = IR & 0x01; tempAdd = (RAM[ACC] & 0x0F) + (RAM[RAM[GetRegisterBank()+regNum]] & 0x0F); if( (tempAdd & 0x0010) == 0x0010 ) carry3 = true; tempAdd += (RAM[ACC] & 0x70) + (RAM[RAM[GetRegisterBank()+regNum]] & 0x70); if( (tempAdd & 0x0080) == 0x0080 ) carry6 = true; tempAdd += (RAM[ACC] & 0x80) + (RAM[RAM[GetRegisterBank()+regNum]] & 0x80); if( (tempAdd & 0x0100) == 0x0100 ) carry7 = true; RAM[ACC] = tempAdd; if( carry3 ) SetBit(RAM[PSW], AC); else ClearBit(RAM[PSW], AC); if( carry7 ) SetBit(RAM[PSW], CY); else ClearBit(RAM[PSW], CY); if( (carry6 && !carry7) || (!carry6 && carry7) ) SetBit(RAM[PSW], OV); else ClearBit(RAM[PSW], OV); cycleCount += 12; break; // ADD A, (#data) case ADD4: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "ADD4: " << endl; #endif carry3 = false; carry6 = false; carry7 = false; IR = ROM[PC++]; tempAdd = (RAM[ACC] & 0x0F) + ((char)IR & 0x0F); if( (tempAdd & 0x0010) == 0x0010 ) carry3 = true; tempAdd += (RAM[ACC] & 0x70) + ((char)IR & 0x70); if( (tempAdd & 0x0080) == 0x0080 ) carry6 = true; tempAdd += (RAM[ACC] & 0x80) + ((char)IR & 0x80); if( (tempAdd & 0x0100) == 0x0100 ) carry7 = true; RAM[ACC] = tempAdd; if( carry3 ) SetBit(RAM[PSW], AC); else ClearBit(RAM[PSW], AC); if( carry7 ) SetBit(RAM[PSW], CY); else ClearBit(RAM[PSW], CY); if( (carry6 && !carry7) || (!carry6 && carry7) ) SetBit(RAM[PSW], OV); else ClearBit(RAM[PSW], OV); cycleCount += 12; break; // ADDC A, (Rn) case ADDC1: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "ADDC1: " << endl; #endif carry3 = false; carry6 = false; carry7 = false; regNum = IR & 0x07; tempAdd = (RAM[ACC] & 0x0F) + (RAM[GetRegisterBank()+regNum] & 0x0F) + GetBit(RAM[PSW], CY); if( (tempAdd & 0x0010) == 0x0010 ) carry3 = true; tempAdd += (RAM[ACC] & 0x70) + (RAM[GetRegisterBank()+regNum] & 0x70); if( (tempAdd & 0x0080) == 0x0080 ) carry6 = true; tempAdd += (RAM[ACC] & 0x80) + (RAM[GetRegisterBank()+regNum] & 0x80); if( (tempAdd & 0x0100) == 0x0100 ) carry7 = true; RAM[ACC] = tempAdd; if( carry3 ) SetBit(RAM[PSW], AC); else ClearBit(RAM[PSW], AC); if( carry7 ) SetBit(RAM[PSW], CY); else ClearBit(RAM[PSW], CY); if( (carry6 && !carry7) || (!carry6 && carry7) ) SetBit(RAM[PSW], OV); else ClearBit(RAM[PSW], OV); cycleCount += 12; break; // ADDC A, (direct) case ADDC2: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "ADDC2: " << endl; #endif carry3 = false; carry6 = false; carry7 = false; IR = ROM[PC++]; tempAdd = (RAM[ACC] & 0x0F) + (RAM[IR <128 ? IR : (IR+128)] & 0x0F) + GetBit(RAM[PSW], CY); if( (tempAdd & 0x0010) == 0x0010 ) carry3 = true; tempAdd += (RAM[ACC] & 0x70) + (RAM[IR <128 ? IR : (IR+128)] & 0x70); if( (tempAdd & 0x0080) == 0x0080 ) carry6 = true; tempAdd += (RAM[ACC] & 0x80) + (RAM[IR <128 ? IR : (IR+128)] & 0x80); if( (tempAdd & 0x0100) == 0x0100 ) carry7 = true; RAM[ACC] = tempAdd; if( carry3 ) SetBit(RAM[PSW], AC); else ClearBit(RAM[PSW], AC); if( carry7 ) SetBit(RAM[PSW], CY); else ClearBit(RAM[PSW], CY); if( (carry6 && !carry7) || (!carry6 && carry7) ) SetBit(RAM[PSW], OV); else ClearBit(RAM[PSW], OV); cycleCount += 12; break; // ADDC A, ((Ri)) case ADDC3: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "ADDC3: " << endl; #endif carry3 = false; carry6 = false; carry7 = false; regNum = IR & 0x01; tempAdd = (RAM[ACC] & 0x0F) + (RAM[RAM[GetRegisterBank()+regNum]] & 0x0F) + GetBit(RAM[PSW], CY); if( (tempAdd & 0x0010) == 0x0010 ) carry3 = true; tempAdd += (RAM[ACC] & 0x70) + (RAM[RAM[GetRegisterBank()+regNum]] & 0x70); if( (tempAdd & 0x0080) == 0x0080 ) carry6 = true; tempAdd += (RAM[ACC] & 0x80) + (RAM[RAM[GetRegisterBank()+regNum]] & 0x80); if( (tempAdd & 0x0100) == 0x0100 ) carry7 = true; RAM[ACC] = tempAdd; if( carry3 ) SetBit(RAM[PSW], AC); else ClearBit(RAM[PSW], AC); if( carry7 ) SetBit(RAM[PSW], CY); else ClearBit(RAM[PSW], CY); if( (carry6 && !carry7) || (!carry6 && carry7) ) SetBit(RAM[PSW], OV); else ClearBit(RAM[PSW], OV); cycleCount += 12; break; // ADDC A, (#data) case ADDC4: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "ADDC4: " << endl; #endif carry3 = false; carry6 = false; carry7 = false; IR = ROM[PC++]; tempAdd = (RAM[ACC] & 0x0F) + ((char)IR & 0x0F) + GetBit(RAM[PSW], CY); if( (tempAdd & 0x0010) == 0x0010 ) carry3 = true; tempAdd += (RAM[ACC] & 0x70) + ((char)IR & 0x70); if( (tempAdd & 0x0080) == 0x0080 ) carry6 = true; tempAdd += (RAM[ACC] & 0x80) + ((char)IR & 0x80); if( (tempAdd & 0x0100) == 0x0100 ) carry7 = true; RAM[ACC] = tempAdd; if( carry3 ) SetBit(RAM[PSW], AC); else ClearBit(RAM[PSW], AC); if( carry7 ) SetBit(RAM[PSW], CY); else ClearBit(RAM[PSW], CY); if( (carry6 && !carry7) || (!carry6 && carry7) ) SetBit(RAM[PSW], OV); else ClearBit(RAM[PSW], OV); cycleCount += 12; break; // SUBB (A), (Rn) case SUBB1: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "SUBB1: " << endl; #endif borrow3 = false; borrow6 = false; borrow7 = false; regNum = IR & 0x07; if( (unsigned char)(RAM[ACC] & 0x0F) < (unsigned char)((RAM[GetRegisterBank()+regNum] & 0x0F) + GetBit(RAM[PSW], CY)) ) { borrow3 = true; } if( (unsigned char)(RAM[ACC] & 0x7F) < (unsigned char)((RAM[GetRegisterBank()+regNum] & 0x7F) + GetBit(RAM[PSW], CY)) ) { borrow6 = true; } if( (unsigned char)RAM[ACC] < (unsigned char)(RAM[GetRegisterBank()+regNum] + GetBit(RAM[PSW], CY)) ) { borrow7 = true; } RAM[ACC] = (unsigned char)RAM[ACC] - (unsigned char)(RAM[GetRegisterBank()+regNum] + GetBit(RAM[PSW], CY)); if( borrow3 ) SetBit(RAM[PSW], AC); else ClearBit(RAM[PSW], AC); if( borrow7 ) SetBit(RAM[PSW], CY); else ClearBit(RAM[PSW], CY); if( (borrow6 && !borrow7) || (!borrow6 && borrow7) ) SetBit(RAM[PSW], OV); else ClearBit(RAM[PSW], OV); cycleCount += 12; break; // SUBB (A), direct case SUBB2: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "SUBB2: " << endl; #endif borrow3 = false; borrow6 = false; borrow7 = false; IR = ROM[PC++]; if( (unsigned char)(RAM[ACC] & 0x0F) < (unsigned char)((RAM[IR <128 ? IR : (IR+128)] & 0x0F) + GetBit(RAM[PSW], CY)) ) { borrow3 = true; } if( (unsigned char)(RAM[ACC] & 0x7F) < (unsigned char)((RAM[IR <128 ? IR : (IR+128)] & 0x7F) + GetBit(RAM[PSW], CY)) ) { borrow6 = true; } if( (unsigned char)RAM[ACC] < (unsigned char)(RAM[IR <128 ? IR : (IR+128)] + GetBit(RAM[PSW], CY)) ) { borrow7 = true; } RAM[ACC] = (unsigned char)RAM[ACC] - (unsigned char)(RAM[IR <128 ? IR : (IR+128)] + GetBit(RAM[PSW], CY)); if( borrow3 ) SetBit(RAM[PSW], AC); else ClearBit(RAM[PSW], AC); if( borrow7 ) SetBit(RAM[PSW], CY); else ClearBit(RAM[PSW], CY); if( (borrow6 && !borrow7) || (!borrow6 && borrow7) ) SetBit(RAM[PSW], OV); else ClearBit(RAM[PSW], OV); cycleCount += 12; break; // SUBB (A), ((Ri)) case SUBB3: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "SUBB3: " << endl; #endif borrow3 = false; borrow6 = false; borrow7 = false; regNum = IR & 0x01; if( (unsigned char)(RAM[ACC] & 0x0F) < (unsigned char)((RAM[RAM[GetRegisterBank()+regNum]] & 0x0F) + GetBit(RAM[PSW], CY)) ) { borrow3 = true; } if( (unsigned char)(RAM[ACC] & 0x7F) < (unsigned char)((RAM[RAM[GetRegisterBank()+regNum]] & 0x7F) + GetBit(RAM[PSW], CY)) ) { borrow6 = true; } if( (unsigned char)RAM[ACC] < (unsigned char)(RAM[RAM[GetRegisterBank()+regNum]] + GetBit(RAM[PSW], CY)) ) { borrow7 = true; } RAM[ACC] = (unsigned char)RAM[ACC] - (unsigned char)(RAM[RAM[GetRegisterBank()+regNum]] + GetBit(RAM[PSW], CY)); if( borrow3 ) SetBit(RAM[PSW], AC); else ClearBit(RAM[PSW], AC); if( borrow7 ) SetBit(RAM[PSW], CY); else ClearBit(RAM[PSW], CY); if( (borrow6 && !borrow7) || (!borrow6 && borrow7) ) SetBit(RAM[PSW], OV); else ClearBit(RAM[PSW], OV); cycleCount += 12; break; // SUBB A, (#data) case SUBB4: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "SUBB4: " << endl; #endif borrow3 = false; borrow6 = false; borrow7 = false; IR = ROM[PC++]; if( (unsigned char)(RAM[ACC] & 0x0F) < (unsigned char)((IR & 0x0F) + GetBit(RAM[PSW], CY)) ) { borrow3 = true; } if( (unsigned char)(RAM[ACC] & 0x7F) < (unsigned char)((IR & 0x7F) + GetBit(RAM[PSW], CY)) ) { borrow6 = true; } if( (unsigned char)RAM[ACC] < (unsigned char)(IR + GetBit(RAM[PSW], CY)) ) { borrow7 = true; } RAM[ACC] = (unsigned char)RAM[ACC] - (unsigned char)(IR + GetBit(RAM[PSW], CY)); if( borrow3 ) SetBit(RAM[PSW], AC); else ClearBit(RAM[PSW], AC); if( borrow7 ) SetBit(RAM[PSW], CY); else ClearBit(RAM[PSW], CY); if( (borrow6 && !borrow7) || (!borrow6 && borrow7) ) SetBit(RAM[PSW], OV); else ClearBit(RAM[PSW], OV); cycleCount += 12; break; // Return case RET: #ifdef DEBUG PrintHex(IR, &os); os << " - " << "RETURN" << endl; #endif ((unsigned char*)&PC)[1] = RAM[(unsigned char)RAM[SP]]; RAM[SP] = (unsigned char)RAM[SP] - 1; ((unsigned char*)&PC)[0] = RAM[(unsigned char)RAM[SP]]; RAM[SP] = (unsigned char)RAM[SP] - 1; cycleCount += 24; break; default: cerr << "ERROR in ROM. Execution stopped." << endl; progEnd = true; break; } #ifdef PORTS if( (lastP0 != RAM[P0]) || (lastP1 != RAM[P1]) || (lastP2 != RAM[P2]) || (lastP3 != RAM[P3]) ) { lastP0 = RAM[P0]; lastP1 = RAM[P1]; lastP2 = RAM[P2]; lastP3 = RAM[P3]; PrintPorts(); } #endif if( ProgramCompletion() ) progEnd = true; } end = clock(); double time = (double)(end - begin)/(double)(CLOCKS_PER_SEC); cout << setiosflags(ios::left); cout << endl; cout << setw(45) << "Instruction Executed: " << instrCount << endl; cout << setw(45) << "Execution Time(seconds): " << time << endl; cout << setw(45) << "Average Instructions/second: " << instrCount/time << endl; cout << endl; cout << setw(45) << "Clock Cycles Required for 8051: " << cycleCount << endl; cout << setw(45) << "Execution Time for 8051(12 MHz)(seconds): " << cycleCount/12e6 << endl; cout << setw(45) << "Average Instructions/second for 8051: " << instrCount/(cycleCount/12e6) << endl; cout << endl; return true; } } //----------------------------------------------------------------------------- bool I8051::ProgramCompletion() { #ifdef PROGRAM_COMPLETION if( PROGRAM_COMPLETION ) return true; #endif return false; } //----------------------------------------------------------------------------- void I8051::Stop() { progEnd = true; } //----------------------------------------------------------------------------- // Initialize special areas of memory to specified values. // 8051 default values for Special Purpose Registers. void I8051::Init8051(char RAM[]) { for(unsigned int i=0;i> thisBit); } //----------------------------------------------------------------------------- // Returns the integer value for the current register bank. unsigned char I8051::GetRegisterBank() { return 8 * ((RAM[PSW] & 0x18) >> 3); } //----------------------------------------------------------------------------- void I8051::PrintHex(unsigned char byte, ostream* os) { unsigned char upperNibble = (byte & 0xF0) >> 4; unsigned char lowerNibble = byte & 0x0F; upperNibble = (upperNibble > 9) ? 'A'+(upperNibble-10) : '0'+upperNibble; lowerNibble = (lowerNibble > 9) ? 'A'+(lowerNibble-10) : '0'+lowerNibble; *os << "0x" << upperNibble << lowerNibble; } //----------------------------------------------------------------------------- void I8051::PrintPorts() { PrintHex(RAM[P0]); cout << "\t"; PrintHex(RAM[P1]); cout << "\t"; PrintHex(RAM[P2]); cout << "\t"; PrintHex(RAM[P3]); cout << "\n"; } //----------------------------------------------------------------------------- bool I8051::Hex2Short(const char* buf, unsigned &val) { int i; if( sscanf(buf, "%x", &i) != 1 ) { cerr << "Error: hex file error." << endl; return false; } val = i; return true; } //---------------------------------------------------------------------------- bool I8051::Load(const char* buf, unsigned char* rom, unsigned& prgSize) { unsigned len, base, type; unsigned char checksum = 0; char hex[16]; if( buf[0] != ':' ) { cerr << "Error: hex file error." << endl; return false; } hex[0] = buf[1]; hex[1] = buf[2]; hex[2] = 0; if( !Hex2Short(hex, len) ) return false; hex[0] = buf[3]; hex[1] = buf[4]; hex[2] = buf[5]; hex[3] = buf[6]; hex[4] = 0; if( !Hex2Short(hex, base) ) return false; hex[0] = buf[7]; hex[1] = buf[8]; hex[2] = 0; if( !Hex2Short(hex, type) ) return false; if( type == 1 ) return true; for(unsigned i=0; i RomSize ) { cerr << "Error: program too large." << endl; return false; } hex[0] = buf[ 9 + i * 2]; hex[1] = buf[10 + i * 2]; unsigned temp; if( !Hex2Short(hex, temp) ) return false; rom[base + i] = (unsigned char)temp; } for(unsigned i=0; buf[i * 2 + 1] && buf[i * 2 + 2]; i++) { hex[0] = buf[i * 2 + 1]; hex[1] = buf[i * 2 + 2]; unsigned temp; if( !Hex2Short(hex, temp) ) return false; checksum += (unsigned char)temp; } if( checksum != 0 ) { cerr << "Error: checksum failed." << endl; return false; } return false; } //----------------------------------------------------------------------------- bool I8051::LoadHex(char *filename) { unsigned prgSize; char buf[256]; ifstream ifs(filename); memset(ROM, 0, sizeof(char)*RomSize); if( ifs.bad() ) { cerr << "Error: invalid HEX file." << endl; return false; } while( !ifs.eof() ) { ifs.getline(buf, sizeof(buf)); if( Load(buf, (unsigned char*)ROM, prgSize) ) break; } return true; } //-----------------------------------------------------------------------------