diff --git a/font.bmp b/font.bmp new file mode 100644 index 0000000..b68787a Binary files /dev/null and b/font.bmp differ 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); }