diff --git a/boom.sav b/boom.sav new file mode 100644 index 0000000..6600edf Binary files /dev/null and b/boom.sav differ diff --git a/main.cpp b/main.cpp index 9871456..123d9da 100644 --- a/main.cpp +++ b/main.cpp @@ -11,6 +11,7 @@ #include "ui.h" #include "ui_menu.h" #include "z80analyze.h" +#include "ui_window.h" uint8_t memory[65536]; uint32_t time = 0; @@ -68,6 +69,7 @@ int main(int argc, char *argv[]) fread(memory, 1024, 16, f); fclose(f); + z80dis::loadSymbols(); z80::reset(memory); z80::connect_port(0xfe, zx_ula::port_in, zx_ula::port_out); @@ -114,108 +116,20 @@ int main(int argc, char *argv[]) { while (SDL_PollEvent(&e)) { + bool result = true; + if (e.type == SDL_QUIT) { should_exit=true; break; } + if (e.type == SDL_MOUSEBUTTONUP) result = ui::window::sendEvent(e.button.windowID, &e); + if (e.type == SDL_MOUSEMOTION) result = ui::window::sendEvent(e.motion.windowID, &e); + if (e.type == SDL_WINDOWEVENT) result = ui::window::sendEvent(e.window.windowID, &e); + if (e.type == SDL_MOUSEWHEEL) result = ui::window::sendEvent(e.wheel.windowID, &e); + if (e.type == SDL_KEYDOWN) result = ui::window::sendEvent(e.key.windowID, &e); + if (e.type == SDL_TEXTINPUT) result = ui::window::sendEvent(e.text.windowID, &e); + if (e.type == SDL_MOUSEBUTTONUP && e.button.button==1) ui::setClicked(true); - if ((e.type==SDL_WINDOWEVENT) && (e.window.event==SDL_WINDOWEVENT_CLOSE)) { - should_exit=true; break; - } - if (z80debug::debugging()) { - if ((e.type==SDL_WINDOWEVENT) && ((e.window.event==SDL_WINDOWEVENT_SHOWN) || (e.window.event==SDL_WINDOWEVENT_EXPOSED))) { - z80debug::refresh(); - zxscreen::redraw(); - } - if (e.type == SDL_MOUSEWHEEL) { - if (e.wheel.mouseX<46*CHR_W && e.wheel.mouseY<20*CHR_H) { - if (e.wheel.y>0) { - z80debug::cursorback(); - z80debug::refresh(); - } else if (e.wheel.y<0) { - z80debug::cursorfwd(); - z80debug::refresh(); - } - } - } - 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_F10) { - z80debug::history::gototop(); - const uint8_t dt = z80::step(); - z80debug::refresh(); - zxscreen::refresh(dt); - zxscreen::redraw(); - } else if (e.key.keysym.scancode==SDL_SCANCODE_F11) { - z80debug::history::gototop(); - const uint8_t dt = z80debug::next(); - zxscreen::refresh(dt); - zxscreen::redraw(); - } else if (e.key.keysym.scancode==SDL_SCANCODE_F1) { - z80debug::history::gototop(); - z80debug::refresh(); - } else if (e.key.keysym.scancode==SDL_SCANCODE_F2) { - z80debug::history::goback(); - z80debug::refresh(); - } else if (e.key.keysym.scancode==SDL_SCANCODE_F3) { - z80debug::history::goforward(); - z80debug::refresh(); - } else if (e.key.keysym.scancode==SDL_SCANCODE_F5) { - z80debug::history::gototop(); - const uint8_t dt = z80::step(); - z80debug::cont(); - zxscreen::refresh(dt); - /*} else if (e.key.keysym.scancode==SDL_SCANCODE_F6) { - z80debug::history::gototop(); - const uint8_t dt = z80::step(); - z80debug::refresh(); - zxscreen::refresh(dt);*/ - } else if (e.key.keysym.scancode==SDL_SCANCODE_UP) { - z80debug::cursorback(); - z80debug::refresh(); - } else if (e.key.keysym.scancode==SDL_SCANCODE_DOWN) { - z80debug::cursorfwd(); - z80debug::refresh(); - } else if (e.key.keysym.scancode==SDL_SCANCODE_RETURN) { - z80debug::executeConsole(); - } else if (e.key.keysym.scancode==SDL_SCANCODE_BACKSPACE) { - z80debug::DeleteCharConsole(); - } - } - if (e.type == SDL_TEXTINPUT) { - z80debug::sendToConsole(e.text.text); - } - - } else if (z80debug::paused()) { - if (e.type == SDL_KEYDOWN) { - if (e.key.keysym.scancode==SDL_SCANCODE_ESCAPE) { - const uint8_t dt = z80::step(); - z80debug::cont(); - zxscreen::refresh(dt); - } - } - - } else { - if (e.type == SDL_KEYDOWN) { - if (e.key.keysym.scancode==SDL_SCANCODE_ESCAPE) { - z80debug::pause(); - ui::setrenderer(zxscreen::getrenderer()); - zxscreen::redraw(); - } else if (e.key.keysym.scancode==SDL_SCANCODE_F1) { - zxscreen::decZoom(); - } else if (e.key.keysym.scancode==SDL_SCANCODE_F2) { - zxscreen::incZoom(); - } else if (e.key.keysym.scancode==SDL_SCANCODE_F3) { - zxscreen::toggleFullscreen(); - } else if (e.key.keysym.scancode==SDL_SCANCODE_F8) { - z80debug::stop(); - zxscreen::redraw(); - } else if (e.key.keysym.scancode==SDL_SCANCODE_F12) { - zx_tape::play(); - } else if (e.key.keysym.scancode==SDL_SCANCODE_F11) { - zx_tape::rewind(); - } - } - } + if (!result) + should_exit = true; break; } if (!z80debug::debugging() && !z80debug::paused()) { @@ -261,6 +175,7 @@ int main(int argc, char *argv[]) while (SDL_GetTicks() + +namespace ui +{ + namespace window + { + struct window_t + { + Uint32 window; + bool (*callback)(SDL_Event*); + }; + std::vector windows; + + void registerWindow(Uint32 window, bool(*callback)(SDL_Event*)) + { + for (auto win : windows) if (win.window == window) return; + windows.push_back((window_t){window, callback}); + } + + void unregisterWindow(Uint32 window) + { + for (auto win = windows.begin(); win != windows.end(); win++) if ((*win).window == window) { windows.erase(win); return; } + } + + bool sendEvent(Uint32 window, SDL_Event *e) + { + for (auto win : windows) if (win.window == window) return win.callback(e); + return true; + } + + } +} diff --git a/ui_window.h b/ui_window.h new file mode 100644 index 0000000..1ff0983 --- /dev/null +++ b/ui_window.h @@ -0,0 +1,12 @@ +#pragma once +#include + +namespace ui +{ + namespace window + { + void registerWindow(Uint32 window, bool(*callback)(SDL_Event *e)); + void unregisterWindow(Uint32 window); + bool sendEvent(Uint32 window, SDL_Event *e); + } +} diff --git a/z80.cpp b/z80.cpp index e286f1a..1c860ad 100644 --- a/z80.cpp +++ b/z80.cpp @@ -7,6 +7,7 @@ namespace z80 { static uint8_t *memory = nullptr; static uint8_t memtag[65536]; + static uint8_t memtouched[65536]; static uint32_t t = 0; static uint16_t current_opcode_address = 0; bool options[Z80_NUM_OPTIONS] = { true }; @@ -1071,6 +1072,7 @@ namespace z80 t = 0; const uint8_t opcode = READ_M1(); memtag[current_opcode_address] = MEMTAG_INST; + memtouched[current_opcode_address] = MEMTAG_INST; uint16_t tmp; switch (opcode) @@ -2738,6 +2740,18 @@ namespace z80 uint8_t getMemTag(const uint16_t addr) { return memtag[addr]; }; + void clearMemTag() + { + for (int i=0; i<65536; ++i) memtag[i] = MEMTAG_NONE; + } + + uint8_t getMemTouched(const uint16_t addr) { return memtouched[addr]; } + + void clearMemTouched() + { + for (int i=0; i<65536; ++i) memtouched[i] = MEMTAG_NONE; + } + const bool getOption(const int option) { return options[option]; diff --git a/z80.h b/z80.h index 7920c39..053128e 100644 --- a/z80.h +++ b/z80.h @@ -37,6 +37,10 @@ namespace z80 void setPC(const uint16_t addr); uint8_t getMemTag(const uint16_t addr); + void clearMemTag(); + + uint8_t getMemTouched(const uint16_t addr); + void clearMemTouched(); const bool getOption(const int option); void setOption(const int option, const bool value); diff --git a/z80analyze.cpp b/z80analyze.cpp index 996531b..43b8e18 100644 --- a/z80analyze.cpp +++ b/z80analyze.cpp @@ -1,6 +1,7 @@ #include "z80analyze.h" #include "z80.h" #include +#include "ui_window.h" namespace z80analyze { @@ -8,34 +9,64 @@ namespace z80analyze SDL_Renderer *ren = nullptr; SDL_Texture *tex = nullptr; + void refreshTitle(); + + bool handleEvent(SDL_Event *e) + { + if (e->type == SDL_MOUSEBUTTONUP) + { + z80::clearMemTouched(); + refresh(); + } + if (e->type == SDL_MOUSEMOTION) + { + refreshTitle(); + } + return true; + } + void show() { if (!win) { - win = SDL_CreateWindow("Z80 Analyzer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 256, 256, SDL_WINDOW_SHOWN); + win = SDL_CreateWindow("Z80 Analyzer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 512, 512, SDL_WINDOW_SHOWN); ren = SDL_CreateRenderer(win, -1, 0); tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 256, 256); + ui::window::registerWindow(SDL_GetWindowID(win), handleEvent); } refresh(); } + char tmp[10]; + void refreshTitle() + { + int mx, my; + SDL_GetMouseState(&mx, &my); + mx/=2; my/=2; + SDL_SetWindowTitle(win, SDL_itoa(mx+my*256, tmp, 16)); + } void refresh() { + if (!win) return; + Uint32 *pixels; int pitch; SDL_LockTexture(tex, NULL, (void**)&pixels, &pitch); for (int i=0; i<65536; ++i) { - uint8_t tag = z80::getMemTag(i); + uint8_t tag = z80::getMemTouched(i); pixels[i] = tag==MEMTAG_NONE ? 0x808080 : tag==MEMTAG_DATA ? 0x0000FF : 0x00FF00; } + pixels[z80::getPC()] = 0xFF0000; SDL_UnlockTexture(tex); SDL_RenderCopy(ren, tex, NULL, NULL); SDL_RenderPresent(ren); + refreshTitle(); } void hide() { + ui::window::unregisterWindow(SDL_GetWindowID(win)); SDL_DestroyTexture(tex); SDL_DestroyRenderer(ren); SDL_DestroyWindow(win); diff --git a/z80debug.cpp b/z80debug.cpp index ec65fb5..e308917 100644 --- a/z80debug.cpp +++ b/z80debug.cpp @@ -5,6 +5,10 @@ #include "zx_ula.h" #include "zx_tape.h" #include "ui.h" +#include "ui_window.h" +#include "zx_screen.h" +#include "z80analyze.h" + namespace z80debug { namespace history @@ -40,6 +44,85 @@ namespace z80debug return temp; } + bool eventHandler(SDL_Event *e) + { + if (z80debug::debugging()) { + if (e->type==SDL_WINDOWEVENT) { + if ((e->window.event==SDL_WINDOWEVENT_SHOWN) || (e->window.event==SDL_WINDOWEVENT_EXPOSED)) { + z80debug::refresh(); + zxscreen::redraw(); + } else if (e->window.event == SDL_WINDOWEVENT_CLOSE) { + z80debug::history::gototop(); + const uint8_t dt = z80::step(); + z80debug::cont(); + zxscreen::refresh(dt); + } + } + if (e->type == SDL_MOUSEWHEEL) { + if (e->wheel.mouseX<46*CHR_W && e->wheel.mouseY<20*CHR_H) { + if (e->wheel.y>0) { + z80debug::cursorback(); + z80debug::refresh(); + } else if (e->wheel.y<0) { + z80debug::cursorfwd(); + z80debug::refresh(); + } + } + } + if (e->type == SDL_KEYDOWN) { + if (e->key.keysym.scancode==SDL_SCANCODE_ESCAPE) { + return false; + } else if (e->key.keysym.scancode==SDL_SCANCODE_F10) { + z80debug::history::gototop(); + const uint8_t dt = z80::step(); + z80debug::refresh(); + zxscreen::refresh(dt); + zxscreen::redraw(); + z80analyze::refresh(); + } else if (e->key.keysym.scancode==SDL_SCANCODE_F11) { + z80debug::history::gototop(); + const uint8_t dt = z80debug::next(); + zxscreen::refresh(dt); + zxscreen::redraw(); + z80analyze::refresh(); + } else if (e->key.keysym.scancode==SDL_SCANCODE_F1) { + z80debug::history::gototop(); + z80debug::refresh(); + } else if (e->key.keysym.scancode==SDL_SCANCODE_F2) { + z80debug::history::goback(); + z80debug::refresh(); + } else if (e->key.keysym.scancode==SDL_SCANCODE_F3) { + z80debug::history::goforward(); + z80debug::refresh(); + } else if (e->key.keysym.scancode==SDL_SCANCODE_F5) { + z80debug::history::gototop(); + const uint8_t dt = z80::step(); + z80debug::cont(); + zxscreen::refresh(dt); + /*} else if (e->key.keysym.scancode==SDL_SCANCODE_F6) { + z80debug::history::gototop(); + const uint8_t dt = z80::step(); + z80debug::refresh(); + zxscreen::refresh(dt);*/ + } else if (e->key.keysym.scancode==SDL_SCANCODE_UP) { + z80debug::cursorback(); + z80debug::refresh(); + } else if (e->key.keysym.scancode==SDL_SCANCODE_DOWN) { + z80debug::cursorfwd(); + z80debug::refresh(); + } else if (e->key.keysym.scancode==SDL_SCANCODE_RETURN) { + z80debug::executeConsole(); + } else if (e->key.keysym.scancode==SDL_SCANCODE_BACKSPACE) { + z80debug::DeleteCharConsole(); + } + } + if (e->type == SDL_TEXTINPUT) { + z80debug::sendToConsole(e->text.text); + } + } + return true; + } + void processCommand(); void init() @@ -54,12 +137,14 @@ namespace z80debug if (win) return; win = SDL_CreateWindow("Z80 Debugger", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 71*CHR_W, 34*CHR_H, SDL_WINDOW_RESIZABLE); ren = SDL_CreateRenderer(win, -1, 0); + ui::window::registerWindow(SDL_GetWindowID(win), eventHandler); z80debug::refresh(); } void hide() { + ui::window::unregisterWindow(SDL_GetWindowID(win)); if (ren) SDL_DestroyRenderer(ren); if (win) SDL_DestroyWindow(win); ren = NULL; @@ -140,6 +225,8 @@ namespace z80debug SDL_SetRenderDrawColor(ren, 30, 30, 30, 255); SDL_RenderClear(ren); + // DISSASSEBLY + // ****************************************** ui::setoffset(0, 0); ui::box(0,0,46,20,COLOR_WHITE); @@ -166,6 +253,9 @@ namespace z80debug printDissasemblerLine(pos, i); } + // REGISTERS + // ****************************************** + ui::setoffset(0, 0); ui::box(46,0,25,8,COLOR_WHITE); ui::printrect(48,0, 12,1, COLOR_DARK); @@ -210,6 +300,10 @@ namespace z80debug ui::printtxt(6,5,"N", flags&0x02 ? (mod_flags&0x02 ? COLOR_RED : COLOR_WHITE) : (mod_flags&0x02 ? COLOR_BROWN : COLOR_GRAY) ); ui::printtxt(7,5,"C", flags&0x01 ? (mod_flags&0x01 ? COLOR_RED : COLOR_WHITE) : (mod_flags&0x01 ? COLOR_BROWN : COLOR_GRAY) ); + + // STACK + // ****************************************** + ui::setoffset(0, 0); ui::box(46,8,11,12,COLOR_WHITE); ui::printrect(48,8, 8,1, COLOR_DARK); @@ -227,6 +321,10 @@ namespace z80debug sp+=2; } + + // BREAKPOINTS + // ****************************************** + ui::setoffset(0, 0); ui::box(57,8,14,12,COLOR_WHITE); ui::printrect(59,8, 9,1, COLOR_DARK); @@ -245,6 +343,10 @@ namespace z80debug } } + + // MEMORY + // ****************************************** + ui::setoffset(0, 0); ui::box(0,20,71,8,COLOR_WHITE); ui::printrect(2,20, 9,1, COLOR_DARK); @@ -264,6 +366,10 @@ namespace z80debug //printtxt(53,0, "0123456789AB\tDEF", COLOR_GRAY); } + + // CONSOLE + // ****************************************** + ui::setoffset(0, 0); ui::box(0,28,71,6,COLOR_WHITE); ui::printrect(2,28, 10,1, COLOR_DARK); @@ -355,7 +461,9 @@ namespace z80debug z80::step(); z80debug::cont(); } else if (strcmp(cmd, "r")==0 || strcmp(cmd, "reset")==0) { - z80::reset(z80::getMem()); + uint8_t *mem = z80::getMem(); + for (int i=0; i<65536; ++i) mem[i]=0; + z80::reset(mem); z80::connect_port(0xfe, zx_ula::port_in, zx_ula::port_out); //for (int i=0; i<65536; ++i) breakpoints[i]=0; z80debug::refresh(); diff --git a/z80dis.cpp b/z80dis.cpp index fd40232..6b69bdb 100644 --- a/z80dis.cpp +++ b/z80dis.cpp @@ -7,6 +7,8 @@ namespace z80dis { char buffer[256]; int opcode_size = 0; + char symbols[65536][15]; + // $%04x // $%02x // %hhd @@ -35,6 +37,20 @@ namespace z80dis // const char *iy_opcodes[256] = {"", "", "", "", "inc b", "dec b", "ld b,N", "", "", "add iy,bc", "", "", "inc c", "dec c", "ld c,N", "", "", "", "", "", "inc d", "dec d", "ld d,N", "", "", "add iy,de", "", "", "inc e", "dec e", "ld e,N", "", "", "ld iy,NN", "ld (NN),iy", "inc iy", "inc iyh", "dec iyh", "ld iyh,N", "", "", "add iy,iy", "ld iy,(NN)", "dec iy", "inc iyl", "dec iyl", "ld iyl,N", "", "", "", "", "", "inc (iy+D)", "dec (iy+D)", "ld (iy+D),N", "", "", "add iy,sp", "", "", "inc a", "dec a", "ld a,N", "", "ld b,b", "ld b,c", "ld b,d", "ld b,e", "ld b,iyh", "ld b,iyl", "ld b,(iy+D)", "ld b,a", "ld c,b", "ld c,c", "ld c,d", "ld c,e", "ld c,iyh", "ld c,iyl", "ld c,(iy+D)", "ld c,a", "ld d,b", "ld d,c", "ld d,d", "ld d,e", "ld d,iyh", "ld d,iyl", "ld d,(iy+D)", "ld d,a", "ld e,b", "ld e,c", "ld e,d", "ld e,e", "ld e,iyh", "ld e,iyl", "ld e,(iy+D)", "ld e,a", "ld iyh,b", "ld iyh,c", "ld iyh,d", "ld iyh,e", "ld iyh,iyh", "ld iyh,iyl", "ld h,(iy+D)", "ld iyh,a", "ld iyl,b", "ld iyl,c", "ld iyl,d", "ld iyl,e", "ld iyl,iyh", "ld iyl,iyl", "ld l,(iy+D)", "ld iyl,a", "ld (iy+D),b", "ld (iy+D),c", "ld (iy+D),d", "ld (iy+D),e", "ld (iy+D),h", "ld (iy+D),l", "", "ld (iy+D),a", "ld a,b", "ld a,c", "ld a,d", "ld a,e", "ld a,iyh", "ld a,iyl", "ld a,(iy+D)", "ld a,a", "add a,b", "add a,c", "add a,d", "add a,e", "add a,iyh", "add a,iyl", "add a,(iy+D)", "add a,a", "adc a,b", "adc a,c", "adc a,d", "adc a,e", "adc a,iyh", "adc a,iyl", "adc a,(iy+D)", "adc a,a", "sub b", "sub c", "sub d", "sub e", "sub iyh", "sub iyl", "sub (iy+D)", "sub a", "sbc a,b", "sbc a,c", "sbc a,d", "sbc a,e", "sbc a,iyh", "sbc a,iyl", "sbc a,(iy+D)", "sbc a,a", "and b", "and c", "and d", "and e", "and iyh", "and iyl", "and (iy+D)", "and a", "xor b", "xor c", "xor d", "xor e", "xor iyh", "xor iyl", "xor (iy+D)", "xor a", "or b", "or c", "or d", "or e", "or iyh", "or iyl", "or (iy+D)", "or a", "cp b", "cp c", "cp d", "cp e", "cp iyh", "cp iyl", "cp (iy+D)", "cp a", "", "", "", "", "", "", "", "", "", "", "", "_IY Bit_", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "pop iy", "", "ex (sp),iy", "", "push iy", "", "", "", "jp (iy)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "ld sp,iy", "", "", "", "", "", ""}; // const char *iy_bit_opcodes[256] = {"rlc (iy+D),b", "rlc (iy+D),c", "rlc (iy+D),d", "rlc (iy+D),e", "rlc (iy+D),h", "rlc (iy+D),l", "rlc (iy+D)", "rlc (iy+D),a", "rrc (iy+D),b", "rrc (iy+D),c", "rrc (iy+D),d", "rrc (iy+D),e", "rrc (iy+D),h", "rrc (iy+D),l", "rrc (iy+D)", "rrc (iy+D),a", "rl (iy+D),b", "rl (iy+D),c", "rl (iy+D),d", "rl (iy+D),e", "rl (iy+D),h", "rl (iy+D),l", "rl (iy+D)", "rl (iy+D),a", "rr (iy+D),b", "rr (iy+D),c", "rr (iy+D),d", "rr (iy+D),e", "rr (iy+D),h", "rr (iy+D),l", "rr (iy+D)", "rr (iy+D),a", "sla (iy+D),b", "sla (iy+D),c", "sla (iy+D),d", "sla (iy+D),e", "sla (iy+D),h", "sla (iy+D),l", "sla (iy+D)", "sla (iy+D),a", "sra (iy+D),b", "sra (iy+D),c", "sra (iy+D),d", "sra (iy+D),e", "sra (iy+D),h", "sra (iy+D),l", "sra (iy+D)", "sra (iy+D),a", "sll (iy+D),b", "sll (iy+D),c", "sll (iy+D),d", "sll (iy+D),e", "sll (iy+D),h", "sll (iy+D),l", "sll (iy+D)", "sll (iy+D),a", "srl (iy+D),b", "srl (iy+D),c", "srl (iy+D),d", "srl (iy+D),e", "srl (iy+D),h", "srl (iy+D),l", "srl (iy+D)", "srl (iy+D),a", "bit 0,(iy+D)", "bit 0,(iy+D)", "bit 0,(iy+D)", "bit 0,(iy+D)", "bit 0,(iy+D)", "bit 0,(iy+D)", "bit 0,(iy+D)", "bit 0,(iy+D)", "bit 1,(iy+D)", "bit 1,(iy+D)", "bit 1,(iy+D)", "bit 1,(iy+D)", "bit 1,(iy+D)", "bit 1,(iy+D)", "bit 1,(iy+D)", "bit 1,(iy+D)", "bit 2,(iy+D)", "bit 2,(iy+D)", "bit 2,(iy+D)", "bit 2,(iy+D)", "bit 2,(iy+D)", "bit 2,(iy+D)", "bit 2,(iy+D)", "bit 2,(iy+D)", "bit 3,(iy+D)", "bit 3,(iy+D)", "bit 3,(iy+D)", "bit 3,(iy+D)", "bit 3,(iy+D)", "bit 3,(iy+D)", "bit 3,(iy+D)", "bit 3,(iy+D)", "bit 4,(iy+D)", "bit 4,(iy+D)", "bit 4,(iy+D)", "bit 4,(iy+D)", "bit 4,(iy+D)", "bit 4,(iy+D)", "bit 4,(iy+D)", "bit 4,(iy+D)", "bit 5,(iy+D)", "bit 5,(iy+D)", "bit 5,(iy+D)", "bit 5,(iy+D)", "bit 5,(iy+D)", "bit 5,(iy+D)", "bit 5,(iy+D)", "bit 5,(iy+D)", "bit 6,(iy+D)", "bit 6,(iy+D)", "bit 6,(iy+D)", "bit 6,(iy+D)", "bit 6,(iy+D)", "bit 6,(iy+D)", "bit 6,(iy+D)", "bit 6,(iy+D)", "bit 7,(iy+D)", "bit 7,(iy+D)", "bit 7,(iy+D)", "bit 7,(iy+D)", "bit 7,(iy+D)", "bit 7,(iy+D)", "bit 7,(iy+D)", "bit 7,(iy+D)", "res 0,(iy+D),b", "res 0,(iy+D),c", "res 0,(iy+D),d", "res 0,(iy+D),e", "res 0,(iy+D),h", "res 0,(iy+D),l", "res 0,(iy+D)", "res 0,(iy+D),a", "res 1,(iy+D),b", "res 1,(iy+D),c", "res 1,(iy+D),d", "res 1,(iy+D),e", "res 1,(iy+D),h", "res 1,(iy+D),l", "res 1,(iy+D)", "res 1,(iy+D),a", "res 2,(iy+D),b", "res 2,(iy+D),c", "res 2,(iy+D),d", "res 2,(iy+D),e", "res 2,(iy+D),h", "res 2,(iy+D),l", "res 2,(iy+D)", "res 2,(iy+D),a", "res 3,(iy+D),b", "res 3,(iy+D),c", "res 3,(iy+D),d", "res 3,(iy+D),e", "res 3,(iy+D),h", "res 3,(iy+D),l", "res 3,(iy+D)", "res 3,(iy+D),a", "res 4,(iy+D),b", "res 4,(iy+D),c", "res 4,(iy+D),d", "res 4,(iy+D),e", "res 4,(iy+D),h", "res 4,(iy+D),l", "res 4,(iy+D)", "res 4,(iy+D),a", "res 5,(iy+D),b", "res 5,(iy+D),c", "res 5,(iy+D),d", "res 5,(iy+D),e", "res 5,(iy+D),h", "res 5,(iy+D),l", "res 5,(iy+D)", "res 5,(iy+D),a", "res 6,(iy+D),b", "res 6,(iy+D),c", "res 6,(iy+D),d", "res 6,(iy+D),e", "res 6,(iy+D),h", "res 6,(iy+D),l", "res 6,(iy+D)", "res 6,(iy+D),a", "res 7,(iy+D),b", "res 7,(iy+D),c", "res 7,(iy+D),d", "res 7,(iy+D),e", "res 7,(iy+D),h", "res 7,(iy+D),l", "res 7,(iy+D)", "res 7,(iy+D),a", "set 0,(iy+D),b", "set 0,(iy+D),c", "set 0,(iy+D),d", "set 0,(iy+D),e", "set 0,(iy+D),h", "set 0,(iy+D),l", "set 0,(iy+D)", "set 0,(iy+D),a", "set 1,(iy+D),b", "set 1,(iy+D),c", "set 1,(iy+D),d", "set 1,(iy+D),e", "set 1,(iy+D),h", "set 1,(iy+D),l", "set 1,(iy+D)", "set 1,(iy+D),a", "set 2,(iy+D),b", "set 2,(iy+D),c", "set 2,(iy+D),d", "set 2,(iy+D),e", "set 2,(iy+D),h", "set 2,(iy+D),l", "set 2,(iy+D)", "set 2,(iy+D),a", "set 3,(iy+D),b", "set 3,(iy+D),c", "set 3,(iy+D),d", "set 3,(iy+D),e", "set 3,(iy+D),h", "set 3,(iy+D),l", "set 3,(iy+D)", "set 3,(iy+D),a", "set 4,(iy+D),b", "set 4,(iy+D),c", "set 4,(iy+D),d", "set 4,(iy+D),e", "set 4,(iy+D),h", "set 4,(iy+D),l", "set 4,(iy+D)", "set 4,(iy+D),a", "set 5,(iy+D),b", "set 5,(iy+D),c", "set 5,(iy+D),d", "set 5,(iy+D),e", "set 5,(iy+D),h", "set 5,(iy+D),l", "set 5,(iy+D)", "set 5,(iy+D),a", "set 6,(iy+D),b", "set 6,(iy+D),c", "set 6,(iy+D),d", "set 6,(iy+D),e", "set 6,(iy+D),h", "set 6,(iy+D),l", "set 6,(iy+D)", "set 6,(iy+D),a", "set 7,(iy+D),b", "set 7,(iy+D),c", "set 7,(iy+D),d", "set 7,(iy+D),e", "set 7,(iy+D),h", "set 7,(iy+D),l", "set 7,(iy+D)", "set 7,(iy+D),a"}; + void loadSymbols() + { + for (int i=0; i<65536; ++i) symbols[i][0] = 0; + FILE *f = fopen("symbols.txt", "r"); + while (true) { + uint16_t address; + char tmp[15]; + const int result = fscanf(f, "%x %s", &address, tmp); + if (result != 2) break; + strcpy(symbols[address], tmp); + } + fclose(f); + } + const char *getBase(const uint16_t pos) { const uint8_t *memory = &z80::getMem()[pos]; @@ -93,8 +109,20 @@ namespace z80dis { opcode_size+=2; const uint16_t word = *(uint16_t*)(memory+1); - strcpy(base, buffer); - sprintf(buffer, base, word); + if (symbols[word][0]!=0) { + char *p = strstr(buffer, "$"); + (*p)='%'; p++; + (*p)='s'; p++; + while (*(p-1) != 0) { + *p = *(p+3); + p++; + } + strcpy(base, buffer); + sprintf(buffer, base, symbols[word]); + } else { + strcpy(base, buffer); + sprintf(buffer, base, word); + } } if (strstr(buffer, "2x") && strstr(buffer, "hhd")) diff --git a/z80dis.h b/z80dis.h index c1e0a54..cf27ee1 100644 --- a/z80dis.h +++ b/z80dis.h @@ -4,6 +4,7 @@ namespace z80dis { + void loadSymbols(); const char *getAsm(const uint16_t pos); const char *getOpcode(const uint16_t pos); const int getOpcodeSize(const uint16_t pos); diff --git a/zx_screen.cpp b/zx_screen.cpp index 2adfa1f..c11c10a 100644 --- a/zx_screen.cpp +++ b/zx_screen.cpp @@ -3,6 +3,9 @@ #include "zx_ula.h" #include #include "zx_tape.h" +#include "ui_window.h" +#include "z80debug.h" +#include "ui.h" namespace zxscreen { @@ -85,8 +88,50 @@ namespace zxscreen //printf("COUNT: %i\n", count); } + bool eventHandler(SDL_Event *e) + { + if ((e->type==SDL_WINDOWEVENT) && (e->window.event==SDL_WINDOWEVENT_CLOSE)) { + return false; + } + if (!z80debug::debugging()) { + if (z80debug::paused()) { + if (e->type == SDL_KEYDOWN) { + if (e->key.keysym.scancode==SDL_SCANCODE_ESCAPE) { + const uint8_t dt = z80::step(); + z80debug::cont(); + zxscreen::refresh(dt); + } + } + } else { + if (e->type == SDL_KEYDOWN) { + if (e->key.keysym.scancode==SDL_SCANCODE_ESCAPE) { + z80debug::pause(); + ui::setrenderer(zxscreen::getrenderer()); + zxscreen::redraw(); + } else if (e->key.keysym.scancode==SDL_SCANCODE_F1) { + zxscreen::decZoom(); + } else if (e->key.keysym.scancode==SDL_SCANCODE_F2) { + zxscreen::incZoom(); + } else if (e->key.keysym.scancode==SDL_SCANCODE_F3) { + zxscreen::toggleFullscreen(); + } else if (e->key.keysym.scancode==SDL_SCANCODE_F8) { + z80debug::stop(); + zxscreen::redraw(); + } else if (e->key.keysym.scancode==SDL_SCANCODE_F12) { + zx_tape::play(); + } else if (e->key.keysym.scancode==SDL_SCANCODE_F11) { + zx_tape::rewind(); + } + } + } + } + return true; + } + void reinit() { + if (win) ui::window::unregisterWindow(SDL_GetWindowID(win)); + if (tex) SDL_DestroyTexture(tex); if (ren) SDL_DestroyRenderer(ren); if (win) SDL_DestroyWindow(win); @@ -96,6 +141,8 @@ namespace zxscreen ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED); tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 352, 296); + ui::window::registerWindow(SDL_GetWindowID(win), eventHandler); + if (fullscreen) { int w, h;