CPUBrowserWindow::CPUBrowserWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog),
layout(new QVBoxLayout), text(new QLabel),
refresh(new QPushButton(tr("Refresh"))),
- bpm(new QCheckBox(tr("BPM"))), bpmAddress(new QLineEdit)
+ bpm(new QCheckBox(tr("BPM"))), bpmAddress(new QLineEdit),
+ bpmContinue(new QPushButton(tr("Resume")))
{
setWindowTitle(tr("CPU Browser"));
QHBoxLayout * hbox1 = new QHBoxLayout;
hbox1->addWidget(bpm);
hbox1->addWidget(bpmAddress);
+ hbox1->addWidget(bpmContinue);
QFont fixedFont("Lucida Console", 8, QFont::Normal);
// QFont fixedFont("", 8, QFont::Normal);
connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents()));
connect(bpm, SIGNAL(clicked(bool)), this, SLOT(HandleBPM(bool)));
connect(bpmAddress, SIGNAL(textChanged(const QString &)), this, SLOT(HandleBPMAddress(const QString &)));
+ connect(bpmContinue, SIGNAL(clicked()), this, SLOT(HandleBPMContinue()));
}
}
+void CPUBrowserWindow::HandleBPMContinue(void)
+{
+ M68KDebugResume();
+}
+
+
void CPUBrowserWindow::keyPressEvent(QKeyEvent * e)
{
if (e->key() == Qt::Key_Escape)
void RefreshContents(void);
void HandleBPM(bool);
void HandleBPMAddress(const QString &);
+ void HandleBPMContinue(void);
protected:
void keyPressEvent(QKeyEvent *);
QPushButton * refresh;
QCheckBox * bpm;
QLineEdit * bpmAddress;
+ QPushButton * bpmContinue;
// int32_t memBase;
};
if (c == 0x20)
sprintf(buf, " ");
- if ((c < 0x20) || ((c > 0x7F) && (c < 0xA0)))
+ if ((c < 0x20) || (c > 0x7E))
sprintf(buf, ".");
strcat(string, buf);
powerRed.addFile(":/res/power-off.png", QSize(), QIcon::Normal, QIcon::Off);
powerRed.addFile(":/res/power-on-red.png", QSize(), QIcon::Normal, QIcon::On);
-// powerAct = new QAction(QIcon(":/res/power.png"), tr("&Power"), this);
powerAct = new QAction(powerGreen, tr("&Power"), this);
powerAct->setStatusTip(tr("Powers Jaguar on/off"));
powerAct->setCheckable(true);
powerAct->setChecked(false);
-// powerAct->setDisabled(true);
connect(powerAct, SIGNAL(triggered()), this, SLOT(TogglePowerState()));
QIcon pauseIcon;
pauseIcon.addFile(":/res/pause-off", QSize(), QIcon::Normal, QIcon::Off);
pauseIcon.addFile(":/res/pause-on", QSize(), QIcon::Normal, QIcon::On);
-// pauseAct = new QAction(QIcon(":/res/pause.png"), tr("Pause"), this);
pauseAct = new QAction(pauseIcon, tr("Pause"), this);
pauseAct->setStatusTip(tr("Toggles the running state"));
pauseAct->setCheckable(true);
palAct->setCheckable(true);
connect(palAct, SIGNAL(triggered()), this, SLOT(SetPAL()));
- blurAct = new QAction(QIcon(":/res/blur.png"), tr("Blur"), this);
+ blur.addFile(":/res/blur-off.png", QSize(), QIcon::Normal, QIcon::Off);
+ blur.addFile(":/res/blur-on.png", QSize(), QIcon::Normal, QIcon::On);
+
+ blurAct = new QAction(blur, tr("Blur"), this);
blurAct->setStatusTip(tr("Sets OpenGL rendering to GL_NEAREST"));
blurAct->setCheckable(true);
connect(blurAct, SIGNAL(triggered()), this, SLOT(ToggleBlur()));
HandleGamepads();
JaguarExecuteNew();
videoWidget->HandleMouseHiding();
+
+static uint32_t refresh = 0;
+ // Do autorefresh on debug windows
+ // Have to be careful, too much causes the emulator to slow way down!
+ if (vjs.hardwareTypeAlpine)
+ {
+ if (refresh == 60)
+ {
+ memBrowseWin->RefreshContents();
+ cpuBrowseWin->RefreshContents();
+ refresh = 0;
+ }
+ else
+ refresh++;
+ }
}
videoWidget->updateGL();
QIcon powerGreen;
QIcon powerRed;
+ QIcon blur;
uint32_t testPattern[VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT_PAL];
uint32_t testPattern2[VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT_PAL];
};
<file>../../res/zoom100.png</file>
<file>../../res/zoom200.png</file>
<file>../../res/zoom300.png</file>
- <file>../../res/blur.png</file>
+ <file>../../res/blur-off.png</file>
+ <file>../../res/blur-on.png</file>
<file>../../res/fullscreen.png</file>
<file>../../res/tool-memory.png</file>
<file>../../res/tool-cpu.png</file>
uint32_t d5Queue[0x400];
uint32_t d6Queue[0x400];
uint32_t d7Queue[0x400];
+uint32_t srQueue[0x400];
uint32_t pcQPtr = 0;
bool startM68KTracing = false;
d5Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_D5);
d6Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_D6);
d7Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_D7);
+ srQueue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_SR);
pcQPtr++;
pcQPtr &= 0x3FF;
for(int i=0; i<0x400; i++)
{
// WriteLog("[A2=%08X, D0=%08X]\n", a2Queue[(pcQPtr + i) & 0x3FF], d0Queue[(pcQPtr + i) & 0x3FF]);
- WriteLog("[A0=%08X, A1=%08X, A2=%08X, A3=%08X, A4=%08X, A5=%08X, A6=%08X, A7=%08X, D0=%08X, D1=%08X, D2=%08X, D3=%08X, D4=%08X, D5=%08X, D6=%08X, D7=%08X]\n", a0Queue[(pcQPtr + i) & 0x3FF], a1Queue[(pcQPtr + i) & 0x3FF], a2Queue[(pcQPtr + i) & 0x3FF], a3Queue[(pcQPtr + i) & 0x3FF], a4Queue[(pcQPtr + i) & 0x3FF], a5Queue[(pcQPtr + i) & 0x3FF], a6Queue[(pcQPtr + i) & 0x3FF], a7Queue[(pcQPtr + i) & 0x3FF], d0Queue[(pcQPtr + i) & 0x3FF], d1Queue[(pcQPtr + i) & 0x3FF], d2Queue[(pcQPtr + i) & 0x3FF], d3Queue[(pcQPtr + i) & 0x3FF], d4Queue[(pcQPtr + i) & 0x3FF], d5Queue[(pcQPtr + i) & 0x3FF], d6Queue[(pcQPtr + i) & 0x3FF], d7Queue[(pcQPtr + i) & 0x3FF]);
+ WriteLog("[A0=%08X, A1=%08X, A2=%08X, A3=%08X, A4=%08X, A5=%08X, A6=%08X, A7=%08X, D0=%08X, D1=%08X, D2=%08X, D3=%08X, D4=%08X, D5=%08X, D6=%08X, D7=%08X, SR=%04X]\n", a0Queue[(pcQPtr + i) & 0x3FF], a1Queue[(pcQPtr + i) & 0x3FF], a2Queue[(pcQPtr + i) & 0x3FF], a3Queue[(pcQPtr + i) & 0x3FF], a4Queue[(pcQPtr + i) & 0x3FF], a5Queue[(pcQPtr + i) & 0x3FF], a6Queue[(pcQPtr + i) & 0x3FF], a7Queue[(pcQPtr + i) & 0x3FF], d0Queue[(pcQPtr + i) & 0x3FF], d1Queue[(pcQPtr + i) & 0x3FF], d2Queue[(pcQPtr + i) & 0x3FF], d3Queue[(pcQPtr + i) & 0x3FF], d4Queue[(pcQPtr + i) & 0x3FF], d5Queue[(pcQPtr + i) & 0x3FF], d6Queue[(pcQPtr + i) & 0x3FF], d7Queue[(pcQPtr + i) & 0x3FF], srQueue[(pcQPtr + i) & 0x3FF]);
m68k_disassemble(buffer, pcQueue[(pcQPtr + i) & 0x3FF], 0);//M68K_CPU_TYPE_68000);
WriteLog("\t%08X: %s\n", pcQueue[(pcQPtr + i) & 0x3FF], buffer);
}
// IPL1 is connected to INTL on TOM (OUT to 68K)
// IPL0-2 are also tied to Vcc via 4.7K resistors!
// (DINT on TOM goes into DINT on JERRY (IN Tom from Jerry))
- // There doesn't seem to be any other path to IPL0 or 2 on the schematic, which means
- // that *all* IRQs to the 68K are routed thru TOM at level 2. Which means they're all maskable.
+ // There doesn't seem to be any other path to IPL0 or 2 on the schematic,
+ // which means that *all* IRQs to the 68K are routed thru TOM at level 2.
+ // Which means they're all maskable.
- // The GPU/DSP/etc are probably *not* issuing an NMI, but it seems to work OK...
+ // The GPU/DSP/etc are probably *not* issuing an NMI, but it seems to work
+ // OK...
// They aren't, and this causes problems with a, err, specific ROM. :-D
if (level == 2)
// Unknown read/write byte/word routines
//
-// It's hard to believe that developers would be sloppy with their memory writes, yet in
-// some cases the developers screwed up royal. E.g., Club Drive has the following code:
+// It's hard to believe that developers would be sloppy with their memory
+// writes, yet in some cases the developers screwed up royal. E.g., Club Drive
+// has the following code:
//
// 807EC4: movea.l #$f1b000, A1
// 807ECA: movea.l #$8129e0, A0
// 807EDC: move.l (A0)+, (A1)+
// 807EDE: dbra D1, 807edc
//
-// The problem is at $807ED0--instead of putting A0 into D0, they really meant to put A1
-// in. This mistake causes it to try and overwrite approximately $700000 worth of address
-// space! (That is, unless the 68K causes a bus error...)
+// The problem is at $807ED0--instead of putting A0 into D0, they really meant
+// to put A1 in. This mistake causes it to try and overwrite approximately
+// $700000 worth of address space! (That is, unless the 68K causes a bus
+// error...)
void jaguar_unknown_writebyte(unsigned address, unsigned data, uint32_t who/*=UNKNOWN*/)
{
void JaguarWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/)
{
+/* if ((offset & 0x1FFFFF) >= 0xE00 && (offset & 0x1FFFFF) < 0xE18)
+ {
+ WriteLog("JWB: Byte %02X written at %08X by %s\n", data, offset, whoName[who]);
+ }//*/
/* if (offset >= 0x4E00 && offset < 0x4E04)
WriteLog("JWB: Byte %02X written at %08X by %s\n", data, offset, whoName[who]);//*/
//Need to check for writes in the range of $18FA70 + 8000...
uint32_t starCount;
void JaguarWriteWord(uint32_t offset, uint16_t data, uint32_t who/*=UNKNOWN*/)
{
+/* if ((offset & 0x1FFFFF) >= 0xE00 && (offset & 0x1FFFFF) < 0xE18)
+ {
+ WriteLog("JWW: Word %04X written at %08X by %s\n", data, offset, whoName[who]);
+ WriteLog(" GPU PC = $%06X\n", GPUReadLong(0xF02110, DEBUG));
+ }//*/
/* if (offset >= 0x4E00 && offset < 0x4E04)
WriteLog("JWW: Word %04X written at %08X by %s\n", data, offset, whoName[who]);//*/
/*if (offset == 0x0100)//64*4)
// on Atari ST, because it's possible to change the MFP's vector base
// and get a conflict with 'normal' cpu exceptions.
//
+#if 0
+/*
+This is the STOP # function. Dunno if exception handling occurs when it hits here or not, because don't know if the regs.s bit is set or not!
+Seems to be...
+
+SR-----------------
+1111 11
+5432 1098 7654 3210
+---- ---- ---- ----
+ 1 1
+
+
+*/
+unsigned long CPUFUNC(op_4e72_5)(uint32_t opcode) /* STOP */
+{
+ OpcodeFamily = 44;
+ CurrentInstrCycles = 4;
+
+ if (!regs.s)
+ {
+ Exception(8, 0, M68000_EXC_SRC_CPU);
+ }
+ else
+ {
+ int16_t src = get_iword_prefetch(2);
+ regs.sr = src;
+ MakeFromSR();
+ m68k_setstopped(1);
+ m68k_incpc(4);
+ fill_prefetch_0();
+ }
+
+ return 4;
+}
+#endif
+//tmp...
+void WriteLog(const char * text, ...);
void Exception(int nr, uint32_t oldpc, int ExceptionSource)
{
uint32_t currpc = m68k_getpc(), newpc;
"Trap #"
};
-printf("Exception #%i occurred! (%s)\n", nr, (nr < 32 ? excNames[nr] : (nr < 48 ? "Trap #" : "????")));
-printf("Vector @ #%i = %08X\n", nr, m68k_read_memory_32(nr * 4));
+WriteLog("Exception #%i occurred! (%s)\n", nr, (nr < 32 ? excNames[nr] : (nr < 48 ? "Trap #" : "????")));
+WriteLog("Vector @ #%i = %08X\n", nr, m68k_read_memory_32(nr * 4));
//abort();
-printf("PC = $%08X\n", currpc);
-printf("A0 = $%08X A1 = $%08X A2 = $%08X A3 = $%08X\n", m68k_areg(regs, 0), m68k_areg(regs, 1), m68k_areg(regs, 2), m68k_areg(regs, 3));
-printf("A4 = $%08X A5 = $%08X A6 = $%08X A7 = $%08X\n", m68k_areg(regs, 4), m68k_areg(regs, 5), m68k_areg(regs, 6), m68k_areg(regs, 7));
-printf("D0 = $%08X D1 = $%08X D2 = $%08X D3 = $%08X\n", m68k_dreg(regs, 0), m68k_dreg(regs, 1), m68k_dreg(regs, 2), m68k_dreg(regs, 3));
-printf("D4 = $%08X D5 = $%08X D6 = $%08X D7 = $%08X\n", m68k_dreg(regs, 4), m68k_dreg(regs, 5), m68k_dreg(regs, 6), m68k_dreg(regs, 7));
-printf("\n");
+WriteLog("PC = $%08X\n", currpc);
+WriteLog("A0 = $%08X A1 = $%08X A2 = $%08X A3 = $%08X\n", m68k_areg(regs, 0), m68k_areg(regs, 1), m68k_areg(regs, 2), m68k_areg(regs, 3));
+WriteLog("A4 = $%08X A5 = $%08X A6 = $%08X A7 = $%08X\n", m68k_areg(regs, 4), m68k_areg(regs, 5), m68k_areg(regs, 6), m68k_areg(regs, 7));
+WriteLog("D0 = $%08X D1 = $%08X D2 = $%08X D3 = $%08X\n", m68k_dreg(regs, 0), m68k_dreg(regs, 1), m68k_dreg(regs, 2), m68k_dreg(regs, 3));
+WriteLog("D4 = $%08X D5 = $%08X D6 = $%08X D7 = $%08X\n", m68k_dreg(regs, 4), m68k_dreg(regs, 5), m68k_dreg(regs, 6), m68k_dreg(regs, 7));
+WriteLog("\n");
uint32_t disPC = currpc - 10;
char buffer[128];
{
uint32_t oldpc = disPC;
disPC += m68k_disassemble(buffer, disPC, 0);
- printf("%s%08X: %s\n", (oldpc == currpc ? ">" : " "), oldpc, buffer);
+ WriteLog("%s%08X: %s\n", (oldpc == currpc ? ">" : " "), oldpc, buffer);
}
while (disPC < (currpc + 10));
#endif
REG_PC = m68ki_read_imm_32();
m68ki_jump(REG_PC);
#else
+ checkForIRQToHandle = 0;
regs.spcflags = 0;
regs.stopped = 0;
regs.remainingCycles = 0;
// prolly, for debugging/alpine mode... :-/
// but then again, this should be handled already by the main execution loop :-P
// If we are halted, don't do anything
-// if (regs.stopped)
+// if (regs.halted)
// return;
// Acknowledge the interrupt (NOTE: This is a user supplied function!)