From 02274606ab08772dc7b88299a0386f206d1cd661 Mon Sep 17 00:00:00 2001 From: mborik128 Date: Thu, 4 Apr 2019 23:15:22 +0200 Subject: [PATCH] final stage of full-featured debugger - dump window done - editable memory content - refactoring --- README.md | 2 +- arm/Makefile | 1 + arm/shell/debugger.asm.cpp | 271 +++--------------------------------- arm/shell/debugger.asm.h | 237 +++++++++++++++++++++++++++++++ arm/shell/debugger.cpp | 99 +++++-------- arm/shell/debugger.dump.cpp | 240 +++++++++++++++++++++++++++++++ arm/shell/debugger.h | 7 +- speccy2010.hlp | 5 +- 8 files changed, 541 insertions(+), 321 deletions(-) create mode 100644 arm/shell/debugger.asm.h create mode 100644 arm/shell/debugger.dump.cpp diff --git a/README.md b/README.md index f86f06a..2550d58 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ - **Scorpion** 256 modes * Disk interfaces - **Betadisk** (real floppy disk controller emulation, supported TRD, SCL and FDI disk images) - - **DivMMC** (basically [DivIDE](https://divide.speccy.cz/files/pgm_model.txt) control register and memory model will all 64 x 8kB SRAM pages) + - **DivMMC** (basically [DivIDE](https://divide.speccy.cz/files/pgm_model.txt) control register and memory model with all 64 x 8kB SRAM pages) - **MB-02** (without Z80DMA or real floppy disk controller but specifically modified original BIOS and simplified data transfer with new BS-DOS 308s firmware) * 2xAY (Turbosound), Covox/Soundrive * TAP / TZX support diff --git a/arm/Makefile b/arm/Makefile index 6345f5f..a8004a7 100644 --- a/arm/Makefile +++ b/arm/Makefile @@ -133,6 +133,7 @@ CXX_SRCS = \ $(SRCDIR)/shell/viewer.cpp \ $(SRCDIR)/shell/commander.cpp \ $(SRCDIR)/shell/debugger.asm.cpp \ + $(SRCDIR)/shell/debugger.dump.cpp \ $(SRCDIR)/shell/debugger.cpp ASM_SRCS = \ diff --git a/arm/shell/debugger.asm.cpp b/arm/shell/debugger.asm.cpp index 46fc0eb..3444f49 100644 --- a/arm/shell/debugger.asm.cpp +++ b/arm/shell/debugger.asm.cpp @@ -1,5 +1,6 @@ #include #include "debugger.h" +#include "debugger.asm.h" #include "screen.h" #include "dialog.h" #include "../system.h" @@ -11,9 +12,6 @@ #define TABSTOP_INST 15 #define TABSTOP_OPER 20 -#define TRACEWIN_OFF_Y 6 -#define TRACEWIN_WIDTH (24 - TRACEWIN_OFF_Y) - #define TWF_BRANCH 0x010000 #define TWF_BRADDR 0x020000 #define TWF_LOOPCMD 0x040000 @@ -31,9 +29,12 @@ static byte dbuf[8]; static char line[33], curline[33]; static unsigned stackPos[8] = { -1U }, stackCur[8] = { -1U }; +extern byte activeWindow; +extern bool activeRegPanel; + unsigned breakpoints[BREAKPOINTS_COUNT]; byte cpuTraceCol = 2; -word cpuPCTrace[TRACEWIN_WIDTH + 1]; +word cpuPCTrace[WINDOW_HEIGHT + 1]; byte cpuCursorY; word cpuTraceCur, cpuTraceTop; unsigned cpuTraceFlg, cpuNextPC = -1U; @@ -48,238 +49,6 @@ static const byte cs[3][4] = { }; static const byte flags[] = { 0x40, 0x01, 0x04, 0x80 }; // ZF,CF,PV,SF -//--------------------------------------------------------------------------------------- -#define _iw 9 -#define _ib 10 -#define _shrt 27 -#define _ld 0x89 -#define _zr16 0x8A -#define _zr8 0x8B -#define _cb 0x8C -#define _zjr 0x8D -#define _hl 0x8E -#define _zr81 0x8F -#define _zop 0x90 -#define _zf 0x91 -#define _zr16a 0x92 -#define _zr8_ 0x9D -#define _zr81_ 0x9E - -static const byte asm_tab_z80[] = { - 2, 0xED, 0x70, 0xFF, 0xFF, // in (c) - 'i', 'n', ' ', '(', 'c', ')', 0, - 2, 0xED, 0x71, 0xFF, 0xFF, // out (c),0 - 'o', 'u', 't', ' ', '(', 'c', ')', ',', '0', 0, - 2, 0xED, 0x40, 0xFF, 0xC7, // in r8,(c) - 'i', 'n', ' ', _zr8, ',', '(', 'c', ')', 0, - 2, 0xED, 0x41, 0xFF, 0xC7, // out (c),r8 - 'o', 'u', 't', ' ', '(', 'c', ')', ',', _zr8, 0, - - 1, 0xCB, 0xFF, // all cb-opcodes - _cb, 0, - 1, 0x00, 0xFF, // nop - 'n', 'o', 'p', 0, - 1, 0x08, 0xFF, // ex af,af' - 'e', 'x', ' ', 'a', 'f', ',', 'a', 'f', '\'', 0, - 1, 0x02, 0xFF, // ld (bc),a - _ld, '(', 'b', 'c', ')', ',', 'a', 0, - 1, 0x12, 0xFF, // ld (de),a - _ld, '(', 'd', 'e', ')', ',', 'a', 0, - 1, 0x0A, 0xFF, // ld a,(bc) - _ld, 'a', ',', '(', 'b', 'c', ')', 0, - 1, 0x1A, 0xFF, // ld a,(de) - _ld, 'a', ',', '(', 'd', 'e', ')', 0, - 1, 0x03, 0xCF, // inc r16 - 'i', 'n', 'c', ' ', _zr16, 0, - 1, 0x0B, 0xCF, // dec r16 - 'd', 'e', 'c', ' ', _zr16, 0, - 1, 0x04, 0xC7, // inc r8 - 'i', 'n', 'c', ' ', _zr8, 0, - 1, 0x05, 0xC7, // dec r8 - 'd', 'e', 'c', ' ', _zr8, 0, - 1, 0x07, 0xFF, // rlca - 'r', 'l', 'c', 'a', 0, - 1, 0x17, 0xFF, // rla - 'r', 'l', 'a', 0, - 1, 0x27, 0xFF, // daa - 'd', 'a', 'a', 0, - 1, 0x37, 0xFF, // scf - 's', 'c', 'f', 0, - 1, 0x0F, 0xFF, // rrca - 'r', 'r', 'c', 'a', 0, - 1, 0x1F, 0xFF, // rra - 'r', 'r', 'a', 0, - 1, 0x2F, 0xFF, // cpl - 'c', 'p', 'l', 0, - 1, 0x3F, 0xFF, // ccf - 'c', 'c', 'f', 0, - 1, 0x00, 0xC7, // relative jumps - _zjr, _shrt, 0, - 1, 0x09, 0xCF, // add hl, r16 - 'a', 'd', 'd', ' ', _hl, ',', _zr16, 0, - 1, 0x32, 0xFF, // ld (nnnn),a - _ld, '(', _iw, ')', ',', 'a', 0, - 1, 0x3A, 0xFF, // ld a,(nnnn) - _ld, 'a', ',', '(', _iw, ')', 0, - 1, 0x22, 0xFF, // ld (nnnn),hl - _ld, '(', _iw, ')', ',', _hl, 0, - 1, 0x2A, 0xFF, // ld hl,(nnnn) - _ld, _hl, ',', '(', _iw, ')', 0, - 1, 0x76, 0xFF, // halt - 'h', 'a', 'l', 't', 0, - 1, 0x40, 0xC0, // ld r8,r8 - _ld, _zr8_, ',', _zr81_, 0, - 1, 0x80, 0xC0, // op r8 - _zop /*, ' '*/, _zr81, 0, - 1, 0xC0, 0xC7, // ret cc - 'r', 'e', 't', ' ', _zf, 0, - 1, 0xC2, 0xC7, // jp cc, nnnn - 'j', 'p', ' ', _zf, ',', _iw, 0, - 1, 0xC4, 0xC7, // call cc, nnnn - 'c', 'a', 'l', 'l', ' ', _zf, ',', _iw, 0, - 1, 0xC6, 0xC7, // op immb - _zop /*, ' '*/, _ib, 0, - 1, 0xC1, 0xCF, // pop r16a - 'p', 'o', 'p', ' ', _zr16a, 0, - 1, 0xC5, 0xCF, // push r16a - 'p', 'u', 's', 'h', ' ', _zr16a, 0, - 1, 0xC3, 0xFF, // jp nnnn - 'j', 'p', ' ', _iw, 0, - 1, 0xD3, 0xFF, // out (nn),a - 'o', 'u', 't', ' ', '(', _ib, ')', ',', 'a', 0, - 1, 0xE3, 0xFF, // ex (sp),hl - 'e', 'x', ' ', '(', 's', 'p', ')', ',', _hl, 0, - 1, 0xF3, 0xFF, // di - 'd', 'i', 0, - 1, 0xC9, 0xFF, // ret - 'r', 'e', 't', 0, - 1, 0xD9, 0xFF, // exx - 'e', 'x', 'x', 0, - 1, 0xE9, 0xFF, // jp (hl) - 'j', 'p', ' ', '(', _hl, ')', 0, - 1, 0xF9, 0xFF, // ld sp, hl - _ld, 's', 'p', ',', _hl, 0, - 1, 0xDB, 0xFF, // in a,(nn) - 'i', 'n', ' ', 'a', ',', '(', _ib, ')', 0, - 1, 0xEB, 0xFF, // ex de,hl - no 'ex de,ix' ! - 'e', 'x', ' ', 'd', 'e', ',', 'h', 'l', 0, - 1, 0xFB, 0xFF, // ei - 'e', 'i', 0, - 1, 0xCD, 0xFF, // call nnnn - 'c', 'a', 'l', 'l', ' ', _iw, 0, - 1, 0xC7, 0xFF, // rst 0 - 'r', 's', 't', ' ', '0', 0, - 1, 0xCF, 0xFF, // rst 8 - 'r', 's', 't', ' ', '8', 0, - 1, 0xD7, 0xFF, // rst 10 - 'r', 's', 't', ' ', '1', '0', 0, - 1, 0xDF, 0xFF, // rst 18 - 'r', 's', 't', ' ', '1', '8', 0, - 1, 0xE7, 0xFF, // rst 20 - 'r', 's', 't', ' ', '2', '0', 0, - 1, 0xEF, 0xFF, // rst 28 - 'r', 's', 't', ' ', '2', '8', 0, - 1, 0xF7, 0xFF, // rst 30 - 'r', 's', 't', ' ', '3', '0', 0, - 1, 0xFF, 0xFF, // rst 38 - 'r', 's', 't', ' ', '3', '8', 0, - - // ED opcodes - 2, 0xED, 0x42, 0xFF, 0xCF, // sbc hl,r16 - 's', 'b', 'c', ' ', 'h', 'l', ',', _zr16, 0, - 2, 0xED, 0x4A, 0xFF, 0xCF, // adc hl,r16 - 'a', 'd', 'c', ' ', 'h', 'l', ',', _zr16, 0, - 2, 0xED, 0x43, 0xFF, 0xCF, // ld (nnnn), r16 - _ld, '(', _iw, ')', ',', _zr16, 0, - 2, 0xED, 0x4B, 0xFF, 0xCF, // ld r16, (nnnn) - _ld, _zr16, ',', '(', _iw, ')', 0, - 2, 0xED, 0x44, 0xFF, 0xC7, // neg - 'n', 'e', 'g', 0, - 2, 0xED, 0x45, 0xFF, 0xCF, // retn - 'r', 'e', 't', 'n', 0, - 2, 0xED, 0x4D, 0xFF, 0xCF, // reti - 'r', 'e', 't', 'i', 0, - 2, 0xED, 0x46, 0xFF, 0xDF, // im 0 - 'i', 'm', ' ', '0', 0, - 2, 0xED, 0x56, 0xFF, 0xDF, // im 1 - 'i', 'm', ' ', '1', 0, - 2, 0xED, 0x5E, 0xFF, 0xDF, // im 2 - 'i', 'm', ' ', '2', 0, - 2, 0xED, 0x4E, 0xFF, 0xDF, // im 0/1 - 'i', 'm', ' ', '0', '/', '1', 0, - 2, 0xED, 0x47, 0xFF, 0xFF, // ld i,a - _ld, 'i', ',', 'a', 0, - 2, 0xED, 0x57, 0xFF, 0xFF, // ld a,i - _ld, 'a', ',', 'i', 0, - 2, 0xED, 0x67, 0xFF, 0xFF, // rrd - 'r', 'r', 'd', 0, - 2, 0xED, 0x4F, 0xFF, 0xFF, // ld r,a - _ld, 'r', ',', 'a', 0, - 2, 0xED, 0x5F, 0xFF, 0xFF, // ld a,r - _ld, 'a', ',', 'r', 0, - 2, 0xED, 0x6F, 0xFF, 0xFF, // rld - 'r', 'l', 'd', 0, - - 2, 0xED, 0xA0, 0xFF, 0xFF, // ldi - 'l', 'd', 'i', 0, - 2, 0xED, 0xA1, 0xFF, 0xFF, // cpi - 'c', 'p', 'i', 0, - 2, 0xED, 0xA2, 0xFF, 0xFF, // ini - 'i', 'n', 'i', 0, - 2, 0xED, 0xA3, 0xFF, 0xFF, // outi - 'o', 'u', 't', 'i', 0, - 2, 0xED, 0xA8, 0xFF, 0xFF, // ldd - 'l', 'd', 'd', 0, - 2, 0xED, 0xA9, 0xFF, 0xFF, // cpd - 'c', 'p', 'd', 0, - 2, 0xED, 0xAA, 0xFF, 0xFF, // ind - 'i', 'n', 'd', 0, - 2, 0xED, 0xAB, 0xFF, 0xFF, // outd - 'o', 'u', 't', 'd', 0, - - 2, 0xED, 0xB0, 0xFF, 0xFF, // ldir - 'l', 'd', 'i', 'r', 0, - 2, 0xED, 0xB1, 0xFF, 0xFF, // cpir - 'c', 'p', 'i', 'r', 0, - 2, 0xED, 0xB2, 0xFF, 0xFF, // inir - 'i', 'n', 'i', 'r', 0, - 2, 0xED, 0xB3, 0xFF, 0xFF, // otir - 'o', 't', 'i', 'r', 0, - 2, 0xED, 0xB8, 0xFF, 0xFF, // lddr - 'l', 'd', 'd', 'r', 0, - 2, 0xED, 0xB9, 0xFF, 0xFF, // cpdr - 'c', 'p', 'd', 'r', 0, - 2, 0xED, 0xBA, 0xFF, 0xFF, // indr - 'i', 'n', 'd', 'r', 0, - 2, 0xED, 0xBB, 0xFF, 0xFF, // otdr - 'o', 't', 'd', 'r', 0, - - 2, 0xED, 0x00, 0xFF, 0x00, // all others 'ED' - 'n', 'o', 'p', '*', 0, - - // place immediates after all - 'ld a,b' is not 'ld a,0B' - 1, 0x01, 0xCF, // ld r16,imm16 - _ld, _zr16, ',', _iw, 0, - 1, 0x06, 0xC7, // ld r8, imm8 - _ld, _zr8, ',', _ib, 0, - - 0 // end -}; - -static const char *z80r16_1 = "bc\0de\0hl\0sp"; -static const char *z80r16_2 = "bc\0de\0ix\0sp"; -static const char *z80r16_3 = "bc\0de\0iy\0sp"; -static const char *z80r8_1 = "b\0\0\0\0c\0\0\0\0d\0\0\0\0e\0\0\0\0h\0\0\0\0l\0\0\0\0(hl)\0a"; -static const char *z80r8_2 = "b\0\0\0\0c\0\0\0\0d\0\0\0\0e\0\0\0\0xh\0\0\0xl\0\0\0(1x)\0a"; -static const char *z80r8_3 = "b\0\0\0\0c\0\0\0\0d\0\0\0\0e\0\0\0\0yh\0\0\0yl\0\0\0(1y)\0a"; -static const char *cbtab = "rlc \0\0\0rrc \0\0\0rl \0\0\0\0rr \0\0\0\0sla \0\0\0sra \0\0\0sli \0\0\0srl \0\0\0" - "bit 0,\0bit 1,\0bit 2,\0bit 3,\0bit 4,\0bit 5,\0bit 6,\0bit 7,\0" - "res 0,\0res 1,\0res 2,\0res 3,\0res 4,\0res 5,\0res 6,\0res 7,\0" - "set 0,\0set 1,\0set 2,\0set 3,\0set 4,\0set 5,\0set 6,\0set 7,\0"; -static const char *zjr = "xxxxxx\0xxxxxx\0djnz \0\0jr \0\0\0\0jr nz,\0jr z,\0\0jr nc,\0jr c,\0"; -static const char *zop = "add a,\0\0adc a,\0\0sub \0\0\0\0sbc a,\0\0and \0\0\0\0xor \0\0\0\0or \0\0\0\0\0cp \0\0\0\0\0"; -static const char *zf = "nz\0z\0\0nc\0c\0\0po\0pe\0p\0\0m"; - //--------------------------------------------------------------------------------------- void disasm_genidx(char *buf, byte z80p, byte *cm) { @@ -670,7 +439,7 @@ unsigned cpu_up(unsigned ip) //--------------------------------------------------------------------------------------- void Debugger_UpdateTrace() { - byte atr0 = IsRegPanel() ? COL_NORMAL : COL_ACTIVE; + byte atr0 = activeRegPanel ? COL_NORMAL : COL_ACTIVE; word realPC = GetCPUState(REG_PC); unsigned y, ii, pc; @@ -680,7 +449,7 @@ void Debugger_UpdateTrace() cpuCursorY = 0xFF; pc = cpuTraceTop; - for (ii = 0, y = TRACEWIN_OFF_Y; ii < TRACEWIN_WIDTH; ii++, y++) { + for (ii = 0, y = WINDOW_OFF_Y; ii < WINDOW_HEIGHT; ii++, y++) { pc &= 0xFFFF; cpuPCTrace[ii] = pc; int len = disasm_line(pc); @@ -705,7 +474,7 @@ void Debugger_UpdateTrace() cpuCursorY = ii; memcpy(curline, line, sizeof(line)); - if (!IsRegPanel()) { + if (!activeRegPanel) { if (cpuTraceCol > 1) atr = COL_CURSOR; DrawAttr8(cs[cpuTraceCol][0], y, COL_CURSOR, cs[cpuTraceCol][1]); @@ -741,7 +510,7 @@ bool Debugger_Editor() char *ptr = curline + c[2], key; byte x = c[0] * 8; - byte y = cpuCursorY + TRACEWIN_OFF_Y; + byte y = cpuCursorY + WINDOW_OFF_Y; bool result = false; int p = 0, s, i; @@ -801,7 +570,7 @@ bool Debugger_TestKeyTrace(byte key, bool *updateAll) { unsigned i, curs = 0; - if (!IsRegPanel()) { + if (activeWindow == WIN_TRACE && !activeRegPanel) { if (key == K_BACKSPACE) pop_pos(); @@ -816,7 +585,7 @@ bool Debugger_TestKeyTrace(byte key, bool *updateAll) else if (key == K_UP) { if (cpuTraceCur > cpuTraceTop) { - for (i = 1; i < TRACEWIN_WIDTH; i++) { + for (i = 1; i < WINDOW_HEIGHT; i++) { if (cpuPCTrace[i] == cpuTraceCur) cpuTraceCur = cpuPCTrace[i - 1]; } @@ -825,31 +594,31 @@ bool Debugger_TestKeyTrace(byte key, bool *updateAll) cpuTraceTop = cpuTraceCur = cpu_up(cpuTraceCur); } else if (key == K_DOWN) { - for (i = 0; i < TRACEWIN_WIDTH; i++) { + for (i = 0; i < WINDOW_HEIGHT; i++) { if (cpuPCTrace[i] == cpuTraceCur) { cpuTraceCur = cpuPCTrace[i + 1]; - if (i == TRACEWIN_WIDTH - 1) + if (i == WINDOW_HEIGHT - 1) cpuTraceTop = cpuPCTrace[1]; break; } } } else if (key == K_PAGEUP) { - for (i = 0; i < TRACEWIN_WIDTH; i++) + for (i = 0; i < WINDOW_HEIGHT; i++) if (cpuTraceCur == cpuPCTrace[i]) curs = i; - for (i = 0; i < TRACEWIN_WIDTH; i++) + for (i = 0; i < WINDOW_HEIGHT; i++) cpuTraceTop = cpu_up(cpuTraceTop); Debugger_UpdateTrace(); reqUpdateRefresh = URQ_PAGE_SW | curs; } else if (key == K_PAGEDOWN) { - for (i = 0; i < TRACEWIN_WIDTH; i++) + for (i = 0; i < WINDOW_HEIGHT; i++) if (cpuTraceCur == cpuPCTrace[i]) curs = i; - cpuTraceTop = cpuPCTrace[TRACEWIN_WIDTH]; + cpuTraceTop = cpuPCTrace[WINDOW_HEIGHT]; Debugger_UpdateTrace(); reqUpdateRefresh = URQ_PAGE_SW | curs; @@ -882,6 +651,8 @@ bool Debugger_TestKeyTrace(byte key, bool *updateAll) WriteByteAtCursor(curs++, i); } } + + Debugger_UpdateTrace(); } else { // TODO parse & assembly @@ -962,6 +733,8 @@ bool Debugger_TestKeyTrace(byte key, bool *updateAll) reqUpdateRefresh = URQ_BREAKPT; return true; } + else + return Debugger_TestKeyDump(key, updateAll); return false; } @@ -973,7 +746,7 @@ void Debugger_RefreshRequested(bool firstTime) cpuTraceCur = newpc; - if (firstTime || newpc < cpuTraceTop || newpc >= cpuPCTrace[TRACEWIN_WIDTH] || cpuCursorY == 0xFF) + if (firstTime || newpc < cpuTraceTop || newpc >= cpuPCTrace[WINDOW_HEIGHT] || cpuCursorY == 0xFF) cpuTraceTop = newpc; } else if (reqUpdateRefresh & URQ_PAGE_SW) diff --git a/arm/shell/debugger.asm.h b/arm/shell/debugger.asm.h new file mode 100644 index 0000000..b86dd14 --- /dev/null +++ b/arm/shell/debugger.asm.h @@ -0,0 +1,237 @@ +#ifndef SHELL_DEBUGGER_ASM_H_INCLUDED +#define SHELL_DEBUGGER_ASM_H_INCLUDED + +#include "../types.h" + +#define _iw 9 +#define _ib 10 +#define _shrt 27 +#define _ld 0x89 +#define _zr16 0x8A +#define _zr8 0x8B +#define _cb 0x8C +#define _zjr 0x8D +#define _hl 0x8E +#define _zr81 0x8F +#define _zop 0x90 +#define _zf 0x91 +#define _zr16a 0x92 +#define _zr8_ 0x9D +#define _zr81_ 0x9E + +static const byte asm_tab_z80[] = { + 2, 0xED, 0x70, 0xFF, 0xFF, // in (c) + 'i', 'n', ' ', '(', 'c', ')', 0, + 2, 0xED, 0x71, 0xFF, 0xFF, // out (c),0 + 'o', 'u', 't', ' ', '(', 'c', ')', ',', '0', 0, + 2, 0xED, 0x40, 0xFF, 0xC7, // in r8,(c) + 'i', 'n', ' ', _zr8, ',', '(', 'c', ')', 0, + 2, 0xED, 0x41, 0xFF, 0xC7, // out (c),r8 + 'o', 'u', 't', ' ', '(', 'c', ')', ',', _zr8, 0, + + 1, 0xCB, 0xFF, // all cb-opcodes + _cb, 0, + 1, 0x00, 0xFF, // nop + 'n', 'o', 'p', 0, + 1, 0x08, 0xFF, // ex af,af' + 'e', 'x', ' ', 'a', 'f', ',', 'a', 'f', '\'', 0, + 1, 0x02, 0xFF, // ld (bc),a + _ld, '(', 'b', 'c', ')', ',', 'a', 0, + 1, 0x12, 0xFF, // ld (de),a + _ld, '(', 'd', 'e', ')', ',', 'a', 0, + 1, 0x0A, 0xFF, // ld a,(bc) + _ld, 'a', ',', '(', 'b', 'c', ')', 0, + 1, 0x1A, 0xFF, // ld a,(de) + _ld, 'a', ',', '(', 'd', 'e', ')', 0, + 1, 0x03, 0xCF, // inc r16 + 'i', 'n', 'c', ' ', _zr16, 0, + 1, 0x0B, 0xCF, // dec r16 + 'd', 'e', 'c', ' ', _zr16, 0, + 1, 0x04, 0xC7, // inc r8 + 'i', 'n', 'c', ' ', _zr8, 0, + 1, 0x05, 0xC7, // dec r8 + 'd', 'e', 'c', ' ', _zr8, 0, + 1, 0x07, 0xFF, // rlca + 'r', 'l', 'c', 'a', 0, + 1, 0x17, 0xFF, // rla + 'r', 'l', 'a', 0, + 1, 0x27, 0xFF, // daa + 'd', 'a', 'a', 0, + 1, 0x37, 0xFF, // scf + 's', 'c', 'f', 0, + 1, 0x0F, 0xFF, // rrca + 'r', 'r', 'c', 'a', 0, + 1, 0x1F, 0xFF, // rra + 'r', 'r', 'a', 0, + 1, 0x2F, 0xFF, // cpl + 'c', 'p', 'l', 0, + 1, 0x3F, 0xFF, // ccf + 'c', 'c', 'f', 0, + 1, 0x00, 0xC7, // relative jumps + _zjr, _shrt, 0, + 1, 0x09, 0xCF, // add hl, r16 + 'a', 'd', 'd', ' ', _hl, ',', _zr16, 0, + 1, 0x32, 0xFF, // ld (nnnn),a + _ld, '(', _iw, ')', ',', 'a', 0, + 1, 0x3A, 0xFF, // ld a,(nnnn) + _ld, 'a', ',', '(', _iw, ')', 0, + 1, 0x22, 0xFF, // ld (nnnn),hl + _ld, '(', _iw, ')', ',', _hl, 0, + 1, 0x2A, 0xFF, // ld hl,(nnnn) + _ld, _hl, ',', '(', _iw, ')', 0, + 1, 0x76, 0xFF, // halt + 'h', 'a', 'l', 't', 0, + 1, 0x40, 0xC0, // ld r8,r8 + _ld, _zr8_, ',', _zr81_, 0, + 1, 0x80, 0xC0, // op r8 + _zop /*, ' '*/, _zr81, 0, + 1, 0xC0, 0xC7, // ret cc + 'r', 'e', 't', ' ', _zf, 0, + 1, 0xC2, 0xC7, // jp cc, nnnn + 'j', 'p', ' ', _zf, ',', _iw, 0, + 1, 0xC4, 0xC7, // call cc, nnnn + 'c', 'a', 'l', 'l', ' ', _zf, ',', _iw, 0, + 1, 0xC6, 0xC7, // op immb + _zop /*, ' '*/, _ib, 0, + 1, 0xC1, 0xCF, // pop r16a + 'p', 'o', 'p', ' ', _zr16a, 0, + 1, 0xC5, 0xCF, // push r16a + 'p', 'u', 's', 'h', ' ', _zr16a, 0, + 1, 0xC3, 0xFF, // jp nnnn + 'j', 'p', ' ', _iw, 0, + 1, 0xD3, 0xFF, // out (nn),a + 'o', 'u', 't', ' ', '(', _ib, ')', ',', 'a', 0, + 1, 0xE3, 0xFF, // ex (sp),hl + 'e', 'x', ' ', '(', 's', 'p', ')', ',', _hl, 0, + 1, 0xF3, 0xFF, // di + 'd', 'i', 0, + 1, 0xC9, 0xFF, // ret + 'r', 'e', 't', 0, + 1, 0xD9, 0xFF, // exx + 'e', 'x', 'x', 0, + 1, 0xE9, 0xFF, // jp (hl) + 'j', 'p', ' ', '(', _hl, ')', 0, + 1, 0xF9, 0xFF, // ld sp, hl + _ld, 's', 'p', ',', _hl, 0, + 1, 0xDB, 0xFF, // in a,(nn) + 'i', 'n', ' ', 'a', ',', '(', _ib, ')', 0, + 1, 0xEB, 0xFF, // ex de,hl - no 'ex de,ix' ! + 'e', 'x', ' ', 'd', 'e', ',', 'h', 'l', 0, + 1, 0xFB, 0xFF, // ei + 'e', 'i', 0, + 1, 0xCD, 0xFF, // call nnnn + 'c', 'a', 'l', 'l', ' ', _iw, 0, + 1, 0xC7, 0xFF, // rst 0 + 'r', 's', 't', ' ', '0', 0, + 1, 0xCF, 0xFF, // rst 8 + 'r', 's', 't', ' ', '8', 0, + 1, 0xD7, 0xFF, // rst 10 + 'r', 's', 't', ' ', '1', '0', 0, + 1, 0xDF, 0xFF, // rst 18 + 'r', 's', 't', ' ', '1', '8', 0, + 1, 0xE7, 0xFF, // rst 20 + 'r', 's', 't', ' ', '2', '0', 0, + 1, 0xEF, 0xFF, // rst 28 + 'r', 's', 't', ' ', '2', '8', 0, + 1, 0xF7, 0xFF, // rst 30 + 'r', 's', 't', ' ', '3', '0', 0, + 1, 0xFF, 0xFF, // rst 38 + 'r', 's', 't', ' ', '3', '8', 0, + + // ED opcodes + 2, 0xED, 0x42, 0xFF, 0xCF, // sbc hl,r16 + 's', 'b', 'c', ' ', 'h', 'l', ',', _zr16, 0, + 2, 0xED, 0x4A, 0xFF, 0xCF, // adc hl,r16 + 'a', 'd', 'c', ' ', 'h', 'l', ',', _zr16, 0, + 2, 0xED, 0x43, 0xFF, 0xCF, // ld (nnnn), r16 + _ld, '(', _iw, ')', ',', _zr16, 0, + 2, 0xED, 0x4B, 0xFF, 0xCF, // ld r16, (nnnn) + _ld, _zr16, ',', '(', _iw, ')', 0, + 2, 0xED, 0x44, 0xFF, 0xC7, // neg + 'n', 'e', 'g', 0, + 2, 0xED, 0x45, 0xFF, 0xCF, // retn + 'r', 'e', 't', 'n', 0, + 2, 0xED, 0x4D, 0xFF, 0xCF, // reti + 'r', 'e', 't', 'i', 0, + 2, 0xED, 0x46, 0xFF, 0xDF, // im 0 + 'i', 'm', ' ', '0', 0, + 2, 0xED, 0x56, 0xFF, 0xDF, // im 1 + 'i', 'm', ' ', '1', 0, + 2, 0xED, 0x5E, 0xFF, 0xDF, // im 2 + 'i', 'm', ' ', '2', 0, + 2, 0xED, 0x4E, 0xFF, 0xDF, // im 0/1 + 'i', 'm', ' ', '0', '/', '1', 0, + 2, 0xED, 0x47, 0xFF, 0xFF, // ld i,a + _ld, 'i', ',', 'a', 0, + 2, 0xED, 0x57, 0xFF, 0xFF, // ld a,i + _ld, 'a', ',', 'i', 0, + 2, 0xED, 0x67, 0xFF, 0xFF, // rrd + 'r', 'r', 'd', 0, + 2, 0xED, 0x4F, 0xFF, 0xFF, // ld r,a + _ld, 'r', ',', 'a', 0, + 2, 0xED, 0x5F, 0xFF, 0xFF, // ld a,r + _ld, 'a', ',', 'r', 0, + 2, 0xED, 0x6F, 0xFF, 0xFF, // rld + 'r', 'l', 'd', 0, + + 2, 0xED, 0xA0, 0xFF, 0xFF, // ldi + 'l', 'd', 'i', 0, + 2, 0xED, 0xA1, 0xFF, 0xFF, // cpi + 'c', 'p', 'i', 0, + 2, 0xED, 0xA2, 0xFF, 0xFF, // ini + 'i', 'n', 'i', 0, + 2, 0xED, 0xA3, 0xFF, 0xFF, // outi + 'o', 'u', 't', 'i', 0, + 2, 0xED, 0xA8, 0xFF, 0xFF, // ldd + 'l', 'd', 'd', 0, + 2, 0xED, 0xA9, 0xFF, 0xFF, // cpd + 'c', 'p', 'd', 0, + 2, 0xED, 0xAA, 0xFF, 0xFF, // ind + 'i', 'n', 'd', 0, + 2, 0xED, 0xAB, 0xFF, 0xFF, // outd + 'o', 'u', 't', 'd', 0, + + 2, 0xED, 0xB0, 0xFF, 0xFF, // ldir + 'l', 'd', 'i', 'r', 0, + 2, 0xED, 0xB1, 0xFF, 0xFF, // cpir + 'c', 'p', 'i', 'r', 0, + 2, 0xED, 0xB2, 0xFF, 0xFF, // inir + 'i', 'n', 'i', 'r', 0, + 2, 0xED, 0xB3, 0xFF, 0xFF, // otir + 'o', 't', 'i', 'r', 0, + 2, 0xED, 0xB8, 0xFF, 0xFF, // lddr + 'l', 'd', 'd', 'r', 0, + 2, 0xED, 0xB9, 0xFF, 0xFF, // cpdr + 'c', 'p', 'd', 'r', 0, + 2, 0xED, 0xBA, 0xFF, 0xFF, // indr + 'i', 'n', 'd', 'r', 0, + 2, 0xED, 0xBB, 0xFF, 0xFF, // otdr + 'o', 't', 'd', 'r', 0, + + 2, 0xED, 0x00, 0xFF, 0x00, // all others 'ED' + 'n', 'o', 'p', '*', 0, + + // place immediates after all - 'ld a,b' is not 'ld a,0B' + 1, 0x01, 0xCF, // ld r16,imm16 + _ld, _zr16, ',', _iw, 0, + 1, 0x06, 0xC7, // ld r8, imm8 + _ld, _zr8, ',', _ib, 0, + + 0 // end +}; + +static const char *z80r16_1 = "bc\0de\0hl\0sp"; +static const char *z80r16_2 = "bc\0de\0ix\0sp"; +static const char *z80r16_3 = "bc\0de\0iy\0sp"; +static const char *z80r8_1 = "b\0\0\0\0c\0\0\0\0d\0\0\0\0e\0\0\0\0h\0\0\0\0l\0\0\0\0(hl)\0a"; +static const char *z80r8_2 = "b\0\0\0\0c\0\0\0\0d\0\0\0\0e\0\0\0\0xh\0\0\0xl\0\0\0(1x)\0a"; +static const char *z80r8_3 = "b\0\0\0\0c\0\0\0\0d\0\0\0\0e\0\0\0\0yh\0\0\0yl\0\0\0(1y)\0a"; +static const char *cbtab = "rlc \0\0\0rrc \0\0\0rl \0\0\0\0rr \0\0\0\0sla \0\0\0sra \0\0\0sli \0\0\0srl \0\0\0" + "bit 0,\0bit 1,\0bit 2,\0bit 3,\0bit 4,\0bit 5,\0bit 6,\0bit 7,\0" + "res 0,\0res 1,\0res 2,\0res 3,\0res 4,\0res 5,\0res 6,\0res 7,\0" + "set 0,\0set 1,\0set 2,\0set 3,\0set 4,\0set 5,\0set 6,\0set 7,\0"; +static const char *zjr = "xxxxxx\0xxxxxx\0djnz \0\0jr \0\0\0\0jr nz,\0jr z,\0\0jr nc,\0jr c,\0"; +static const char *zop = "add a,\0\0adc a,\0\0sub \0\0\0\0sbc a,\0\0and \0\0\0\0xor \0\0\0\0or \0\0\0\0\0cp \0\0\0\0\0"; +static const char *zf = "nz\0z\0\0nc\0c\0\0po\0pe\0p\0\0m"; + +#endif diff --git a/arm/shell/debugger.cpp b/arm/shell/debugger.cpp index 3572cf1..a1e5250 100644 --- a/arm/shell/debugger.cpp +++ b/arm/shell/debugger.cpp @@ -40,9 +40,12 @@ word regBuffer[15]; byte activeWindow = WIN_TRACE; bool activeRegPanel = false; -bool dumpWindowAsciiMode = false; + byte watcherMode = 0; byte lastWatcherMode = -1; + +extern bool dumpWindowAsciiMode; +extern bool dumpWindowRightPane; //--------------------------------------------------------------------------------------- dword CalculateAddrAtCursor(word addr) { @@ -116,8 +119,6 @@ void WriteByteAtCursor(word addr, byte data) SystemBus_Write(CalculateAddrAtCursor(addr), data); } //--------------------------------------------------------------------------------------- -bool IsRegPanel() { return activeRegPanel; } -//--------------------------------------------------------------------------------------- word GetCPUState(byte reg) { return regBuffer[reg]; } //--------------------------------------------------------------------------------------- void SetCPUState(byte reg, word value) { regBuffer[reg] = value; } @@ -129,15 +130,13 @@ void Debugger_SwitchPanel() byte y; for (y = 1; y < 5; y++) DrawAttr8(0, y, activeRegPanel ? COL_ACTIVE : COL_NORMAL, 24); - for (++y; y < 24; y++) { - if (activeWindow == WIN_TRACE) + + if (activeWindow == WIN_TRACE) { + for (++y; y < 24; y++) DrawAttr8( 0, y, activeRegPanel ? COL_NORMAL : COL_ACTIVE, 24); - else if (activeWindow == WIN_MEMDUMP) { - byte w = dumpWindowAsciiMode ? 21 : 29; - DrawAttr8( 0, y, activeRegPanel ? COL_NORMAL : COL_ACTIVE, w); - DrawAttr8(w, y, (activeRegPanel ? COL_NORMAL : COL_ACTIVE) & ~3, (32 - w)); - } } + else if (activeWindow == WIN_MEMDUMP) + Debugger_UpdateDumpAttrs(); } //--------------------------------------------------------------------------------------- void Debugger_Screen() @@ -512,21 +511,23 @@ void Shell_Debugger() bool firstTime = true; bool updateAll = true; bool updateRegs = false; - bool updateTrace = false; + bool updateWindow = false; while (true) { if (updateRegs || updateAll) { Debugger_UpdateRegs(updateAll); updateRegs = false; } - if (updateTrace || updateAll) { + if (updateWindow || updateAll) { Debugger_RefreshRequested(firstTime); firstTime = false; if (activeWindow == WIN_TRACE) Debugger_UpdateTrace(); + else if (activeWindow == WIN_MEMDUMP) + Debugger_UpdateDump(updateAll); - updateTrace = false; + updateWindow = false; } if (updateAll) { Debugger_UpdateSidePanel(); @@ -547,76 +548,38 @@ void Shell_Debugger() updateAll = true; } else if (key == K_F3) { - if (activeWindow == WIN_TRACE) { + if (activeWindow == WIN_TRACE) activeWindow = WIN_MEMDUMP; - Debugger_Screen(); - updateAll = true; - } - else { + else dumpWindowAsciiMode = !dumpWindowAsciiMode; - Debugger_SwitchPanel(); - } + + Debugger_Screen(); + updateAll = true; } else if (key == K_TAB) { - activeRegPanel = !activeRegPanel; + if (activeWindow == WIN_MEMDUMP && !activeRegPanel && !dumpWindowAsciiMode && !dumpWindowRightPane) + dumpWindowRightPane = true; + else { + activeRegPanel = !activeRegPanel; + dumpWindowRightPane = false; + } + Debugger_SwitchPanel(); updateRegs = true; - updateTrace = true; + updateWindow = true; } - - else if ((ReadKeyFlags() & fKeyCtrl) != 0) { - switch (key) { - case 'h': - watcherMode = REG_HL; - updateAll = true; - break; - case 'H': - watcherMode = REG_HL_; - updateAll = true; - break; - case 'd': - watcherMode = REG_DE; - updateAll = true; - break; - case 'D': - watcherMode = REG_DE_; - updateAll = true; - break; - case 'b': - watcherMode = REG_BC; - updateAll = true; - break; - case 'B': - watcherMode = REG_BC_; - updateAll = true; - break; - case 'x': - watcherMode = REG_IX; - updateAll = true; - break; - case 'y': - watcherMode = REG_IY; - updateAll = true; - break; - case 'p': - watcherMode = 0; - updateAll = true; - break; - } + else if (key == K_ESC) { + DelayMs(100); + break; } - else if (activeRegPanel && Debugger_TestKeyRegs(key)) updateRegs = true; else if (Debugger_TestKeyTrace(key, &updateAll)) { if (key == K_F4 || key == K_F8) break; - updateTrace = true; - } - else if (key == K_ESC) { - DelayMs(100); - break; + updateWindow = true; } } diff --git a/arm/shell/debugger.dump.cpp b/arm/shell/debugger.dump.cpp new file mode 100644 index 0000000..9f00374 --- /dev/null +++ b/arm/shell/debugger.dump.cpp @@ -0,0 +1,240 @@ +#include "debugger.h" +#include "screen.h" +#include "dialog.h" +#include "../system.h" +#include "../specKeyboard.h" + +#define _W(x) ((x) & 0xFFFF) + +unsigned dumpTop = 0; +unsigned dumpPos = 0; +unsigned lastDumpTop = -1U; +unsigned lastDumpPos = -1U; + +bool dumpWindowAsciiMode = false; +bool dumpWindowRightPane = false; +bool lowNibble = false; + +extern byte activeWindow; +extern bool activeRegPanel; +extern byte watcherMode; +extern bool allowROMAccess; +//--------------------------------------------------------------------------------------- +void Debugger_UpdateDump(bool forceRedraw) +{ + if (lastDumpTop != dumpTop || forceRedraw) { + byte i, j, y, c; + word inc = dumpWindowAsciiMode ? 0x20 : 0x08; + word pc = _W(dumpTop & (-inc)); + + for (i = 0, y = WINDOW_OFF_Y; i < WINDOW_HEIGHT; i++, y++) { + DrawHexNum(0, y, pc, 4, 'A'); + + for (j = 0; j < inc; j++, pc++) { + c = ReadByteAtCursor(pc); + + if (dumpWindowAsciiMode) + DrawSaveChar(35 + (j * 6), y, c, false, (pc == _W(dumpPos))); + else { + DrawHexNum(35 + (j * 16), y, c, 2, 'A'); + DrawSaveChar(169 + (j * 8), y, c); + } + } + + if (dumpWindowAsciiMode) + DrawChar(227, y, ' '); + + DrawChar(238, y, '\x1C'); + DrawHexNum(244, y, (pc - 1) & 0xFF, 2, 'A'); + } + + lastDumpTop = dumpTop; + } + else if (dumpWindowAsciiMode) { + int offset = lastDumpPos - lastDumpTop; + byte x = offset % 0x20; + byte y = offset / 0x20; + byte c = ReadByteAtCursor(lastDumpPos); + + DrawSaveChar(35 + (x * 6), WINDOW_OFF_Y + y, c); + + offset = dumpPos - dumpTop; + x = offset % 0x20; + y = offset / 0x20; + c = ReadByteAtCursor(dumpPos); + + DrawSaveChar(35 + (x * 6), WINDOW_OFF_Y + y, c, false, true); + } + + lastDumpPos = dumpPos; + + Debugger_UpdateDumpAttrs(); +} +//--------------------------------------------------------------------------------------- +void Debugger_UpdateDumpAttrs() +{ + byte atr0 = activeRegPanel ? COL_NORMAL : COL_ACTIVE; + byte atr1 = atr0 & ~3; + + int offset = dumpPos - dumpTop; + byte offX = offset % 8; + byte offY = offset / 8; + + for (byte i = 0, y = WINDOW_OFF_Y; i < WINDOW_HEIGHT; i++, y++) { + if (dumpWindowAsciiMode) + DrawAttr8( 0, y, atr0, 29); + else { + DrawAttr8( 0, y, atr0, 21); + DrawAttr8(21, y, atr1 + 1, 8); + + if (!activeRegPanel && i == offY) { + if (dumpWindowRightPane) + DrawAttr8(21 + offX, y, COL_CURSOR); + else + DrawAttr8(4 + (offX << 1), y, COL_CURSOR, 2); + } + } + + DrawAttr8(29, y, atr1, 3); + } +} +//--------------------------------------------------------------------------------------- +bool Debugger_TestKeyDump(byte key, bool *updateAll) +{ + bool isDump = (activeWindow == WIN_MEMDUMP); + int reg = -1; + + if ((ReadKeyFlags() & fKeyCtrl) != 0) { + switch (key) { + case 'h': + reg = REG_HL; + break; + case 'H': + reg = REG_HL_; + break; + case 'd': + reg = REG_DE; + break; + case 'D': + reg = REG_DE_; + break; + case 'b': + reg = REG_BC; + break; + case 'B': + reg = REG_BC_; + break; + case 'x': + reg = REG_IX; + break; + case 'y': + reg = REG_IY; + break; + case 's': + if (!isDump) + break; + + reg = REG_SP; + break; + case 'p': + // PC or switch watcher to ports + reg = isDump ? REG_PC : 0; + break; + default: + reg = -1; + } + } + + if (isDump) { + unsigned inc = dumpWindowAsciiMode ? 0x20 : 0x08; + unsigned page = (WINDOW_HEIGHT * inc); + + unsigned top = (dumpTop < (0x10000 - page)) ? (dumpTop + 0x10000) : dumpTop; + unsigned pos = (dumpPos < (0x10000 - page)) ? (dumpPos + 0x10000) : dumpPos; + + if (reg > 0) + top = pos = GetCPUState(reg & 0xFF); + else if (key == K_UP) + pos -= inc; + else if (key == K_DOWN) + pos += inc; + else if (key == K_LEFT) + pos--; + else if (key == K_RIGHT) + pos++; + else if (key == K_PAGEUP) { + pos -= page; + top -= page; + } + else if (key == K_PAGEDOWN) { + pos += page; + top += page; + } + else if (key == K_HOME) + pos &= ~(inc - 1); + else if (key == K_END) + pos |= (inc - 1); + + else if (key >= ' ') { + if (dumpPos < 0x4000 && !allowROMAccess) { + allowROMAccess = Shell_MessageBox("ROM Access", + "You are about to modify contents", + "of (EP)ROM directly in SD-RAM.", + "You have been warned! Sure?", MB_YESNO); + + if (!allowROMAccess) + return true; + } + + if (dumpWindowAsciiMode || dumpWindowRightPane) { + WriteByteAtCursor(pos++, key); + *updateAll = true; + } + else { + if (key >= '0' && key <= '9') + key -= '0'; + else if (key >= 'A' && key <= 'F') + key -= ('A' - 10); + else if (key >= 'a' && key <= 'f') + key -= ('a' - 10); + else + return false; + + byte c = ReadByteAtCursor(pos); + if (lowNibble) + c = (c & 0xF0) | key; + else + c = (c & 0x0F) | (key << 4); + + WriteByteAtCursor(pos, c); + + if (lowNibble) { + *updateAll = true; + pos++; + } + else + return (*updateAll = lowNibble = true); + } + } + else + return false; + + while (pos < top) + top -= inc; + while ((pos - top) >= page) + top += inc; + + dumpPos = pos & 0xFFFF; + dumpTop = top & _W(-inc); + + lowNibble = false; + return true; + } + else if (reg >= 0) { + watcherMode = reg & 0xFF; + return (*updateAll = true); + } + + return false; +} +//--------------------------------------------------------------------------------------- diff --git a/arm/shell/debugger.h b/arm/shell/debugger.h index ba39672..dcfc9bc 100644 --- a/arm/shell/debugger.h +++ b/arm/shell/debugger.h @@ -14,6 +14,9 @@ #define COL_SIDE_HI 0141 #define COL_WTCHREG 0163 +#define WINDOW_OFF_Y 6 +#define WINDOW_HEIGHT (24 - WINDOW_OFF_Y) + #ifdef __cplusplus extern "C" { @@ -36,12 +39,14 @@ void Shell_Debugger(); byte ReadByteAtCursor(word addr); void WriteByteAtCursor(word addr, byte data); -bool IsRegPanel(); word GetCPUState(byte reg); void SetCPUState(byte reg, word value); void Debugger_UpdateTrace(); +void Debugger_UpdateDump(bool forceRedraw = false); +void Debugger_UpdateDumpAttrs(); bool Debugger_TestKeyTrace(byte key, bool *updateAll); +bool Debugger_TestKeyDump(byte key, bool *updateAll); void Debugger_RefreshRequested(bool firstTime = false); void Debugger_HandleBreakpoint(); void Debugger_Init(); diff --git a/speccy2010.hlp b/speccy2010.hlp index 18b8b74..c93e991 100644 --- a/speccy2010.hlp +++ b/speccy2010.hlp @@ -65,7 +65,7 @@ Arrows/PgUp/PgDown - move cursor Enter - modify value Quote - push cursor and goto inst.operand Backspace - pop cursor from jumpstack -Space - toggle breakpoint on current PC +Space - toggle breakpoint on cursor Home - move cursor to current PC F2 - trace window F3 - dump window / toggle hexdump/ASCII @@ -74,5 +74,6 @@ F7 - execute single step F8 - trace to next instruction G - push cursor and goto spec.address Z - set PC to current cursor position -Ctrl+H/D/B/X/Y/P - watch HL/DE/BC/IX/IY or ports Ctrl+Shift+H/D/B - watch HL`/DE`/BC` +Ctrl+H/D/B/X/Y/P + - watch HL/DE/BC/IX/IY/PC or ports