- the big mergecheit

This commit is contained in:
2025-07-21 19:21:18 +02:00
parent 300f95803e
commit 13354b855d
17 changed files with 273 additions and 19 deletions

View File

@@ -15,6 +15,9 @@
#include "z80mem.h" #include "z80mem.h"
#include "zx_48mem.h" #include "zx_48mem.h"
#include "zx_128mem.h" #include "zx_128mem.h"
#include "z80viewer.h"
#include "zx_128bankviewer.h"
#include "zx_128pageviewer.h"
uint8_t memory[65536]; uint8_t memory[65536];
uint32_t time = 0; uint32_t time = 0;
@@ -87,8 +90,16 @@ int main(int argc, char *argv[])
SDL_Init(SDL_INIT_EVERYTHING); SDL_Init(SDL_INIT_EVERYTHING);
z80debug::init(); z80debug::init();
zxscreen::init(SCREEN_MODE_128K); zxscreen::init(SCREEN_MODE_48K);
//zxscreen::init(SCREEN_MODE_48K); //zxscreen::init(SCREEN_MODE_128K);
//z80viewer *v = new zx_128bankviewer();
//v->show();
//z80viewer::registerViewer("128BANK", v);
//v = new zx_128pageviewer();
//v->show();
//z80viewer::registerViewer("128PAGE", v);
ui::menu::init(); ui::menu::init();
ui::menu::setexitcallback(actions::exitMenu); ui::menu::setexitcallback(actions::exitMenu);
@@ -121,6 +132,7 @@ int main(int argc, char *argv[])
if (argc==3) { z80debug::loadngo(argv[1], argv[2]); } if (argc==3) { z80debug::loadngo(argv[1], argv[2]); }
z80debug::stop(); z80debug::stop();
z80debug::stop();
bool should_exit = false; bool should_exit = false;
SDL_Event e; SDL_Event e;
@@ -156,6 +168,7 @@ int main(int argc, char *argv[])
} else { } else {
z80debug::show(); z80debug::show();
} }
z80viewer::refreshAll();
} else if (e.key.keysym.scancode==SDL_SCANCODE_F10) { } else if (e.key.keysym.scancode==SDL_SCANCODE_F10) {
if (z80debug::debugging()) { if (z80debug::debugging()) {
z80debug::show(); z80debug::show();
@@ -165,6 +178,7 @@ int main(int argc, char *argv[])
zxscreen::fullrefresh(); zxscreen::fullrefresh();
zxscreen::redraw(); zxscreen::redraw();
z80analyze::refresh(); z80analyze::refresh();
z80viewer::refreshAll();
} }
} else if (e.key.keysym.scancode==SDL_SCANCODE_F11) { } else if (e.key.keysym.scancode==SDL_SCANCODE_F11) {
if (z80debug::debugging()) { if (z80debug::debugging()) {
@@ -175,6 +189,7 @@ int main(int argc, char *argv[])
zxscreen::refresh(dt); zxscreen::refresh(dt);
zxscreen::redraw(); zxscreen::redraw();
z80analyze::refresh(); z80analyze::refresh();
z80viewer::refreshAll();
} }
} else if (e.key.keysym.scancode==SDL_SCANCODE_F12) { } else if (e.key.keysym.scancode==SDL_SCANCODE_F12) {
if (z80debug::debugging()) { if (z80debug::debugging()) {
@@ -185,6 +200,7 @@ int main(int argc, char *argv[])
zxscreen::refresh(dt); zxscreen::refresh(dt);
zxscreen::redraw(); zxscreen::redraw();
z80analyze::refresh(); z80analyze::refresh();
z80viewer::refreshAll();
} }
} }
result = ui::window::sendEvent(e.key.windowID, &e); result = ui::window::sendEvent(e.key.windowID, &e);
@@ -243,6 +259,7 @@ int main(int argc, char *argv[])
t_states -= update_freq; t_states -= update_freq;
time = SDL_GetTicks(); time = SDL_GetTicks();
z80analyze::refresh(); z80analyze::refresh();
z80viewer::refreshAll();
} }
z80analyze::refresh(true); z80analyze::refresh(true);

27
z80.cpp
View File

