1 //////////////////////////////////////////////////
2 // //
3 // Emu64 //
4 // von Thorsten Kattanek //
5 // //
6 // #file: debugger_window.cpp //
7 // //
8 // Dieser Sourcecode ist Copyright geschützt! //
9 // Geistiges Eigentum von Th.Kattanek //
10 // //
11 // Letzte Änderung am 01.04.2020 //
12 // www.emu64.de //
13 // //
14 //////////////////////////////////////////////////
15
16 #include <QScreen>
17 #include <QStyle>
18
19 #include "./debugger_window.h"
20 #include "./ui_debugger_window.h"
21 #include "./micro_code_tbl_6510.h"
22 #include "./micro_code_string_tbl_6510.h"
23
DebuggerWindow(QWidget * parent,QSettings * ini)24 DebuggerWindow::DebuggerWindow(QWidget* parent, QSettings* ini) :
25 QDialog(parent),
26 ui(new Ui::DebuggerWindow),
27 memory_window(nullptr),
28 vic_window(nullptr),
29 iec_window(nullptr)
30 {
31 this->ini = ini;
32 c64 = nullptr;
33
34 current_source = 0;
35
36 table_back_color = QColor(255,255,255);
37 table_position_color = QColor(255,200,200);
38
39 old_adresse = 0;
40 old_make_idx = 0;
41
42 ui->setupUi(this);
43
44 // Center Window
45 setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, size(), QGuiApplication::screens()[0]->availableGeometry()));
46
47 memory_window = new MemoryWindow(this);
48 memory_window->ChangeSource(0);
49
50 vic_window = new DebuggerVicWindow(this);
51 iec_window = new DebuggerIECWindow(this);
52
53 new_refresh = false;
54 timer1 = new QTimer(this);
55 connect(timer1, SIGNAL(timeout()), this, SLOT(onTimerAnimationRefresh()));
56 timer1->setInterval(10);
57
58 icon_off = new QIcon(":/grafik/blue_led_off.png");
59 icon_on = new QIcon(":/grafik/blue_led_on.png");
60 ui->EingabeFeld->hide();
61
62 QFontDatabase fontDB;
63 fontDB.addApplicationFont(":/fonts/lucon.ttf");
64 QFont font1("Lucida Console",8);
65
66 ui->MCodeHelp->setFont(font1);
67
68 ui->DisAssTable->setColumnCount(4);
69 ui->DisAssTable->setColumnWidth(0, 44);
70 ui->DisAssTable->setColumnWidth(1, 70);
71 ui->DisAssTable->setColumnWidth(2, 30);
72 ui->DisAssTable->setColumnWidth(3, 57);
73
74 ui->DisAssTable->setFont(font1);
75 ui->DisAssTable->setRowCount(DISASS_ROW);
76
77 ui->AssAdresseIn->setFont(font1);
78 ui->AssMnemonicIn->setFont(font1);
79 ui->AssAdressierungIn->setFont(font1);
80
81 ui->BreakpointTree->setColumnCount(2);
82 ui->BreakpointTree->setColumnWidth(0, 175);
83 ui->BreakpointTree->setColumnWidth(1, 50);
84 new_breakpoint_found = false;
85
86 ui->HistoryList->setFont(font1);
87 for(int i=0; i<HISTORY_ROW; i++)
88 {
89 QListWidgetItem *item = new QListWidgetItem(ui->HistoryList);
90 item->setText(QVariant(i).toString());
91 ui->HistoryList->addItem(item);
92 }
93
94 for(int i=0; i<DISASS_ROW; i++)
95 {
96 view_code_address[i] = 0;
97 disass_pc[i] = new QTableWidgetItem();
98 disass_pc[i]->setBackground(table_back_color);
99 ui->DisAssTable->setItem(i, 0, disass_pc[i]);
100 disass_memory[i] = new QTableWidgetItem();
101 disass_memory[i]->setBackground(table_back_color);
102 ui->DisAssTable->setItem(i, 1, disass_memory[i]);
103 disass_mnemonic[i] = new QTableWidgetItem();
104 disass_mnemonic[i]->setBackground(table_back_color);
105 ui->DisAssTable->setItem(i, 2, disass_mnemonic[i]);
106 disass_addressing[i] = new QTableWidgetItem();
107 disass_addressing[i]->setBackground(table_back_color);
108 ui->DisAssTable->setItem(i, 3, disass_addressing[i]);
109 }
110
111 connect(ui->sr_widget, SIGNAL(ChangeValue(uint8_t)), this, SLOT(onSr_widget_ValueChange(uint8_t)));
112 connect(ui->pc_out, SIGNAL(clicked(LabelWidgetMod*)), this, SLOT(onReg_label_clicked(LabelWidgetMod*)));
113 connect(ui->sp_out, SIGNAL(clicked(LabelWidgetMod*)), this, SLOT(onReg_label_clicked(LabelWidgetMod*)));
114 connect(ui->ac_out, SIGNAL(clicked(LabelWidgetMod*)), this, SLOT(onReg_label_clicked(LabelWidgetMod*)));
115 connect(ui->xr_out, SIGNAL(clicked(LabelWidgetMod*)), this, SLOT(onReg_label_clicked(LabelWidgetMod*)));
116 connect(ui->yr_out, SIGNAL(clicked(LabelWidgetMod*)), this, SLOT(onReg_label_clicked(LabelWidgetMod*)));
117 connect(ui->sr_out, SIGNAL(clicked(LabelWidgetMod*)), this, SLOT(onReg_label_clicked(LabelWidgetMod*)));
118
119 current_edit_reg = -1;
120
121 rw_string = QStringList() << "[READ]" << "[WRITE]";
122
123 connect(ui->DisAssTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onShowContextMenu(QPoint)));
124
125 ////////// Load from INI ///////////
126 if(ini != nullptr)
127 {
128 ini->beginGroup("DebuggerWindow");
129 if(ini->contains("Geometry")) restoreGeometry(ini->value("Geometry").toByteArray());
130 ini->endGroup();
131 }
132 ////////////////////////////////////
133
134 timer1->start();
135 }
136
~DebuggerWindow()137 DebuggerWindow::~DebuggerWindow()
138 {
139 ////////// Save to INI ///////////
140 if(ini != nullptr)
141 {
142 ini->beginGroup("DebuggerWindow");
143 if(is_one_showed) ini->setValue("Geometry", saveGeometry());
144 if(isHidden()) ini->setValue("Show", false);
145 else ini->setValue("Show", true);
146 ini->endGroup();
147 }
148 ////////////////////////////////////
149
150 delete icon_off;
151 delete icon_on;
152 delete timer1;
153 delete ui;
154
155 if(memory_window != nullptr) delete memory_window;
156 if(vic_window != nullptr) delete vic_window;
157 if(iec_window != nullptr) delete iec_window;
158 }
159
AnimationRefreshProc()160 void DebuggerWindow::AnimationRefreshProc()
161 {
162 new_refresh = true;
163 }
164
onTimerAnimationRefresh()165 void DebuggerWindow::onTimerAnimationRefresh()
166 {
167 if(new_refresh)
168 {
169 new_refresh = false;
170 if(c64 != nullptr)
171 {
172 if(current_source > 0)
173 {
174 floppy_cpu_reg[currnet_floppy_nr].reg_mask = REG_MASK_ALL;
175 c64->floppy[currnet_floppy_nr]->GetCpuReg(&floppy_cpu_reg[currnet_floppy_nr], &floppy_cpu_ireg[currnet_floppy_nr]);
176 FillDisassemblyList(floppy_cpu_ireg[currnet_floppy_nr].current_opcode_pc, false);
177 }
178 else
179 {
180 c64_cpu_reg.reg_mask = REG_MASK_ALL;
181 c64->GetC64CpuReg(&c64_cpu_reg,&c64_cpu_ireg);
182 FillDisassemblyList(c64_cpu_ireg.current_opcode_pc,false);
183 }
184 }
185
186 UpdateRegister();
187 FillHistoryList(static_cast<uint8_t>(ui->HistoryScroll->value()));
188 memory_window->UpdateMemoryList();
189 vic_window->UpdateOutputList();
190 iec_window->UpdateSignals();
191 }
192
193 if(new_breakpoint_found)
194 {
195 new_breakpoint_found = false;
196 on_AnimationStop_clicked();
197
198 for(int i=0;i<c64->GetBreakGroupCount();i++)
199 {
200 BREAK_GROUP *bg = c64->GetBreakGroup(i);
201 if(bg->bTrue)
202 {
203 ui->ChangeSource->setCurrentIndex(0);
204 if(i < ui->BreakpointTree->topLevelItemCount())
205 {
206 ui->BreakpointTree->topLevelItem(i)->setBackground(0, QColor(0, 255, 0));
207 ui->BreakpointTree->topLevelItem(i)->setBackground(1, QColor(1, 255, 0));
208 ui->BreakpointTree->topLevelItem(i)->setText(1, tr("ERFÜLLT !"));
209 }
210 }
211 }
212
213 for(int i=0; i<MAX_FLOPPY_NUM; i++)
214 {
215 if(c64->floppy[i]->GetEnableFloppy())
216 {
217 for(int ii=0; ii<c64->floppy[i]->GetBreakGroupCount(); ii++)
218 {
219 BREAK_GROUP *bg = c64->floppy[i]->GetBreakGroup(ii);
220 if(bg->bTrue)
221 {
222 ui->ChangeSource->setCurrentIndex(i+1);
223 if(ii < ui->BreakpointTree->topLevelItemCount())
224 {
225 ui->BreakpointTree->topLevelItem(ii)->setBackground(0, QColor(0, 255, 0));
226 ui->BreakpointTree->topLevelItem(ii)->setBackground(1, QColor(1, 255, 0));
227 ui->BreakpointTree->topLevelItem(ii)->setText(1, tr("ERFÜLLT !"));
228 }
229 }
230 }
231 }
232 }
233 show();
234 }
235 }
236
RetranslateUi()237 void DebuggerWindow::RetranslateUi()
238 {
239 ui->retranslateUi(this);
240 ui->sr_widget->RetranslateUi();
241
242 this->update();
243 this->UpdateRegister();
244
245 vic_window->RetranslateUi();
246 memory_window->RetranslateUi();
247 iec_window->RetranslateUi();
248 }
249
SetC64Pointer(C64Class * c64)250 void DebuggerWindow::SetC64Pointer(C64Class *c64)
251 {
252 this->c64 = c64;
253 memory_window->SetC64Pointer(c64);
254 vic_window->SetC64Pointer(c64);
255 iec_window->SetC64Pointer(c64);
256 this->c64->AnimationRefreshProc = bind(&DebuggerWindow::AnimationRefreshProc, this);
257 this->c64->BreakpointProc = bind(&DebuggerWindow::BreakpointProc, this);
258 }
259
showEvent(QShowEvent *)260 void DebuggerWindow::showEvent(QShowEvent*)
261 {
262 is_one_showed = true;
263 c64->SetDebugMode(true);
264 RefreshGUI();
265 }
266
hideEvent(QHideEvent *)267 void DebuggerWindow::hideEvent(QHideEvent*)
268 {
269 /// HIDE ///
270
271 memory_window->hide();
272 vic_window->hide();
273 iec_window->hide();
274
275 c64->SetDebugMode(false);
276 c64->SetDebugAnimation(false);
277
278 ui->OneOpcode->setEnabled(true);
279 ui->OneZyklus->setEnabled(true);
280 ui->AnimationStart->setEnabled(true);
281 ui->AnimationStop->setEnabled(false);
282 ui->DisAssScroll->setEnabled(true);
283
284 ui->AssAdresseIn->setEnabled(true);
285 ui->AssMnemonicIn->setEnabled(true);
286 ui->AssAdressierungIn->setEnabled(true);
287 }
288
UpdateRegister()289 void DebuggerWindow::UpdateRegister()
290 {
291 if(c64 == nullptr) return;
292
293 char str00[1024];
294
295 if(current_source > 0)
296 {
297 /// Floppy's ///
298
299 if(!c64->floppy[currnet_floppy_nr]->GetEnableFloppy()) return;
300
301 sprintf(str00,"$%4.4X", floppy_cpu_reg[currnet_floppy_nr].pc);
302 ui->pc_out->setText(QString(str00));
303 sprintf(str00,"$%2.2X", floppy_cpu_reg[currnet_floppy_nr].sp + 0x100);
304 ui->sp_out->setText(QString(str00));
305 sprintf(str00,"$%2.2X", floppy_cpu_reg[currnet_floppy_nr].ac);
306 ui->ac_out->setText(QString(str00));
307 sprintf(str00,"$%2.2X", floppy_cpu_reg[currnet_floppy_nr].xr);
308 ui->xr_out->setText(QString(str00));
309 sprintf(str00,"$%2.2X", floppy_cpu_reg[currnet_floppy_nr].yr);
310 ui->yr_out->setText(QString(str00));
311 sprintf(str00,"$%2.2X", floppy_cpu_reg[currnet_floppy_nr].sr);
312 ui->sr_out->setText(QString(str00));
313 ui->sr_widget->SetValue(floppy_cpu_reg[currnet_floppy_nr].sr);
314
315 sprintf(str00,"$%4.4X", floppy_cpu_reg[currnet_floppy_nr].irq);
316 ui->irq_out->setText(QString(str00));
317 sprintf(str00,"$%4.4X", floppy_cpu_reg[currnet_floppy_nr].nmi);
318 ui->nmi_out->setText(QString(str00));
319 sprintf(str00,"$%4.4X", floppy_cpu_reg[currnet_floppy_nr]._0314);
320 ui->_0314_out->setText(QString(str00));
321 sprintf(str00,"$%4.4X", floppy_cpu_reg[currnet_floppy_nr]._0318);
322 ui->_0318_out->setText(QString(str00));
323
324 sprintf(str00,"$%4.4X", floppy_cpu_ireg[currnet_floppy_nr].current_opcode_pc);
325 ui->opcode_pc_out->setText(QString(str00));
326 sprintf(str00,"$%3.3X", floppy_cpu_ireg[currnet_floppy_nr].current_opcode);
327 ui->opcode_out->setText(QString(str00));
328 sprintf(str00,"$%4.4X", floppy_cpu_ireg[currnet_floppy_nr].address);
329 ui->adresse_out->setText(QString(str00));
330 sprintf(str00,"$%4.4X", floppy_cpu_ireg[currnet_floppy_nr].branch_address);
331 ui->branch_adresse_out->setText(QString(str00));
332 sprintf(str00,"$%2.2X", floppy_cpu_ireg[currnet_floppy_nr].pointer);
333 ui->pointer_out->setText(QString(str00));
334 sprintf(str00,"$%2.2X", floppy_cpu_ireg[currnet_floppy_nr].tmp_byte);
335 ui->tmp_byte_out->setText(QString(str00));
336 sprintf(str00,"%10.10d", floppy_cpu_ireg[currnet_floppy_nr].cycle_counter);
337 ui->CycleCounter_Out->setText(QString(str00));
338
339 sprintf(str00,"%3.3d ", floppy_cpu_ireg[currnet_floppy_nr].current_micro_code);
340 ui->micro_code_out->setText(str00 + rw_string[micro_code_rw_table_6510[floppy_cpu_ireg[currnet_floppy_nr].current_micro_code]]);
341
342 ui->MCodeHelp->setText(micro_code_string_table_6510[floppy_cpu_ireg[currnet_floppy_nr].current_micro_code]);
343 ui->mnemonic_out->setText(QString(CpuOPC).mid(floppy_cpu_ireg[currnet_floppy_nr].current_opcode * 3, 3));
344
345 if(floppy_cpu_ireg[currnet_floppy_nr].irq) ui->irq_led->setIcon(*icon_on);
346 else ui->irq_led->setIcon(*icon_off);
347 if(!floppy_cpu_ireg[currnet_floppy_nr].reset) ui->reset_led->setIcon(*icon_on);
348 else ui->reset_led->setIcon(*icon_off);
349 }
350 else
351 {
352 /// C64 ///
353 sprintf(str00, "$%4.4X", c64_cpu_reg.pc);
354 ui->pc_out->setText(QString(str00));
355 sprintf(str00, "$%2.2X", c64_cpu_reg.sp + 0x100);
356 ui->sp_out->setText(QString(str00));
357 sprintf(str00, "$%2.2X", c64_cpu_reg.ac);
358 ui->ac_out->setText(QString(str00));
359 sprintf(str00, "$%2.2X", c64_cpu_reg.xr);
360 ui->xr_out->setText(QString(str00));
361 sprintf(str00, "$%2.2X", c64_cpu_reg.yr);
362 ui->yr_out->setText(QString(str00));
363 sprintf(str00, "$%2.2X", c64_cpu_reg.sr);
364 ui->sr_out->setText(QString(str00));
365 ui->sr_widget->SetValue(c64_cpu_reg.sr);
366
367 sprintf(str00, "$%4.4X", c64_cpu_reg.irq);
368 ui->irq_out->setText(QString(str00));
369 sprintf(str00, "$%4.4X", c64_cpu_reg.nmi);
370 ui->nmi_out->setText(QString(str00));
371 sprintf(str00, "$%4.4X", c64_cpu_reg._0314);
372 ui->_0314_out->setText(QString(str00));
373 sprintf(str00, "$%4.4X", c64_cpu_reg._0318);
374 ui->_0318_out->setText(QString(str00));
375
376 sprintf(str00, "$%4.4X", c64_cpu_ireg.current_opcode_pc);
377 ui->opcode_pc_out->setText(QString(str00));
378 sprintf(str00, "$%3.3X", c64_cpu_ireg.current_opcode);
379 ui->opcode_out->setText(QString(str00));
380 sprintf(str00, "$%4.4X", c64_cpu_ireg.address);
381 ui->adresse_out->setText(QString(str00));
382 sprintf(str00, "$%4.4X", c64_cpu_ireg.branch_address);
383 ui->branch_adresse_out->setText(QString(str00));
384 sprintf(str00, "$%2.2X", c64_cpu_ireg.pointer);
385 ui->pointer_out->setText(QString(str00));
386 sprintf(str00, "$%2.2X", c64_cpu_ireg.tmp_byte);
387 ui->tmp_byte_out->setText(QString(str00));
388 sprintf(str00,"%10.10d", c64_cpu_ireg.cycle_counter);
389 ui->CycleCounter_Out->setText(QString(str00));
390
391 sprintf(str00, "%3.3d ", c64_cpu_ireg.current_micro_code);
392 ui->micro_code_out->setText(str00 + rw_string[micro_code_rw_table_6510[c64_cpu_ireg.current_micro_code]]);
393
394 ui->MCodeHelp->setText(micro_code_string_table_6510[c64_cpu_ireg.current_micro_code]);
395 ui->mnemonic_out->setText(QString(CpuOPC).mid(c64_cpu_ireg.current_opcode * 3, 3));
396
397 if(c64_cpu_ireg.cpu_wait) ui->wait_led->setIcon(*icon_on);
398 else ui->wait_led->setIcon(*icon_off);
399
400 if(!ui->man_lines->checkState())
401 {
402 if(c64_cpu_ireg.irq) ui->irq_led->setIcon(*icon_on);
403 else ui->irq_led->setIcon(*icon_off);
404 if(c64_cpu_ireg.nmi) ui->nmi_led->setIcon(*icon_on);
405 else ui->nmi_led->setIcon(*icon_off);
406 if(c64_cpu_ireg.rdy) ui->rdy_led->setIcon(*icon_on);
407 else ui->rdy_led->setIcon(*icon_off);
408 }
409 if(!c64_cpu_ireg.reset) ui->reset_led->setIcon(*icon_on);
410 else ui->reset_led->setIcon(*icon_off);
411 if(c64_cpu_ireg.exrom) ui->exrom_led->setIcon(*icon_on);
412 else ui->exrom_led->setIcon(*icon_off);
413 if(c64_cpu_ireg.game) ui->game_led->setIcon(*icon_on);
414 else ui->game_led->setIcon(*icon_off);
415 }
416 }
417
onShowContextMenu(const QPoint & pos)418 void DebuggerWindow::onShowContextMenu(const QPoint& pos)
419 {
420 // for most widgets
421 QPoint globalPos = ui->DisAssTable->mapToGlobal(pos);
422 // for QAbstractScrollArea and derived classes you would use:
423 // QPoint globalPos = myWidget->viewport()->mapToGlobal(pos);
424
425 QMenu myMenu;
426 myMenu.addAction(tr("Test1"));
427 // ...
428
429 QAction* selectedItem = myMenu.exec(globalPos);
430 if (selectedItem)
431 {
432 // something was chosen, do stuff
433 }
434 else
435 {
436 // nothing was chosen
437 }
438 }
439
onSr_widget_ValueChange(uint8_t value)440 void DebuggerWindow::onSr_widget_ValueChange(uint8_t value)
441 {
442 on_AnimationStop_clicked();
443
444 ui->EingabeFeld->hide();
445
446 REG_STRUCT cpu_reg;
447 cpu_reg.reg_mask = REG_MASK_SR;
448 cpu_reg.sr = value;
449
450 char str00[50];
451
452 sprintf(str00,"$%2.2X",value);
453 ui->sr_out->setText(str00);
454
455 if(current_source > 0)
456 {
457 c64->floppy[currnet_floppy_nr]->SetCpuReg(&cpu_reg);
458 }
459 else c64->cpu->SetRegister(&cpu_reg);
460 }
461
onReg_label_clicked(LabelWidgetMod * label)462 void DebuggerWindow::onReg_label_clicked(LabelWidgetMod* label)
463 {
464 on_AnimationStop_clicked();
465
466 current_edit_reg = -1;
467
468 if(label->objectName() == "pc_out") current_edit_reg = 0;
469 if(label->objectName() == "sp_out") current_edit_reg = 1;
470 if(label->objectName() == "ac_out") current_edit_reg = 2;
471 if(label->objectName() == "xr_out") current_edit_reg = 3;
472 if(label->objectName() == "yr_out") current_edit_reg = 4;
473 if(label->objectName() == "sr_out") current_edit_reg = 5;
474
475 ui->EingabeFeld->setGeometry(label->geometry());
476
477 ui->EingabeFeld->setText(label->text());
478 ui->EingabeFeld->selectAll();
479 ui->EingabeFeld->show();
480 ui->EingabeFeld->setFocus();
481 }
482
on_EingabeFeld_returnPressed()483 void DebuggerWindow::on_EingabeFeld_returnPressed()
484 {
485 if(current_edit_reg == -1)
486 {
487 ui->EingabeFeld->hide();
488 return;
489 }
490
491 bool ok;
492 QString in_str = ui->EingabeFeld->text();
493 uint16_t value;
494
495 if(in_str.left(1) == "$") in_str.replace(0, 1, "0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
496
497 value = in_str.toUShort(&ok, 0);
498
499 if(!ok)
500 {
501 QMessageBox::warning(this, tr("Eingabefehler..."), tr("Es wurde kein gültiges Zahlenformat benutzt !"));
502 return;
503 }
504
505 REG_STRUCT cpu_reg;
506
507 switch(current_edit_reg)
508 {
509 case 0:
510 cpu_reg.reg_mask = REG_MASK_PC;
511 cpu_reg.pc = value;
512 break;
513 case 1:
514 if(value > 0x100) value -= 0x100;
515 if(value > 0xFF)
516 {
517 QMessageBox::warning(this, tr("Eingabefehler..."), tr("Der Wert muss zwischen 0 und 511 liegen !"));
518 return;
519 }
520 cpu_reg.reg_mask = REG_MASK_SP;
521 cpu_reg.sp = static_cast<uint8_t>(value);
522 break;
523 case 2:
524 if(value > 0xFF)
525 {
526 QMessageBox::warning(this, tr("Eingabefehler..."), tr("Der Wert muss zwischen 0 und 255 liegen !"));
527 return;
528 }
529 cpu_reg.reg_mask = REG_MASK_AC;
530 cpu_reg.ac = static_cast<uint8_t>(value);
531 break;
532 case 3:
533 if(value > 0xFF)
534 {
535 QMessageBox::warning(this, tr("Eingabefehler..."), tr("Der Wert muss zwischen 0 und 255 liegen !"));
536 return;
537 }
538 cpu_reg.reg_mask = REG_MASK_XR;
539 cpu_reg.xr = static_cast<uint8_t>(value);
540 break;
541 case 4:
542 if(value > 0xFF)
543 {
544 QMessageBox::warning(this, tr("Eingabefehler..."), tr("Der Wert muss zwischen 0 und 255 liegen !"));
545 return;
546 }
547 cpu_reg.reg_mask = REG_MASK_YR;
548 cpu_reg.yr = static_cast<uint8_t>(value);
549 break;
550 case 5:
551 if(value > 0xFF)
552 {
553 QMessageBox::warning(this, tr("Eingabefehler..."), tr("Der Wert muss zwischen 0 und 255 liegen !"));
554 return;
555 }
556 cpu_reg.reg_mask = REG_MASK_SR;
557 cpu_reg.sr = static_cast<uint8_t>(value);
558 break;
559 }
560
561 if(current_source > 0)
562 {
563 c64->floppy[currnet_floppy_nr]->SetCpuReg(&cpu_reg);
564 c64->floppy[currnet_floppy_nr]->GetCpuReg(&floppy_cpu_reg[currnet_floppy_nr], &floppy_cpu_ireg[currnet_floppy_nr]);
565 }
566 else
567 {
568 c64->cpu->SetRegister(&cpu_reg);
569 c64->cpu->GetRegister(&c64_cpu_reg);
570 }
571
572 current_edit_reg = -1;
573 ui->EingabeFeld->hide();
574 UpdateRegister();
575 }
576
on_OneZyklus_clicked()577 void DebuggerWindow::on_OneZyklus_clicked()
578 {
579 ui->EingabeFeld->hide();
580 ClearAllBreakpointBackcolors();
581 c64->OneCycle();
582 }
583
on_OneOpcode_clicked()584 void DebuggerWindow::on_OneOpcode_clicked()
585 {
586 ui->EingabeFeld->hide();
587 ClearAllBreakpointBackcolors();
588 c64->OneOpcode(current_source);
589 }
590
on_CycleCounterReset_clicked()591 void DebuggerWindow::on_CycleCounterReset_clicked()
592 {
593 if(current_source > 0)
594 {
595 c64->floppy[currnet_floppy_nr]->ResetCycleCounter();
596 }
597 else
598 {
599 c64->ResetC64CycleCounter();
600 }
601 ui->CycleCounter_Out->setText("0000000000");
602 }
603
FillDisassemblyList(uint16_t address,bool new_refresh)604 void DebuggerWindow::FillDisassemblyList(uint16_t address, bool new_refresh)
605 {
606 uint16_t pc = address;
607 char str00[50];
608 uint16_t tmp;
609 uint16_t word;
610 uint8_t tmp1;
611 bool find = false;
612 int akt_make_idx = 0;
613
614 if(current_source > 0)
615 {
616 if(!c64->floppy[current_source-1]->GetEnableFloppy()) return;
617 }
618
619 if(!new_refresh)
620 {
621 for(int i=0;i<DISASS_ROW;i++)
622 {
623 if(view_code_address[i] == address)
624 {
625 find = true;
626 akt_make_idx = i;
627 }
628 }
629 }
630
631 if(find)
632 {
633 disass_pc[old_make_idx]->setBackground(table_back_color);
634 disass_memory[old_make_idx]->setBackground(table_back_color);
635 disass_mnemonic[old_make_idx]->setBackground(table_back_color);
636 disass_addressing[old_make_idx]->setBackground(table_back_color);
637
638 disass_pc[akt_make_idx]->setBackground(table_position_color);
639 disass_memory[akt_make_idx]->setBackground(table_position_color);
640 disass_mnemonic[akt_make_idx]->setBackground(table_position_color);
641 disass_addressing[akt_make_idx]->setBackground(table_position_color);
642
643 old_make_idx = akt_make_idx;
644 pc = old_adresse;
645 }
646 else
647 {
648 disass_pc[old_make_idx]->setBackground(table_back_color);
649 disass_memory[old_make_idx]->setBackground(table_back_color);
650 disass_mnemonic[old_make_idx]->setBackground(table_back_color);
651 disass_addressing[old_make_idx]->setBackground(table_back_color);
652
653 disass_pc[0]->setBackground(table_position_color);
654 disass_memory[0]->setBackground(table_position_color);
655 disass_mnemonic[0]->setBackground(table_position_color);
656 disass_addressing[0]->setBackground(table_position_color);
657
658 old_make_idx = akt_make_idx = 0;
659 pc = old_adresse = address;
660 }
661
662 uint8_t ram0;
663 uint8_t ram1;
664 uint8_t ram2;
665
666 for(int i=0; i<DISASS_ROW; i++)
667 {
668 view_code_address[i] = pc;
669 sprintf(str00, "$%4.4X", pc);
670 disass_pc[i]->setText(str00);
671
672 if(current_source > 0)
673 {
674 currnet_floppy_nr = current_source - 1;
675 ram0 = c64->floppy[currnet_floppy_nr]->ReadByte(pc+0);
676 ram1 = c64->floppy[currnet_floppy_nr]->ReadByte(pc+1);
677 ram2 = c64->floppy[currnet_floppy_nr]->ReadByte(pc+2);
678 }
679 else
680 {
681 ram0 = c64->ReadC64Byte(pc+0);
682 ram1 = c64->ReadC64Byte(pc+1);
683 ram2 = c64->ReadC64Byte(pc+2);
684 }
685
686 disass_mnemonic[i]->setText(QString(CpuOPC).mid(ram0*3, 3));
687
688 tmp = CpuOPCInfo[ram0];
689
690 if(!(tmp&8))
691 {
692 disass_mnemonic[i]->setForeground(QColor(0,0,0));
693 }
694 else
695 {
696 disass_mnemonic[i]->setForeground(QColor(255,0,0));
697 }
698
699 tmp >>= 4;
700 tmp &= 15;
701 switch(tmp)
702 {
703 case 0:
704 disass_addressing[i]->setText("");
705
706 sprintf(str00,"%2.2X -- --",ram0);
707 disass_memory[i]->setText(str00);
708 pc++;
709 break;
710 case 1:
711 sprintf(str00,"#$%2.2X",ram1);
712 disass_addressing[i]->setText(str00);
713
714 sprintf(str00,"%2.2X %2.2X --",ram0,ram1);
715 disass_memory[i]->setText(str00);
716 pc+=2;
717 break;
718 case 2:
719 word=ram1;
720 word|=ram2<<8;
721 sprintf(str00,"$%4.4X",word);
722 disass_addressing[i]->setText(str00);
723
724 sprintf(str00,"%2.2X %2.2X %2.2X",ram0,ram1,ram2);
725 disass_memory[i]->setText(str00);
726 pc+=3;
727 break;
728 case 3:
729 sprintf(str00,"$%2.2X",ram1);
730 disass_addressing[i]->setText(str00);
731
732 sprintf(str00,"%2.2X %2.2X --",ram0,ram1);
733 disass_memory[i]->setText(str00);
734 pc+=2;
735 break;
736 case 4:
737 word=ram1;
738 word|=ram2<<8;
739 sprintf(str00,"$%4.4X,X",word);
740 disass_addressing[i]->setText(str00);
741
742 sprintf(str00,"%2.2X %2.2X %2.2X",ram0,ram1,ram2);
743 disass_memory[i]->setText(str00);
744 pc+=3;
745 break;
746 case 5:
747 word=ram1;
748 word|=ram2<<8;
749 sprintf(str00,"$%4.4X,Y",word);
750 disass_addressing[i]->setText(str00);
751
752 sprintf(str00,"%2.2X %2.2X %2.2X",ram0,ram1,ram2);
753 disass_memory[i]->setText(str00);
754 pc+=3;
755 break;
756 case 6:
757 sprintf(str00,"$%2.2X,X",ram1);
758 disass_addressing[i]->setText(str00);
759
760 sprintf(str00,"%2.2X %2.2X --",ram0,ram1);
761 disass_memory[i]->setText(str00);
762 pc+=2;
763 break;
764 case 7:
765 sprintf(str00,"($%2.2X,X)",ram1);
766 disass_addressing[i]->setText(str00);
767
768 sprintf(str00,"%2.2X %2.2X --",ram0,ram1);
769 disass_memory[i]->setText(str00);
770 pc+=2;
771 break;
772 case 8:
773 sprintf(str00,"($%2.2X),Y",ram1);
774 disass_addressing[i]->setText(str00);
775
776 sprintf(str00,"%2.2X %2.2X --",ram0,ram1);
777 disass_memory[i]->setText(str00);
778 pc+=2;
779 break;
780 case 9:
781 tmp1 = ram1;
782 word = (pc+2)+tmp1;
783 sprintf(str00,"$%4.4X",word);
784 disass_addressing[i]->setText(str00);
785
786 sprintf(str00,"%2.2X %2.2X --",ram0,ram1);
787 disass_memory[i]->setText(str00);
788 pc+=2;
789 break;
790 case 10:
791 word=ram1;
792 word|=ram2<<8;
793 sprintf(str00,"($%4.4X)",word);
794 disass_addressing[i]->setText(str00);
795
796 sprintf(str00,"%2.2X %2.2X %2.2X",ram0,ram1,ram2);
797 disass_memory[i]->setText(str00);
798 pc+=3;
799 break;
800 case 11:
801 sprintf(str00,"$%2.2X,Y",ram1);
802 disass_addressing[i]->setText(str00);
803
804 sprintf(str00,"%2.2X %2.2X --",ram0,ram1);
805 disass_memory[i]->setText(str00);
806 pc+=2;
807 break;
808 }
809 }
810 }
811
FillHistoryList(uint8_t index)812 void DebuggerWindow::FillHistoryList(uint8_t index)
813 {
814 char str00[10];
815 uint8_t hp;
816
817 if(current_source > 0)
818 {
819 if(!c64->floppy[currnet_floppy_nr]->GetEnableFloppy()) return;
820 hp = c64->floppy[currnet_floppy_nr]->HistoryPointer;
821 for(int i=0; i<HISTORY_ROW; i++)
822 {
823 sprintf(str00, "$%4.4X", c64->floppy[currnet_floppy_nr]->History[hp--]);
824 ui->HistoryList->item(i)->setText(QString(str00));
825 }
826 }
827 else
828 {
829 hp = c64->cpu_pc_history_pos - index;
830 for(int i=0; i<HISTORY_ROW; i++)
831 {
832 sprintf(str00, "$%4.4X", c64->cpu_pc_history[hp--]);
833 ui->HistoryList->item(i)->setText(QString(str00));
834 }
835 }
836 }
837
on_ChangeSource_currentIndexChanged(int index)838 void DebuggerWindow::on_ChangeSource_currentIndexChanged(int index)
839 {
840 current_source = index;
841 if(current_source > 0)
842 {
843 currnet_floppy_nr = current_source - 1;
844 ui->BreakpointTree->clear();
845
846 if(c64 == nullptr) return;
847 break_point_update_enable = false;
848 int anz = c64->floppy[currnet_floppy_nr]->GetBreakGroupCount();
849 for(int i=0;i<anz;i++)
850 {
851 BREAK_GROUP *bg = c64->floppy[currnet_floppy_nr]->GetBreakGroup(i);
852 AddBreakpointTreeRoot(bg->Name, bg);
853 }
854 break_point_update_enable = true;
855 }
856 else
857 {
858 /// Alle Haltepunke ins TreeWidget einfügen ///
859
860 ui->BreakpointTree->clear();
861
862 if(c64 == nullptr) return;
863 break_point_update_enable = false;
864 int anz = c64->GetBreakGroupCount();
865 for(int i=0;i<anz;i++)
866 {
867 BREAK_GROUP *bg = c64->GetBreakGroup(i);
868 AddBreakpointTreeRoot(bg->Name, bg);
869 }
870 break_point_update_enable = true;
871 }
872
873 ui->AssAdresseIn->setText("");
874 ui->AssMnemonicIn->setText("");
875 ui->AssAdressierungIn->setText("");
876 memory_window->ChangeSource(current_source);
877 RefreshGUI();
878 }
879
on_AssAdresseIn_returnPressed()880 void DebuggerWindow::on_AssAdresseIn_returnPressed()
881 {
882 bool ok;
883 uint16_t value;
884 QString in_str = ui->AssAdresseIn->text();
885
886 if(in_str.left(1) == "$") in_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
887 value = in_str.toUShort(&ok,0);
888 if(!ok)
889 {
890 QMessageBox::warning(this, tr("Eingabefehler..."), tr("Es wurde kein gültiges Zahlenformat benutzt !"));
891 return;
892 }
893
894 char out_str[10];
895 sprintf(out_str, "$%4.4X", value);
896
897 ui->AssAdresseIn->setText(out_str);
898 ui->AssMnemonicIn->clear();
899 ui->AssAdressierungIn->clear();
900 ui->AssMnemonicIn->setFocus();
901 }
902
on_AssMnemonicIn_textChanged(const QString & arg1)903 void DebuggerWindow::on_AssMnemonicIn_textChanged(const QString &arg1)
904 {
905 if(arg1.length() == 3)
906 {
907 if(FindMnemonic(arg1))
908 {
909 ui->AssMnemonicIn->setText(ui->AssMnemonicIn->text().toUpper());
910 ui->AssAdressierungIn->clear();
911 ui->AssAdressierungIn->setFocus();
912 }
913 else
914 {
915 QMessageBox::warning(this,"Eingabefehler...","Unbekanntes Mnemonic !");
916 ui->AssMnemonicIn->setFocus();
917 ui->AssMnemonicIn->selectAll();
918 }
919 }
920 }
921
FindMnemonic(QString mnemonic,uint8_t * opcode,uint8_t * opcode_count)922 bool DebuggerWindow::FindMnemonic(QString mnemonic, uint8_t *opcode, uint8_t *opcode_count)
923 {
924 bool found = false;
925 uint8_t count = 0;
926
927 for(int i=0; i<256; i++)
928 {
929 if(mnemonic.toUpper() == QString(CpuOPC).mid(i*3,3))
930 {
931 found = true;
932 if(opcode != nullptr) opcode[count++] = static_cast<uint8_t>(i);
933 }
934 }
935 if(opcode_count != nullptr) *opcode_count = count;
936 return found;
937 }
938
FindAddressing(QString address_string,uint8_t * address_type,uint16_t * address_value)939 bool DebuggerWindow::FindAddressing(QString address_string, uint8_t *address_type, uint16_t *address_value)
940 {
941 uint32_t integer;
942 bool ok;
943
944 QString in_str = address_string.toUpper();
945
946 if(in_str == "")
947 {
948 *address_type = 0;
949 *address_value = 0;
950 return true;
951 }
952
953
954 if(in_str.left(1) == "$") in_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
955 integer = in_str.toUShort(&ok,0);
956 if(ok)
957 {
958 if(integer <= 0xFF)
959 {
960 *address_type = 3;
961 *address_value = static_cast<uint16_t>(integer);
962 return true;
963 }
964
965 if(integer <= 0xFFFF)
966 {
967 *address_type = 2;
968 *address_value = static_cast<uint16_t>(integer);
969 return true;
970 }
971 }
972
973 if(in_str.left(1) == "#")
974 {
975 in_str.remove(0,1);
976 if(in_str.left(1) == "$") in_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
977 integer = in_str.toUShort(&ok,0);
978 if(ok)
979 {
980 if(integer <= 0xFF)
981 {
982 *address_type = 1;
983 *address_value = static_cast<uint16_t>(integer);
984 return true;
985 }
986 else return false;
987 }
988 else return false;
989 }
990
991 if(in_str.right(2) == ",X")
992 {
993 QString tmp_str = in_str;
994 tmp_str.remove(tmp_str.length()-2,2);
995 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
996 integer = tmp_str.toUShort(&ok,0);
997 if(ok)
998 {
999 if(integer <= 0xFF)
1000 {
1001 *address_type = 6;
1002 *address_value = static_cast<uint16_t>(integer);
1003 return true;
1004 }
1005
1006 if(integer <= 0xFFFF)
1007 {
1008 *address_type = 4;
1009 *address_value = static_cast<uint16_t>(integer);
1010 return true;
1011 }
1012 return false;
1013 }
1014 }
1015
1016 if(in_str.right(2) == ",Y")
1017 {
1018 QString tmp_str = in_str;
1019 tmp_str.remove(tmp_str.length()-2,2);
1020 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1021 integer = tmp_str.toUShort(&ok,0);
1022 if(ok)
1023 {
1024 if(integer <= 0xFF)
1025 {
1026 *address_type = 11;
1027 *address_value = static_cast<uint16_t>(integer);
1028 return true;
1029 }
1030
1031 if(integer <= 0xFFFF)
1032 {
1033 *address_type = 5;
1034 *address_value = static_cast<uint16_t>(integer);
1035 return true;
1036 }
1037 return false;
1038 }
1039 }
1040
1041 if((in_str.left(1) == "(") && (in_str.right(3) == ",X)"))
1042 {
1043 QString tmp_str = in_str;
1044 tmp_str = tmp_str.mid(1,tmp_str.length()-4);
1045 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1046 integer = tmp_str.toUShort(&ok,0);
1047 if(ok)
1048 {
1049 if(integer <= 0xFF)
1050 {
1051 *address_type = 7;
1052 *address_value = static_cast<uint16_t>(integer);
1053 return true;
1054 }
1055 else return false;
1056 }
1057 else return false;
1058 }
1059
1060 if((in_str.left(1) == "(") && (in_str.right(3) == "),Y"))
1061 {
1062 QString tmp_str = in_str;
1063 tmp_str = tmp_str.mid(1,tmp_str.length()-4);
1064 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1065 integer = tmp_str.toUShort(&ok,0);
1066 if(ok)
1067 {
1068 if(integer <= 0xFF)
1069 {
1070 *address_type = 8;
1071 *address_value = static_cast<uint16_t>(integer);
1072 return true;
1073 }
1074 else return false;
1075 }
1076 else return false;
1077 }
1078
1079 if((in_str.left(1) == "(") && (in_str.right(1) == ")"))
1080 {
1081 QString tmp_str = in_str;
1082 tmp_str = tmp_str.mid(1,tmp_str.length()-2);
1083 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1084 integer = tmp_str.toUShort(&ok,0);
1085 if(ok)
1086 {
1087 if(integer <= 0xFFFF)
1088 {
1089 *address_type = 10;
1090 *address_value = static_cast<uint16_t>(integer);
1091 return true;
1092 }
1093 else return false;
1094 }
1095 else return false;
1096 }
1097 return false;
1098 }
1099
on_AssAdressierungIn_returnPressed()1100 void DebuggerWindow::on_AssAdressierungIn_returnPressed()
1101 {
1102 uint16_t ass_adress;
1103 uint16_t new_adress;
1104
1105 if(Assemble(ui->AssAdresseIn->text(), ui->AssMnemonicIn->text(), ui->AssAdressierungIn->text(), &ass_adress, &new_adress))
1106 {
1107 char out_str[10];
1108 sprintf(out_str, "$%4.4X", new_adress);
1109 ui->AssAdresseIn->setText(QString(out_str));
1110 ui->AssMnemonicIn->clear();
1111 ui->AssAdressierungIn->clear();
1112 ui->AssMnemonicIn->setFocus();
1113
1114 FillDisassemblyList(ass_adress, false);
1115 memory_window->update();
1116 }
1117 else
1118 {
1119 switch(new_adress)
1120 {
1121 case 0:
1122 QMessageBox::warning(this, tr("Fehler...!"), tr("Fehlerhafte Adresse."));
1123 ui->AssAdresseIn->selectAll();
1124 ui->AssAdresseIn->setFocus();
1125 break;
1126 case 1:
1127 QMessageBox::warning(this, tr("Fehler...!"), tr("Unbekanntes Mnemonic."));
1128 ui->AssMnemonicIn->selectAll();
1129 ui->AssMnemonicIn->setFocus();
1130 break;
1131 case 2:
1132 QMessageBox::warning(this, tr("Fehler...!"), tr("Unbekannte Adressierung."));
1133 ui->AssAdressierungIn->selectAll();
1134 ui->AssAdressierungIn->setFocus();
1135 break;
1136 case 3:
1137 QMessageBox::warning(this, tr("Fehler...!"), tr("Spungweite für Branchbefehl ist zu groß."));
1138 ui->AssAdressierungIn->selectAll();
1139 ui->AssAdressierungIn->setFocus();
1140 break;
1141 case 4:
1142 QMessageBox::warning(this, tr("Fehler...!"), tr("Dieser Opcode unterstützt nicht diese Adressierung."));
1143 ui->AssAdressierungIn->selectAll();
1144 ui->AssAdressierungIn->setFocus();
1145 break;
1146 }
1147 }
1148 }
1149
Assemble(QString address,QString mnemonic,QString addressing,uint16_t * ass_address,uint16_t * new_adress)1150 bool DebuggerWindow::Assemble(QString address, QString mnemonic, QString addressing, uint16_t *ass_address, uint16_t *new_adress)
1151 {
1152 uint32_t start_address;
1153 uint8_t opcode[32];
1154 uint8_t opcode_count;
1155 uint8_t address_type;
1156 uint16_t address_value;
1157
1158 bool ok;
1159
1160 QString in_str = address;
1161 if(in_str.left(1) == "$") in_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1162 start_address = in_str.toUShort(&ok,0);
1163 if(!ok)
1164 {
1165 *new_adress = 0;
1166 return false;
1167 }
1168
1169 if(!FindMnemonic(mnemonic,opcode,&opcode_count))
1170 {
1171 *new_adress = 1;
1172 return false;
1173 }
1174
1175 if(!FindAddressing(addressing,&address_type,&address_value))
1176 {
1177 *new_adress = 2;
1178 return false;
1179 }
1180
1181 *ass_address = static_cast<uint16_t>(start_address);
1182
1183 if((opcode[0]==0x90)||(opcode[0]==0xB0)||(opcode[0]==0xF0)||(opcode[0]==0x30)||(opcode[0]==0xD0)||(opcode[0]==0x10)||(opcode[0]==0x50)||(opcode[0]==0x70))
1184 {
1185 if((address_type == 2) || (address_type == 3))
1186 {
1187 int16_t jmp_adress = static_cast<int16_t>(address_value) - static_cast<int16_t>(start_address) - 2;
1188 if((jmp_adress < -128) || (jmp_adress > 127))
1189 {
1190 *new_adress = 3;
1191 return false;
1192 }
1193
1194 if(current_source > 0)
1195 {
1196 c64->floppy[currnet_floppy_nr]->WriteByte(static_cast<uint16_t>(start_address), opcode[0]);
1197 c64->floppy[currnet_floppy_nr]->WriteByte(static_cast<uint16_t>(start_address)+1, static_cast<uint8_t>(jmp_adress));
1198 }
1199 else
1200 {
1201 c64->WriteC64Byte(static_cast<uint16_t>(start_address), opcode[0]);
1202 c64->WriteC64Byte(static_cast<uint16_t>(start_address)+1, static_cast<uint8_t>(jmp_adress));
1203 }
1204
1205 *new_adress = static_cast<uint16_t>(start_address) + 2;
1206 return true;
1207 }
1208 }
1209
1210 for(int i=0;i<opcode_count;i++)
1211 {
1212 if((CpuOPCInfo[opcode[i]]>>4) == address_type)
1213 {
1214 switch (address_type)
1215 {
1216 case 0:
1217 if(current_source > 0)
1218 {
1219 c64->floppy[currnet_floppy_nr]->WriteByte(static_cast<uint16_t>(start_address), opcode[i]);
1220 }
1221 else
1222 {
1223 c64->WriteC64Byte(static_cast<uint16_t>(start_address), opcode[i]);
1224 }
1225 *new_adress = static_cast<uint16_t>(start_address)+1;
1226 break;
1227 case 1: case 3: case 6: case 7: case 8: case 11:
1228 if(current_source > 0)
1229 {
1230 c64->floppy[currnet_floppy_nr]->WriteByte(static_cast<uint16_t>(start_address), opcode[i]);
1231 c64->floppy[currnet_floppy_nr]->WriteByte(static_cast<uint16_t>(start_address)+1, static_cast<uint8_t>(address_value));
1232 }
1233 else
1234 {
1235 c64->WriteC64Byte(static_cast<uint16_t>(start_address), opcode[i]);
1236 c64->WriteC64Byte(static_cast<uint16_t>(start_address)+1, static_cast<uint8_t>(address_value));
1237 }
1238 *new_adress = static_cast<uint16_t>(start_address)+2;
1239 break;
1240 case 2: case 4: case 5: case 10:
1241 if(current_source > 0)
1242 {
1243 c64->floppy[currnet_floppy_nr]->WriteByte(static_cast<uint16_t>(start_address), opcode[i]);
1244 c64->floppy[currnet_floppy_nr]->WriteByte(static_cast<uint16_t>(start_address)+1, static_cast<uint8_t>(address_value));
1245 c64->floppy[currnet_floppy_nr]->WriteByte(static_cast<uint16_t>(start_address)+2, static_cast<uint8_t>(address_value>>8));
1246 }
1247 else
1248 {
1249 c64->WriteC64Byte(static_cast<uint16_t>(start_address), opcode[i]);
1250 c64->WriteC64Byte(static_cast<uint16_t>(start_address)+1, static_cast<uint8_t>(address_value));
1251 c64->WriteC64Byte(static_cast<uint16_t>(start_address)+2, static_cast<uint8_t>(address_value>>8));
1252 }
1253 *new_adress = static_cast<uint16_t>(start_address)+3;
1254 break;
1255 }
1256 return true;
1257 }
1258 }
1259
1260 *new_adress = 4;
1261 return false;
1262 }
1263
on_AnimationStart_clicked()1264 void DebuggerWindow::on_AnimationStart_clicked()
1265 {
1266 ClearAllBreakpointBackcolors();
1267
1268 ui->OneOpcode->setEnabled(false);
1269 ui->OneZyklus->setEnabled(false);
1270 ui->AnimationStart->setEnabled(false);
1271 ui->AnimationStop->setEnabled(true);
1272 ui->DisAssScroll->setEnabled(false);
1273
1274 ui->AssAdresseIn->setEnabled(false);
1275 ui->AssMnemonicIn->setEnabled(false);
1276 ui->AssAdressierungIn->setEnabled(false);
1277 ui->EingabeFeld->setVisible(false);
1278
1279 c64->SetDebugAnimation(true);
1280 }
1281
on_AnimationStop_clicked()1282 void DebuggerWindow::on_AnimationStop_clicked()
1283 {
1284 ui->OneOpcode->setEnabled(true);
1285 ui->OneZyklus->setEnabled(true);
1286 ui->AnimationStart->setEnabled(true);
1287 ui->AnimationStop->setEnabled(false);
1288 ui->DisAssScroll->setEnabled(true);
1289
1290 ui->AssAdresseIn->setEnabled(true);
1291 ui->AssMnemonicIn->setEnabled(true);
1292 ui->AssAdressierungIn->setEnabled(true);
1293
1294 c64->SetDebugAnimation(false);
1295 }
1296
on_AnimationSpeed_valueChanged(int value)1297 void DebuggerWindow::on_AnimationSpeed_valueChanged(int value)
1298 {
1299 if(value == 1) ui->anispeed_out->setText(QVariant(value).toString() + tr(" Zyklus/Sek"));
1300 else ui->anispeed_out->setText(QVariant(value).toString() + tr(" Zyklen/Sek"));
1301 c64->SetDebugAnimationSpeed(value);
1302 }
1303
on_DisAssTable_doubleClicked(const QModelIndex & index)1304 void DebuggerWindow::on_DisAssTable_doubleClicked(const QModelIndex &index)
1305 {
1306 ui->AssAdresseIn->setText(ui->DisAssTable->item(index.row(),0)->text());
1307 ui->AssMnemonicIn->setText(ui->DisAssTable->item(index.row(),2)->text());
1308 ui->AssAdressierungIn->setText(ui->DisAssTable->item(index.row(),3)->text());
1309 }
1310
on_DisAssScroll_valueChanged(int value)1311 void DebuggerWindow::on_DisAssScroll_valueChanged(int value)
1312 {
1313 FillDisassemblyList(static_cast<uint16_t>(value), false);
1314 }
1315
on_AddBreakpoint_clicked()1316 void DebuggerWindow::on_AddBreakpoint_clicked()
1317 {
1318 static int auto_num[MAX_FLOPPY_NUM+1] = {1,1,1,1,1};
1319 BREAK_GROUP *bg;
1320 int index;
1321
1322 if(current_source > 0)
1323 {
1324 index = c64->floppy[currnet_floppy_nr]->AddBreakGroup();
1325 }
1326 else index = c64->AddBreakGroup();
1327
1328 if(index > -1)
1329 {
1330 if(current_source > 0) bg = c64->floppy[currnet_floppy_nr]->GetBreakGroup(index);
1331 else bg = c64->GetBreakGroup(index);
1332
1333 QString Name = tr("Haltepunkt (") + QVariant(auto_num[current_source]++).toString() + ")";
1334 strcpy(bg->Name,Name.toLocal8Bit().constData());
1335 bg->Enable = true;
1336
1337 AddBreakpointTreeRoot(Name,bg);
1338 }
1339 }
1340
on_DelBreakpoint_clicked()1341 void DebuggerWindow::on_DelBreakpoint_clicked()
1342 {
1343 int bg_index;
1344 QString Name;
1345
1346 if(ui->BreakpointTree->selectedItems().count() == 1)
1347 {
1348 QTreeWidgetItem *item = ui->BreakpointTree->selectedItems()[0];
1349
1350 if(item->parent() == nullptr)
1351 {
1352 bg_index = ui->BreakpointTree->indexOfTopLevelItem(item);
1353 Name = item->text(0);
1354 }
1355 else
1356 {
1357 bg_index = ui->BreakpointTree->indexOfTopLevelItem(item->parent());
1358 Name = item->parent()->text(0);
1359 }
1360
1361 if(QMessageBox::Yes == QMessageBox::question(this,tr("Haltepunkt löschen..."),tr("Möchten Sie den folgenden Haltepunkt löschen?\n") + ">> " + Name + " <<",QMessageBox::Yes | QMessageBox::No))
1362 {
1363 ui->BreakpointTree->takeTopLevelItem(bg_index);
1364 if(current_source > 0) c64->floppy[currnet_floppy_nr]->DelBreakGroup(bg_index);
1365 else c64->DelBreakGroup(bg_index);
1366 }
1367 }
1368 }
1369
AddBreakpointTreeRoot(QString name,BREAK_GROUP * bg)1370 void DebuggerWindow::AddBreakpointTreeRoot(QString name,BREAK_GROUP *bg)
1371 {
1372 QTreeWidgetItem *item = new QTreeWidgetItem(0);
1373 item->setText(0,name);
1374 item->setForeground(0,QBrush(QColor(200,0,0)));
1375 item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsSelectable | Qt::ItemIsEditable);
1376 item->setCheckState(0,Qt::Checked);
1377 item->setDisabled(false);
1378 item->setToolTip(0,tr("Der Name des Haltepunkts kann frei gewählt werden."));
1379 ui->BreakpointTree->addTopLevelItem(item);
1380
1381 break_point_update_enable = false;
1382 AddBreakpointTreeChild(item,bg->iPC,bg->bPC,tr("Wenn der Wert gleich dem Programm Counter (PC) ist."));
1383 AddBreakpointTreeChild(item,bg->iAC,bg->bAC,tr("Wenn der Wert gleich dem Accu Register (AC) ist."));
1384 AddBreakpointTreeChild(item,bg->iXR,bg->bXR,tr("Wenn der Wert gleich dem X Register (XR) ist."));
1385 AddBreakpointTreeChild(item,bg->iYR,bg->bYR,tr("Wenn der Wert gleich dem Y Register (YR) ist."));
1386 AddBreakpointTreeChild(item,bg->iRAdresse,bg->bRAdresse,tr("Wenn ein Lesezugriff an dieser Adresse statt findet."));
1387 AddBreakpointTreeChild(item,bg->iWAdresse,bg->bWAdresse,tr("Wenn ein Schreibzugriff an dieser Adresse statt findet."));
1388 AddBreakpointTreeChild(item,bg->iRWert,bg->bRWert,tr("Wenn aus einer Adresse dieser Wert ausgelesen wird."));
1389 AddBreakpointTreeChild(item,bg->iWWert,bg->bWWert,tr("Wenn in einer Adresse dieser Wert geschrieben wird."));
1390 if(current_source == 0)
1391 {
1392 AddBreakpointTreeChild(item,bg->iRZ,bg->bRZ,tr("Wenn der Wert gleich der Aktuellen Rasterzeile ist."));
1393 AddBreakpointTreeChild(item,bg->iRZZyklus,bg->bRZZyklus,tr("Wenn der Wert gleich dem Aktuellen Zyklus in einer Rasterzeile ist."));
1394 }
1395 break_point_update_enable = true;
1396 c64->UpdateBreakGroup();
1397 }
1398
AddBreakpointTreeChild(QTreeWidgetItem * parent,uint16_t value,uint8_t checked,QString tooltip)1399 void DebuggerWindow::AddBreakpointTreeChild(QTreeWidgetItem *parent, uint16_t value, uint8_t checked, QString tooltip)
1400 {
1401 QTreeWidgetItem *item = new QTreeWidgetItem(parent);
1402 item->setText(1,QVariant(value).toString());
1403 item->setForeground(0,QBrush(QColor(0,0,0)));
1404 item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsSelectable | Qt::ItemIsEditable);
1405 if(checked) item->setCheckState(0,Qt::Checked);
1406 else item->setCheckState(0,Qt::Unchecked);
1407 item->setDisabled(false);
1408 item->setToolTip(0,tooltip);
1409 item->setToolTip(1,tr("Doppelklick um Werte zu verändern."));
1410 item->setBackground(1,QColor(200,200,255));
1411 item->setForeground(1,QColor(200,0,0));
1412 parent->addChild(item);
1413 }
1414
on_BreakpointTree_itemChanged(QTreeWidgetItem * item,int column)1415 void DebuggerWindow::on_BreakpointTree_itemChanged(QTreeWidgetItem *item, int column)
1416 {
1417 int bg_index;
1418 int child_index;
1419
1420 if(item->parent() == nullptr)
1421 {
1422 /// TopLevel Item (Breakpointname) ///
1423
1424 bg_index = ui->BreakpointTree->indexOfTopLevelItem(item);
1425 BREAK_GROUP *bg;
1426 if(current_source > 0)
1427 {
1428 bg = c64->floppy[currnet_floppy_nr]->GetBreakGroup(bg_index);
1429 }
1430 else bg = c64->GetBreakGroup(bg_index);
1431
1432 strcpy(bg->Name,item->text(0).toLocal8Bit().constData());
1433 bg->Enable = item->checkState(0);
1434 c64->UpdateBreakGroup();
1435 }
1436 else
1437 {
1438 /// Child Item ///
1439 bg_index = ui->BreakpointTree->indexOfTopLevelItem(item->parent());
1440 child_index = item->parent()->indexOfChild(item);
1441
1442 BREAK_GROUP *bg;
1443 if(current_source > 0)
1444 {
1445 bg = c64->floppy[currnet_floppy_nr]->GetBreakGroup(bg_index);
1446 }
1447 else bg = c64->GetBreakGroup(bg_index);
1448
1449 if(column == 0 || 1)
1450 {
1451 QString tmp_str = item->text(1);
1452 bool ok;
1453 uint16_t integer;
1454 char str_00[10];
1455
1456 switch(child_index)
1457 {
1458 case 0:
1459 item->setText(0,"PC:");
1460
1461 if(tmp_str != "")
1462 {
1463 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1464 integer = tmp_str.toUShort(&ok,0);
1465 if(ok)
1466 {
1467 bg->iPC = integer;
1468 sprintf(str_00,"$%4.4X",integer);
1469 item->setText(1,QString(str_00));
1470 item->setBackground(1,QColor(200,200,255));
1471 item->setForeground(1,QColor(200,0,0));
1472 }
1473 else
1474 {
1475 item->setCheckState(0,Qt::Unchecked);
1476 item->setBackground(1,QColor(200,0,0));
1477 item->setForeground(1,QColor(200,200,200));
1478 }
1479 }
1480 else item->setCheckState(0,Qt::Unchecked);
1481 bg->bPC = item->checkState(0);
1482
1483 break;
1484 case 1:
1485 item->setText(0,"AC:");
1486
1487 if(tmp_str != "")
1488 {
1489 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1490 integer = tmp_str.toUShort(&ok,0);
1491 if(ok)
1492 {
1493 if(integer <= 0xff)
1494 {
1495 bg->iAC = integer;
1496 sprintf(str_00,"$%2.2X",integer);
1497 item->setText(1,QString(str_00));
1498 item->setBackground(1,QColor(200,200,255));
1499 item->setForeground(1,QColor(200,0,0));
1500 }
1501 else
1502 {
1503 item->setCheckState(0,Qt::Unchecked);
1504 item->setBackground(1,QColor(200,0,0));
1505 item->setForeground(1,QColor(200,200,200));
1506 }
1507 }
1508 else
1509 {
1510 item->setCheckState(0,Qt::Unchecked);
1511 item->setBackground(1,QColor(200,0,0));
1512 item->setForeground(1,QColor(200,200,200));
1513 }
1514 }
1515 else item->setCheckState(0,Qt::Unchecked);
1516 bg->bAC = item->checkState(0);
1517 break;
1518 case 2:
1519 item->setText(0,"XR:");
1520
1521 if(tmp_str != "")
1522 {
1523 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1524 integer = tmp_str.toUShort(&ok,0);
1525 if(ok)
1526 {
1527 if(integer <= 0xff)
1528 {
1529 bg->iXR = integer;
1530 sprintf(str_00,"$%2.2X",integer);
1531 item->setText(1,QString(str_00));
1532 item->setBackground(1,QColor(200,200,255));
1533 item->setForeground(1,QColor(200,0,0));
1534 }
1535 else
1536 {
1537 item->setCheckState(0,Qt::Unchecked);
1538 item->setBackground(1,QColor(200,0,0));
1539 item->setForeground(1,QColor(200,200,200));
1540 }
1541 }
1542 else
1543 {
1544 item->setCheckState(0,Qt::Unchecked);
1545 item->setBackground(1,QColor(200,0,0));
1546 item->setForeground(1,QColor(200,200,200));
1547 }
1548 }
1549 else item->setCheckState(0,Qt::Unchecked);
1550 bg->bXR = item->checkState(0);
1551 break;
1552 case 3:
1553 item->setText(0,"YR:");
1554
1555 if(tmp_str != "")
1556 {
1557 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1558 integer = tmp_str.toUShort(&ok,0);
1559 if(ok)
1560 {
1561 if(integer <= 0xff)
1562 {
1563 bg->iYR = integer;
1564 sprintf(str_00,"$%2.2X",integer);
1565 item->setText(1,QString(str_00));
1566 item->setBackground(1,QColor(200,200,255));
1567 item->setForeground(1,QColor(200,0,0));
1568 }
1569 else
1570 {
1571 item->setCheckState(0,Qt::Unchecked);
1572 item->setBackground(1,QColor(200,0,0));
1573 item->setForeground(1,QColor(200,200,200));
1574 }
1575 }
1576 else
1577 {
1578 item->setCheckState(0,Qt::Unchecked);
1579 item->setBackground(1,QColor(200,0,0));
1580 item->setForeground(1,QColor(200,200,200));
1581 }
1582 }
1583 else item->setCheckState(0,Qt::Unchecked);
1584 bg->bYR = item->checkState(0);
1585 break;
1586 case 4:
1587 item->setText(0,tr("Lesen von Adresse:"));
1588
1589 if(tmp_str != "")
1590 {
1591 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1592 integer = tmp_str.toUShort(&ok,0);
1593 if(ok)
1594 {
1595 bg->iRAdresse = integer;
1596 sprintf(str_00,"$%4.4X",integer);
1597 item->setText(1,QString(str_00));
1598 item->setBackground(1,QColor(200,200,255));
1599 item->setForeground(1,QColor(200,0,0));
1600 }
1601 else
1602 {
1603 item->setCheckState(0,Qt::Unchecked);
1604 item->setBackground(1,QColor(200,0,0));
1605 item->setForeground(1,QColor(200,200,200));
1606 }
1607 }
1608 else item->setCheckState(0,Qt::Unchecked);
1609 bg->bRAdresse = item->checkState(0);
1610 break;
1611 case 5:
1612 item->setText(0,tr("Schreiben in Adresse:"));
1613
1614 if(tmp_str != "")
1615 {
1616 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1617 integer = tmp_str.toUShort(&ok,0);
1618 if(ok)
1619 {
1620 bg->iWAdresse = integer;
1621 sprintf(str_00,"$%4.4X",integer);
1622 item->setText(1,QString(str_00));
1623 item->setBackground(1,QColor(200,200,255));
1624 item->setForeground(1,QColor(200,0,0));
1625 }
1626 else
1627 {
1628 item->setCheckState(0,Qt::Unchecked);
1629 item->setBackground(1,QColor(200,0,0));
1630 item->setForeground(1,QColor(200,200,200));
1631 }
1632 }
1633 else item->setCheckState(0,Qt::Unchecked);
1634 bg->bWAdresse = item->checkState(0);
1635 break;
1636 case 6:
1637 item->setText(0,tr("Lesen von Wert:"));
1638
1639 if(tmp_str != "")
1640 {
1641 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1642 integer = tmp_str.toUShort(&ok,0);
1643 if(ok)
1644 {
1645 if(integer <= 0xff)
1646 {
1647 bg->iRWert = integer;
1648 sprintf(str_00,"$%2.2X",integer);
1649 item->setText(1,QString(str_00));
1650 item->setBackground(1,QColor(200,200,255));
1651 item->setForeground(1,QColor(200,0,0));
1652 }
1653 else
1654 {
1655 item->setCheckState(0,Qt::Unchecked);
1656 item->setBackground(1,QColor(200,0,0));
1657 item->setForeground(1,QColor(200,200,200));
1658 }
1659 }
1660 else
1661 {
1662 item->setCheckState(0,Qt::Unchecked);
1663 item->setBackground(1,QColor(200,0,0));
1664 item->setForeground(1,QColor(200,200,200));
1665 }
1666 }
1667 else item->setCheckState(0,Qt::Unchecked);
1668 bg->bRWert = item->checkState(0);
1669 break;
1670 case 7:
1671 item->setText(0,tr("Schreiben von Wert:"));
1672
1673 if(tmp_str != "")
1674 {
1675 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1676 integer = tmp_str.toUShort(&ok,0);
1677 if(ok)
1678 {
1679 if(integer <= 0xff)
1680 {
1681 bg->iWWert = integer;
1682 sprintf(str_00,"$%2.2X",integer);
1683 item->setText(1,QString(str_00));
1684 item->setBackground(1,QColor(200,200,255));
1685 item->setForeground(1,QColor(200,0,0));
1686 }
1687 else
1688 {
1689 item->setCheckState(0,Qt::Unchecked);
1690 item->setBackground(1,QColor(200,0,0));
1691 item->setForeground(1,QColor(200,200,200));
1692 }
1693 }
1694 else
1695 {
1696 item->setCheckState(0,Qt::Unchecked);
1697 item->setBackground(1,QColor(200,0,0));
1698 item->setForeground(1,QColor(200,200,200));
1699 }
1700 }
1701 else item->setCheckState(0,Qt::Unchecked);
1702 bg->bWWert = item->checkState(0);
1703 break;
1704 case 8:
1705 item->setText(0,tr("Rasterzeile:"));
1706
1707 if(tmp_str != "")
1708 {
1709 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1710 integer = tmp_str.toUShort(&ok,0);
1711 if(ok)
1712 {
1713 if(integer <= 311) // PAL 0 - 311
1714 {
1715 bg->iRZ = integer;
1716 sprintf(str_00,"%d",integer);
1717 item->setText(1,QString(str_00));
1718 item->setBackground(1,QColor(200,200,255));
1719 item->setForeground(1,QColor(200,0,0));
1720 }
1721 else
1722 {
1723 item->setCheckState(0,Qt::Unchecked);
1724 item->setBackground(1,QColor(200,0,0));
1725 item->setForeground(1,QColor(200,200,200));
1726 }
1727 }
1728 else
1729 {
1730 item->setCheckState(0,Qt::Unchecked);
1731 item->setBackground(1,QColor(200,0,0));
1732 item->setForeground(1,QColor(200,200,200));
1733 }
1734 }
1735 else item->setCheckState(0,Qt::Unchecked);
1736 bg->bRZ = item->checkState(0);
1737 break;
1738 case 9:
1739 item->setText(0,tr("Zyklus:"));
1740
1741 if(tmp_str != "")
1742 {
1743 if(tmp_str.left(1) == "$") tmp_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1744 integer = tmp_str.toUShort(&ok,0);
1745 if(ok)
1746 {
1747 if((integer > 0) && (integer <= 63)) // PAL 1 - 63
1748 {
1749 bg->iRZZyklus = integer;
1750 sprintf(str_00,"%d",integer);
1751 item->setText(1,QString(str_00));
1752 item->setBackground(1,QColor(200,200,255));
1753 item->setForeground(1,QColor(200,0,0));
1754 }
1755 else
1756 {
1757 item->setCheckState(0,Qt::Unchecked);
1758 item->setBackground(1,QColor(200,0,0));
1759 item->setForeground(1,QColor(200,200,200));
1760 }
1761 }
1762 else
1763 {
1764 item->setCheckState(0,Qt::Unchecked);
1765 item->setBackground(1,QColor(200,0,0));
1766 item->setForeground(1,QColor(200,200,200));
1767 }
1768 }
1769 else item->setCheckState(0,Qt::Unchecked);
1770 bg->bRZZyklus = item->checkState(0);
1771 break;
1772 default:
1773 item->setText(0,"???");
1774 break;
1775 }
1776 }
1777 if(break_point_update_enable)c64->UpdateBreakGroup();
1778 }
1779 }
1780
ClearAllBreakpointBackcolors()1781 void DebuggerWindow::ClearAllBreakpointBackcolors()
1782 {
1783 for(int i=0;i<ui->BreakpointTree->topLevelItemCount();i++)
1784 {
1785 ui->BreakpointTree->topLevelItem(i)->setBackground(0,QColor(255,255,255));
1786 ui->BreakpointTree->topLevelItem(i)->setBackground(1,QColor(255,255,255));
1787 ui->BreakpointTree->topLevelItem(i)->setText(1,"");
1788 }
1789 }
1790
BreakpointProc()1791 void DebuggerWindow::BreakpointProc()
1792 {
1793 new_breakpoint_found = true;
1794 }
1795
on_LoadBreakpoints_clicked()1796 void DebuggerWindow::on_LoadBreakpoints_clicked()
1797 {
1798 if(ui->BreakpointTree->topLevelItemCount() > 0)
1799 if(QMessageBox::No == QMessageBox::question(this, tr("Haltepunkte laden..."), tr("Es werden alle Haltepunkte gelöscht !\nMöchten Sie fortfahren?"),QMessageBox::Yes | QMessageBox::No))
1800 return;
1801
1802 ui->BreakpointTree->clear();
1803
1804 if(current_source > 0) c64->floppy[currnet_floppy_nr]->DeleteAllBreakGroups();
1805 else c64->DeleteAllBreakGroups();
1806
1807 QString filename = QFileDialog::getOpenFileName(this, tr("Haltepunkte öffnen"), QDir::homePath(), tr("Emu64 Haltepunkt Datei ") + "(*.bpt)", nullptr, QFileDialog::DontUseNativeDialog);
1808 if(filename != "")
1809 {
1810 int ret;
1811 if(current_source > 0) ret = c64->floppy[currnet_floppy_nr]->LoadBreakGroups(filename.toLocal8Bit());
1812 else ret = c64->LoadBreakGroups(filename.toLocal8Bit());
1813
1814 if(ret != 0)
1815 {
1816 switch(ret)
1817 {
1818 case -1:
1819 QMessageBox::warning(this,tr("Fehler..."),tr("Die Datei konnte nicht geöffnet werden."));
1820 break;
1821 case -2:
1822 QMessageBox::warning(this,tr("Fehler..."),tr("Es handelt sich nicht um eine Emu64 Datei."));
1823 break;
1824 case -3:
1825 QMessageBox::warning(this,tr("Fehler..."),tr("Diese Datei wurde mit einer neueren Emu64 Version erstellt."));
1826 break;
1827 case -4:
1828 QMessageBox::warning(this,tr("Fehler..."),tr("Diese Datei enthält keine Haltepunkte."));
1829 break;
1830 }
1831 }
1832 else
1833 {
1834 /// Alle Haltepunke ins TreeWidget einfügen ///
1835 if(current_source > 0)
1836 {
1837 int count = c64->floppy[currnet_floppy_nr]->GetBreakGroupCount();
1838 for(int i=0; i<count; i++)
1839 {
1840 BREAK_GROUP *bg = c64->floppy[currnet_floppy_nr]->GetBreakGroup(i);
1841 AddBreakpointTreeRoot(bg->Name,bg);
1842 }
1843 }
1844 else
1845 {
1846 int count = c64->GetBreakGroupCount();
1847 for(int i=0; i<count; i++)
1848 {
1849 BREAK_GROUP *bg = c64->GetBreakGroup(i);
1850 AddBreakpointTreeRoot(bg->Name,bg);
1851 }
1852 }
1853 }
1854 }
1855 }
1856
on_SaveBreakpoints_clicked()1857 void DebuggerWindow::on_SaveBreakpoints_clicked()
1858 {
1859 if(ui->BreakpointTree->topLevelItemCount() == 0) return;
1860
1861 QString filename;
1862 QString fileext;
1863
1864 QStringList filters;
1865 filters << tr("Emu64 Haltepunkt Datei (*.bpt)")
1866 << tr("Alle Dateien (*.*)");
1867
1868 if(!CustomSaveFileDialog::GetSaveFileName(this, tr("Haltepunkte speichern"), filters, &filename, &fileext))
1869 {
1870 return;
1871 }
1872
1873 if(current_source > 0)
1874 {
1875 if(!c64->floppy[currnet_floppy_nr]->SaveBreakGroups(filename.toLocal8Bit()))
1876 QMessageBox::warning(this,tr("Fehler..."),tr("Die Haltepunkte konnten nicht gespeichert werden."));
1877 }
1878 else
1879 {
1880 if(!c64->SaveBreakGroups(filename.toLocal8Bit()))
1881 QMessageBox::warning(this,tr("Fehler..."),tr("Die Haltepunkte konnten nicht gespeichert werden."));
1882 }
1883 }
1884
on_DelAllBreakpoints_clicked()1885 void DebuggerWindow::on_DelAllBreakpoints_clicked()
1886 {
1887 if(ui->BreakpointTree->topLevelItemCount() > 0)
1888 if(QMessageBox::Yes == QMessageBox::question(this, tr("Achtung..."), tr("Es werden alle Haltepunkte gelöscht !\nMöchten Sie fortfahren?"),QMessageBox::Yes | QMessageBox::No))
1889 {
1890 if(current_source > 0) c64->floppy[currnet_floppy_nr]->DeleteAllBreakGroups();
1891 else c64->DeleteAllBreakGroups();
1892 ui->BreakpointTree->clear();
1893 }
1894 }
1895
on_HistoryScroll_valueChanged(int value)1896 void DebuggerWindow::on_HistoryScroll_valueChanged(int value)
1897 {
1898 FillHistoryList(static_cast<uint8_t>(value));
1899 }
1900
on_ExportDisAss_clicked()1901 void DebuggerWindow::on_ExportDisAss_clicked()
1902 {
1903 bool ok;
1904 QString in_str;
1905 uint16_t value;
1906 uint16_t start, end;
1907
1908 in_str = ui->ExportStartIn->text();
1909 if(in_str.left(1) == "$") in_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1910 value = in_str.toUShort(&ok,0);
1911 if(!ok)
1912 {
1913 QMessageBox::warning(this,tr("Eingabefehler..."),tr("Es wurde kein gültiges Zahlenformat benutzt ! [Export Von:]"));
1914 return;
1915 }
1916 start = value;
1917
1918 in_str = ui->ExportEndIn->text();
1919 if(in_str.left(1) == "$") in_str.replace(0,1,"0x"); // Steht am Anfang ein '$' wird dieses in '0X' gewandelt
1920 value = in_str.toUShort(&ok,0);
1921 if(!ok)
1922 {
1923 QMessageBox::warning(this,tr("Eingabefehler..."),tr("Es wurde kein gültiges Zahlenformat benutzt ! [Export Bis:]"));
1924 return;
1925 }
1926 end = value;
1927
1928 if(start >= end)
1929 {
1930 QMessageBox::warning(this,tr("Fehler..."),tr("Startadresse muss kleiner sein als Endadresse."));
1931 return;
1932 }
1933
1934 QString filename;
1935 QString fileext;
1936
1937 QStringList filters;
1938 filters << tr("Disassembler Listing (*.txt)")
1939 << tr("C64 Programm Datei (*.prg)")
1940 << tr("Alle Dateien (*.*)");
1941
1942 if(!CustomSaveFileDialog::GetSaveFileName(this,tr("Export..."), filters, &filename, &fileext))
1943 {
1944 return;
1945 }
1946
1947 fileext = fileext.toUpper();
1948 if(fileext == "TXT")
1949 {
1950 if(!c64->ExportASM(filename.toLocal8Bit(),start,end,current_source))
1951 QMessageBox::warning(this,tr("Fehler..."),tr("Fehler beim speichern der Disassembler Datei."));
1952 }
1953
1954 if(fileext == "PRG")
1955 {
1956 if((current_source > 0) && (end > 0x07FF))
1957 {
1958 QMessageBox::warning(this,tr("Fehler..."),tr("Floppy RAM geht nur von $0000 - $07FF (2KB)."));
1959 return;
1960 }
1961 if(!c64->ExportPRG(filename.toLocal8Bit(),start,end,current_source))
1962 QMessageBox::warning(this,tr("Fehler..."),tr("Fehler beim speichern der Programm Datei."));
1963 }
1964 }
1965
onChangeFloppyStatus(void)1966 void DebuggerWindow::onChangeFloppyStatus(void)
1967 {
1968 RefreshGUI();
1969 }
1970
RefreshGUI(void)1971 void DebuggerWindow::RefreshGUI(void)
1972 {
1973 if(c64 == nullptr) return;
1974
1975 c64_cpu_reg.reg_mask = REG_MASK_ALL;
1976 c64->GetC64CpuReg(&c64_cpu_reg,&c64_cpu_ireg);
1977
1978 if(current_source > 0)
1979 {
1980 /// Floppy's ///
1981 floppy_cpu_reg[currnet_floppy_nr].reg_mask = REG_MASK_ALL;
1982 c64->floppy[currnet_floppy_nr]->GetCpuReg(&floppy_cpu_reg[currnet_floppy_nr],&floppy_cpu_ireg[currnet_floppy_nr]);
1983
1984 /// Register Group ///
1985 ui->RegisterGroup->setTitle(tr("CPU 6502 Register"));
1986 ui->label_nmi->setVisible(false);
1987 ui->label_0314->setVisible(false);
1988 ui->label_0318->setVisible(false);
1989 ui->nmi_out->setVisible(false);
1990 ui->_0314_out->setVisible(false);
1991 ui->_0318_out->setVisible(false);
1992
1993 /// IRegister Group ///
1994 ui->IRegisterGroup->setTitle(tr("CPU 6502 Interne Register (Emu64 Modell)"));
1995 ui->label_cpu_wait->setVisible(false);
1996 ui->wait_led->setVisible(false);
1997
1998 /// Costum Chips ///
1999 ui->VIC->setVisible(false);
2000 ui->SID->setVisible(false);
2001 ui->CIA1->setVisible(false);
2002 ui->CIA2->setVisible(false);
2003 ui->VIA1->setVisible(true);
2004 ui->VIA2->setVisible(true);
2005
2006 /// Leitungen ///
2007 ui->label_nmi_2->setVisible(false);
2008 ui->label_ba->setVisible(false);
2009 ui->label_exrom->setVisible(false);
2010 ui->label_game->setVisible(false);
2011 ui->nmi_led->setVisible(false);
2012 ui->rdy_led->setVisible(false);
2013 ui->exrom_led->setVisible(false);
2014 ui->game_led->setVisible(false);
2015
2016 if(c64->floppy[current_source-1]->GetEnableFloppy())
2017 {
2018 ui->label_floppy_off->setVisible(false);
2019 ui->RegisterGroup->setEnabled(true);
2020 ui->IRegisterGroup->setEnabled(true);
2021 ui->VIA1->setEnabled(true);
2022 ui->VIA2->setEnabled(true);
2023 ui->LeitungenGroup->setEnabled(true);
2024 ui->CycleGroup->setEnabled(true);
2025 ui->VerlaufGroup->setEnabled(true);
2026 ui->DisassGroup->setEnabled(true);
2027 ui->ExportGroup->setEnabled(true);
2028 ui->BreakGroup->setEnabled(true);
2029
2030 /// Alle Haltepunke ins TreeWidget einfügen ///
2031 FillDisassemblyList(floppy_cpu_ireg[currnet_floppy_nr].current_opcode_pc,false);
2032 }
2033 else
2034 {
2035 ui->label_floppy_off->setVisible(true);
2036 ui->RegisterGroup->setEnabled(false);
2037 ui->pc_out->setText("");
2038 ui->ac_out->setText("");
2039 ui->xr_out->setText("");
2040 ui->yr_out->setText("");
2041 ui->sp_out->setText("");
2042 ui->sr_out->setText("");
2043 ui->irq_out->setText("");
2044 ui->_0314_out->setText("");
2045 ui->sr_widget->SetValue(0);
2046
2047 ui->IRegisterGroup->setEnabled(false);
2048 ui->opcode_pc_out->setText("");
2049 ui->adresse_out->setText("");
2050 ui->branch_adresse_out->setText("");
2051 ui->opcode_out->setText("");
2052 ui->pointer_out->setText("");
2053 ui->tmp_byte_out->setText("");
2054 ui->mnemonic_out->setText("");
2055 ui->micro_code_out->setText("");
2056 ui->MCodeHelp->setText("");
2057
2058 ui->VIA1->setEnabled(false);
2059 ui->VIA2->setEnabled(false);
2060
2061 ui->LeitungenGroup->setEnabled(false);
2062 ui->irq_led->setIcon(*icon_off);
2063 ui->reset_led->setIcon(*icon_off);
2064
2065 ui->CycleGroup->setEnabled(false);
2066 ui->CycleCounter_Out->setText("");
2067
2068 ui->VerlaufGroup->setEnabled(false);
2069 for(int i=0;i<HISTORY_ROW;i++) ui->HistoryList->item(i)->setText("");
2070
2071 ui->DisassGroup->setEnabled(false);
2072 for(int i=0;i<DISASS_ROW;i++)
2073 {
2074 disass_pc[i]->setText("");
2075 disass_pc[i]->setBackground(table_back_color);
2076 disass_memory[i]->setText("");
2077 disass_memory[i]->setBackground(table_back_color);
2078 disass_mnemonic[i]->setText("");
2079 disass_mnemonic[i]->setBackground(table_back_color);
2080 disass_addressing[i]->setText("");
2081 disass_addressing[i]->setBackground(table_back_color);
2082 }
2083 ui->ExportGroup->setEnabled(false);
2084
2085 ui->BreakGroup->setEnabled(false);
2086 }
2087 }
2088 else
2089 {
2090 /// C64 ///
2091
2092 /// Register Group ///
2093 ui->RegisterGroup->setTitle(tr("CPU 6510 Register"));
2094 ui->label_nmi->setVisible(true);
2095 ui->label_0314->setVisible(true);
2096 ui->label_0318->setVisible(true);
2097 ui->nmi_out->setVisible(true);
2098 ui->_0314_out->setVisible(true);
2099 ui->_0318_out->setVisible(true);
2100
2101 /// IRegister Group ///
2102 ui->IRegisterGroup->setTitle(tr("CPU 6510 Interne Register (Emu64 Modell)"));
2103 ui->label_cpu_wait->setVisible(true);
2104 ui->wait_led->setVisible(true);
2105
2106 /// Costum Chips ///
2107 ui->VIC->setVisible(true);
2108 ui->SID->setVisible(true);
2109 ui->CIA1->setVisible(true);
2110 ui->CIA2->setVisible(true);
2111 ui->VIA1->setVisible(false);
2112 ui->VIA2->setVisible(false);
2113
2114 /// Leitungen ///
2115 ui->label_nmi_2->setVisible(true);
2116 ui->label_ba->setVisible(true);
2117 ui->label_exrom->setVisible(true);
2118 ui->label_game->setVisible(true);
2119 ui->nmi_led->setVisible(true);
2120 ui->rdy_led->setVisible(true);
2121 ui->exrom_led->setVisible(true);
2122 ui->game_led->setVisible(true);
2123
2124 /// All Enable ///
2125 ui->label_floppy_off->setVisible(false);
2126 ui->RegisterGroup->setEnabled(true);
2127 ui->IRegisterGroup->setEnabled(true);
2128 ui->LeitungenGroup->setEnabled(true);
2129 ui->CycleGroup->setEnabled(true);
2130 ui->VerlaufGroup->setEnabled(true);
2131 ui->DisassGroup->setEnabled(true);
2132 ui->ExportDisAss->setEnabled(true);
2133 ui->BreakGroup->setEnabled(true);
2134 FillDisassemblyList(c64_cpu_ireg.current_opcode_pc,false);
2135 }
2136
2137 ui->EingabeFeld->hide();
2138 UpdateRegister();
2139 FillHistoryList(static_cast<uint8_t>(ui->HistoryScroll->value()));
2140 memory_window->UpdateMemoryList();
2141 vic_window->UpdateOutputList();
2142
2143 on_AnimationSpeed_valueChanged(ui->AnimationSpeed->value());
2144 }
2145
on_MemEdit_clicked()2146 void DebuggerWindow::on_MemEdit_clicked()
2147 {
2148 if(memory_window->isHidden())
2149 {
2150 memory_window->show();
2151 memory_window->UpdateMemoryList();
2152 }
2153 else memory_window->hide();
2154 }
2155
on_VIC_clicked()2156 void DebuggerWindow::on_VIC_clicked()
2157 {
2158 if(vic_window->isHidden())
2159 {
2160 vic_window->show();
2161 vic_window->UpdateOutputList();
2162 }
2163 else vic_window->hide();
2164 }
2165
on_IEC_clicked()2166 void DebuggerWindow::on_IEC_clicked()
2167 {
2168 if(iec_window->isHidden())
2169 {
2170 iec_window->show();
2171 iec_window->UpdateSignals();
2172 }
2173 else iec_window->hide();
2174 }
2175
on_man_lines_clicked(bool checked)2176 void DebuggerWindow::on_man_lines_clicked(bool checked)
2177 {
2178 c64->SetCpuExtLines(checked);
2179
2180 if(!checked)
2181 {
2182 if(c64_cpu_ireg.irq) ui->irq_led->setIcon(*icon_on);
2183 else ui->irq_led->setIcon(*icon_off);
2184 if(c64_cpu_ireg.nmi) ui->nmi_led->setIcon(*icon_on);
2185 else ui->nmi_led->setIcon(*icon_off);
2186 if(c64_cpu_ireg.rdy) ui->rdy_led->setIcon(*icon_on);
2187 else ui->rdy_led->setIcon(*icon_off);
2188 }
2189 else
2190 {
2191 ui->rdy_led->setChecked(true);
2192 ui->rdy_led->setIcon(*icon_on);
2193 c64->SetExtRDY(true);
2194
2195 ui->irq_led->setChecked(false);
2196 ui->irq_led->setIcon(*icon_off);
2197
2198 ui->nmi_led->setChecked(false);
2199 ui->nmi_led->setIcon(*icon_off);
2200 }
2201 }
2202
on_rdy_led_clicked(bool checked)2203 void DebuggerWindow::on_rdy_led_clicked(bool checked)
2204 {
2205 if(ui->man_lines->checkState())
2206 {
2207 c64->SetExtRDY(checked);
2208 if(checked) ui->rdy_led->setIcon(*icon_on);
2209 else ui->rdy_led->setIcon(*icon_off);
2210 }
2211 }
2212
on_irq_led_clicked(bool checked)2213 void DebuggerWindow::on_irq_led_clicked(bool checked)
2214 {
2215 if(ui->man_lines->checkState())
2216 {
2217 if(checked) c64->cpu->TriggerInterrupt(EXT_IRQ);
2218 else c64->cpu->ClearInterrupt(EXT_IRQ);
2219 if(checked) ui->irq_led->setIcon(*icon_on);
2220 else ui->irq_led->setIcon(*icon_off);
2221 }
2222 }
2223
on_nmi_led_clicked(bool checked)2224 void DebuggerWindow::on_nmi_led_clicked(bool checked)
2225 {
2226 if(ui->man_lines->checkState())
2227 {
2228 if(checked) c64->cpu->TriggerInterrupt(EXT_NMI);
2229 else c64->cpu->ClearInterrupt(EXT_NMI);
2230 if(checked) ui->nmi_led->setIcon(*icon_on);
2231 else ui->nmi_led->setIcon(*icon_off);
2232 }
2233 }
2234