/* * This file is part of the QtHPConnect distribution (https://github.com/Indy970/QtHPConnect.git). * Copyright (c) 2020 Ian Gebbie. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 or later. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include "global.h" #include "hpusb.h" #include "matrixdata.h" #include "abstractdata.h" uint16_t crc16_block(const uint8_t * buffer, uint32_t len); int BCD2I(quint8 num) { int ds,ret; if(num>0) { ds=((num&0xF0)>>4)*10; ds+=(num&0x0F); ret=ds; } else { ret=0; } errlog(QString("Num= %1 Ret= %2").arg(num,1,16).arg(ret)); return ret; } quint8 I2BCD(int num) { quint8 ret; int shift =0; ret=0; while (num > 0) { ret |= (num % 10) << (shift++ << 2); num /= 10; } errlog(QString("Num= %1 Ret= %2").arg(num,1,16).arg(ret)); qDebug()< 0) { ret |= (num % 10) << (shift++ << 2); num /= 10; } errlog(QString("Num= %1 Ret= %2").arg(num,1,16).arg(ret)); qDebug()<(rawValue); } else { // Otherwise perform the 2's complement math on the value errlog(QString("List 2C Negative Detected")); ret = static_cast(~(rawValue - 0x01)) * - 1; // ret = ~rawValue; } errlog(QString("2C: %1 %2").arg(rawValue,1,16).arg(ret,1,16)); return ret; } qint16 TwosComp2Int_8(qint16 rawValue) { qint16 ret; // If a positive value, return it if ((rawValue & 0x800) == 0) { ret = rawValue; } else { // Otherwise perform the 2's complement math on the value ret = (~(rawValue - 0x01)&(0x0FFF)) * -1; // ret = ~rawValue; } return ret; } QString value2Str(int sign, double m, double exp) { QString value; QString neg=QStringLiteral(""); if (sign<0) { neg=QStringLiteral("-"); } if (exp!=0.0) { value=neg+QString("%1E%2").arg(m).arg(exp); } else { if (m==0.0) { value=neg+QString("0"); } else value=neg+QString("%1").arg(m); } return value; } QString complex2Str(QString real, QString imag) { QString value; if((imag[0]!="+")&&(imag[0]!="-")) { value = real+"+"+imag+"*i"; } else { value = real+imag+"*i"; } if(real=="0") { value = imag+"*i"; } if ((real!="0")&&(imag=="0")) { value = real; } return value; } itemData extract16(QByteArray item) { ; itemData listvalue; QString msg; QString value=QStringLiteral(""); QString neg=QStringLiteral(""); qint8 sign; int multi; long exp; double base; double m,ret; int k; multi=1; // base=BCD2I(item[2]); base=10; sign=TwosComplement2Int(static_cast(item[3])); exp=((((((((static_cast(item[7])&0xFF)<<8)+(static_cast(item[6])&0xFF))<<8)+(static_cast(item[5])&0xFF)))<<8) +(static_cast(item[4])&0xFF)); errlog(QString("extract16: exp %1").arg(exp)); // exp=TwosComplement2Int(exp); m=0; for (k=8;k<16;k++) { if(static_cast(item[k])!=0) { m=m*0.01+static_cast(multi)*BCD2I(static_cast(item[k])); } } ret=sign*m*qPow(base,exp); value = value2Str(sign,m,exp); msg=QString("multi:%1 base:%2 sign:%3 exp:%4 m:%5").arg(multi).arg(base).arg(sign).arg(exp).arg(m); // msg=QString("value: %1").arg(value); errlog(msg); errlog((QString("Ans: %1").arg(ret))); listvalue.dReal=ret; listvalue.sValue=value; return listvalue; } itemData extract8(QByteArray item) { ; itemData listvalue; QString value=QStringLiteral("");; qint8 sign=1; quint8 l; qint8 v; int multi; qint16 exp=0; double base; double m,ret,n; int k; multi=1; base=10; exp=(((((static_cast(item[1])&0x0F)))<<8)+(static_cast(item[0])&0xFF)); exp=TwosComp2Int_8(exp); m=0; l=item[7]&0xF0; if ((l&0xFF)==0x90) { sign=-1; } for (k=1;k<8;k++) { v=item[k]; if (k==7) { v=v&0x0F; } if (k==1) { v=v&0xF0; } n=static_cast(multi)*BCD2I(v); m=m*0.01+n; if(k!=7) { if ((m>0)||(k>5)) value=QString("%1").arg(n,0)+value; } else value=QString("%1.").arg(n,0)+value; } ret=sign*m*qPow(base,exp); if(sign<0) { value=QString("-")+value; } if(exp!=0) value=value+"E"+QString("%1").arg(exp,0); listvalue.dReal=ret; listvalue.sValue=value; return listvalue; } double step(double edge, double x) { if ( x < edge ) { return 0.0; } else { return 1.0; } } //I to BCD quint8 BCDi(quint8 in1, quint8 in2) { quint8 out = ((in1<<4)&0b11110000) | (in2&0b00001111); return out; } ///Real to BCD bool BCD(QDataStream &ds, double real) { double base=0.0; quint16 expn; int i; double fractpart, intpart; quint8 num1; quint8 num2; quint8 num; double F = abs(real); double sign; double exponent = floor(log10(F)); double mantissa = F/(pow(10,exponent)); quint8 data[8]; qDebug()<<"BCD from "<0) { fractpart=modf(base,&intpart); num1=(quint8)intpart; base=fractpart*10.0; // num1=i*2; } fractpart=modf(base,&intpart); num2=(quint8)intpart; base=fractpart*10.0; // num2=i*2+1; num=BCDi(num1,num2); qDebug()<<"base: "<>c; a1.append(c); } data = a1; parseData(); } AbstractData::~AbstractData() { qDebug()<<"~AbstractData"; } //REAL // Application::Application(QString name_in, hp_DataType type_in): AbstractData(name_in, type_in) { setFileCode(HP_TP_FUNCTIONS); } void Application::parseData() { } //REAL // Real::Real(QString name_in, hp_DataType type_in): AbstractData(name_in, type_in) { setFileCode(HP_TP_SETTINGS); } //Find the vars in the calc.hpsettings file. Marker b4 01 00 void Real::parseData() { QByteArray a1; int ind=0; int len; int j; int start; QByteArray searchstr=QByteArrayLiteral("\x0c\x00\xc0\x05"); QByteArrayMatcher matcher(searchstr); QByteArray item; itemData value1,value2; itemData listvalue; QString name; errlog("Real: Parsing Vars"); name=getName(); errlog(name); a1.clear(); a1=getData(); main_err->dump((uint8_t *)searchstr.constData(),4); // ind=a1.indexOf(searchstr,0); ind=matcher.indexIn(a1,0); if (ind>0) len=((((a1[ind-3])&0x0F)<<8)+((a1[ind-4])&0xFF)-4)/16; else len=0; errlog(QString("Real: %1 %2 %3").arg(ind,0,10) .arg(searchstr.size()) .arg(len,2,10)); // ind=a1.indexOf(searchstr,0); ind=matcher.indexIn(a1,0); if (ind>0) len=((((a1[ind-3])&0x0F)<<8)+((a1[ind-4])&0xFF)-4)/16; else len=0; start=ind+4; qDebug()<(item[2])==0x13) { main_err->dump((uint8_t *)item.constData(),16); value1=extract16(item); j++; start=start+16; item=a1.mid(start,16); main_err->dump((uint8_t *)item.constData(),16); value2=extract16(item); listvalue.dReal=value1.dReal; listvalue.sValue=value1.sValue; listvalue.dImaginary=value2.dReal; listvalue.sValue=complex2Str(value1.sValue,value2.sValue); start=start+16; } else { main_err->dump((uint8_t *)item.constData(),16); listvalue=extract16(item); start=start+16; } setListItem(getListSize(),listvalue); } // errlog("Real Dump"); // main_err->dump((uint8_t *)a1.constData(),a1.size()); } //Gets a list item from the list itemData Real::getListItem(int row) { itemData null; if (row0) len=((((a1[ind-3])&0x0F)<<8)+((a1[ind-4])&0xFF)-4)/16; else len=0; errlog(QString("Real: %1 %2 %3").arg(ind,0,10) .arg(searchstr.size()) .arg(len,2,10)); // ind=a1.indexOf(searchstr,0); ind=matcher.indexIn(a1,0); if (ind>0) len=((((a1[ind-3])&0x0F)<<8)+((a1[ind-4])&0xFF)-4)/16; else len=0; start=ind+4; qDebug()<(item[2])==0x13) { main_err->dump((uint8_t *)item.constData(),16); value1=extract16(item); j++; start=start+16; item=a1.mid(start,16); main_err->dump((uint8_t *)item.constData(),16); value2=extract16(item); listvalue.dReal=value1.dReal; listvalue.sValue=value1.sValue; listvalue.dImaginary=value2.dReal; listvalue.sValue=complex2Str(value1.sValue,value2.sValue); start=start+16; } else { main_err->dump((uint8_t *)item.constData(),16); listvalue=extract16(item); start=start+16; } setListItem(getListSize(),listvalue); } // main_err->dump((uint8_t *)a1.constData(),a1.size()); } //Gets a list item from the list itemData Complex::getListItem(int row) { itemData null; if (row(searchstr),0); //look for FF 16 00 len=a1[ind+3]; for(j=0;j(item[2])==0x13) { main_err->dump((uint8_t *)(item.constData()),16); value1=extract16(item); j++; start=start+16; item=a1.mid(start,16); main_err->dump((uint8_t *)item.constData(),16); value2=extract16(item); listvalue.dReal=value1.dReal; listvalue.sValue=value1.sValue; listvalue.dImaginary=value2.dReal; listvalue.sValue=complex2Str(value1.sValue,value2.sValue); start=start+16; } else { main_err->dump((uint8_t *)item.constData(),16); listvalue=extract16(item); start=start+16; } setListItem(-1,listvalue); } main_err->dump((uint8_t *)a1.constData(),a1.size()); } //Gets a list item from the list itemData List::getListItem(int row) { itemData null; if (row>c; a1.append(c); } data = a1; parseData(); } //Parse a matrix // void Matrix::parseData() { QByteArray a1; QByteArray item; itemData listvalue,value1,value2; QString name; QString msg; QString value=QStringLiteral("");; int mrows; int mcolumns; int start; int k,j; int ind; int flag =0; qint8 vtype; QString ds; // QByteArray searchstr((char *)std::begin({0x01,0x00}),2); //Matrix header //Start keeps changing 01 or 02 //0x00 //0x14 real 0x94 Complex //0x80?? CRC?? //0x02 //0x00 //0x00 //0x00 qDebug()<<"Matrix: Parsing a Matrix"; name=getName(); errlog(name); a1=data; // ind=a1.indexOf(searchstr,0); ind=0; vtype=a1[ind+2]; errlog(QString("vtype=%1").arg(vtype,1,16)); if ((vtype&0x7F)==0x14) { errlog("matrix found"); flag =1; } errlog(QString("vtype=%1").arg(vtype&0x7F,1,16)); if ((vtype&0x80)==0x80) { errlog("complex found"); flag =2; } errlog(QString("vtype=%1").arg(vtype&0x80,1,16)); //look for 00 14 errlog(QString("Found string at %1").arg(ind)); mcolumns=a1[ind+12]; mrows=a1[ind+8]; qDebug()<dump((uint8_t *)a1.constData(),a1.size()); } //Gets a item from the matrix itemData Matrix::getListItem(int row, int column) { itemData data; data=mdata.at(row,column); return data; } //Gets a list item in the matrix at position row,column void Matrix::setListItem(int row, int column, itemData item) { mdata.insert(row,column,item); } //Gets a string representation of the list item in the matrix at position row,column QString Matrix::getItem(int row, int column) { itemData data; QString item; data=mdata.at(row,column); item=data.sValue; // item=QString("%1").arg(data.dReal,5); return item; } //Passes a string representation of the item in the matrix at position position row,column void Matrix::setItem(int row, int column, QString string) { setItem(row,column,string,string.toDouble()); } //Passes a string representation of the list item in the matrix at position row,column void Matrix::setItem(int row, int column, QString string, double value) { itemData item; item.dReal=value; item.sValue=string; setListItem(row,column,item); } bool Matrix::getData(QDataStream &ds) { qDebug()<<"Matrix::getData(ds)"; return mdata.dataOut(ds); } //Passes the number of entries in the list m_Size Matrix::getMatrixSize() { m_Size size; size.row=mdata.rows(); size.column=mdata.columns(); return size; } //Passes the number of entries in the list int Matrix::getMatrixRows() { return mdata.rows(); } //Passes the number of entries in the list int Matrix::getMatrixColumns() { return mdata.columns(); } //Program Program::Program(QString name_in, hp_DataType type_in, QString data): AbstractData(name_in, type_in) { setFileCode(HP_TP_PROG); setProg(data); } QString Program::getProg() { return text; } void Program::setProg(QString data_in) { QByteArray ba_data=data_in.toUtf8(); setData(ba_data); text=data_in; qDebug()<toUnicode(a1); return; } void Program::parseData(QDataStream& in) { QTextCodec * codec = QTextCodec::codecForName("ISO 8859-1"); QByteArrayMatcher matcher; QByteArray search; QByteArray phrase; int ind; int pos; QString str; in.setByteOrder(QDataStream::LittleEndian); qint8 c; QByteArray a1; uint length; length=16; qDebug()<<"Parsing Program"; in.startTransaction(); while(!in.atEnd()) { in>>c; a1.append(c); } main_err->dump((uint8_t *)a1.constData(),a1.size()); search="\x7c\x61"; matcher.setPattern(search); ind=matcher.indexIn(a1,0); if (ind>-1) { search=QByteArrayLiteral("\x54\x0\x0\x0\x44\x0\x0\x0"); main_err->dump((uint8_t *)search.data(),search.length()); matcher.setPattern(search); pos=0; while(pos>-1) { pos=matcher.indexIn(a1,ind); if (pos>-1) { ind=pos+10; phrase=a1.mid(ind,16*3); //add array to catch variable list str=codec->toUnicode(phrase); errlog(QString("TD...%1 %2").arg(pos,0,16).arg(ind)); main_err->dump((uint8_t *)phrase.data(),3*16); errlog(str); } } } else { errlog("Data is not a program file"); } // char cstr[20]; // in.readRawData(cstr,20); // str=QString(cstr); // qDebug()<toUnicode(a1); setProg(codec->toUnicode(a1)); return; } QByteArray Program::fileOut() { QByteArray out; out.clear(); out.append("\x7c\x61\x8a\x62\xfe\xff\xff\xff\x00\x00\x00\x00\x08\x00\x00\x00"); out.append("\x05\xff\x7f\x00\x00\x00\x00\x00\x08\x00\x00\x00\x05\xff\x3f\x02"); out.append(data); //temp should be string text qDebug()<toUnicode(a1); format = codec->toUnicode(a3); } void Notes::setNote(QString data_in) { text=data_in; } //Variables Variables::Variables(QString name_in, hp_DataType type_in): AbstractData(name_in, type_in) { setFileCode(HP_TP_SETTINGS); } void Variables::parseData() { // quint16 len1,len2; QByteArray a1,a3; a1=getData(); } //CAS Variables CASVariables::CASVariables(QString name_in, hp_DataType type_in): AbstractData(name_in, type_in) { setFileCode(HP_TP_SETTINGS); } void CASVariables::parseData() { // quint16 len1,len2; QByteArray a1,a3; a1=getData(); } //Settings Settings::Settings(QString name_in, hp_DataType type_in): AbstractData(name_in, type_in) { setFileCode(HP_TP_SETTINGS); } void Settings::parseData() { // quint16 len1,len2; QByteArray a1,a3; a1=getData(); } void Settings::setData(QByteArray datain) { qDebug()<<"Settings Compare:"; int len1=data.size(); int len2=datain.size(); errlog(QString("Settings Compare %1 %2").arg(len1).arg(len2)); int i=0; while ((i