@@ -1,7 +1,7 @@
#include "z80.h" #include "z80.h"
#include "z80debug.h" #include "z80debug.h"
#include "z80mem.h" #include "z80mem.h"
#include "zx_tape.h" //#include "zx_tape.h"
#include <stdio.h> #include <stdio.h>
namespace z80 namespace z80
@@ -15,8 +15,8 @@ namespace z80
bool options[Z80_NUM_OPTIONS] = { true, false }; bool options[Z80_NUM_OPTIONS] = { true, false };
int calls_stacked = 0; int calls_stacked = 0;
int (*in_ports[65536])(int); int (*in_ports[256])(int);
void (*out_ports[65536])(int, int); void (*out_ports[256])(int, int);
//#define _rM16(a) (uint16_t*)&memory[a] //#define _rM16(a) (uint16_t*)&memory[a]
//#define rM16(a) *_rM16(a) //#define rM16(a) *_rM16(a)
@@ -186,10 +186,10 @@ namespace z80
{ {
t+=1; t+=1;
reading_m1 = true; reading_m1 = true;
if (rPC==0x056c) { /*if (rPC==0x056c) {
zx_tape::rewind(); zx_tape::rewind();
zx_tape::play(); zx_tape::play();
} }*/
return READ_MEM_8(); return READ_MEM_8();
} }
@@ -1008,6 +1008,7 @@ namespace z80
t+=4; t+=4;
if (port == 0x10000) { if (port == 0x10000) {
port = rBC; port = rBC;
if (rC==0xfe) port = 0xfe;
} }
if (out_ports[port&0xff]) out_ports[port&0xff](port, val); if (out_ports[port&0xff]) out_ports[port&0xff](port, val);
} }
@@ -2265,7 +2266,7 @@ namespace z80
switch (opcode) switch (opcode)
{ {
case 0x40: rB = IN(); break; case 0x40: rB = IN(); break;
case 0x41: OUT(rB, rC); break; case 0x41: OUT(rB); break;
case 0x42: SBC16(_rHL, rBC); break; case 0x42: SBC16(_rHL, rBC); break;
case 0x43: WRITE_MEM_16(READ_MEM_16(), rBC);break; case 0x43: WRITE_MEM_16(READ_MEM_16(), rBC);break;
case 0x44: NEG(); break; case 0x44: NEG(); break;
@@ -2273,42 +2274,42 @@ namespace z80
case 0x46: IM(0); break; case 0x46: IM(0); break;
case 0x47: rI = rA; t++; break; case 0x47: rI = rA; t++; break;
case 0x48: rC = IN(); break; case 0x48: rC = IN(); break;
case 0x49: OUT(rC, rC); break; case 0x49: OUT(rC); break;
case 0x4A: ADC16(_rHL, rBC); break; case 0x4A: ADC16(_rHL, rBC); break;
case 0x4B: rBC = READ_MEM_16(READ_MEM_16());break; case 0x4B: rBC = READ_MEM_16(READ_MEM_16());break;
case 0x4D: RETI(); break; case 0x4D: RETI(); break;
case 0x4F: rR = rA; t++; break; case 0x4F: rR = rA; t++; break;
case 0x50: rD = IN(); break; case 0x50: rD = IN(); break;
case 0x51: OUT(rD, rC); break; case 0x51: OUT(rD); break;
case 0x52: SBC16(_rHL, rDE); break; case 0x52: SBC16(_rHL, rDE); break;
case 0x53: WRITE_MEM_16(READ_MEM_16(), rDE);break; case 0x53: WRITE_MEM_16(READ_MEM_16(), rDE);break;
case 0x56: IM(1); break; case 0x56: IM(1); break;
case 0x57: LD_A_I(); break; case 0x57: LD_A_I(); break;
case 0x58: rE = IN(); break; case 0x58: rE = IN(); break;
case 0x59: OUT(rE, rC); break; case 0x59: OUT(rE); break;
case 0x5A: ADC16(_rHL, rDE); break; case 0x5A: ADC16(_rHL, rDE); break;
case 0x5B: rDE = READ_MEM_16(READ_MEM_16());break; case 0x5B: rDE = READ_MEM_16(READ_MEM_16());break;
case 0x5E: IM(2); break; case 0x5E: IM(2); break;
case 0x5F: LD_A_R(); break; case 0x5F: LD_A_R(); break;
case 0x60: rH = IN(); break; case 0x60: rH = IN(); break;
case 0x61: OUT(rH, rC); break; case 0x61: OUT(rH); break;
case 0x62: SBC16(_rHL, rHL); break; case 0x62: SBC16(_rHL, rHL); break;
case 0x63: WRITE_MEM_16(READ_MEM_16(), rHL);break; case 0x63: WRITE_MEM_16(READ_MEM_16(), rHL);break;
case 0x67: RRD(); break; case 0x67: RRD(); break;
case 0x68: rL = IN(); break; case 0x68: rL = IN(); break;
case 0x69: OUT(rL, rC); break; case 0x69: OUT(rL); break;
case 0x6A: ADC16(_rHL, rHL); break; case 0x6A: ADC16(_rHL, rHL); break;
case 0x6B: rHL = READ_MEM_16(READ_MEM_16());break; case 0x6B: rHL = READ_MEM_16(READ_MEM_16());break;
case 0x6F: RLD(); break; case 0x6F: RLD(); break;
case 0x70: IN(); break; case 0x70: IN(); break;
case 0x71: OUT(0, rC); break; case 0x71: OUT(0); break;
case 0x72: SBC16(_rHL, rSP); break; case 0x72: SBC16(_rHL, rSP); break;
case 0x73: WRITE_MEM_16(READ_MEM_16(), rSP);break; case 0x73: WRITE_MEM_16(READ_MEM_16(), rSP);break;
case 0x78: rA = IN(); break; case 0x78: rA = IN(); break;
case 0x79: OUT(rA, rC); break; case 0x79: OUT(rA); break;
case 0x7A: ADC16(_rHL, rSP); break; case 0x7A: ADC16(_rHL, rSP); break;
case 0x7B: rSP = READ_MEM_16(READ_MEM_16());break; case 0x7B: rSP = READ_MEM_16(READ_MEM_16());break;

View File

@@ -84,6 +84,7 @@ namespace z80analyze
SDL_SetWindowTitle(win, SDL_itoa(address, tmp, 16)); SDL_SetWindowTitle(win, SDL_itoa(address, tmp, 16));
} }
} }
void refresh(const bool conditional) void refresh(const bool conditional)
{ {
if (!win) return; if (!win) return;

View File

@@ -801,6 +801,7 @@ namespace z80debug
} else if (strcmp(cmd, "r")==0 || strcmp(cmd, "reset")==0) { } else if (strcmp(cmd, "r")==0 || strcmp(cmd, "reset")==0) {
z80::reset(); z80::reset();
z80::connect_port(0xfe, zx_ula::port_in, zx_ula::port_out); z80::connect_port(0xfe, zx_ula::port_in, zx_ula::port_out);
history::reset();
z80debug::refresh(); z80debug::refresh();
z80analyze::refresh(); z80analyze::refresh();
} else if (strcmp(cmd, "b")==0 || strcmp(cmd, "break")==0) { } else if (strcmp(cmd, "b")==0 || strcmp(cmd, "break")==0) {
@@ -897,6 +898,7 @@ namespace z80debug
else if (strcmp(cmd, "d")==0) { getcmd(); int value = getnum(cmd); z80::getRegs()[5] = value; } else if (strcmp(cmd, "d")==0) { getcmd(); int value = getnum(cmd); z80::getRegs()[5] = value; }
else if (strcmp(cmd, "l")==0) { getcmd(); int value = getnum(cmd); z80::getRegs()[6] = value; } else if (strcmp(cmd, "l")==0) { getcmd(); int value = getnum(cmd); z80::getRegs()[6] = value; }
else if (strcmp(cmd, "h")==0) { getcmd(); int value = getnum(cmd); z80::getRegs()[7] = value; } else if (strcmp(cmd, "h")==0) { getcmd(); int value = getnum(cmd); z80::getRegs()[7] = value; }
else if (strcmp(cmd, "pc")==0) { getcmd(); int value = getnum(cmd); z80::getRegs()[24] = value&0xff; z80::getRegs()[25] = (value>>8)&0xff; }
else { sendToConsoleLog("Syntax error: invalid register"); return; } else { sendToConsoleLog("Syntax error: invalid register"); return; }
} else if (strcmp(cmd, "g")==0 || strcmp(cmd, "goto")==0) { } else if (strcmp(cmd, "g")==0 || strcmp(cmd, "goto")==0) {
getcmd(); getcmd();
@@ -1149,6 +1151,12 @@ namespace z80debug
namespace history namespace history
{ {
void reset()
{
buffer[0]=buffer[1]=0;
cursor=pos=top=0;
}
void store() void store()
{ {
buffer[++top] = z80::getPC(); buffer[++top] = z80::getPC();

View File

@@ -44,6 +44,7 @@ namespace z80debug
void search(const char *seq=nullptr); void search(const char *seq=nullptr);
namespace history namespace history
{ {
void reset();
void store(); void store();
void gototop(); void gototop();
void goforward(); void goforward();

View File

@@ -36,6 +36,7 @@ class z80mem
virtual uint32_t getSize() = 0; virtual uint32_t getSize() = 0;
virtual uint8_t *rawPtr(uint32_t address) = 0; virtual uint8_t *rawPtr(uint32_t address) = 0;
virtual uint8_t *rawTagPtr(uint32_t address) = 0;
protected: protected:

33
z80viewer.cpp Normal file
View File

@@ -0,0 +1,33 @@
#include "z80viewer.h"
#include "ui.h"
#include "ui_window.h"
std::vector<viewer_t> z80viewer::viewers;
void z80viewer::registerViewer(const char *name, z80viewer *viewer)
{
viewer_t v;
strcpy(v.name, name);
v.viewer = viewer;
viewers.push_back( v );
}
z80viewer *z80viewer::getViewer(const char *name)
{
for (auto v : viewers)
{
if (strcmp(name, v.name)==0) return v.viewer;
}
return nullptr;
}
void z80viewer::refreshAll()
{
for (auto v : viewers) v.viewer->refresh();
}
bool z80viewer::handleEvents(SDL_Event *e)
{
for (auto v : viewers) v.viewer->handleEvent(e);
return true;
}

34
z80viewer.h Normal file
View File

@@ -0,0 +1,34 @@
#pragma once
#include <SDL2/SDL.h>
#include <vector>
class z80viewer;
struct viewer_t
{
char name[12];
z80viewer *viewer;
};
class z80viewer
{
public:
virtual void show() = 0;
virtual void refresh() = 0;
virtual void hide() = 0;
virtual void focus() = 0;
virtual bool handleEvent(SDL_Event *e) = 0;
static void registerViewer(const char *name, z80viewer *viewer);
static z80viewer *getViewer(const char *name);
static void refreshAll();
static bool handleEvents(SDL_Event *e);
protected:
SDL_Window *win = nullptr;
SDL_Renderer *ren = nullptr;
SDL_Texture *tex = nullptr;
SDL_Texture *uitex = nullptr;
static std::vector<viewer_t> viewers;
};

60
zx_128bankviewer.cpp Normal file
View File

@@ -0,0 +1,60 @@
#include "zx_128bankviewer.h"
#include "z80.h"
#include "z80mem.h"
void zx_128bankviewer::show()
{
if (!win)
{
win = SDL_CreateWindow("Z80 Analyzer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 128, 512, SDL_WINDOW_SHOWN);
ren = SDL_CreateRenderer(win, -1, 0);
tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 128, 512);
//ui::window::registerWindow(SDL_GetWindowID(win), handleEvent);
}
refresh();
}
void zx_128bankviewer::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);
//pixels[i] = tag==MEMTAG_NONE ? 0x808080 : tag==MEMTAG_DATA ? 0x0000FF : tag==MEMTAG_MIXED ? 0xFF00FF : 0x00FF00;
uint32_t none_color = i<0x4000 ? 0x101010 : i<0x5800 ? 0x202020 : i<0x5b00 ? 0x404040 : 0x808080;
uint8_t tag = z80mem::get()->getTag(i);
pixels[i] = !(tag & MEMTAG_TOUCHED) ? none_color : (tag & MEMTAG_TINST) ? 0x00FF00 : (tag & MEMTAG_TREPEAT) ? 0xFF0000 : 0x0000FF;
}
pixels[z80::getPC()] = 0xFFFFFF;
SDL_UnlockTexture(tex);
SDL_RenderCopy(ren, tex, NULL, NULL);
SDL_RenderPresent(ren);
}
void zx_128bankviewer::hide()
{
//ui::window::unregisterWindow(SDL_GetWindowID(win));
SDL_DestroyTexture(tex); tex = nullptr;
SDL_DestroyRenderer(ren); ren = nullptr;
SDL_DestroyWindow(win); win = nullptr;
}
void zx_128bankviewer::focus()
{
if (win) {
SDL_RaiseWindow(win);
refresh();
}
}
bool zx_128bankviewer::handleEvent(SDL_Event *e)
{
return true;
}

12
zx_128bankviewer.h Normal file
View File

@@ -0,0 +1,12 @@
#pragma once
#include "z80viewer.h"
class zx_128bankviewer : public z80viewer
{
public:
void show();
void refresh();
void hide();
void focus();
bool handleEvent(SDL_Event *e);
};

View File

@@ -6,7 +6,7 @@
#include <stdio.h> #include <stdio.h>
#define ZX_128MEM_PAGE 0x07 #define ZX_128MEM_PAGE 0x07
#define ZX_128MEM_SCREEN 0x04 #define ZX_128MEM_SCREEN 0x08
#define ZX_128MEM_ROM 0x10 #define ZX_128MEM_ROM 0x10
#define ZX_128MEM_DISPAG 0x20 #define ZX_128MEM_DISPAG 0x20
@@ -157,4 +157,9 @@ uint32_t zx_128mem::getSize()
uint8_t *zx_128mem::rawPtr(uint32_t address) uint8_t *zx_128mem::rawPtr(uint32_t address)
{ {
return &memory[address]; return &memory[address];
} }
uint8_t *zx_128mem::rawTagPtr(uint32_t address)
{
return &tags[address];
}

View File

@@ -26,6 +26,7 @@ class zx_128mem : public z80mem
uint32_t getSize(); uint32_t getSize();
uint8_t *rawPtr(uint32_t address); uint8_t *rawPtr(uint32_t address);
uint8_t *rawTagPtr(uint32_t address);
protected: protected:

61
zx_128pageviewer.cpp Normal file
View File

@@ -0,0 +1,61 @@
#include "zx_128pageviewer.h"
#include "z80.h"
#include "z80mem.h"
void zx_128pageviewer::show()
{
if (!win)
{
win = SDL_CreateWindow("ZX128 Page Viewer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1024, 128, SDL_WINDOW_SHOWN);
ren = SDL_CreateRenderer(win, -1, 0);
tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 1024, 128);
//ui::window::registerWindow(SDL_GetWindowID(win), handleEvent);
}
refresh();
}
void zx_128pageviewer::refresh()
{
if (!win) return;
Uint32 *pixels;
int pitch;
const uint8_t *tags = z80mem::get()->rawTagPtr(0);
SDL_LockTexture(tex, NULL, (void**)&pixels, &pitch);
for (int i=0; i<131072; ++i)
{
const int x = (i&0x7f) + (((i>>14)&0x07)*128);
const int y = (i>>7)&0x7f;
uint32_t none_color = 0x808080; //i<0x4000 ? 0x101010 : i<0x5800 ? 0x202020 : i<0x5b00 ? 0x404040 : 0x808080;
uint8_t tag = tags[i];
pixels[x+y*1024] = !(tag & MEMTAG_TOUCHED) ? none_color : (tag & MEMTAG_TINST) ? 0x00FF00 : (tag & MEMTAG_TREPEAT) ? 0xFF0000 : 0x0000FF;
}
//pixels[z80::getPC()] = 0xFFFFFF;
SDL_UnlockTexture(tex);
SDL_RenderCopy(ren, tex, NULL, NULL);
SDL_RenderPresent(ren);
}
void zx_128pageviewer::hide()
{
//ui::window::unregisterWindow(SDL_GetWindowID(win));
SDL_DestroyTexture(tex); tex = nullptr;
SDL_DestroyRenderer(ren); ren = nullptr;
SDL_DestroyWindow(win); win = nullptr;
}
void zx_128pageviewer::focus()
{
if (win) {
SDL_RaiseWindow(win);
refresh();
}
}
bool zx_128pageviewer::handleEvent(SDL_Event *e)
{
return true;
}

13
zx_128pageviewer.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#include "z80viewer.h"
class zx_128pageviewer : public z80viewer
{
public:
void show();
void refresh();
void hide();
void focus();
bool handleEvent(SDL_Event *e);
};

View File

@@ -62,4 +62,9 @@ uint32_t zx_48mem::getSize()
uint8_t *zx_48mem::rawPtr(uint32_t address) uint8_t *zx_48mem::rawPtr(uint32_t address)
{ {
return &memory[address]; return &memory[address];
}
uint8_t *zx_48mem::rawTagPtr(uint32_t address)
{
return &tags[address];
} }

View File

@@ -22,6 +22,7 @@ class zx_48mem : public z80mem
uint32_t getSize(); uint32_t getSize();
uint8_t *rawPtr(uint32_t address); uint8_t *rawPtr(uint32_t address);
uint8_t *rawTagPtr(uint32_t address);
protected: protected:

View File

@@ -293,11 +293,11 @@ namespace zx_ula
if (t_sound>=317) { if (t_sound>=317) {
t_sound-=317; t_sound-=317;
samples_generated++; samples_generated++;
if (samples_t >=z80::getClock()) { /*if (samples_t >=z80::getClock()) {
//printf("%i\n", samples_generated); //printf("%i\n", samples_generated);
samples_generated=0; samples_generated=0;
samples_t = 0; samples_t = 0;
} }*/
/*if (SDL_GetTicks()>=samples_time+1000) { /*if (SDL_GetTicks()>=samples_time+1000) {
printf("%i\n", samples_generated); printf("%i\n", samples_generated);
samples_generated=0; samples_generated=0;