void DisasmView_DoDraw(HDC hdc) { ASSERT(g_pBoard != NULL); // Create and select font HFONT hFont = CreateMonospacedFont(); HGDIOBJ hOldFont = SelectObject(hdc, hFont); int cxChar, cyLine; GetFontWidthAndHeight(hdc, &cxChar, &cyLine); COLORREF colorOld = SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT)); SetBkMode(hdc, TRANSPARENT); //COLORREF colorBkOld = SetBkColor(hdc, GetSysColor(COLOR_WINDOW)); CProcessor* pDisasmPU = (m_okDisasmProcessor) ? g_pBoard->GetCPU() : g_pBoard->GetPPU(); // Draw disassembly for the current processor WORD prevPC = (m_okDisasmProcessor) ? g_wEmulatorPrevCpuPC : g_wEmulatorPrevPpuPC; int yFocus = DisasmView_DrawDisassemble(hdc, pDisasmPU, m_wDisasmBaseAddr, prevPC, 0, 2 + 0 * cyLine); SetTextColor(hdc, colorOld); //SetBkColor(hdc, colorBkOld); SelectObject(hdc, hOldFont); DeleteObject(hFont); if (::GetFocus() == m_hwndDisasmViewer) { RECT rcFocus; GetClientRect(m_hwndDisasmViewer, &rcFocus); if (yFocus >= 0) { rcFocus.top = yFocus; rcFocus.bottom = yFocus + cyLine; } DrawFocusRect(hdc, &rcFocus); } }
void DebugView_DrawProcessor(HDC hdc, const CProcessor* pProc, int x, int y, WORD* arrR, BOOL* arrRChanged) { int cxChar, cyLine; GetFontWidthAndHeight(hdc, &cxChar, &cyLine); COLORREF colorText = GetSysColor(COLOR_WINDOWTEXT); DrawRectangle(hdc, x - cxChar, y - 8, x + cxChar + 31 * cxChar, y + 8 + cyLine * 14); // Registers for (int r = 0; r < 8; r++) { ::SetTextColor(hdc, arrRChanged[r] ? COLOR_RED : colorText); LPCTSTR strRegName = REGISTER_NAME[r]; TextOut(hdc, x, y + r * cyLine, strRegName, (int) _tcslen(strRegName)); WORD value = arrR[r]; //pProc->GetReg(r); DrawOctalValue(hdc, x + cxChar * 3, y + r * cyLine, value); DrawHexValue(hdc, x + cxChar * 10, y + r * cyLine, value); DrawBinaryValue(hdc, x + cxChar * 15, y + r * cyLine, value); } ::SetTextColor(hdc, colorText); // CPC value ::SetTextColor(hdc, arrRChanged[9] ? COLOR_RED : colorText); TextOut(hdc, x, y + 8 * cyLine, _T("PC'"), 3); WORD cpc = arrR[9]; DrawOctalValue(hdc, x + cxChar * 3, y + 8 * cyLine, cpc); DrawHexValue(hdc, x + cxChar * 10, y + 8 * cyLine, cpc); DrawBinaryValue(hdc, x + cxChar * 15, y + 8 * cyLine, cpc); // PSW value ::SetTextColor(hdc, arrRChanged[8] ? COLOR_RED : colorText); TextOut(hdc, x, y + 10 * cyLine, _T("PS"), 2); WORD psw = arrR[8]; // pProc->GetPSW(); DrawOctalValue(hdc, x + cxChar * 3, y + 10 * cyLine, psw); DrawHexValue(hdc, x + cxChar * 10, y + 10 * cyLine, psw); TextOut(hdc, x + cxChar * 15, y + 9 * cyLine, _T(" HP TNZVC"), 16); DrawBinaryValue(hdc, x + cxChar * 15, y + 10 * cyLine, psw); // CPSW value ::SetTextColor(hdc, arrRChanged[10] ? COLOR_RED : colorText); TextOut(hdc, x, y + 11 * cyLine, _T("PS'"), 3); WORD cpsw = arrR[10]; DrawOctalValue(hdc, x + cxChar * 3, y + 11 * cyLine, cpsw); DrawHexValue(hdc, x + cxChar * 10, y + 11 * cyLine, cpsw); DrawBinaryValue(hdc, x + cxChar * 15, y + 11 * cyLine, cpsw); ::SetTextColor(hdc, colorText); // Processor mode - HALT or USER BOOL okHaltMode = pProc->IsHaltMode(); TextOut(hdc, x, y + 13 * cyLine, okHaltMode ? _T("HALT") : _T("USER"), 4); // "Stopped" flag BOOL okStopped = pProc->IsStopped(); if (okStopped) TextOut(hdc, x + 6 * cxChar, y + 13 * cyLine, _T("STOP"), 4); }
void DebugView_DoDraw(HDC hdc) { ASSERT(g_pBoard != NULL); // Create and select font HFONT hFont = CreateMonospacedFont(); HGDIOBJ hOldFont = SelectObject(hdc, hFont); int cxChar, cyLine; GetFontWidthAndHeight(hdc, &cxChar, &cyLine); COLORREF colorOld = SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT)); COLORREF colorBkOld = SetBkColor(hdc, GetSysColor(COLOR_WINDOW)); CProcessor* pDebugPU = (m_okDebugProcessor) ? g_pBoard->GetCPU() : g_pBoard->GetPPU(); ASSERT(pDebugPU != NULL); WORD* arrR = (m_okDebugProcessor) ? m_wDebugCpuR : m_wDebugPpuR; BOOL* arrRChanged = (m_okDebugProcessor) ? m_okDebugCpuRChanged : m_okDebugPpuRChanged; //LPCTSTR sProcName = pDebugPU->GetName(); //TextOut(hdc, cxChar * 1, 2 + 1 * cyLine, sProcName, 3); DebugView_DrawProcessor(hdc, pDebugPU, 30 + cxChar * 2, 2 + 1 * cyLine, arrR, arrRChanged); // Draw stack for the current processor DebugView_DrawMemoryForRegister(hdc, 6, pDebugPU, 30 + 35 * cxChar, 2 + 0 * cyLine); CMemoryController* pDebugMemCtl = pDebugPU->GetMemoryController(); DebugView_DrawPorts(hdc, m_okDebugProcessor, pDebugMemCtl, g_pBoard, 30 + 57 * cxChar, 2 + 0 * cyLine); //DebugView_DrawChannels(hdc, 75 * cxChar, 2 + 0 * cyLine); SetTextColor(hdc, colorOld); SetBkColor(hdc, colorBkOld); SelectObject(hdc, hOldFont); DeleteObject(hFont); if (::GetFocus() == m_hwndDebugViewer) { RECT rcClient; GetClientRect(m_hwndDebugViewer, &rcClient); DrawFocusRect(hdc, &rcClient); } }
void DebugView_DrawMemoryForRegister(HDC hdc, int reg, CProcessor* pProc, int x, int y) { int cxChar, cyLine; GetFontWidthAndHeight(hdc, &cxChar, &cyLine); WORD current = pProc->GetReg(reg); BOOL okExec = (reg == 7); // Читаем из памяти процессора в буфер WORD memory[16]; const CMemoryController* pMemCtl = pProc->GetMemoryController(); for (int idx = 0; idx < 16; idx++) { BOOL okValidAddress; memory[idx] = pMemCtl->GetWordView( (WORD)(current + idx * 2 - 16), pProc->IsHaltMode(), okExec, &okValidAddress); } WORD address = current - 16; for (int index = 0; index < 16; index++) // Рисуем строки { // Адрес DrawOctalValue(hdc, x + 4 * cxChar, y, address); // Значение по адресу WORD value = memory[index]; DrawOctalValue(hdc, x + 12 * cxChar, y, value); // Текущая позиция if (address == current) { TextOut(hdc, x + 2 * cxChar, y, _T(">>"), 2); TextOut(hdc, x, y, REGISTER_NAME[reg], 2); } address += 2; y += cyLine; } }
int DisasmView_DrawDisassemble(HDC hdc, CProcessor* pProc, WORD base, WORD previous, int x, int y) { int result = -1; int cxChar, cyLine; GetFontWidthAndHeight(hdc, &cxChar, &cyLine); COLORREF colorText = GetSysColor(COLOR_WINDOWTEXT); const CMemoryController* pMemCtl = pProc->GetMemoryController(); WORD proccurrent = pProc->GetPC(); WORD current = base; // Draw current line background if (!m_okDisasmSubtitles) //NOTE: Subtitles can move lines down { HGDIOBJ oldBrush = SelectObject(hdc, CreateSolidBrush(COLOR_CURRENT)); int yCurrent = (proccurrent - (current - 5)) * cyLine; PatBlt(hdc, 0, yCurrent, 1000, cyLine, PATCOPY); SelectObject(hdc, oldBrush); } // Читаем из памяти процессора в буфер const int nWindowSize = 30; WORD memory[nWindowSize + 2]; for (int idx = 0; idx < nWindowSize; idx++) { BOOL okValidAddress; memory[idx] = pMemCtl->GetWordView( (WORD)(current + idx * 2 - 10), pProc->IsHaltMode(), TRUE, &okValidAddress); } WORD address = current - 10; WORD disasmfrom = current; if (previous >= address && previous < current) disasmfrom = previous; int length = 0; WORD wNextBaseAddr = 0; for (int index = 0; index < nWindowSize; index++) // Рисуем строки { if (m_okDisasmSubtitles) // Subtitles - комментарий к блоку { DisasmSubtitleItem* pSubItem = DisasmView_FindSubtitle(address, SUBTYPE_BLOCKCOMMENT); if (pSubItem != NULL && pSubItem->comment != NULL) { LPCTSTR strBlockSubtitle = pSubItem->comment; ::SetTextColor(hdc, COLOR_SUBTITLE); TextOut(hdc, x + 21 * cxChar, y, strBlockSubtitle, (int) _tcslen(strBlockSubtitle)); ::SetTextColor(hdc, colorText); y += cyLine; } } DrawOctalValue(hdc, x + 5 * cxChar, y, address); // Address // Value at the address WORD value = memory[index]; ::SetTextColor(hdc, COLOR_VALUE); DrawOctalValue(hdc, x + 13 * cxChar, y, value); ::SetTextColor(hdc, colorText); // Current position if (address == current) { TextOut(hdc, x + 1 * cxChar, y, _T(" >"), 3); result = y; // Remember line for the focus rect } if (address == proccurrent) TextOut(hdc, x + 1 * cxChar, y, _T("PC>>"), 4); else if (address == previous) { ::SetTextColor(hdc, COLOR_BLUE); TextOut(hdc, x + 1 * cxChar, y, _T(" > "), 4); } BOOL okData = FALSE; if (m_okDisasmSubtitles) // Show subtitle { DisasmSubtitleItem* pSubItem = DisasmView_FindSubtitle(address, SUBTYPE_COMMENT | SUBTYPE_DATA); if (pSubItem != NULL && (pSubItem->type & SUBTYPE_DATA) != 0) okData = TRUE; if (pSubItem != NULL && (pSubItem->type & SUBTYPE_COMMENT) != 0 && pSubItem->comment != NULL) { LPCTSTR strSubtitle = pSubItem->comment; ::SetTextColor(hdc, COLOR_SUBTITLE); TextOut(hdc, x + 52 * cxChar, y, strSubtitle, (int) _tcslen(strSubtitle)); ::SetTextColor(hdc, colorText); // Строку с субтитром мы можем использовать как опорную для дизассемблера if (disasmfrom > address) disasmfrom = address; } } if (address >= disasmfrom && length == 0) { TCHAR strInstr[8]; TCHAR strArg[32]; if (okData) // По этому адресу лежат данные -- нет смысла дизассемблировать { lstrcpy(strInstr, _T("data")); PrintOctalValue(strArg, *(memory + index)); length = 1; } else { length = DisassembleInstruction(memory + index, address, strInstr, strArg); int delta; if (!m_okDisasmSubtitles && //NOTE: Subtitles can move lines down DisasmView_CheckForJump(memory + index, address, &delta) && abs(delta) < 32) { DisasmView_DrawJump(hdc, y, delta, x + (30 + _tcslen(strArg)) * cxChar, cyLine); } } if (index + length <= nWindowSize) { TextOut(hdc, x + 21 * cxChar, y, strInstr, (int) _tcslen(strInstr)); TextOut(hdc, x + 29 * cxChar, y, strArg, (int) _tcslen(strArg)); } ::SetTextColor(hdc, colorText); if (wNextBaseAddr == 0) wNextBaseAddr = (WORD)(address + length * 2); } if (length > 0) length--; address += 2; y += cyLine; } m_wDisasmNextBaseAddr = wNextBaseAddr; return result; }
void MemoryView_OnDraw(HDC hdc) { ASSERT(g_pBoard != NULL); // Create and select font HFONT hFont = CreateMonospacedFont(); HGDIOBJ hOldFont = SelectObject(hdc, hFont); int cxChar, cyLine; GetFontWidthAndHeight(hdc, &cxChar, &cyLine); COLORREF colorText = GetSysColor(COLOR_WINDOWTEXT); COLORREF colorOld = SetTextColor(hdc, colorText); COLORREF colorBkOld = SetBkColor(hdc, GetSysColor(COLOR_WINDOW)); m_cyLineMemory = cyLine; const TCHAR* ADDRESS_LINE = _T("address 0 2 4 6 10 12 14 16"); TextOut(hdc, cxChar * 4, 0, ADDRESS_LINE, (int) _tcslen(ADDRESS_LINE)); RECT rcClip; GetClipBox(hdc, &rcClip); RECT rcClient; GetClientRect(m_hwndMemoryViewer, &rcClient); m_nPageSize = rcClient.bottom / cyLine - 1; WORD address = m_wBaseAddress; int y = 1 * cyLine; for (;;) // Draw lines { DrawOctalValue(hdc, 5 * cxChar, y, address); int x = 13 * cxChar; TCHAR wchars[16]; for (int j = 0; j < 8; j++) // Draw words as octal value { // Get word from memory WORD word = 0; int addrtype; BOOL okHalt = FALSE; WORD wChanged = 0; //switch (m_Mode) { // case MEMMODE_RAM0: // case MEMMODE_RAM1: // case MEMMODE_RAM2: // word = g_pBoard->GetRAMWord(m_Mode, address); // wChanged = Emulator_GetChangeRamStatus(m_Mode, address); // break; // case MEMMODE_ROM: // ROM - only 32 Kbytes // if (address < 0100000) // okValid = FALSE; // else // word = g_pBoard->GetROMWord(address - 0100000); // break; // case MEMMODE_CPU: okHalt = g_pBoard->GetCPU()->IsHaltMode(); word = g_pBoard->GetWordView(address, okHalt, FALSE, &addrtype); wChanged = Emulator_GetChangeRamStatus(address); // break; //} if ((addrtype & (ADDRTYPE_IO | ADDRTYPE_DENY)) == 0) { ::SetTextColor(hdc, (wChanged != 0) ? RGB(255, 0, 0) : colorText); DrawOctalValue(hdc, x, y, word); } // Prepare characters to draw at right BYTE ch1 = LOBYTE(word); TCHAR wch1 = Translate_BK_Unicode(ch1); if (ch1 < 32) wch1 = _T('·'); wchars[j * 2] = wch1; BYTE ch2 = HIBYTE(word); TCHAR wch2 = Translate_BK_Unicode(ch2); if (ch2 < 32) wch2 = _T('·'); wchars[j * 2 + 1] = wch2; address += 2; x += 7 * cxChar; } ::SetTextColor(hdc, colorText); // Draw characters at right int xch = x + cxChar; TextOut(hdc, xch, y, wchars, 16); y += cyLine; if (y > rcClip.bottom) break; } SetTextColor(hdc, colorOld); SetBkColor(hdc, colorBkOld); SelectObject(hdc, hOldFont); DeleteObject(hFont); if (::GetFocus() == m_hwndMemoryViewer) { RECT rcFocus = rcClient; rcFocus.left += cxChar * 4; rcFocus.top += cyLine; rcFocus.right = cxChar * (63 + 24); DrawFocusRect(hdc, &rcFocus); } }
void DebugView_DrawChannels(HDC hdc, int x, int y) { int cxChar, cyLine; GetFontWidthAndHeight(hdc, &cxChar, &cyLine); //CProcessor* pCPU = g_pBoard->GetCPU(); //CProcessor* pPPU = g_pBoard->GetPPU(); //CMemoryController* pCPUMemCtl = pCPU->GetMemoryController(); //CMemoryController* pPPUMemCtl = pPPU->GetMemoryController(); TextOut(hdc, x, y, _T("Channels:"), 9); TCHAR bufData[7]; TCHAR buffer[32]; chan_stc tmpstc; tmpstc = g_pBoard->GetChannelStruct(0, 0, 0); PrintOctalValue(bufData, tmpstc.data); wsprintf(buffer, _T("PPU CH:0 RX D:%s RDY:%d IRQ:%d"), bufData + 3, tmpstc.ready, tmpstc.irq); TextOut(hdc, x, y + 1 * cyLine, buffer, lstrlen(buffer)); tmpstc = g_pBoard->GetChannelStruct(0, 1, 0); PrintOctalValue(bufData, tmpstc.data); wsprintf(buffer, _T("PPU CH:1 RX D:%s RDY:%d IRQ:%d"), bufData + 3, tmpstc.ready, tmpstc.irq); TextOut(hdc, x, y + 2 * cyLine, buffer, lstrlen(buffer)); tmpstc = g_pBoard->GetChannelStruct(0, 2, 0); PrintOctalValue(bufData, tmpstc.data); wsprintf(buffer, _T("PPU CH:2 RX D:%s RDY:%d IRQ:%d"), bufData + 3, tmpstc.ready, tmpstc.irq); TextOut(hdc, x, y + 3 * cyLine, buffer, lstrlen(buffer)); tmpstc = g_pBoard->GetChannelStruct(0, 0, 1); wsprintf(buffer, _T("PPU CH:0 TX RDY:%d IRQ:%d"), tmpstc.ready, tmpstc.irq); TextOut(hdc, x, y + 4 * cyLine, buffer, lstrlen(buffer)); tmpstc = g_pBoard->GetChannelStruct(0, 1, 1); wsprintf(buffer, _T("PPU CH:1 TX RDY:%d IRQ:%d"), tmpstc.ready, tmpstc.irq); TextOut(hdc, x, y + 5 * cyLine, buffer, lstrlen(buffer)); tmpstc = g_pBoard->GetChannelStruct(1, 0, 0); PrintOctalValue(bufData, tmpstc.data); wsprintf(buffer, _T("CPU CH:0 RX D:%s RDY:%d IRQ:%d"), bufData + 3, tmpstc.ready, tmpstc.irq); TextOut(hdc, x, y + 6 * cyLine, buffer, lstrlen(buffer)); tmpstc = g_pBoard->GetChannelStruct(1, 1, 0); PrintOctalValue(bufData, tmpstc.data); wsprintf(buffer, _T("CPU CH:1 RX D:%s RDY:%d IRQ:%d"), bufData + 3, tmpstc.ready, tmpstc.irq); TextOut(hdc, x, y + 7 * cyLine, buffer, lstrlen(buffer)); tmpstc = g_pBoard->GetChannelStruct(1, 0, 1); wsprintf(buffer, _T("CPU CH:0 TX RDY:%d IRQ:%d"), tmpstc.ready, tmpstc.irq); TextOut(hdc, x, y + 8 * cyLine, buffer, lstrlen(buffer)); tmpstc = g_pBoard->GetChannelStruct(1, 1, 1); wsprintf(buffer, _T("CPU CH:1 TX RDY:%d IRQ:%d"), tmpstc.ready, tmpstc.irq); TextOut(hdc, x, y + 9 * cyLine, buffer, lstrlen(buffer)); tmpstc = g_pBoard->GetChannelStruct(1, 2, 1); wsprintf(buffer, _T("CPU CH:2 TX RDY:%d IRQ:%d"), tmpstc.ready, tmpstc.irq); TextOut(hdc, x, y + 10 * cyLine, buffer, lstrlen(buffer)); }
void DebugView_DrawPorts(HDC hdc, BOOL okProcessor, const CMemoryController* pMemCtl, CMotherboard* pBoard, int x, int y) { int cxChar, cyLine; GetFontWidthAndHeight(hdc, &cxChar, &cyLine); TextOut(hdc, x, y, _T("Ports:"), 6); if (okProcessor) // CPU { WORD value176640 = pMemCtl->GetPortView(0176640); DrawOctalValue(hdc, x + 0 * cxChar, y + 1 * cyLine, 0176640); DrawOctalValue(hdc, x + 8 * cxChar, y + 1 * cyLine, value176640); WORD value176642 = pMemCtl->GetPortView(0176642); DrawOctalValue(hdc, x + 0 * cxChar, y + 2 * cyLine, 0176642); DrawOctalValue(hdc, x + 8 * cxChar, y + 2 * cyLine, value176642); //TODO } else // PPU { WORD value177010 = pMemCtl->GetPortView(0177010); DrawOctalValue(hdc, x + 0 * cxChar, y + 1 * cyLine, 0177010); DrawOctalValue(hdc, x + 8 * cxChar, y + 1 * cyLine, value177010); WORD value177012 = pMemCtl->GetPortView(0177012); DrawOctalValue(hdc, x + 0 * cxChar, y + 2 * cyLine, 0177012); DrawOctalValue(hdc, x + 8 * cxChar, y + 2 * cyLine, value177012); WORD value177014 = pMemCtl->GetPortView(0177014); DrawOctalValue(hdc, x + 0 * cxChar, y + 3 * cyLine, 0177014); DrawOctalValue(hdc, x + 8 * cxChar, y + 3 * cyLine, value177014); WORD value177016 = pMemCtl->GetPortView(0177016); DrawOctalValue(hdc, x + 0 * cxChar, y + 4 * cyLine, 0177016); DrawOctalValue(hdc, x + 8 * cxChar, y + 4 * cyLine, value177016); WORD value177020 = pMemCtl->GetPortView(0177020); DrawOctalValue(hdc, x + 0 * cxChar, y + 5 * cyLine, 0177020); DrawOctalValue(hdc, x + 8 * cxChar, y + 5 * cyLine, value177020); WORD value177022 = pMemCtl->GetPortView(0177022); DrawOctalValue(hdc, x + 0 * cxChar, y + 6 * cyLine, 0177022); DrawOctalValue(hdc, x + 8 * cxChar, y + 6 * cyLine, value177022); WORD value177024 = pMemCtl->GetPortView(0177024); DrawOctalValue(hdc, x + 0 * cxChar, y + 7 * cyLine, 0177024); DrawOctalValue(hdc, x + 8 * cxChar, y + 7 * cyLine, value177024); WORD value177026 = pMemCtl->GetPortView(0177026); DrawOctalValue(hdc, x + 0 * cxChar, y + 8 * cyLine, 0177026); DrawOctalValue(hdc, x + 8 * cxChar, y + 8 * cyLine, value177026); WORD value177054 = pMemCtl->GetPortView(0177054); DrawOctalValue(hdc, x + 0 * cxChar, y + 9 * cyLine, 0177054); DrawOctalValue(hdc, x + 8 * cxChar, y + 9 * cyLine, value177054); WORD value177700 = pMemCtl->GetPortView(0177700); DrawOctalValue(hdc, x + 0 * cxChar, y + 10 * cyLine, 0177700); DrawOctalValue(hdc, x + 8 * cxChar, y + 10 * cyLine, value177700); WORD value177716 = pMemCtl->GetPortView(0177716); DrawOctalValue(hdc, x + 0 * cxChar, y + 11 * cyLine, 0177716); DrawOctalValue(hdc, x + 8 * cxChar, y + 11 * cyLine, value177716); WORD value177710 = pBoard->GetTimerStateView(); DrawOctalValue(hdc, x + 0 * cxChar, y + 13 * cyLine, 0177710); DrawOctalValue(hdc, x + 8 * cxChar, y + 13 * cyLine, value177710); WORD value177712 = pBoard->GetTimerReloadView(); DrawOctalValue(hdc, x + 0 * cxChar, y + 14 * cyLine, 0177712); DrawOctalValue(hdc, x + 8 * cxChar, y + 14 * cyLine, value177712); WORD value177714 = pBoard->GetTimerValueView(); DrawOctalValue(hdc, x + 0 * cxChar, y + 15 * cyLine, 0177714); DrawOctalValue(hdc, x + 8 * cxChar, y + 15 * cyLine, value177714); } }