📄 i8051.cc.txt
字号:
} if( (unsigned char)(RAM[ACC] & 0x7F) < (unsigned char)((RAM[RAM[GetRegisterBank()+regNum]] & 0x7F) + (char)GetBit(RAM[PSW], CY)) ) { borrow6 = true; } if( (unsigned char)RAM[ACC] < (unsigned char)(RAM[RAM[GetRegisterBank()+regNum]] + (char)GetBit(RAM[PSW], CY)) ) { borrow7 = true; } RAM[ACC] = RAM[ACC] - (RAM[RAM[GetRegisterBank()+regNum]] + (char)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 os << "SUBB 4" << endl; #ifdef DETAIL os << "\t" << "A <- A - "; PrintHex(ROM[PC], &os); os << " - C" << endl; #endif #endif borrow3 = false; borrow6 = false; borrow7 = false; IR = ROM[PC++]; if( (unsigned char)(RAM[ACC] & 0x0F) < (unsigned char)((IR & 0x0F) + (char)GetBit(RAM[PSW], CY)) ) { borrow3 = true; } if( (unsigned char)(RAM[ACC] & 0x7F) < (unsigned char)((IR & 0x7F) + (char)GetBit(RAM[PSW], CY)) ) { borrow6 = true; } if( (unsigned char)RAM[ACC] < (unsigned char)(IR + (char)GetBit(RAM[PSW], CY)) ) { borrow7 = true; } RAM[ACC] = (unsigned char)RAM[ACC] - (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: ((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; #ifdef DEBUG os << "RET" << endl; #ifdef DETAIL os << "\t" << "RET " << PC << endl; #endif #endif 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; }} //-----------------------------------------------------------------------------boolI8051::ProgramCompletion() { #ifdef PROGRAM_COMPLETION if( PROGRAM_COMPLETION ) return true; #endif return false;}//-----------------------------------------------------------------------------voidI8051::Stop() { progEnd = true;}//-----------------------------------------------------------------------------// Initialize special areas of memory to specified values.// 8051 default values for Special Purpose Registers.voidI8051::Init8051(char RAM[]) { for(unsigned int i=0;i<RamSize;i++) RAM[i] = 0x00; // initialize SFR RAM[ACC] = 0x00; RAM[PSW] = 0x00; RAM[P0] = 0xFF; RAM[P1] = 0xFF; RAM[P2] = 0xFF; RAM[P3] = 0xFF; RAM[B] = 0x00; RAM[SP] = 0x07; RAM[DPH] = 0x00; RAM[DPL] = 0x00; #ifdef PORTS cout << "P0\tP1\tP2\tP3" << endl; PrintPorts(); #endif}//-----------------------------------------------------------------------------// Decodes the given instruction and returns the instruction type.Opcode I8051::Decode(const unsigned char IR) { // BBBBBBBB switch( IR ) { case 0x25: return ADD2; case 0x24: return ADD4; case 0x35: return ADDC2; case 0x34: return ADDC4; case 0x55: return ANL2; case 0x54: return ANL4; case 0x52: return ANL5; case 0x53: return ANL6; case 0x82: return ANL7; case 0xB0: return ANL8; case 0xB5: return CJNE1; case 0xB4: return CJNE2; case 0xE4: return CLR1; case 0xC3: return CLR2; case 0xC2: return CLR3; case 0xF4: return CPL1; case 0xB3: return CPL2; case 0xB2: return CPL3; case 0xD4: return DA; case 0x14: return DEC1; case 0x15: return DEC3; case 0x84: return DIV; case 0xD5: return DJNZ2; case 0x04: return INC1; case 0x05: return INC3; case 0xA3: return INC5; case 0x20: return JB; case 0x10: return JBC; case 0x40: return JC; case 0x73: return JMP; case 0x30: return JNB; case 0x50: return JNC; case 0x70: return JNZ; case 0x60: return JZ; case 0x12: return LCALL; case 0x02: return LJMP; case 0xE5: return MOV2; case 0x74: return MOV4; case 0xF5: return MOV8; case 0x85: return MOV10; case 0x75: return MOV12; case 0xA2: return MOV16; case 0x92: return MOV17; case 0x90: return MOV18; case 0x93: return MOVC1; case 0x83: return MOVC2; case 0xE0: return MOVX2; case 0xF0: return MOVX4; case 0xA4: return MUL; case 0x45: return ORL2; case 0x44: return ORL4; case 0x42: return ORL5; case 0x43: return ORL6; case 0x72: return ORL7; case 0xA0: return ORL8; case 0xD0: return POP; case 0xC0: return PUSH; case 0x22: return RET; case 0x32: return RETI; case 0x23: return RL; case 0x33: return RLC; case 0x03: return RR; case 0x13: return RRC; case 0xD3: return SETB1; case 0xD2: return SETB2; case 0x80: return SJMP; case 0x95: return SUBB2; case 0x94: return SUBB4; case 0xC4: return SWAP; case 0xC5: return XCH2; case 0x65: return XRL2; case 0x64: return XRL4; case 0x62: return XRL5; case 0x63: return XRL6; default: break; } // BBBBBBBX switch( IR & 0xFE ) { case 0x26: return ADD3; case 0x36: return ADDC3; case 0x56: return ANL3; case 0xB6: return CJNE4; case 0x16: return DEC4; case 0x06: return INC4; case 0xE6: return MOV3; case 0x86: return MOV11; case 0xF6: return MOV13; case 0xA6: return MOV14; case 0x76: return MOV15; case 0xE2: return MOVX1; case 0xF2: return MOVX3; case 0x46: return ORL3; case 0x96: return SUBB3; case 0xC6: return XCH3; case 0xD6: return XCHD; case 0x66: return XRL3; default: break; } // BBBBBXXX switch( IR & 0xF8 ) { case 0x28: return ADD1; case 0x38: return ADDC1; case 0x58: return ANL1; case 0xB8: return CJNE3; case 0x18: return DEC2; case 0xD8: return DJNZ1; case 0x08: return INC2; case 0xE8: return MOV1; case 0xF8: return MOV5; case 0xA8: return MOV6; case 0x78: return MOV7; case 0x88: return MOV9; case 0x48: return ORL1; case 0x98: return SUBB1; case 0x68: return XRL1; case 0xC8: return XCH1; default: break; } // XXXBBBBB switch( IR & 0x1F ) { case 0x11: return ACALL; case 0x01: return AJMP; default: break; } return NOP;}//-----------------------------------------------------------------------------// Set single bit of the given byte at the given location.void I8051::SetBit(char &thisByte, unsigned char thisBit) { thisByte |= (0x01 << thisBit);}//-----------------------------------------------------------------------------// Clear single bit of the given byte at the given location.void I8051::ClearBit(char &thisByte, unsigned char thisBit) { thisByte &= ~(0x01 << thisBit);}//-----------------------------------------------------------------------------// Return value of bit as 0 or 1.unsigned charI8051::GetBit(char thisByte, unsigned char thisBit) { return( (thisByte & (0x01 << thisBit)) >> thisBit);}//-----------------------------------------------------------------------------// Returns the integer value for the current register bank.unsigned char I8051::GetRegisterBank() { return 8 * ((RAM[PSW] & 0x18) >> 3);}//-----------------------------------------------------------------------------voidI8051::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;}//-----------------------------------------------------------------------------voidI8051::PrintPorts() { PrintHex(RAM[P0]); cout << "\t"; PrintHex(RAM[P1]); cout << "\t"; PrintHex(RAM[P2]); cout << "\t"; PrintHex(RAM[P3]); cout << "\n";}//-----------------------------------------------------------------------------boolI8051::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 temp; 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<len; i++) { prgSize++; if( prgSize > RomSize ) { cerr << "Error: program too large." << endl; return false; } hex[0] = buf[ 9 + i * 2]; hex[1] = buf[10 + i * 2];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -