diff --git a/debug.cpp b/debug.cpp index 8c77011..444bb8c 100644 --- a/debug.cpp +++ b/debug.cpp @@ -6,7 +6,7 @@ //#include "z80analyze.h" #include "ui.h" #include "ui_window.h" -//#include "zx_screen.h" +#include "gbscreen.h" #define RESIZING_NONE 0 #define RESIZING_MEMORY 1 @@ -105,10 +105,10 @@ namespace debug con_y = win_h - con_h; sym_h = win_h - sym_y; debug::refresh(); - //zxscreen::redraw(); + gbscreen::redraw(); } else if (e->window.event == SDL_WINDOWEVENT_CLOSE) { hide(); - //zxscreen::focus(); + gbscreen::focus(); } } if (e->type == SDL_MOUSEWHEEL) { @@ -356,18 +356,18 @@ namespace debug void stop() { //history::gototop(); - //zxscreen::setTitle(" (stopped)"); + gbscreen::setTitle(" (stopped)"); pause(); is_debugging = true; show(); - //if ( zxscreen::getFullRefresh()) zxscreen::fullrefresh(); + if ( gbscreen::getFullRefresh()) gbscreen::fullrefresh(); } void cont() { - //zxscreen::setTitle(""); + gbscreen::setTitle(""); is_debugging = is_paused = false; refresh(); - //zxscreen::focus(); + gbscreen::focus(); //zx_ula::sound_enable(); } @@ -777,7 +777,7 @@ namespace debug uint8_t dt = sm83::step(); //zx_tape::update(dt); //zx_ula::sound_update(dt); - //zxscreen::fullrefresh(); + gbscreen::fullrefresh(); //z80analyze::refresh(); } else if (strcmp(cmd, "c")==0 || strcmp(cmd, "cont")==0) { sm83::step(); diff --git a/gbscreen.cpp b/gbscreen.cpp index bb653e1..317208f 100644 --- a/gbscreen.cpp +++ b/gbscreen.cpp @@ -7,7 +7,7 @@ #include "debug.h" #include "ui.h" -namespace zxscreen +namespace gbscreen { uint32_t palette[4] = { 0xFFFFFF, 0xAAAAAA, 0x555555, 0x000000 @@ -31,72 +31,11 @@ namespace zxscreen uint32_t t_screen = 0; - int pixels_draw = 0; - uint8_t gb_pixels[160*144]; uint8_t *ptr_pixel = gb_pixels; - #define SCREEN_SYNC 0xFFFF - #define SCREEN_BORDER 0xFFFE - - void create_tables() - { - uint32_t count = 0; - - if (pixel_addr) free(pixel_addr); - if (color_addr) free(color_addr); - pixel_addr = (uint16_t*)malloc(t_states_total*sizeof(uint16_t)); - color_addr = (uint16_t*)malloc(t_states_total*sizeof(uint16_t)); - - uint16_t *ptr_pixel = pixel_addr; - uint16_t *ptr_color = color_addr; - - // vsync - for (int i=0; i>3)*32; - uint16_t address = /*0x4000 |*/ (x&0x1f) | ((y&0x7)<<8) | ((y&0x38)<<2) | ((y&0xc0)<<5); - for (int i=7;i>0;i-=2) - { - *(ptr_pixel++) = (address & 0x1FFF) | (i << 13); - *(ptr_color++) = color; - count+=2; - } - } - - // Right border - for (int j=0;j<24;++j) { *(ptr_pixel++) = 0; *(ptr_color++) = SCREEN_BORDER; count+=2; } - } - - // Lower border - for (int i=0; i<56;++i) { - // hsync - for (int j=0;jtype == SDL_KEYDOWN) { if (e->key.keysym.scancode==SDL_SCANCODE_ESCAPE) { - const uint8_t dt = z80::step(); - z80debug::cont(); - zxscreen::refresh(dt); + const uint8_t dt = sm83::step(); + debug::cont(); + gbscreen::refresh(dt); } } } else { if (e->type == SDL_KEYDOWN) { if (e->key.keysym.scancode==SDL_SCANCODE_ESCAPE) { - z80debug::pause(); - zxscreen::redraw(); + debug::pause(); + gbscreen::redraw(); } else if (e->key.keysym.scancode==SDL_SCANCODE_F1) { - zxscreen::decZoom(); + gbscreen::decZoom(); } else if (e->key.keysym.scancode==SDL_SCANCODE_F2) { - zxscreen::incZoom(); + gbscreen::incZoom(); } else if (e->key.keysym.scancode==SDL_SCANCODE_F3) { - zxscreen::toggleFullscreen(); + gbscreen::toggleFullscreen(); } else if (e->key.keysym.scancode==SDL_SCANCODE_F6) { - zx_tape::play(); + //zx_tape::play(); } else if (e->key.keysym.scancode==SDL_SCANCODE_F7) { - zx_tape::rewind(); + //zx_tape::rewind(); } } } @@ -151,9 +90,9 @@ namespace zxscreen if (win) SDL_DestroyWindow(win); const int z = fullscreen ? 1 : zoom; - win = SDL_CreateWindow("ZX Spectrum Screen", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 352*z, 296*z, fullscreen?SDL_WINDOW_FULLSCREEN_DESKTOP:SDL_WINDOW_SHOWN); + win = SDL_CreateWindow("Gameboy Screen", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 160*z, 144*z, fullscreen?SDL_WINDOW_FULLSCREEN_DESKTOP:SDL_WINDOW_SHOWN); ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED); - tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 352, 296); + tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 160, 144); uitex = ui::createtexture(ren); ui::window::registerWindow(SDL_GetWindowID(win), eventHandler); @@ -162,44 +101,24 @@ namespace zxscreen { int w, h; SDL_GetWindowSize(win, &w, &h); - fullscreen_scale = h/296; - dest_rect.w = 352 * fullscreen_scale; - dest_rect.h = 296 * fullscreen_scale; + fullscreen_scale = h/144; + dest_rect.w = 160 * fullscreen_scale; + dest_rect.h = 144 * fullscreen_scale; dest_rect.x = (w - dest_rect.w)/2; dest_rect.y = (h - dest_rect.h)/2; } else { dest_rect.x = dest_rect.y = 0; - dest_rect.w = 352 * zoom; - dest_rect.h = 296 * zoom; + dest_rect.w = 160 * zoom; + dest_rect.h = 144 * zoom; } focus(); } - void setBaseAddresses(const uint32_t pixeladdr, const uint32_t coloraddr) - { - pixel_base_addr = pixeladdr; - color_base_addr = coloraddr; - } - void init(int mode) { - zxscreen::mode = mode; - if (mode==SCREEN_MODE_48K) { - setBaseAddresses(0x4000, 0x5800); - t_states_total = 69888; - t_states_per_scanline = 224; - vsync_lines = 16; - } else if (mode==SCREEN_MODE_128K) { - setBaseAddresses(0x14000, 0x15800); - t_states_total = 70908; - t_states_per_scanline = 228; - vsync_lines = 15; - } - - create_tables(); reinit(); } @@ -212,55 +131,131 @@ namespace zxscreen } } - void refresh(const uint32_t dt, const bool full) + void fill_line_buffer(uint8_t LY) { - const uint8_t* pixel_mem = z80mem::get()->rawPtr(pixel_base_addr); - const uint8_t* color_mem = z80mem::get()->rawPtr(color_base_addr); - const uint8_t border_color = zx_ula::get_border_color(); + const uint8_t LCDC = mem::readMem(0xff40); + const uint8_t SCY = mem::readMem(0xff42); + const uint8_t SCX = mem::readMem(0xff43); + const uint8_t ty = uint8_t(SCY+LY) >> 3; + const uint8_t ly = uint8_t(SCY+LY) & 0x7; + uint8_t tx = SCX >> 3; + uint8_t ox = SCX & 0x7; - for (int i=0;ireadMem(color_base_addr + color_addr[t_screen]); - uint8_t c1 = color&0x7, c2 = (color>>3)&0x7; - if ((color&0x80) && flash) { c1=c2; c2=color&0x7; } - if ((color&0x40)) { c1 |= 0x8; c2 |= 0x8; } - uint16_t address = /*(0x4000) |*/ (pixel_addr[t_screen]&0x1FFF); - uint8_t mask = 1 << (pixel_addr[t_screen]>>13); - uint8_t block = *(pixel_mem + address); // z80mem::get()->readMem(pixel_base_addr + address); - *(ptr_pixel++)=(block&mask) ? c1 : c2; - mask>>=1; - *(ptr_pixel++)=(block&mask) ? c1 : c2; + ox--; } - pixels_draw+=2; - } - t_screen++; - if (t_screen>=t_states_total) { - pixels_draw=0; - t_flash++; - if (t_flash==16) { t_flash=0; flash = !flash; } - t_screen=0; - ptr_pixel = zx_pixels; - redraw(); - if (!full) z80::interrupt(); + a<<1; b<<1; + if (pi==160) return; } } + + } + + void refresh(const uint32_t dt, const bool full) + { + const uint8_t LCDC = mem::readMem(0xff40); + if ((LCDC&0x80)==0) return; + + uint8_t STAT = mem::readMem(0xff41); + uint8_t LY = mem::readMem(0xff44); + const uint8_t LYC = mem::readMem(0xff45); + for (int i=0;i=t_states_total) + { + t_screen=0; + ptr_pixel = gb_pixels; + redraw(); + if (!full) sm83::interrupt(INTERRUPT_VBLANK); + } + } + mem::writeMem(0xff41, STAT); + mem::writeMem(0xff44, LY); } void fullrefresh() { - uint32_t tmp = t_screen; + /*uint32_t tmp = t_screen; t_screen = 0; uint8_t * tmp_ptr = ptr_pixel; - ptr_pixel = zx_pixels; + ptr_pixel = gb_pixels; refresh(t_states_total, true); ptr_pixel = tmp_ptr; - t_screen = tmp; + t_screen = tmp;*/ } void debugrefresh(const uint32_t dt) @@ -270,14 +265,14 @@ namespace zxscreen void redraw(const bool present) { - if (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD)) return; + //if (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD)) return; ui::setrenderer(ren, uitex); Uint32* pixels; int pitch; SDL_LockTexture(tex, NULL, (void**)&pixels, &pitch); - for (int i=0; i<352*296;++i) *(pixels++) = palette[zx_pixels[i]]; + for (int i=0; i<160*144;++i) *(pixels++) = palette[gb_pixels[i]]; SDL_UnlockTexture(tex); if (fullscreen) @@ -295,7 +290,7 @@ namespace zxscreen { SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawColor(ren, 0, 0, 0, 128); - SDL_Rect rect {0,0,352*zoom,296*zoom}; + SDL_Rect rect {0,0,160*zoom,144*zoom}; if (fullscreen) SDL_GetWindowSize(win, &rect.w, &rect.h); SDL_RenderFillRect(ren, &rect); } @@ -310,7 +305,7 @@ namespace zxscreen void setTitle(const char* title) { char tmp[256]; - strcpy(tmp, "ZX Spectrum Screen"); + strcpy(tmp, "Gameboy Screen"); strcat(tmp, title); SDL_SetWindowTitle(win, tmp); } @@ -321,8 +316,8 @@ namespace zxscreen SDL_DisplayMode dm; SDL_GetCurrentDisplayMode(0, &dm); - if (352*value > dm.w) return; - if (296*value > dm.h) return; + if (160*value > dm.w) return; + if (144*value > dm.h) return; zoom = value; reinit(); @@ -359,7 +354,6 @@ namespace zxscreen return full_refresh; } - SDL_Renderer *getrenderer() { return ren; diff --git a/main.cpp b/main.cpp index ef77f06..ffb0fe1 100644 --- a/main.cpp +++ b/main.cpp @@ -6,7 +6,7 @@ #include "sm83dis.h" #include "debug.h" //#include "zx_ula.h" -//#include "zx_screen.h" +#include "gbscreen.h" //#include "zx_tape.h" #include #include @@ -24,31 +24,31 @@ namespace actions { const uint8_t dt = sm83::step(); debug::cont(); - //zxscreen::refresh(dt); + gbscreen::refresh(dt); } int decZoom(int value) { - //zxscreen::decZoom(); + gbscreen::decZoom(); return 0; } int incZoom(int value) { - //zxscreen::incZoom(); + gbscreen::incZoom(); return 0; } int fullscreen(int value) { - //zxscreen::toggleFullscreen(); - return 0; //zxscreen::getFullscreen(); + gbscreen::toggleFullscreen(); + return gbscreen::getFullscreen(); } int fullrefresh(int value) { - //zxscreen::toggleFullRefresh(); - return 0; //zxscreen::getFullRefresh(); + gbscreen::toggleFullRefresh(); + return gbscreen::getFullRefresh(); } int showAnalyzer(int value) @@ -79,8 +79,8 @@ int main(int argc, char *argv[]) sm83::reset(); SDL_Init(SDL_INIT_EVERYTHING); + gbscreen::init(0); debug::init(); - //zxscreen::init(SCREEN_MODE_48K); ui::menu::init(); ui::menu::setexitcallback(actions::exitMenu); @@ -95,9 +95,9 @@ int main(int argc, char *argv[]) menu = ui::menu::addsubmenu("SCREEN"); ui::menu::addoption(menu, "DEC ZOOM", actions::decZoom); ui::menu::addoption(menu, "INC ZOOM", actions::incZoom); - ui::menu::addbooloption(menu, "FULLSCREEN", false /*zxscreen::getFullscreen()*/, actions::fullscreen); + ui::menu::addbooloption(menu, "FULLSCREEN", gbscreen::getFullscreen(), actions::fullscreen); ui::menu::addseparator(menu); - ui::menu::addbooloption(menu, "FULL REFRESH", false /*zxscreen::getFullRefresh()*/, actions::fullrefresh); + ui::menu::addbooloption(menu, "FULL REFRESH", gbscreen::getFullRefresh(), actions::fullrefresh); menu = ui::menu::addsubmenu("EMULATION"); ui::menu::addbooloption(menu, "STOP ON INVALID OP", sm83::getOption(SM83_OPTION_STOP_ON_INVALID), actions::decZoom); @@ -132,12 +132,12 @@ int main(int argc, char *argv[]) debug::history::gototop(); const uint8_t dt = sm83::step(); debug::cont(); - //zxscreen::refresh(dt); + gbscreen::refresh(dt); } } else if (e.key.keysym.scancode==SDL_SCANCODE_F8) { if (!debug::debugging()) { debug::stop(); - //zxscreen::redraw(); + gbscreen::redraw(); } else { debug::show(); } @@ -147,8 +147,8 @@ int main(int argc, char *argv[]) debug::history::gototop(); const uint8_t dt = sm83::step(); debug::refresh(); - //zxscreen::fullrefresh(); - //zxscreen::redraw(); + gbscreen::fullrefresh(); + gbscreen::redraw(); //z80analyze::refresh(); } } else if (e.key.keysym.scancode==SDL_SCANCODE_F11) { @@ -157,8 +157,8 @@ int main(int argc, char *argv[]) debug::history::gototop(); const uint8_t dt = debug::next(); debug::refresh(); - //zxscreen::refresh(dt); - //zxscreen::redraw(); + gbscreen::refresh(dt); + gbscreen::redraw(); //z80analyze::refresh(); } } else if (e.key.keysym.scancode==SDL_SCANCODE_F12) { @@ -167,8 +167,8 @@ int main(int argc, char *argv[]) debug::history::gototop(); const uint8_t dt = debug::stepout(); debug::refresh(); - //zxscreen::refresh(dt); - //zxscreen::redraw(); + gbscreen::refresh(dt); + gbscreen::redraw(); //z80analyze::refresh(); } } @@ -188,13 +188,13 @@ int main(int argc, char *argv[]) for (int i=0;i<5;++i) { if (debug::isbreak(sm83::getPC(), 9)) { debug::stop(); - //zxscreen::redraw(); + gbscreen::redraw(); break; } else { uint8_t dt = sm83::step(); t_states += dt; //zx_ula::sound_update(dt); - //zxscreen::refresh(dt); + gbscreen::refresh(dt); if (debug::debugging()) break; } } @@ -210,9 +210,9 @@ int main(int argc, char *argv[]) } else if (!debug::debugging() && debug::paused()) { - //zxscreen::redraw(false); + gbscreen::redraw(false); ui::menu::show(); - //zxscreen::present(); + gbscreen::present(); } ui::setClicked(false); } diff --git a/sm83.cpp b/sm83.cpp index 69db0e0..7a755c4 100644 --- a/sm83.cpp +++ b/sm83.cpp @@ -550,10 +550,10 @@ namespace sm83 void interrupt(uint8_t type) { - exit_from_halt = true; const uint8_t IE = mem::readMem(0xffff); + if (IE & type) exit_from_halt = true; const uint8_t IF = mem::readMem(0xff0f); - mem::writeMem(0xff0f, IF || (IE & type)); + mem::writeMem(0xff0f, IF | (IE & type)); processInterrupts(); }