- [NEW] Treballant en modularitzar la memòria, per a començar a implementar soport per als demes Spectrums
This commit is contained in:
12
main.cpp
12
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);
|
||||
|
||||
66
z80.cpp
66
z80.cpp
@@ -1,13 +1,14 @@
|
||||
#include "z80.h"
|
||||
#include "z80debug.h"
|
||||
#include "z80mem.h"
|
||||
#include "zx_tape.h"
|
||||
#include <stdio.h>
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
19
z80.h
19
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);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "z80analyze.h"
|
||||
#include "z80.h"
|
||||
#include "z80debug.h"
|
||||
#include "z80mem.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#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; i<size; ++i) z80mem::get()->setTag(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;
|
||||
|
||||
|
||||
95
z80debug.cpp
95
z80debug.cpp
@@ -2,12 +2,13 @@
|
||||
#include <SDL2/SDL.h>
|
||||
#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) && (chry<mem_y+mem_h-1)) {
|
||||
const uint16_t address = mem_viewer_pos + (chry-mem_y-1)*16 + (chrx-7)/3;
|
||||
inspected_value = z80::getMem()[address];
|
||||
inspected_value = z80mem::get()->readMem(address);
|
||||
refresh();
|
||||
// Si pasa per damunt d'un registre
|
||||
} else if ((chrx>=midx+4) && (chrx<midx+8) && (chry==1)) { inspected_value = z80::getAF(); refresh();
|
||||
} else if ((chrx>=midx+4) && (chrx<midx+8) && (chry==2)) { inspected_value = z80::getBC(); refresh();
|
||||
} else if ((chrx>=midx+4) && (chrx<midx+8) && (chry==3)) { inspected_value = z80::getDE(); refresh();
|
||||
} else if ((chrx>=midx+4) && (chrx<midx+8) && (chry==4)) { inspected_value = z80::getHL(); refresh();
|
||||
} else if ((chrx>=midx+4) && (chrx<midx+8) && (chry==1)) { inspected_value = z80::getAF(); refresh();
|
||||
} else if ((chrx>=midx+4) && (chrx<midx+8) && (chry==2)) { inspected_value = z80::getBC(); refresh();
|
||||
} else if ((chrx>=midx+4) && (chrx<midx+8) && (chry==3)) { inspected_value = z80::getDE(); refresh();
|
||||
} else if ((chrx>=midx+4) && (chrx<midx+8) && (chry==4)) { inspected_value = z80::getHL(); refresh();
|
||||
} else if ((chrx>=midx+12) && (chrx<midx+16) && (chry==1)) { inspected_value = z80::getAF(true); refresh();
|
||||
} else if ((chrx>=midx+12) && (chrx<midx+16) && (chry==2)) { inspected_value = z80::getBC(true); refresh();
|
||||
} else if ((chrx>=midx+12) && (chrx<midx+16) && (chry==3)) { inspected_value = z80::getDE(true); refresh();
|
||||
@@ -223,9 +224,9 @@ namespace z80debug
|
||||
} else if ((chrx>=midx+20) && (chrx<midx+24) && (chry==3)) { inspected_value = z80::getSP(); refresh();
|
||||
} else if ((chrx>=midx+20) && (chrx<midx+24) && (chry==4)) { inspected_value = z80::getPC(); refresh();
|
||||
|
||||
} else if ((chrx>=midx+6) && (chrx<midx+8) && (chry==5)) { inspected_value = z80::getMem()[z80::getBC()]; refresh();
|
||||
} else if ((chrx>=midx+14) && (chrx<midx+16) && (chry==5)) { inspected_value = z80::getMem()[z80::getDE()]; refresh();
|
||||
} else if ((chrx>=midx+22) && (chrx<midx+24) && (chry==5)) { inspected_value = z80::getMem()[z80::getHL()]; refresh();
|
||||
} else if ((chrx>=midx+6) && (chrx<midx+8) && (chry==5)) { inspected_value = z80mem::get()->readMem(z80::getBC()); refresh();
|
||||
} else if ((chrx>=midx+14) && (chrx<midx+16) && (chry==5)) { inspected_value = z80mem::get()->readMem(z80::getDE()); refresh();
|
||||
} else if ((chrx>=midx+22) && (chrx<midx+24) && (chry==5)) { inspected_value = z80mem::get()->readMem(z80::getHL()); refresh();
|
||||
|
||||
} else if ((chrx>=midx+17) && (chrx<midx+19) && (chry==6)) { inspected_value = z80::getI(); refresh();
|
||||
} else if ((chrx>=midx+22) && (chrx<midx+24) && (chry==6)) { inspected_value = z80::getR(); refresh();
|
||||
@@ -392,9 +393,10 @@ namespace z80debug
|
||||
uint16_t find_previous_opcode(uint16_t pc)
|
||||
{
|
||||
pc--;
|
||||
if (z80::getMemTag(pc)!=MEMTAG_CODE && z80::getMemTag(pc)!=MEMTAG_MIXED && z80::getMemTag(pc)!=MEMTAG_INST) return pc;
|
||||
uint8_t tag = z80mem::get()->getTag(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; i<opcodesize; ++i) {
|
||||
const uint8_t tag = z80::getMemTag(address+i);
|
||||
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(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;
|
||||
|
||||
52
z80dis.cpp
52
z80dis.cpp
@@ -1,7 +1,8 @@
|
||||
#include "z80dis.h"
|
||||
#include "z80.h"
|
||||
#include "z80mem.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "z80.h"
|
||||
#include <vector>
|
||||
#include <bits/stdc++.h>
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
41
z80mem.h
Normal file
41
z80mem.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#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;
|
||||
};
|
||||
61
zx_48mem.cpp
Normal file
61
zx_48mem.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "zx_48mem.h"
|
||||
#include "z80mem.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
29
zx_48mem.h
Normal file
29
zx_48mem.h
Normal file
@@ -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];
|
||||
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "zx_screen.h"
|
||||
#include "z80.h"
|
||||
#include "z80mem.h"
|
||||
#include "zx_ula.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#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;i<dt;++i)
|
||||
@@ -199,13 +200,13 @@ namespace zxscreen
|
||||
*(ptr_pixel++) = border_color;
|
||||
*(ptr_pixel++) = border_color;
|
||||
} else {
|
||||
uint8_t color = memory[color_addr[t_screen]];
|
||||
uint8_t color = z80mem::get()->readMem(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;
|
||||
|
||||
Reference in New Issue
Block a user