private void OnTimerEvent(object sender, MicroTimerEventArgs e) { if (++_internalCounter < GetDivider()) { return; } _internalCounter = 0; bool equalUpperLimit = _tcntL.NumValue() == upperLimit[0].NumValue() && _tcntH.NumValue() == upperLimit[1].NumValue(); bool equalLowerLimit = _tcntL.NumValue() == 0 && _tcntH.NumValue() == 0; // Инкремент/декремент if (dec) { if (_tcntL.Dec()) { if (_tcntH.Dec()) { // 0000 -> FFFF underflow Console.WriteLine("Shouldn't normally happen! 0000.Dec()"); } } } else { if (equalUpperLimit) { _tcntL.And(new ExtendedBitArray()); _tcntH.And(new ExtendedBitArray()); SetOverflowFlag(true); } else if (_tcntL.Inc()) { if (_tcntH.Inc()) { // FFFF -> 0000 overflow Console.WriteLine("Shouldn't normally happen! FFFF.Inc()"); SetOverflowFlag(true); } } } equalUpperLimit = _tcntL.NumValue() == upperLimit[0].NumValue() && _tcntH.NumValue() == upperLimit[1].NumValue(); equalLowerLimit = _tcntL.NumValue() == 0 && _tcntH.NumValue() == 0; bool equalTcntOcr = _tcntL.NumValue() == _ocrL.NumValue() && _tcntH.NumValue() == _ocrH.NumValue(); byte mode = GetMode(); switch (mode) { case 1: // сброс при совпадении if (equalTcntOcr) { SetComparisonFlag(true); _tcntH = new ExtendedBitArray(); _tcntL = new ExtendedBitArray(); } break; case 2: // быстрый ШИМ break; case 3: // ШИМ с фазовой коррекцией // проверка совпадения с верхним пределом if (equalUpperLimit) { dec = true; } else if (equalLowerLimit) { dec = false; } break; } byte outputMode = GetOutputMode(); switch (outputMode) { case 0: outputPinValue = false; break; case 1: // инверсия при совпадении TCNT == OCR if (equalTcntOcr) { outputPinValue = !outputPinValue; } break; case 2: if (mode < 2) // Без ШИМ { if (equalTcntOcr) // сброс при совпадении { outputPinValue = false; } } if (mode == 2) // Быстрый ШИМ { if (equalTcntOcr) // сброс при совпадении { outputPinValue = false; } else if (equalUpperLimit) // установка на вершине счета { outputPinValue = true; } } if (mode == 3) // ШИМ с ФК { if (equalTcntOcr) { if (dec) { outputPinValue = true; // установка при совпадении во время обратного счета } else { outputPinValue = false; // сброс при совпадении во время прямого счета } } } break; case 3: if (mode < 2) // Без ШИМ { if (equalTcntOcr) // установка при совпадении { outputPinValue = true; } } if (mode == 2) // Быстрый ШИМ { if (equalTcntOcr) // установка при совпадении { outputPinValue = true; } else if (equalUpperLimit) // сброс на вершине счета { outputPinValue = false; } } if (mode == 3) // ШИМ с ФК { if (equalTcntOcr) { if (dec) { outputPinValue = false; // сброс при совпадении во время обратного счета } else { outputPinValue = true; // установка при совпадении во время прямого счета } } } break; } double nowMillis = DateTime.Now.ToUniversalTime().Subtract( new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) ).TotalMilliseconds; if (nowMillis - _lastUpdateMillis > UPDATE_PERIOD_MILLIS) { _form.Invoke(_updateFormDelegate); _lastUpdateMillis = nowMillis; } }
private void ProcessRegisterCommand(string highHex, string lowBin) { //MOV if (highHex[1] == 'F') { _y46(); _y2(); _y47(); _y5(); return; } //POP if (highHex[1] == 'D') { _y45(); _y1(); _y34(); _y47(); _y5(); return; } //WR if (highHex[1] == 'A') { if (lowBin[1] != '0' || lowBin[2] != '0' || lowBin[3] != '0') { LoadRegister(lowBin); _y49(); _y4(); ModifyRegister(lowBin); } else { // Прямая адресация _y49(); _y47(); _y5(); } return; } LoadRegister(lowBin); //NOT if (highHex[1] == '0') { _flags.SetPreviousState(_rdb); _y52(); _flags.UpdateFlags(_rdb, "not"); UnloadRegister(lowBin); ModifyRegister(lowBin); return; } //ADD if (highHex[1] == '1') { _flags.SetPreviousState(_acc); _flags.SetArgument(_rdb); bool overflow = _acc.Add(_rdb); _flags.UpdateFlags(_acc, "add", overflow, _rdb); ModifyRegister(lowBin); return; } //SUB if (highHex[1] == '2') { _flags.SetPreviousState(_acc); _flags.SetArgument(_rdb); bool overflow = _acc.Sub(_rdb); _flags.UpdateFlags(_acc, "sub", overflow, _rdb); ModifyRegister(lowBin); return; } //MUL if (highHex[1] == '3') { _flags.SetPreviousState(_acc); _flags.SetArgument(_rdb); _perform_mul(); bool overflow = false; _flags.UpdateFlags(_acc, "mul", overflow); ModifyRegister(lowBin); return; } //DIV if (highHex[1] == '4') { _flags.SetPreviousState(_acc); _flags.SetArgument(_rdb); _acc.Div(_rdb); _flags.UpdateFlags(_acc, "div"); ModifyRegister(lowBin); return; } //AND if (highHex[1] == '5') { _flags.SetPreviousState(_acc); _acc.And(_rdb); _flags.UpdateFlags(_acc, "and"); ModifyRegister(lowBin); return; } //OR if (highHex[1] == '6') { _flags.SetPreviousState(_acc); _acc.Or(_rdb); _flags.UpdateFlags(_acc, "or"); ModifyRegister(lowBin); return; } //XOR if (highHex[1] == '7') { _flags.SetPreviousState(_acc); _acc.Xor(_rdb); _flags.UpdateFlags(_acc, "xor"); ModifyRegister(lowBin); return; } //CMP if (highHex[1] == '8') { var temp = new ExtendedBitArray(_rdb); _flags.SetPreviousState(temp); _flags.SetArgument(_rdb); bool overflow = temp.Sub(_acc); _flags.UpdateFlags(temp, "cmp", overflow, _rdb); UnloadRegister(lowBin); ModifyRegister(lowBin); return; } //RD if (highHex[1] == '9') { _acc = new ExtendedBitArray(_rdb); ModifyRegister(lowBin); return; } //INC if (highHex[1] == 'B') { _flags.SetPreviousState(_rdb); var overflow = _rdb.Inc(); _flags.UpdateFlags(_rdb, "inc", overflow); UnloadRegister(lowBin); ModifyRegister(lowBin); return; } //DEC if (highHex[1] == 'C') { _flags.SetPreviousState(_rdb); var overflow = _rdb.Dec(); _flags.UpdateFlags(_rdb, "dec", overflow); UnloadRegister(lowBin); ModifyRegister(lowBin); return; } //PUSH if (highHex[1] == 'E') { _y35(); _y45(); _y4(); ModifyRegister(lowBin); return; } //ADC if (highHex == "F0") { _flags.SetPreviousState(_acc); _flags.SetArgument(_rdb); var overflow = _acc.Add(_rdb); if (_flags.C) { overflow |= _acc.Inc(); } _flags.UpdateFlags(_acc, "adc", overflow, _rdb); ModifyRegister(lowBin); return; } //SUBB if (highHex == "F1") { _flags.SetPreviousState(_acc); _flags.SetArgument(_rdb); var overflow = _acc.Sub(_rdb); if (_flags.C) { overflow |= _acc.Dec(); } _flags.UpdateFlags(_acc, "subb", overflow, _rdb); ModifyRegister(lowBin); } }
private void ProcessNonAddressCommands(string lowHex) { //NOP if (lowHex == "01") { //Do nothing } //RET if (lowHex == "02") { _y45(); _y1(); _y34(); _y29(); _y45(); _y1(); _y34(); _y33(); } //IRET if (lowHex == "03") { _y45(); _y1(); _y34(); _y37(); _y29(); _y45(); _y1(); _y34(); _y33(); _y66(); } //EI if (lowHex == "04") { _flags.I = true; } //DI if (lowHex == "05") { _flags.I = false; } //RR if (lowHex == "06") { _y11(); } //RL if (lowHex == "07") { _y12(); } //RRC if (lowHex == "08") { _y13(); } //RLC if (lowHex == "09") { _y14(); } //HLT if (lowHex == "0A") { _shouldStopRunning = true; } //INCA if (lowHex == "0B") { _flags.SetPreviousState(_acc); var overflow = _acc.Inc(); _flags.UpdateFlags(_acc, "inc", overflow); } //DECA if (lowHex == "0C") { _flags.SetPreviousState(_acc); var overflow = _acc.Dec(); _flags.UpdateFlags(_acc, "dec", overflow); } //SWAPA if (lowHex == "0D") { _y18(); } //DAA if (lowHex == "0E") { _flags.SetPreviousState(_acc); var temp = new ExtendedBitArray(_acc); temp.And(new ExtendedBitArray("00001111")); if (temp.NumValue() > 9 || _flags.A) { _y19(); } temp = new ExtendedBitArray(_acc); temp.And(new ExtendedBitArray("11110000")); if (temp.NumValue() > 144 || _flags.C) { _y20(); } _flags.UpdateFlags(_acc, "daa", _flags.C); } //DSA if (lowHex == "0F") { _flags.SetPreviousState(_acc); if (_flags.A) { _y21(); } if (_flags.C) { _y22(); } _flags.UpdateFlags(_acc, "dsa", _flags.C); } //IN if (lowHex == "10") { } //OUT if (lowHex == "11") { } //ES if (lowHex == "12") { _flags.Flags[6] = !_flags.Flags[6]; } //MOVASR if (lowHex == "13") { _y9(); } //MOVSRA if (lowHex == "14") { _y28(); } //NOTA if (lowHex == "15") { _flags.SetPreviousState(_acc); _y17(); _flags.UpdateFlags(_acc, "not"); } }
private string GetCommandArgument(ExtendedBitArray lowCommand, ExtendedBitArray highCommand) { var highBin = highCommand.ToBinString(); var highHex = highCommand.ToHexString(); var lowBin = lowCommand.ToBinString(); var lowHex = lowCommand.ToHexString(); // Безадресные if (highHex == "00") { return(null); } // DJRNZ if (highBin.StartsWith("0001")) { int register = (highCommand.NumValue() >> 2) & 0b11; string segment = (highCommand.NumValue() & 0b11).ToString(); string address = lowCommand.ToHexString(); return(string.Format("R{0}, 0x{1}{2}", register.ToString(), segment, address)); } // операторы перехода if (highBin.StartsWith("001")) { string segment = (highCommand.NumValue() & 0b11).ToString(); string address = lowCommand.ToHexString(); return(string.Format("0x{0}{1}", segment, address)); } // Операторы передачи управления if (highBin.StartsWith("0100")) { string segment = (highCommand.NumValue() & 0b11).ToString(); string address = lowCommand.ToHexString(); return(string.Format("0x{0}{1}", segment, address)); } // Регистровые команды //Прямая - 000 //@R - 100 //@R+ - 001 //+@R - 101 //@R- - 011 //-@R - 111 // 041537 if (highBin.StartsWith("0101") || highBin.StartsWith("1111")) { int addressType = lowCommand.NumValue() >> 4; int register = lowCommand.NumValue() & 0x0F; string registerFormat = "R{0}"; switch (addressType) { case 0: registerFormat = "R{0}"; break; case 1: registerFormat = "@R{0}"; break; case 4: registerFormat = "@R{0}+"; break; case 5: registerFormat = "+@R{0}"; break; case 6: registerFormat = "@R{0}-"; break; case 7: registerFormat = "-@R{0}"; break; } return(string.Format(registerFormat, register)); } // ОЗУ if (highBin.StartsWith("011")) { string addressOrConst = lowCommand.NumValue().ToString(); bool isConst = highBin.StartsWith("0111"); return((isConst ? "#" : "") + addressOrConst); } // Битовые команды if (highBin.StartsWith("100")) { string bit = (highCommand.NumValue() & 0b111).ToString(); string address = lowCommand.NumValue().ToString(); return(string.Format("{0}, {1}", address, bit)); } if (highBin.StartsWith("101")) { string bit = (highCommand.NumValue() & 0b111).ToString(); ExtendedBitArray addr = new ExtendedBitArray(lowCommand); addr.And(new ExtendedBitArray("0111111")); string address = addr.NumValue().ToString(); return(string.Format("{0}, {1}", address, bit)); } // Команды ввода-вывода if (highBin == "11000000" || highBin == "11000001") { string address = lowCommand.NumValue().ToString(); return(address); } return(null); }