From dbd80694aab7ce4b844036594d5372d060bf8ed7 Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Thu, 19 Dec 2024 17:36:22 +0100 Subject: [PATCH] =?UTF-8?q?-=20[NEW]=20Treballant=20en=20modularitzar=20la?= =?UTF-8?q?=20mem=C3=B2ria,=20per=20a=20comen=C3=A7ar=20a=20implementar=20?= =?UTF-8?q?soport=20per=20als=20demes=20Spectrums?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.cpp | 12 +++---- z80.cpp | 66 ++++++++++++++++++----------------- z80.h | 19 +++++----- z80analyze.cpp | 10 ++++-- z80debug.cpp | 95 ++++++++++++++++++++++++-------------------------- z80dis.cpp | 52 +++++++++++++-------------- z80mem.h | 41 ++++++++++++++++++++++ zx_48mem.cpp | 61 ++++++++++++++++++++++++++++++++ zx_48mem.h | 29 +++++++++++++++ zx_screen.cpp | 13 +++---- 10 files changed, 263 insertions(+), 135 deletions(-) create mode 100644 z80mem.h create mode 100644 zx_48mem.cpp create mode 100644 zx_48mem.h diff --git a/main.cpp b/main.cpp index c39d9e9..e39a8db 100644 --- a/main.cpp +++ b/main.cpp @@ -12,6 +12,8 @@ #include "ui_menu.h" #include "z80analyze.h" #include "ui_window.h" +#include "z80mem.h" +#include "zx_48mem.h" uint8_t memory[65536]; uint32_t time = 0; @@ -70,13 +72,11 @@ namespace actions } int main(int argc, char *argv[]) -{ - FILE* f = fopen("48.rom", "rb"); - fread(memory, 1024, 16, f); - fclose(f); - +{ + new zx_48mem(); + z80dis::loadSymbols(); - z80::reset(memory); + z80::reset(); z80::connect_port(0xfe, zx_ula::port_in, zx_ula::port_out); SDL_Init(SDL_INIT_EVERYTHING); diff --git a/z80.cpp b/z80.cpp index c850643..f628464 100644 --- a/z80.cpp +++ b/z80.cpp @@ -1,13 +1,14 @@ #include "z80.h" #include "z80debug.h" +#include "z80mem.h" #include "zx_tape.h" #include namespace z80 { - static uint8_t *memory = nullptr; - static uint8_t memtag[65536]; - static uint8_t memtouched[65536]; + //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, false }; @@ -16,8 +17,8 @@ namespace z80 int (*in_ports[256])(int); void (*out_ports[256])(int, int); - #define _rM16(a) (uint16_t*)&memory[a] - #define rM16(a) *_rM16(a) + //#define _rM16(a) (uint16_t*)&memory[a] + //#define rM16(a) *_rM16(a) #define fC 0b00000001 #define fN 0b00000010 @@ -151,34 +152,31 @@ namespace z80 { if (z80debug::isbreak(addr, 2)) z80debug::stop(); t+=3; - if (memtag[addr] != MEMTAG_IGNORE) { + const uint8_t tag = z80mem::get()->getTag(addr); + if ( !(tag&MEMTAG_IGNORE) ) { if (!code) { - if ( memtag[addr] == MEMTAG_INST ) { + if ( tag & MEMTAG_INST ) { //printf("WARNING! READING DATA FROM CODE!!! $%4X\n", addr); //z80debug::stop(); } else { - memtag[addr] = MEMTAG_DATA; + z80mem::get()->setTag(addr, tag | MEMTAG_DATA); } } else { - if ( (reading_m1) && (memtag[addr] == MEMTAG_DATA) ) { + if ( (reading_m1) && ( tag & MEMTAG_DATA ) ) { //printf("WARNING! EXECUTING DATA AS CODE!!! $%4X\n", addr); //z80debug::stop(); } } } reading_m1 = false; - return memory[addr]; + return z80mem::get()->readMem(addr); } uint8_t READ_MEM_8() { - uint8_t data = READ_MEM_8(rPC, true); - if ( (memtag[rPC] != MEMTAG_IGNORE) && (memtag[rPC] != MEMTAG_MIXED) ) { - if (memtag[rPC] == MEMTAG_DATA) - memtag[rPC] = MEMTAG_MIXED; - else - memtag[rPC] = MEMTAG_CODE; - } + const uint8_t data = READ_MEM_8(rPC, true); + const uint8_t tag = z80mem::get()->getTag(rPC); + if ( !(tag & MEMTAG_IGNORE) ) z80mem::get()->setTag(rPC, tag | MEMTAG_CODE); rPC++; return data; } @@ -209,19 +207,18 @@ namespace z80 const uint8_t WRITE_MEM_8(const uint16_t addr, const uint8_t value) { t+=3; - if (addr>=0x4000) memory[addr] = value; + if (addr>=0x4000) z80mem::get()->writeMem(addr, value); if (z80debug::isbreak(addr, 4)) z80debug::stop(); //if (z80debug::debugging()) z80debug::setmemmodified(addr); - if ( (memtag[addr] != MEMTAG_IGNORE) && (memtag[addr] != MEMTAG_MIXED) ) { - if (memtag[addr]==MEMTAG_INST) { + + const uint8_t tag = z80mem::get()->getTag(addr); + if ( !(tag & MEMTAG_IGNORE) ) { + if ( tag & MEMTAG_INST ) { //printf("WARNING! WRITING DATA OVER CODE!!! $%4X\n", addr); //z80debug::stop(); - } else if (memtag[addr] == MEMTAG_CODE) { - memtag[addr] = MEMTAG_MIXED; } else { - memtag[addr] = MEMTAG_DATA; - memtouched[addr] = MEMTAG_DATA; + z80mem::get()->setTag(addr, tag | MEMTAG_DATA | MEMTAG_TDATA); } } @@ -1118,13 +1115,14 @@ namespace z80 if (options[Z80_OPTION_STOP_ON_INVALID]) z80debug::stop(); } - void reset(uint8_t* mem) - { - memory = mem; - for (int i=0; i<65536; ++i) memtag[i] = MEMTAG_NONE; + void reset() + { + z80mem::get()->reset(); + 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) { in_ports[i] = nullptr; @@ -1153,8 +1151,11 @@ namespace z80 current_opcode_address = rPC; t = 0; const uint8_t opcode = READ_M1(); - if (memtag[current_opcode_address] != MEMTAG_IGNORE) memtag[current_opcode_address] = MEMTAG_INST; - memtouched[current_opcode_address] = memtouched[current_opcode_address] != MEMTAG_NONE ? MEMTAG_REPEAT : MEMTAG_INST; + + uint8_t tag = z80mem::get()->getTag(current_opcode_address); + if ( !(tag & MEMTAG_IGNORE) ) tag = tag | MEMTAG_INST; + z80mem::get()->setTag(current_opcode_address, tag | !(tag&MEMTAG_TOUCHED) ? MEMTAG_TREPEAT : MEMTAG_TINST); + uint16_t tmp; if (opcode!=0xED && opcode!=0xCB && opcode!=0xDD && opcode!=0xFD ) z80debug::useOpcode(opcode, 0); @@ -2829,7 +2830,7 @@ namespace z80 } } - uint8_t *getMem() { return memory; } + //uint8_t *getMem() { return memory; } uint8_t *getRegs() { return regs; } uint16_t getAF(const bool alt) { return alt?rAF2:rAF; } @@ -2848,6 +2849,7 @@ namespace z80 void setPC(const uint16_t addr) { rPC = addr; } +/* uint8_t getMemTag(const uint16_t addr) { return memtag[addr]; } void setMemTag(const uint16_t addr, const uint8_t value) { memtag[addr] = value; } @@ -2872,7 +2874,7 @@ namespace z80 //else if (memtouched[i]==MEMTAG_DATA) // memtouched[i] = MEMTAG_REPEAT; } - +*/ const bool getOption(const int option) { diff --git a/z80.h b/z80.h index 0dbb029..d74df35 100644 --- a/z80.h +++ b/z80.h @@ -4,26 +4,20 @@ namespace z80 { - #define MEMTAG_NONE 0 - #define MEMTAG_INST 1 - #define MEMTAG_CODE 2 - #define MEMTAG_DATA 3 - #define MEMTAG_REPEAT 4 - #define MEMTAG_MIXED 5 - #define MEMTAG_IGNORE 6 - #define Z80_OPTION_STOP_ON_INVALID 0 #define Z80_OPTION_BREAK_ON_INTERRUPT 1 #define Z80_OPTION_BREAK_ON_RET 2 #define Z80_NUM_OPTIONS 3 - - void reset(uint8_t* mem); + + void reset(); + + //void reset(uint8_t* mem); void connect_port(int num, int (*in_ptr)(int), void (*out_ptr)(int,int)); void interrupt(); uint32_t step(); - uint8_t *getMem(); + //uint8_t *getMem(); uint8_t *getRegs(); uint16_t getAF(const bool alt=false); @@ -41,6 +35,8 @@ namespace z80 void setPC(const uint16_t addr); + + /* uint8_t getMemTag(const uint16_t addr); void setMemTag(const uint16_t addr, const uint8_t value); void clearMemTag(); @@ -48,6 +44,7 @@ namespace z80 uint8_t getMemTouched(const uint16_t addr); void clearMemTouched(); void fixMemTouched(); + */ const bool getOption(const int option); void setOption(const int option, const bool value); diff --git a/z80analyze.cpp b/z80analyze.cpp index d346e57..3a2994a 100644 --- a/z80analyze.cpp +++ b/z80analyze.cpp @@ -1,6 +1,7 @@ #include "z80analyze.h" #include "z80.h" #include "z80debug.h" +#include "z80mem.h" #include #include "ui_window.h" #include "ui.h" @@ -46,11 +47,14 @@ namespace z80analyze } if (e->type == SDL_KEYDOWN) { if (e->key.keysym.scancode == SDL_SCANCODE_RETURN) { + /* z80::fixMemTouched(); refresh(); z80debug::refresh(); + */ } else if (e->key.keysym.scancode == SDL_SCANCODE_BACKSPACE) { - z80::clearMemTouched(); + const uint32_t size = z80mem::get()->getSize(); + for (int i=0; isetTag(i, z80mem::get()->getTag(i) & ~MEMTAG_TOUCHED); refresh(); z80debug::refresh(); } @@ -96,8 +100,8 @@ namespace z80analyze //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 = z80::getMemTouched(i); - pixels[i] = tag==MEMTAG_NONE ? none_color : tag==MEMTAG_DATA ? 0x0000FF : tag==MEMTAG_REPEAT ? 0xFF0000 : 0x00FF00; + 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; diff --git a/z80debug.cpp b/z80debug.cpp index 35bc93f..8d4d1b4 100644 --- a/z80debug.cpp +++ b/z80debug.cpp @@ -2,12 +2,13 @@ #include #include "z80.h" #include "z80dis.h" +#include "z80mem.h" +#include "z80analyze.h" #include "zx_ula.h" #include "zx_tape.h" #include "ui.h" #include "ui_window.h" #include "zx_screen.h" -#include "z80analyze.h" #define RESIZING_NONE 0 #define RESIZING_MEMORY 1 @@ -39,7 +40,7 @@ namespace z80debug uint16_t oAF, oBC, oDE, oHL, oAF2, oBC2, oDE2, oHL2, oIX, oIY, oSP, oPC; uint8_t oI, oR; - bool mem_modified[65536]; + bool mem_modified[65536]; //[CHECK] SDL_Window *win = nullptr; SDL_Renderer *ren = nullptr; @@ -197,7 +198,7 @@ namespace z80debug const int opcodesize = z80dis::getOpcodeSize(address); const int byte = (chrx-19)/3; if (byte < opcodesize) { - inspected_value = z80::getMem()[address+byte]; + inspected_value = z80mem::get()->readMem(address+byte); refresh(); } // Si pasa per damunt de l'adreça en el visor de memòria @@ -207,13 +208,13 @@ namespace z80debug // Si pasa per damunt d'un byte en el visor de memòria } else if ((chrx>6) && (chrx<55) && (chry>mem_y) && (chryreadMem(address); refresh(); // Si pasa per damunt d'un registre - } else if ((chrx>=midx+4) && (chrx=midx+4) && (chrx=midx+4) && (chrx=midx+4) && (chrx=midx+4) && (chrx=midx+4) && (chrx=midx+4) && (chrx=midx+4) && (chrx=midx+12) && (chrx=midx+12) && (chrx=midx+12) && (chrx=midx+20) && (chrx=midx+20) && (chrx=midx+6) && (chrx=midx+14) && (chrx=midx+22) && (chrx=midx+6) && (chrxreadMem(z80::getBC()); refresh(); + } else if ((chrx>=midx+14) && (chrxreadMem(z80::getDE()); refresh(); + } else if ((chrx>=midx+22) && (chrxreadMem(z80::getHL()); refresh(); } else if ((chrx>=midx+17) && (chrx=midx+22) && (chrxgetTag(pc); + if ( !(tag & (MEMTAG_CODE | MEMTAG_INST) ) ) return pc; - while (z80::getMemTag(pc)!=MEMTAG_INST) pc--; + while ( !(z80mem::get()->getTag(pc) & MEMTAG_INST) ) pc--; return pc; /* @@ -414,8 +416,9 @@ namespace z80debug void printDissasemblerLine(const uint16_t address, const int line, const bool heuristics=false) { uint8_t colors[4] = { COLOR_RED, COLOR_CYAN, COLOR_WHITE, COLOR_WHITE}; - if (z80::getMemTouched(address)!=MEMTAG_INST && z80::getMemTouched(address)!=MEMTAG_REPEAT) colors[3]=COLOR_GRAY; - if (z80::getMemTouched(address)==MEMTAG_NONE) colors[1]=COLOR_GRAY; + const uint8_t tag = z80mem::get()->getTag(address); + if ( !(tag & (MEMTAG_TINST | MEMTAG_TREPEAT)) ) colors[3]=COLOR_GRAY; + if ( !(tag & MEMTAG_TOUCHED) ) colors[1]=COLOR_GRAY; if (is_debugging && (address == z80::getPC())) { for (int i=0; i<4;++i) colors[i]=COLOR_YELLOW; @@ -425,14 +428,14 @@ namespace z80debug if (breakpoints[address]&9) ui::printtxt(0,line,"*", colors[0]); ui::printtxt(1,line,tohex(address,4), colors[1]); - if ( (z80::getMemTag(address)==MEMTAG_INST) || heuristics ) { + if ( (tag & MEMTAG_INST) || heuristics ) { const char *sym = z80dis::getSymbol(address); if (sym[0]!=0) ui::printtxt(7,line, sym, COLOR_YELLOW); const int opcodesize = z80dis::getOpcodeSize(address); for (int i=0; igetTag(address+i); + const uint32_t color = !(tag & MEMTAG_KNOWN) ? COLOR_GRAY : (tag & MEMTAG_DATA) ? ( (tag & (MEMTAG_CODE|MEMTAG_INST)) ? COLOR_MAGENTA : COLOR_BLUE ) : COLOR_GREEN; ui::printrect(19+i*3,line,2,1,color); } @@ -440,7 +443,7 @@ namespace z80debug ui::printtxt(31,line, z80dis::getAsm(address), colors[3]); } else { ui::printrect(19,line,2,1,COLOR_GRAY); - ui::printtxt(19,line, tohex(z80::getMem()[address],2), COLOR_WHITE); + ui::printtxt(19,line, tohex(z80mem::get()->readMem(address),2), COLOR_WHITE); ui::printtxt(31,line, "?????????", COLOR_GRAY); } } @@ -461,8 +464,6 @@ namespace z80debug ui::setoffset(1, 1); - uint8_t *memory = z80::getMem(); - uint16_t pc = cursor; //z80::getPC(); if (sync_mem_with_cursor) mem_viewer_pos = cursor; uint16_t pos = pc; @@ -516,9 +517,9 @@ namespace z80debug ui::printtxt(16,5, tohex(z80::getI(), 2), oI != z80::getI() ? COLOR_RED : COLOR_GRAY); ui::printtxt(21,5, tohex(z80::getR(), 2), oR != z80::getR() ? COLOR_RED : COLOR_GRAY); - ui::printtxt(5,4, tohex(memory[z80::getBC()], 2), COLOR_GRAY); - ui::printtxt(13,4, tohex(memory[z80::getDE()], 2), COLOR_GRAY); - ui::printtxt(21,4, tohex(memory[z80::getHL()], 2), COLOR_GRAY); + ui::printtxt(5,4, tohex(z80mem::get()->readMem(z80::getBC()), 2), COLOR_GRAY); + ui::printtxt(13,4, tohex(z80mem::get()->readMem(z80::getDE()), 2), COLOR_GRAY); + ui::printtxt(21,4, tohex(z80mem::get()->readMem(z80::getHL()), 2), COLOR_GRAY); const uint8_t flags = (z80::getAF() & 0xFF); const uint8_t mod_flags = flags ^ (oAF & 0xFF); @@ -534,8 +535,6 @@ namespace z80debug // STACK // ****************************************** - // TODO: Save if stack element was introduced by a call, push or data - // TODO: Click goes to address ui::setoffset(0, 0); ui::box(midx,8,11,12,COLOR_WHITE); ui::printrect(midx+2,8, 8,1, COLOR_DARK); @@ -549,7 +548,8 @@ namespace z80debug c1 = c2 = COLOR_YELLOW; } ui::printtxt(0,i, tohex(sp, 4), c1); - ui::printtxt(5,i, tohex(*((uint16_t*)&memory[sp]),4), c2); + uint16_t value = z80mem::get()->readMem(sp) + (z80mem::get()->readMem(sp+1)<<8); + ui::printtxt(5,i, tohex(value, 4), c2); sp+=2; } @@ -622,12 +622,12 @@ namespace z80debug ui::printtxt(1,i, tohex(mem_viewer_cursor, 4), COLOR_CYAN); for (int j=0; j<16; ++j) { - const uint8_t tag = z80::getMemTag(mem_viewer_cursor); - const uint32_t color = tag==MEMTAG_NONE ? COLOR_GRAY : tag==MEMTAG_DATA ? COLOR_BLUE : tag==MEMTAG_MIXED ? COLOR_MAGENTA : COLOR_GREEN; + const uint8_t tag = z80mem::get()->getTag(mem_viewer_cursor); + const uint32_t color = !(tag & MEMTAG_KNOWN) ? COLOR_GRAY : (tag & MEMTAG_DATA) ? ( (tag & (MEMTAG_CODE|MEMTAG_INST)) ? COLOR_MAGENTA : COLOR_BLUE ) : COLOR_GREEN; ui::printrect(6+j*3,i,2,1,color); ui::printrect(54+j,i,1,1,color); - ui::printtxt(6+j*3, i, tohex(memory[mem_viewer_cursor],2), mem_modified[mem_viewer_cursor] ? COLOR_RED : COLOR_WHITE); - ui::printchar(54+j, i, memory[mem_viewer_cursor], mem_modified[mem_viewer_cursor] ? COLOR_BROWN : COLOR_GRAY); + ui::printtxt(6+j*3, i, tohex(z80mem::get()->readMem(mem_viewer_cursor), 2), ( tag & MEMTAG_MODIFIED) ? COLOR_RED : COLOR_WHITE); + ui::printchar(54+j, i, z80mem::get()->readMem(mem_viewer_cursor), ( tag & MEMTAG_MODIFIED) ? COLOR_BROWN : COLOR_GRAY); mem_viewer_cursor++; } //printtxt(5,0, "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", COLOR_WHITE); @@ -799,11 +799,8 @@ namespace z80debug z80debug::cont(); z80analyze::refresh(); } else if (strcmp(cmd, "r")==0 || strcmp(cmd, "reset")==0) { - uint8_t *mem = z80::getMem(); - for (int i=0x4000; i<=0xffff; ++i) mem[i]=0; - z80::reset(mem); + z80::reset(); z80::connect_port(0xfe, zx_ula::port_in, zx_ula::port_out); - //for (int i=0; i<65536; ++i) breakpoints[i]=0; z80debug::refresh(); z80analyze::refresh(); } else if (strcmp(cmd, "b")==0 || strcmp(cmd, "break")==0) { @@ -883,13 +880,11 @@ namespace z80debug int address = getnum(cmd); getcmd(); int value = getnum(cmd); - uint8_t *mem = z80::getMem(); - mem[address] = value; + z80mem::get()->writeMem(address, value); } else if (strcmp(cmd, "peek")==0) { getcmd(); int address = getnum(cmd); - uint8_t *mem = z80::getMem(); - int value = mem[address]; + int value = z80mem::get()->readMem(address); char tmp[10]; sendToConsoleLog(SDL_itoa(value, tmp, 10)); } else if (strcmp(cmd, "reg")==0) { @@ -907,7 +902,7 @@ namespace z80debug getcmd(); int address = getnum(cmd); if (address<0 || address>=65536) { sendToConsoleLog("Illegal address"); return; } - if (z80::getMemTag(address)!=MEMTAG_INST) address = find_previous_opcode(address); + if ( !(z80mem::get()->getTag(address) & MEMTAG_INST) ) address = find_previous_opcode(address); z80debug::setcursor(address); } else if (strcmp(cmd, "sym")==0 || strcmp(cmd, "symbol")==0) { getcmd(); @@ -958,8 +953,8 @@ namespace z80debug } } else if (strcmp(cmd, "ignore")==0) { getcmd(); - int value = getnum(cmd); - z80::setMemTag(value, MEMTAG_IGNORE); + const int address = getnum(cmd); + z80mem::get()->setTag(address, z80mem::get()->getTag(address) | MEMTAG_IGNORE); } else if (strcmp(cmd, "search")==0) { getcmd(); if (strcmp(cmd, "next")==0) { @@ -1007,6 +1002,7 @@ namespace z80debug void loadngo(const char* filename, const char* addr) { + /* int address = getnum(addr); if (address<0 || address>65536) { sendToConsoleLog("Illegal offset"); return; } @@ -1014,30 +1010,30 @@ namespace z80debug fseek(f, 0, SEEK_END); int size = ftell(f); fseek(f, 0, SEEK_SET); - uint8_t *memory = z80::getMem(); + uint32_t memsize; + uint8_t *memory = z80mem::get()->getRawPointer(&memsize); fread(memory+address, size, 1, f); fclose(f); z80::setPC(address); is_debugging = is_paused = false; + */ } void savestate(const char *filename) { uint8_t *regs = z80::getRegs(); - uint8_t *memory = z80::getMem(); FILE *f = fopen(filename, "wb"); fwrite(regs, 31, 1, f); - fwrite(&memory[0x4000], 0xc000, 1, f); + z80mem::get()->saveState(f); fclose(f); } void loadstate(const char *filename) { uint8_t *regs = z80::getRegs(); - uint8_t *memory = z80::getMem(); FILE *f = fopen(filename, "rb"); fread(regs, 31, 1, f); - fread(&memory[0x4000], 0xc000, 1, f); + z80mem::get()->loadState(f); fclose(f); history::store(); history::gototop(); @@ -1045,7 +1041,7 @@ namespace z80debug void setcursor(const uint16_t address) { - if (z80::getMemTag(address)!=MEMTAG_INST) + if ( !(z80mem::get()->getTag(address) & MEMTAG_INST) ) cursor = find_previous_opcode(address); else cursor = address; @@ -1135,9 +1131,8 @@ namespace z80debug while (*seq!=0) search_sequence[search_sequence_len++] = (hexchartonum(*(seq++))<<4) + hexchartonum(*(seq++)); } int num_found=0; - uint8_t *memory = z80::getMem(); while (search_pos<65536) { - if (search_sequence[num_found] == memory[search_pos]) { + if (search_sequence[num_found] == z80mem::get()->readMem(search_pos)) { num_found++; search_pos++; if (num_found==search_sequence_len) { mem_viewer_pos=search_pos-search_sequence_len; diff --git a/z80dis.cpp b/z80dis.cpp index f5e612b..4f938f3 100644 --- a/z80dis.cpp +++ b/z80dis.cpp @@ -1,7 +1,8 @@ #include "z80dis.h" +#include "z80.h" +#include "z80mem.h" #include #include -#include "z80.h" #include #include @@ -68,44 +69,41 @@ namespace z80dis const char *getBase(const uint16_t pos) { - const uint8_t *memory = &z80::getMem()[pos]; - - if (*memory == 0xCB) { + if (z80mem::get()->readMem(pos) == 0xCB) { opcode_size=2; - return cb_opcodes[*(memory+1)]; - } else if (*memory == 0xDD) { - if (*(memory+1) == 0xCB) { + return cb_opcodes[z80mem::get()->readMem(pos+1)]; + } else if (z80mem::get()->readMem(pos) == 0xDD) { + if (z80mem::get()->readMem(pos+1) == 0xCB) { opcode_size=4; - return ix_bit_opcodes[*(memory+3)]; + return ix_bit_opcodes[z80mem::get()->readMem(pos+3)]; } else { opcode_size=2; - return ix_opcodes[*(memory+1)]; + return ix_opcodes[z80mem::get()->readMem(pos+1)]; } - } else if (*memory == 0xED) { + } else if (z80mem::get()->readMem(pos) == 0xED) { opcode_size=2; - return misc_opcodes[(*(memory+1))-64]; - } else if (*memory == 0xFD) { - if (*(memory+1) == 0xCB) { + return misc_opcodes[(z80mem::get()->readMem(pos+1))-64]; + } else if (z80mem::get()->readMem(pos) == 0xFD) { + if (z80mem::get()->readMem(pos+1) == 0xCB) { opcode_size=4; - return iy_bit_opcodes[*(memory+3)]; + return iy_bit_opcodes[z80mem::get()->readMem(pos+3)]; } else { opcode_size=2; - return iy_opcodes[*(memory+1)]; + return iy_opcodes[z80mem::get()->readMem(pos+1)]; } } else { opcode_size=1; - return base_opcodes[*memory]; + return base_opcodes[z80mem::get()->readMem(pos)]; } } void printOpcode(const uint16_t pos) { - const uint8_t *memory = &z80::getMem()[pos]; char hex[4]; for (int i=0; i<4;++i) { if (opcode_size>i) - sprintf(hex, "%02x ", *(memory+i)); + sprintf(hex, "%02x ", z80mem::get()->readMem(pos+i)); else sprintf(hex, " "); strcat(buffer, hex); @@ -114,8 +112,6 @@ namespace z80dis const char *getAsm(const uint16_t pos) { - const uint8_t *memory = &z80::getMem()[pos]; - opcode_size = 0; char base[256]; strcpy(buffer, getBase(pos)); @@ -123,7 +119,9 @@ namespace z80dis if (strstr(buffer, "4x")) { opcode_size+=2; - const uint16_t word = *(uint16_t*)(memory+((*memory==0xFD) || (*memory==0xDD) || (*memory==0xED)?2:1)); + const uint8_t memvalue = z80mem::get()->readMem(pos); + const uint16_t address = pos + ((memvalue==0xFD) || (memvalue==0xDD) || (memvalue==0xED)?2:1); + const uint16_t word = z80mem::get()->readMem(address) + (z80mem::get()->readMem(address+1)<<8); if (symbols[word][0]!=0) { char *p = strstr(buffer, "$"); (*p)='%'; p++; @@ -144,7 +142,7 @@ namespace z80dis { opcode_size = 4; strcpy(base, buffer); - sprintf(buffer, base, *(memory+2), (int8_t)*(memory+3)); + sprintf(buffer, base, z80mem::get()->readMem(pos+2), (int8_t)z80mem::get()->readMem(pos+3)); return buffer; } @@ -152,7 +150,7 @@ namespace z80dis { opcode_size+=1; strcpy(base, buffer); - sprintf(buffer, base, *(memory+1)); + sprintf(buffer, base, z80mem::get()->readMem(pos+1)); } if (strstr(buffer, "Xx")) @@ -163,9 +161,9 @@ namespace z80dis if (opcode_size>4) { opcode_size=4; - sprintf(buffer, base, pos + opcode_size + (int8_t)*(memory+2)); + sprintf(buffer, base, pos + opcode_size + (int8_t)z80mem::get()->readMem(pos+2)); } else { - sprintf(buffer, base, pos + opcode_size + (int8_t)*(memory+1)); + sprintf(buffer, base, pos + opcode_size + (int8_t)z80mem::get()->readMem(pos+1)); } } @@ -175,9 +173,9 @@ namespace z80dis strcpy(base, buffer); if (opcode_size>4) { opcode_size=4; - sprintf(buffer, base, (int8_t)*(memory+3)); + sprintf(buffer, base, (int8_t)z80mem::get()->readMem(pos+3)); } else { - sprintf(buffer, base, (int8_t)*(memory+2)); + sprintf(buffer, base, (int8_t)z80mem::get()->readMem(pos+2)); } } diff --git a/z80mem.h b/z80mem.h new file mode 100644 index 0000000..abac0ff --- /dev/null +++ b/z80mem.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +#define MEMTAG_NONE 0x00 +#define MEMTAG_DATA 0x01 +#define MEMTAG_INST 0x02 +#define MEMTAG_CODE 0x04 +#define MEMTAG_IGNORE 0x08 +#define MEMTAG_TDATA 0x10 +#define MEMTAG_TINST 0x20 +#define MEMTAG_TREPEAT 0x40 +#define MEMTAG_MODIFIED 0x80 + +#define MEMTAG_KNOWN 0x07 +#define MEMTAG_TOUCHED 0x70 + +class z80mem +{ + public: + static z80mem *get() { return singleton; }; + + virtual uint8_t readMem(uint16_t address); + virtual void writeMem(uint16_t address, uint8_t value); + + virtual void loadMem(uint16_t address, uint16_t len, uint8_t *buffer); + + virtual uint8_t getTag(uint16_t address); + virtual void setTag(uint16_t address, uint8_t value); + virtual void reset(); + + virtual void saveState(FILE* f); + virtual void loadState(FILE* f); + + virtual uint32_t getSize(); + + protected: + + static z80mem *singleton; +}; diff --git a/zx_48mem.cpp b/zx_48mem.cpp new file mode 100644 index 0000000..24afe3d --- /dev/null +++ b/zx_48mem.cpp @@ -0,0 +1,61 @@ +#include "zx_48mem.h" +#include "z80mem.h" +#include +#include + + +zx_48mem::zx_48mem() +{ + z80mem::singleton = this; +} + +uint8_t zx_48mem::readMem(uint16_t address) +{ + return memory[address]; +} + +void zx_48mem::writeMem(uint16_t address, uint8_t value) +{ + memory[address] = value; +} + +void zx_48mem::loadMem(uint16_t address, uint16_t len, uint8_t *buffer) +{ + memcpy(&memory[address], buffer, len); +} + +uint8_t zx_48mem::getTag(uint16_t address) +{ + return tags[address]; +} + +void zx_48mem::setTag(uint16_t address, uint8_t value) +{ + tags[address] = value; +} + +void zx_48mem::reset() +{ + FILE* f = fopen("48.rom", "rb"); + fread(memory, 1024, 16, f); + fclose(f); + + for (int i=0x4000; i<=0xFFFF; ++i) memory[i] = 0; + for (int i=0; i<65536; ++i) tags[i] = MEMTAG_NONE; +} + +void zx_48mem::saveState(FILE *f) +{ + fwrite(&memory[0x4000], 0xc000, 1, f); +} + +void zx_48mem::loadState(FILE *f) +{ + fread(&memory[0x4000], 0xc000, 1, f); +} + +uint32_t zx_48mem::getSize() +{ + return 65536; +} + diff --git a/zx_48mem.h b/zx_48mem.h new file mode 100644 index 0000000..cb03ad8 --- /dev/null +++ b/zx_48mem.h @@ -0,0 +1,29 @@ +#pragma once +#include "z80mem.h" + +class zx_48mem : public z80mem +{ + public: + + zx_48mem(); + + uint8_t readMem(uint16_t address); + void writeMem(uint16_t address, uint8_t value); + + void loadMem(uint16_t address, uint16_t len, uint8_t *buffer); + + uint8_t getTag(uint16_t address); + void setTag(uint16_t address, uint8_t value); + void reset(); + + void saveState(FILE* f); + void loadState(FILE* f); + + uint32_t getSize(); + + protected: + + static uint8_t memory[65536]; + static uint8_t tags[65536]; + +}; diff --git a/zx_screen.cpp b/zx_screen.cpp index 58bc8a0..00bb65a 100644 --- a/zx_screen.cpp +++ b/zx_screen.cpp @@ -1,5 +1,6 @@ #include "zx_screen.h" #include "z80.h" +#include "z80mem.h" #include "zx_ula.h" #include #include "zx_tape.h" @@ -67,8 +68,8 @@ namespace zxscreen // Actual screen for (uint8_t x=0;x<32;++x) { - uint16_t color = 0x5800 + x + (y>>3)*32; - uint16_t address = 0x4000 | (x&0x1f) | ((y&0x7)<<8) | ((y&0x38)<<2) | ((y&0xc0)<<5); + uint16_t color = /*0x5800 +*/ x + (y>>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); @@ -188,7 +189,7 @@ namespace zxscreen void refresh(const uint32_t dt, const bool full) { - const uint8_t* memory = z80::getMem(); + //const uint8_t* memory = z80mem::getRawPointer(0x4000); const uint8_t border_color = zx_ula::get_border_color(); for (int i=0;ireadMem(0x5800+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); + uint16_t address = /*(0x4000) |*/ (pixel_addr[t_screen]&0x1FFF); uint8_t mask = 1 << (pixel_addr[t_screen]>>13); - uint8_t block = memory[address]; + uint8_t block = z80mem::get()->readMem(0x4000 + address); *(ptr_pixel++)=(block&mask) ? c1 : c2; mask>>=1; *(ptr_pixel++)=(block&mask) ? c1 : c2;