From dbff53cc2f9508a8696713b5fc91aa67f87c4e8a Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Thu, 11 Apr 2024 17:37:10 +0200 Subject: [PATCH] - Finestra del depurador amb SDL --- font.bmp | Bin 0 -> 30022 bytes main.cpp | 81 +++++-------------- z80.cpp | 9 ++- z80.h | 2 + z80debug.cpp | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++ z80debug.h | 7 ++ z80dis.cpp | 48 ++++++++---- z80dis.h | 4 +- 8 files changed, 287 insertions(+), 78 deletions(-) create mode 100644 font.bmp create mode 100644 z80debug.cpp create mode 100644 z80debug.h diff --git a/font.bmp b/font.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b68787a322d16888f864ba4b73bd4debcd53a401 GIT binary patch literal 30022 zcmeH}O>SgG5QH1CWXB0O25T0xgEMdm&OdZ?`_qKNnf3F!+aAfU#5gkJuWBBW;jh2H z{dc*YZ`YrHUjO`i{qxWD&o7rhF27#!a@BwT?fysW{d~V%?*C~0uJa}gVbwP*`C#$( zmwWs1!B@Y#&fk*rJ99xOQ_w#xmG8}c^l*7~9`$(s-dO*1UpMm}u=06(>S)e8m%X_w z2M0PwuWNAblb)yYIp_IRzVhY0)$X~}ciy2aUDcdi?s*q_qWjSNUbsX&iTEDntGv3a z<6i07K{R#{zQXk6u1s>iGlTAj1G#^+OVjDR@P3bTNBAm#f5rQs?&X~z8aoK@C{4#X z%_|%pkPh|^(|2_5az}Y`px)mdJVJRK(VS;?pL5RVoPD`>Jst1;?(x|@+?SmEIup5-m{ zg6?4+b*1J#KGT&Pdxx3Bmppr7=U?UN+x07#nTo>$&hA5Z^ei*zKF!IqcSt_<4! z){i{e-OCQTHuEdvhpaeeFgbQ`=0kV%tY#h8eNK(NL$awS&pyLh4>~>U;0~`0Cv&;4 z`p7vd%gzkKgUPd32&XJF*!96XD#L+i2jPWq!j5-s|`dx5frTJUj2VZgCgD>%DE_-}m?ZlVp zT|VQ3+u8Ag>R?W+H12e5#&zCj2)0C+*i$+We3TygEJl->~g7hzK&NO4V-nR-t9AfRmWH1>YMR_bg_f*iK%z{ zF0XsYfZWXv!h^}@-ud9cE{8tC%(8=I*}+vleY1VHf7j3bpyz$Abht#%`7B@VRaPF3 z>u^GN=bV@BTIVMNx{nSx-=FFCcY3eSyrJUI!1S<#_)Z*u0evsd*m+m+3e#V4={fiF z3!Goz`~si-1^o9Izqdf%#$I{dgI;lTNWS9|4ijtuA;Gl&OVs{Hy4${FsLTP?7+ue%~R7cLvp$S)bd2}j2Je|42XBHobFZYhe2hz_D zW*)x7^m{KEIJ}9KPn;hz&S`d@*)jc|kuUemveUy3c6s<+%wF>1HR~|r%^i>P&Uwx~ zK6m~{`ON3;Z*z?q#Fu;W=&RV}S9$rk%V+240$pPU@qmx=na`bjgs!d3nI$9Cp_7^2 zkq$gy@}7B?XVh8U59c{J-UKG!?eId+`s`ZrZH#(?`OV+ESGuT@m8H^Ge17Z zd<$CDb4xE7s3gX_dUJjDo=9k+yQocr>CD? zm>D?deV%1qrwcB7*uj|(9n9Q}M^DV2(T)bvrCo|qDf&wd26 zv+JmQ$<21U(_?K;fWyOP7d%BOF(cl}jPUJkl;=2szi zfVxMsAMO^1UZHbjMo3?JIzD}~T|GK8A9{Lo$2Y^B9A417;XrB3pmWTwiL1`cGt<3u z$LqP3`AGL_M!r1$CTZHiobjTA@FSdgXS#Rqcs;i=AL-u7;01Y;b`BgUo*Aq-v5IEp6V{R^lC>N;i`|0Rlj_B)FIB1UPnCcbI!fhJoCEFoJcP``zvtgj>-!M@z->Y}- vpWRdW;J{gj^vdg;&!fK1_bh&N_cOKbz0bVkqr39&l>0}&=e+Od{{sI5YrlF3 literal 0 HcmV?d00001 diff --git a/main.cpp b/main.cpp index 38e1fe3..dfc22b1 100644 --- a/main.cpp +++ b/main.cpp @@ -2,17 +2,13 @@ #include #include "z80.h" #include "z80dis.h" -#include +#include "z80debug.h" +#include #include uint8_t memory[65536]; uint32_t t = 0; -int w, h; -WINDOW *win_regs; -WINDOW *win_mem; -WINDOW *win_code; - int ula_in() { return 0; @@ -23,17 +19,6 @@ void ula_out(int val) } -void refresh_registers() -{ - mvwprintw(win_regs, 1, 2, "AF: %04X AF': %04X", z80::getAF(), z80::getAF(true)); - mvwprintw(win_regs, 2, 2, "BC: %04X BC': %04X", z80::getBC(), z80::getBC(true)); - mvwprintw(win_regs, 3, 2, "DE: %04X DE': %04X", z80::getDE(), z80::getDE(true)); - mvwprintw(win_regs, 4, 2, "HL: %04X HL': %04X", z80::getHL(), z80::getHL(true)); - mvwprintw(win_regs, 5, 2, "IX: %04X IY': %04X", z80::getIX(), z80::getIY()); - mvwprintw(win_regs, 6, 2, "SP: %04X PC': %04X", z80::getSP(), z80::getPC()); - wrefresh(win_regs); -} - int main(int argc, char *argv[]) { FILE* f = fopen("48.rom", "rb"); @@ -43,54 +28,28 @@ int main(int argc, char *argv[]) z80::reset(memory); z80::connect_port(0xfe, ula_in, ula_out); - initscr(); - start_color(); - init_pair(1, COLOR_WHITE, COLOR_BLACK); - init_pair(2, COLOR_YELLOW, COLOR_BLUE); - getmaxyx(stdscr, h, w); - - win_regs = newwin(10,23,0,0); - win_mem = newwin(10,w-23,0,23); - win_code = newwin(h-10,w,10,0); - refresh(); - - box(win_regs,0,0); - mvwprintw(win_regs, 0, 2, " REGISTERS: "); - refresh_registers(); - - box(win_mem,0,0); - mvwprintw(win_mem, 0, 2, " MEMORY: "); - mvwprintw(win_mem, 1, 2, "%ix%i", w, h); - wrefresh(win_mem); - - box(win_code,0,0); - //wattron(win_code, COLOR_PAIR(1)); - //mvwprintw(win_code, 1, 1, "Hello world %s !!!", "hola"); - //wattroff(win_code, COLOR_PAIR(1)); - wrefresh(win_code); + SDL_Init(SDL_INIT_EVERYTHING); + z80debug::show(); bool should_exit = false; - int linea=1; - char old_line[256]; - old_line[0]=0; - while(!should_exit) + SDL_Event e; + + while (!should_exit) { - uint16_t PC = z80::getPC(); - if (old_line[0]!=0) { - wattron(win_code, COLOR_PAIR(1)); - mvwprintw(win_code, linea-1, 1, old_line); - wattroff(win_code, COLOR_PAIR(1)); + while (SDL_PollEvent(&e)) + { + if (e.type == SDL_QUIT) { should_exit=true; break; } + if (e.type == SDL_KEYDOWN) { + if (e.key.keysym.scancode==SDL_SCANCODE_ESCAPE) { + should_exit=true; break; + } else if (e.key.keysym.scancode==SDL_SCANCODE_RETURN) { + //uint16_t PC = z80::getPC(); + //z80dis::getAsm(&memory[PC]); + t += z80::step(); + z80debug::refresh(); + } + } } - sprintf(old_line, "[%04x] ", PC); - strcat(old_line, z80dis::getAsm(&memory[PC])); - wattron(win_code, COLOR_PAIR(2)); - mvwprintw(win_code, linea, 1, old_line); - wattron(win_code, COLOR_PAIR(2)); - wrefresh(win_code); - linea++; - t += z80::step(); - refresh_registers(); - getch(); } return 0; diff --git a/z80.cpp b/z80.cpp index 8a311cb..81dd32b 100644 --- a/z80.cpp +++ b/z80.cpp @@ -211,13 +211,13 @@ namespace z80 void INC16(uint16_t *reg) { t+=2; - *reg++; + (*reg)++; } void DEC16(uint16_t *reg) { t+=2; - *reg--; + (*reg)--; } void ADD16(uint16_t* a, uint16_t b) @@ -891,7 +891,8 @@ namespace z80 void reset(uint8_t* mem) { memory = mem; - rPC = 0; + rPC = iff1 = iff2 = im = 0; + rAF = rAF2 = rBC = rBC2 = rDE = rDE2 = rHL = rHL2 = rIX = rIY = rSP = 0xffff; t = 0; for (int i=0; i<256; ++i) { @@ -2557,6 +2558,8 @@ namespace z80 } } + uint8_t *getMem() { return memory; } + uint16_t getAF(const bool alt) { return alt?rAF2:rAF; } uint16_t getBC(const bool alt) { return alt?rBC2:rBC; } uint16_t getDE(const bool alt) { return alt?rDE2:rDE; } diff --git a/z80.h b/z80.h index 2e9c71f..ddb311c 100644 --- a/z80.h +++ b/z80.h @@ -8,6 +8,8 @@ namespace z80 void connect_port(int num, int (*in_ptr)(), void (*out_ptr)(int)); uint32_t step(); + uint8_t *getMem(); + uint16_t getAF(const bool alt=false); uint16_t getBC(const bool alt=false); uint16_t getDE(const bool alt=false); diff --git a/z80debug.cpp b/z80debug.cpp new file mode 100644 index 0000000..38b35f1 --- /dev/null +++ b/z80debug.cpp @@ -0,0 +1,214 @@ +#include "z80debug.h" +#include +#include "z80.h" +#include "z80dis.h" + +namespace z80debug +{ + #define CHR_W 6 + #define CHR_H 13 + + #define COLOR_BLACK 0 + #define COLOR_DARK_BLUE 1 + #define COLOR_GREEN 2 + #define COLOR_TEAL 3 + #define COLOR_BROWN 4 + #define COLOR_PURPLE 5 + #define COLOR_ORANGE 6 + #define COLOR_GRAY 7 + #define COLOR_DARK 8 + #define COLOR_BLUE 9 + #define COLOR_LIME 10 + #define COLOR_CYAN 11 + #define COLOR_RED 12 + #define COLOR_MAGENTA 13 + #define COLOR_YELLOW 14 + #define COLOR_WHITE 15 + + uint8_t colors[16][3] = { + {0,0,0}, + {0,0,128}, + {0,128,0}, + {0,128,128}, + {128,0,0}, + {128,0,128}, + {255,128,0}, + {128,128,128}, + {30,30,30}, + {0,0,255}, + {0,255,0}, + {0,255,255}, + {255,0,0}, + {255,0,255}, + {255,255,0}, + {255,255,255}, + }; + + uint8_t offset_x = 0; + uint8_t offset_y = 0; + + SDL_Window *win = nullptr; + SDL_Renderer *ren = nullptr; + SDL_Texture *tex = nullptr; + + uint16_t mem_viewer_pos = 0; + + char temp[256]; + const char *tohex(int value, int numdigits) + { + if (numdigits==2) sprintf(temp, "%02X", value); + else if (numdigits==4) sprintf(temp, "%04X", value); + return temp; + } + + void show() + { + if (win) return; + win = SDL_CreateWindow("Z80 Debugger", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 71*CHR_W, 28*CHR_H, SDL_WINDOW_SHOWN); + ren = SDL_CreateRenderer(win, -1, 0); + tex = SDL_CreateTextureFromSurface(ren, SDL_LoadBMP("font.bmp")); + SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND); + + z80debug::refresh(); + } + + void box(int x, int y, int w, int h, uint8_t color) + { + SDL_Rect rect {((offset_x+x)*CHR_W)+3, ((offset_y+y)*CHR_H)+6, w*CHR_W-6, h*CHR_H-13}; + SDL_SetRenderDrawColor(ren, colors[color][0], colors[color][1], colors[color][2], 255); + SDL_RenderDrawRect(ren, &rect); + } + + void printrect(int x, int y, int w, int h, uint8_t color) + { + SDL_Rect rect {(offset_x+x)*CHR_W, (offset_y+y)*CHR_H, w*CHR_W, h*CHR_H}; + SDL_SetRenderDrawColor(ren, colors[color][0], colors[color][1], colors[color][2], 255); + SDL_RenderFillRect(ren, &rect); + } + + void printchar(int x, int y, char chr, uint8_t color=255) + { + if (color != 255) SDL_SetRenderDrawColor(ren, colors[color][0], colors[color][1], colors[color][2], 255); + if (chr==32) return; + if (chr<32 || chr>127) chr = '.'; + SDL_Rect src {((chr-32)&0xf)*CHR_W, ((chr-32)>>4)*CHR_H, CHR_W, CHR_H}; + SDL_Rect dst {(offset_x+x)*CHR_W, (offset_y+y)*CHR_H, CHR_W, CHR_H}; + SDL_RenderCopy(ren, tex, &src, &dst); + } + + void printtxt(int x, int y, const char *text, uint8_t color) + { + SDL_SetTextureColorMod(tex, colors[color][0], colors[color][1], colors[color][2]); + for (int i=0; i=0;--i) { + pos = find_previous_opcode(pos); + printtxt(1,i,tohex(pos,4), COLOR_CYAN); + printtxt(7,i, z80dis::getOpcode(&memory[pos]), COLOR_GRAY); + printtxt(19,i, z80dis::getAsm(&memory[pos]), COLOR_WHITE); + } + //for (int i=0;i<20;++i) printtxt(1,i,tohex(pc,4), COLOR_CYAN); + + offset_x = offset_y = 0; + box(46,0,25,8,COLOR_WHITE); + printrect(48,0, 12,1, COLOR_DARK); + printtxt(49,0, "REGISTERS:", COLOR_WHITE); + + offset_x=47; + offset_y=1; + printtxt(0,0, "AF AF' IX ", COLOR_WHITE); + printtxt(0,1, "BC BC' IY ", COLOR_WHITE); + printtxt(0,2, "DE DE' SP ", COLOR_WHITE); + printtxt(0,3, "HL HL' PC ", COLOR_WHITE); + printtxt(0,5, "(BC) (DE) (HL) ", COLOR_WHITE); + + printtxt(3,0, tohex(z80::getAF(), 4), COLOR_GRAY); + printtxt(11,0, tohex(z80::getAF(true), 4), COLOR_GRAY); + printtxt(19,0, tohex(z80::getIX(), 4), COLOR_GRAY); + printtxt(3,1, tohex(z80::getBC(), 4), COLOR_GRAY); + printtxt(11,1, tohex(z80::getBC(true), 4), COLOR_GRAY); + printtxt(19,1, tohex(z80::getIY(), 4), COLOR_GRAY); + printtxt(3,2, tohex(z80::getDE(), 4), COLOR_GRAY); + printtxt(11,2, tohex(z80::getDE(true), 4), COLOR_GRAY); + printtxt(19,2, tohex(z80::getSP(), 4), COLOR_GRAY); + printtxt(3,3, tohex(z80::getHL(), 4), COLOR_GRAY); + printtxt(11,3, tohex(z80::getHL(true), 4), COLOR_GRAY); + printtxt(19,3, tohex(z80::getPC(), 4), COLOR_GRAY); + + printtxt(5,5, tohex(memory[z80::getBC()], 2), COLOR_GRAY); + printtxt(13,5, tohex(memory[z80::getDE()], 2), COLOR_GRAY); + printtxt(21,5, tohex(memory[z80::getHL()], 2), COLOR_GRAY); + + offset_x=offset_y=0; + box(0,20,71,8,COLOR_WHITE); + printrect(2,20, 9,1, COLOR_DARK); + printtxt(3,20, "MEMORY:", COLOR_WHITE); + + offset_x=1; offset_y=21; + + uint16_t mem_viewer_cursor = mem_viewer_pos; + for (int i=0; i<6; ++i) { + printtxt(0,i, tohex(mem_viewer_cursor, 4), COLOR_CYAN); + for (int j=0; j<16; ++j) { + printtxt(5+j*3, i, tohex(memory[mem_viewer_cursor++],2), COLOR_WHITE); + printchar(53+j, i, memory[mem_viewer_cursor++], COLOR_GRAY); + } + //printtxt(5,0, "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", COLOR_WHITE); + //printtxt(53,0, "0123456789AB\tDEF", COLOR_GRAY); + } + + SDL_RenderPresent(ren); + } +} \ No newline at end of file diff --git a/z80debug.h b/z80debug.h new file mode 100644 index 0000000..726dd9c --- /dev/null +++ b/z80debug.h @@ -0,0 +1,7 @@ +#pragma once + +namespace z80debug +{ + void show(); + void refresh(); +} \ No newline at end of file diff --git a/z80dis.cpp b/z80dis.cpp index 0ed5e1d..0e914ac 100644 --- a/z80dis.cpp +++ b/z80dis.cpp @@ -69,36 +69,58 @@ namespace z80dis } } - const char *getAsm(const uint8_t *memory, const bool include_opcode) + const char *getAsm(const uint8_t *memory) { opcode_size = 0; - buffer[0]=0; - char txt[20]; const char *base = getBase(memory); if (strstr(base, "4x")) { opcode_size+=2; - printOpcode(memory); const uint16_t word = *(uint16_t*)(memory+1); - sprintf(txt, base, word); + sprintf(buffer, base, word); } else if (strstr(base, "2x")) { opcode_size+=1; - printOpcode(memory); - sprintf(txt, base, *(memory+1)); + sprintf(buffer, base, *(memory+1)); } else if (strstr(base, "hhd")) { opcode_size+=1; - printOpcode(memory); if (opcode_size>4) { opcode_size=4; - sprintf(txt, base, (int8_t)*(memory+2)); + sprintf(buffer, base, (int8_t)*(memory+2)); } else { - sprintf(txt, base, (int8_t)*(memory+1)); + sprintf(buffer, base, (int8_t)*(memory+1)); } } else { - printOpcode(memory); - sprintf(txt, base); + sprintf(buffer, base); } - strcat(buffer, txt); return buffer; } + + const char *getOpcode(const uint8_t *memory) + { + opcode_size = 0; + buffer[0]=0; + const char *base = getBase(memory); + + if (strstr(base, "4x")) { + opcode_size+=2; + } else if (strstr(base, "2x") || strstr(base, "hhd")) { + opcode_size+=1; + } + printOpcode(memory); + return buffer; + } + + const int getOpcodeSize(const uint8_t *memory) + { + opcode_size = 0; + const char *base = getBase(memory); + + if (strstr(base, "4x")) { + opcode_size+=2; + } else if (strstr(base, "2x") || strstr(base, "hhd")) { + opcode_size+=1; + } + return opcode_size; + } + } diff --git a/z80dis.h b/z80dis.h index 2bc4ee0..f0dd9e0 100644 --- a/z80dis.h +++ b/z80dis.h @@ -4,5 +4,7 @@ namespace z80dis { - const char *getAsm(const uint8_t *memory, const bool include_opcode=true); + const char *getAsm(const uint8_t *memory); + const char *getOpcode(const uint8_t *memory); + const int getOpcodeSize(const uint8_t *memory); }