1 // Copyright (c) 2019-2021 hors<horsicq@gmail.com>
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9
10 // The above copyright notice and this permission notice shall be included in all
11 // copies or substantial portions of the Software.
12
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 //
21 #include "guimainwindow.h"
22 #include "ui_guimainwindow.h"
23
GuiMainWindow(QWidget * pParent)24 GuiMainWindow::GuiMainWindow(QWidget *pParent) :
25 QMainWindow(pParent),
26 ui(new Ui::GuiMainWindow)
27 {
28 ui->setupUi(this);
29
30 setWindowTitle(QString("%1 v%2").arg(X_APPLICATIONDISPLAYNAME,X_APPLICATIONVERSION));
31
32 QFont font=ui->lineEditOpcode->font();
33 font.setPointSizeF(font.pointSizeF()*1.5);
34 font.setBold(true);
35 ui->lineEditOpcode->setFont(font);
36
37 g_xOptions.setName(X_OPTIONSFILE);
38
39 QList<XOptions::ID> listIDs;
40
41 listIDs.append(XOptions::ID_STYLE);
42 listIDs.append(XOptions::ID_STAYONTOP);
43
44 g_xOptions.setValueIDs(listIDs);
45 g_xOptions.load();
46
47 adjustWindow();
48
49 ui->comboBoxOpcodeGroup->addItem(tr("Two operands"),OG_TWOOPERANDS);
50 ui->comboBoxOpcodeGroup->addItem(tr("One operand"),OG_ONEOPERAND);
51 ui->comboBoxOpcodeGroup->addItem(tr("Mul/Div"),OG_MULDIV);
52 ui->comboBoxOpcodeGroup->addItem(tr("Shift"),OG_SHIFT);
53 ui->comboBoxOpcodeGroup->addItem(tr("Bits"),OG_BITS);
54 ui->comboBoxOpcodeGroup->addItem(tr("Special"),OG_SPECIAL);
55
56 ui->comboBoxMode->addItem(tr("HEX"),ModeValidator::MODE_HEX);
57 ui->comboBoxMode->addItem(tr("Signed"),ModeValidator::MODE_SIGNED);
58 ui->comboBoxMode->addItem(tr("Unsigned"),ModeValidator::MODE_UNSIGNED);
59
60 g_currentMode=ModeValidator::MODE_HEX;
61
62 setLineEditValue(ui->lineEditOperand1,g_currentMode,0);
63 setLineEditValue(ui->lineEditOperand2,g_currentMode,0);
64
65 ui->lineEditOperand1->setValidator(&(g_modeValidator[0]));
66 ui->lineEditOperand2->setValidator(&(g_modeValidator[1]));
67 ui->lineEditFlagsBefore->setValidator(&g_modeValidatorFlag);
68 }
69
~GuiMainWindow()70 GuiMainWindow::~GuiMainWindow()
71 {
72 g_xOptions.save();
73
74 delete ui;
75 }
76
on_pushButtonExit_clicked()77 void GuiMainWindow::on_pushButtonExit_clicked()
78 {
79 this->close();
80 }
81
on_pushButtonAbout_clicked()82 void GuiMainWindow::on_pushButtonAbout_clicked()
83 {
84 DialogAbout di(this);
85
86 di.exec();
87 }
88
adjustWindow()89 void GuiMainWindow::adjustWindow()
90 {
91 g_xOptions.adjustStayOnTop(this);
92 }
93
calc()94 void GuiMainWindow::calc()
95 {
96 ModeValidator::MODE mode=static_cast<ModeValidator::MODE>(ui->comboBoxMode->currentData().toInt());
97 ASM_DEF::OPCODE_RECORD currentRecord=g_mapOpcodes.value(static_cast<ASM_DEF::OP>(ui->comboBoxOpcode->currentData().toInt()));
98
99 RECDATA data=RECDATA_INIT;
100
101 data.OPERAND[0]=getLineEditValue(ui->lineEditOperand1,mode);
102 data.OPERAND[1]=getLineEditValue(ui->lineEditOperand2,mode);
103 data.FLAG[0]=getLineEditValue(ui->lineEditFlagsBefore,mode);
104
105 data.FLAG[0]&=((ASM_DEF::AF)|(ASM_DEF::CF)|(ASM_DEF::OF)|(ASM_DEF::PF)|(ASM_DEF::SF)|(ASM_DEF::ZF)); // Filter
106
107 bool bSuccess=true;
108
109 if( (currentRecord.opcode==ASM_DEF::OP_DIV)||
110 (currentRecord.opcode==ASM_DEF::OP_IDIV))
111 {
112 if(data.OPERAND[1]==0)
113 {
114 bSuccess=false;
115 }
116 }
117
118 if(bSuccess)
119 {
120 currentRecord.asm_func(&data);
121
122 setLineEditValue(ui->lineEditResult1,mode,data.RESULT[0]);
123
124 if(currentRecord.opcode==ASM_DEF::OP_XADD)
125 {
126 setLineEditValue(ui->lineEditResult2,mode,data.RESULT[2]);
127 setLineEditValue(ui->lineEditResult3,mode,data.RESULT[1]);
128 }
129 else
130 {
131 setLineEditValue(ui->lineEditResult2,mode,data.RESULT[1]);
132 setLineEditValue(ui->lineEditResult3,mode,data.RESULT[2]);
133 }
134
135 setLineEditValue(ui->lineEditResult4,mode,data.RESULT[3]);
136 }
137 else
138 {
139 ui->lineEditResult1->clear();
140 ui->lineEditResult2->clear();
141 ui->lineEditResult3->clear();
142 ui->lineEditResult4->clear();
143
144 data.FLAG[1]=data.FLAG[0];
145 }
146
147 XVALUE nFlag=data.FLAG[1];
148
149 nFlag&=(~(static_cast<XVALUE>(0x202))); // remove
150
151 setLineEditValue(ui->lineEditFlagsAfter,mode,nFlag);
152
153 bool bAF=nFlag&(ASM_DEF::AF);
154 bool bCF=nFlag&(ASM_DEF::CF);
155 bool bOF=nFlag&(ASM_DEF::OF);
156 bool bPF=nFlag&(ASM_DEF::PF);
157 bool bSF=nFlag&(ASM_DEF::SF);
158 bool bZF=nFlag&(ASM_DEF::ZF);
159
160 ui->labelFlagAF->setEnabled(bAF);
161 ui->labelFlagCF->setEnabled(bCF);
162 ui->labelFlagOF->setEnabled(bOF);
163 ui->labelFlagPF->setEnabled(bPF);
164 ui->labelFlagSF->setEnabled(bSF);
165 ui->labelFlagZF->setEnabled(bZF);
166
167 ui->labelJA->setEnabled((bCF==false)&&(bZF==false));
168 ui->labelJBE->setEnabled((bCF==true)||(bZF==true));
169 ui->labelJGE->setEnabled(bSF==bOF);
170 ui->labelJL->setEnabled(bSF!=bOF);
171 ui->labelJLE->setEnabled((bZF==true)||(bSF!=bOF));
172 ui->labelJG->setEnabled((bZF==false)&&(bSF==bOF));
173 ui->labelJB->setEnabled(bCF==true);
174 ui->labelJAE->setEnabled(bCF==false);
175 ui->labelJE->setEnabled(bZF==true);
176 ui->labelJNE->setEnabled(bZF==false);
177 ui->labelJP->setEnabled(bPF==true);
178 ui->labelJNP->setEnabled(bPF==false);
179 ui->labelJS->setEnabled(bSF==true);
180 ui->labelJNS->setEnabled(bSF==false);
181 ui->labelJO->setEnabled(bOF==true);
182 ui->labelJNO->setEnabled(bOF==false);
183 }
184
loadOpcodes(const ASM_DEF::OPCODE_RECORD * pRecords,qint32 nRecordsSize)185 void GuiMainWindow::loadOpcodes(const ASM_DEF::OPCODE_RECORD *pRecords, qint32 nRecordsSize)
186 {
187 #if QT_VERSION >= 0x050300
188 QSignalBlocker blocker(ui->comboBoxOpcode);
189 #else
190 const bool bBlocked1=ui->comboBoxOpcode->blockSignals(true);
191 #endif
192
193 g_mapOpcodes.clear();
194 ui->comboBoxOpcode->clear();
195
196 for(int i=0;i<nRecordsSize;i++)
197 {
198 g_mapOpcodes.insert(pRecords[i].opcode,pRecords[i]);
199
200 ui->comboBoxOpcode->addItem(pRecords[i].pszName,static_cast<int>(pRecords[i].opcode));
201 }
202
203 #if QT_VERSION < 0x050300
204 ui->comboBoxOpcode->blockSignals(bBlocked1);
205 #endif
206 }
207
on_comboBoxOpcode_currentIndexChanged(int nIndex)208 void GuiMainWindow::on_comboBoxOpcode_currentIndexChanged(int nIndex)
209 {
210 if(nIndex!=-1)
211 {
212 adjustMode();
213 calc();
214 }
215 }
216
adjustValue(QGroupBox * pGroupBox,ASM_DEF::VALUE_RECORD vr)217 void GuiMainWindow::adjustValue(QGroupBox *pGroupBox, ASM_DEF::VALUE_RECORD vr)
218 {
219 if(vr.nMaxValue)
220 {
221 pGroupBox->show();
222 pGroupBox->setTitle(vr.pszRegName);
223 }
224 else
225 {
226 pGroupBox->hide();
227 }
228 }
229
adjustMode()230 void GuiMainWindow::adjustMode()
231 {
232 ASM_DEF::OPCODE_RECORD currentRecord=g_mapOpcodes.value(static_cast<ASM_DEF::OP>(ui->comboBoxOpcode->currentData().toInt()));
233
234 ModeValidator::MODE mode=static_cast<ModeValidator::MODE>(ui->comboBoxMode->currentData().toInt());
235
236 ModeValidator::DATA validatorData[2]={};
237 ModeValidator::DATA validatorDataFlag;
238
239 validatorData[0].mode=mode;
240 validatorData[0].nMaxValue=currentRecord.vrOperand[0].nMaxValue;
241
242 validatorData[1].mode=mode;
243 validatorData[1].nMaxValue=currentRecord.vrOperand[1].nMaxValue;
244
245 validatorDataFlag.mode=mode;
246 validatorDataFlag.nMaxValue=0xFFFFFFFF;
247
248 g_modeValidator[0].setData(validatorData[0]);
249 g_modeValidator[1].setData(validatorData[1]);
250 g_modeValidatorFlag.setData(validatorDataFlag);
251
252 ui->lineEditOpcode->setText(currentRecord.pszExample);
253
254 adjustValue(ui->groupBoxOperand1,currentRecord.vrOperand[0]);
255 adjustValue(ui->groupBoxOperand2,currentRecord.vrOperand[1]);
256 adjustValue(ui->groupBoxResult1,currentRecord.vrResult[0]);
257 adjustValue(ui->groupBoxResult2,currentRecord.vrResult[1]);
258 adjustValue(ui->groupBoxResult3,currentRecord.vrResult[2]);
259 adjustValue(ui->groupBoxResult4,currentRecord.vrResult[3]);
260 }
261
on_lineEditOperand1_textChanged(const QString & arg1)262 void GuiMainWindow::on_lineEditOperand1_textChanged(const QString &arg1)
263 {
264 Q_UNUSED(arg1)
265
266 calc();
267 }
268
on_lineEditOperand2_textChanged(const QString & arg1)269 void GuiMainWindow::on_lineEditOperand2_textChanged(const QString &arg1)
270 {
271 Q_UNUSED(arg1)
272
273 calc();
274 }
275
on_lineEditResult1_textChanged(const QString & arg1)276 void GuiMainWindow::on_lineEditResult1_textChanged(const QString &arg1)
277 {
278 Q_UNUSED(arg1)
279
280 calc();
281 }
282
on_lineEditResult2_textChanged(const QString & arg1)283 void GuiMainWindow::on_lineEditResult2_textChanged(const QString &arg1)
284 {
285 Q_UNUSED(arg1)
286
287 calc();
288 }
289
on_pushButtonFlagCF_toggled(bool checked)290 void GuiMainWindow::on_pushButtonFlagCF_toggled(bool checked)
291 {
292 adjustFlags(ASM_DEF::CF,checked);
293 calc();
294 }
295
on_pushButtonFlagPF_toggled(bool checked)296 void GuiMainWindow::on_pushButtonFlagPF_toggled(bool checked)
297 {
298 adjustFlags(ASM_DEF::PF,checked);
299 calc();
300 }
301
on_pushButtonFlagAF_toggled(bool checked)302 void GuiMainWindow::on_pushButtonFlagAF_toggled(bool checked)
303 {
304 adjustFlags(ASM_DEF::AF,checked);
305 calc();
306 }
307
on_pushButtonFlagZF_toggled(bool checked)308 void GuiMainWindow::on_pushButtonFlagZF_toggled(bool checked)
309 {
310 adjustFlags(ASM_DEF::ZF,checked);
311 calc();
312 }
313
on_pushButtonFlagSF_toggled(bool checked)314 void GuiMainWindow::on_pushButtonFlagSF_toggled(bool checked)
315 {
316 adjustFlags(ASM_DEF::SF,checked);
317 calc();
318 }
319
on_pushButtonFlagOF_toggled(bool checked)320 void GuiMainWindow::on_pushButtonFlagOF_toggled(bool checked)
321 {
322 adjustFlags(ASM_DEF::OF,checked);
323 calc();
324 }
325
on_lineEditFlagsBefore_textChanged(const QString & arg1)326 void GuiMainWindow::on_lineEditFlagsBefore_textChanged(const QString &arg1)
327 {
328 Q_UNUSED(arg1)
329
330 XVALUE nFlag=getLineEditValue(ui->lineEditFlagsBefore,g_currentMode);
331
332 ui->pushButtonFlagAF->setChecked(nFlag&(ASM_DEF::AF));
333 ui->pushButtonFlagCF->setChecked(nFlag&(ASM_DEF::CF));
334 ui->pushButtonFlagOF->setChecked(nFlag&(ASM_DEF::OF));
335 ui->pushButtonFlagPF->setChecked(nFlag&(ASM_DEF::PF));
336 ui->pushButtonFlagSF->setChecked(nFlag&(ASM_DEF::SF));
337 ui->pushButtonFlagZF->setChecked(nFlag&(ASM_DEF::ZF));
338
339 calc();
340 }
341
on_comboBoxMode_currentIndexChanged(int index)342 void GuiMainWindow::on_comboBoxMode_currentIndexChanged(int index)
343 {
344 if(index!=-1)
345 {
346 RECDATA _data=RECDATA_INIT;
347
348 _data.OPERAND[0]=getLineEditValue(ui->lineEditOperand1,g_currentMode);
349 _data.OPERAND[1]=getLineEditValue(ui->lineEditOperand2,g_currentMode);
350 _data.FLAG[0]=getLineEditValue(ui->lineEditFlagsBefore,g_currentMode);
351
352 g_currentMode=static_cast<ModeValidator::MODE>(ui->comboBoxMode->currentData().toInt());
353
354 adjustMode();
355
356 setLineEditValue(ui->lineEditOperand1,g_currentMode,_data.OPERAND[0]);
357 setLineEditValue(ui->lineEditOperand2,g_currentMode,_data.OPERAND[1]);
358 setLineEditValue(ui->lineEditFlagsBefore,g_currentMode,_data.FLAG[0]);
359
360 calc();
361 }
362 }
363
getLineEditValue(QLineEdit * pLineEdit,ModeValidator::MODE mode)364 XVALUE GuiMainWindow::getLineEditValue(QLineEdit *pLineEdit, ModeValidator::MODE mode)
365 {
366 XVALUE nValue=0;
367
368 QString sText=pLineEdit->text();
369
370 if(mode==ModeValidator::MODE_HEX)
371 {
372 #ifdef OPCODE32
373 nValue=sText.toULong(nullptr,16);
374 #else
375 nValue=sText.toULongLong(nullptr,16);
376 #endif
377 }
378 else if(mode==ModeValidator::MODE_SIGNED)
379 {
380 #ifdef OPCODE32
381 nValue=static_cast<XVALUE>(sText.toLong(nullptr,10));
382 #else
383 nValue=static_cast<XVALUE>(sText.toLongLong(nullptr,10));
384 #endif
385 }
386 else if(mode==ModeValidator::MODE_UNSIGNED)
387 {
388 #ifdef OPCODE32
389 nValue=sText.toULong(nullptr,10);
390 #else
391 nValue=sText.toULongLong(nullptr,10);
392 #endif
393 }
394
395 return nValue;
396 }
397
setLineEditValue(QLineEdit * pLineEdit,ModeValidator::MODE mode,XVALUE nValue)398 void GuiMainWindow::setLineEditValue(QLineEdit *pLineEdit, ModeValidator::MODE mode, XVALUE nValue)
399 {
400 QString sText;
401
402 if(mode==ModeValidator::MODE_HEX)
403 {
404 sText=QString::number(nValue,16);
405 }
406 else if(mode==ModeValidator::MODE_SIGNED)
407 {
408 sText=QString::number(static_cast<SXVALUE>(nValue),10);
409 }
410 else if(mode==ModeValidator::MODE_UNSIGNED)
411 {
412 sText=QString::number(nValue,10);
413 }
414
415 pLineEdit->setText(sText);
416 }
417
adjustFlags(XVALUE nFlag,bool bState)418 void GuiMainWindow::adjustFlags(XVALUE nFlag, bool bState)
419 {
420 ModeValidator::MODE mode=static_cast<ModeValidator::MODE>(ui->comboBoxMode->currentData().toInt());
421
422 XVALUE nValue=getLineEditValue(ui->lineEditFlagsBefore,mode);
423
424 if(bState)
425 {
426 nValue|=nFlag;
427 }
428 else
429 {
430 nValue&=(~nFlag);
431 }
432
433 setLineEditValue(ui->lineEditFlagsBefore,mode,nValue);
434 }
435
on_comboBoxOpcodeGroup_currentIndexChanged(int index)436 void GuiMainWindow::on_comboBoxOpcodeGroup_currentIndexChanged(int index)
437 {
438 if(index!=-1)
439 {
440 switch(ui->comboBoxOpcodeGroup->currentData(Qt::UserRole).toUInt())
441 {
442 case OG_TWOOPERANDS: loadOpcodes(ASM_DEF::asm_twooperands,sizeof(ASM_DEF::asm_twooperands)/sizeof(ASM_DEF::OPCODE_RECORD)); break;
443 case OG_ONEOPERAND: loadOpcodes(ASM_DEF::asm_oneoperand,sizeof(ASM_DEF::asm_oneoperand)/sizeof(ASM_DEF::OPCODE_RECORD)); break;
444 case OG_MULDIV: loadOpcodes(ASM_DEF::asm_muldiv,sizeof(ASM_DEF::asm_muldiv)/sizeof(ASM_DEF::OPCODE_RECORD)); break;
445 case OG_SHIFT: loadOpcodes(ASM_DEF::asm_shift,sizeof(ASM_DEF::asm_shift)/sizeof(ASM_DEF::OPCODE_RECORD)); break;
446 case OG_BITS: loadOpcodes(ASM_DEF::asm_bits,sizeof(ASM_DEF::asm_bits)/sizeof(ASM_DEF::OPCODE_RECORD)); break;
447 case OG_SPECIAL: loadOpcodes(ASM_DEF::asm_special,sizeof(ASM_DEF::asm_special)/sizeof(ASM_DEF::OPCODE_RECORD)); break;
448 }
449
450 adjustMode();
451 calc();
452 }
453 }
454
on_pushButtonOptions_clicked()455 void GuiMainWindow::on_pushButtonOptions_clicked()
456 {
457 DialogOptions dialogOptions(this,&g_xOptions);
458
459 dialogOptions.exec();
460
461 adjustWindow();
462 }
463