- Finestra del depurador amb SDL
This commit is contained in:
81
main.cpp
81
main.cpp
@@ -2,17 +2,13 @@
|
||||
#include <stdio.h>
|
||||
#include "z80.h"
|
||||
#include "z80dis.h"
|
||||
#include <ncurses.h>
|
||||
#include "z80debug.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <string.h>
|
||||
|
||||
uint8_t memory[65536];
|
||||
uint32_t t = 0;
|
||||
|
||||
int w, h;
|
||||
WINDOW *win_regs;
|
||||
WINDOW *win_mem;
|
||||
WINDOW *win_code;
|
||||
|
||||
int ula_in()
|
||||
{
|
||||
return 0;
|
||||
@@ -23,17 +19,6 @@ void ula_out(int val)
|
||||
|
||||
}
|
||||
|
||||
void refresh_registers()
|
||||
{
|
||||
mvwprintw(win_regs, 1, 2, "AF: %04X AF': %04X", z80::getAF(), z80::getAF(true));
|
||||
mvwprintw(win_regs, 2, 2, "BC: %04X BC': %04X", z80::getBC(), z80::getBC(true));
|
||||
mvwprintw(win_regs, 3, 2, "DE: %04X DE': %04X", z80::getDE(), z80::getDE(true));
|
||||
mvwprintw(win_regs, 4, 2, "HL: %04X HL': %04X", z80::getHL(), z80::getHL(true));
|
||||
mvwprintw(win_regs, 5, 2, "IX: %04X IY': %04X", z80::getIX(), z80::getIY());
|
||||
mvwprintw(win_regs, 6, 2, "SP: %04X PC': %04X", z80::getSP(), z80::getPC());
|
||||
wrefresh(win_regs);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE* f = fopen("48.rom", "rb");
|
||||
@@ -43,54 +28,28 @@ int main(int argc, char *argv[])
|
||||
z80::reset(memory);
|
||||
z80::connect_port(0xfe, ula_in, ula_out);
|
||||
|
||||
initscr();
|
||||
start_color();
|
||||
init_pair(1, COLOR_WHITE, COLOR_BLACK);
|
||||
init_pair(2, COLOR_YELLOW, COLOR_BLUE);
|
||||
getmaxyx(stdscr, h, w);
|
||||
|
||||
win_regs = newwin(10,23,0,0);
|
||||
win_mem = newwin(10,w-23,0,23);
|
||||
win_code = newwin(h-10,w,10,0);
|
||||
refresh();
|
||||
|
||||
box(win_regs,0,0);
|
||||
mvwprintw(win_regs, 0, 2, " REGISTERS: ");
|
||||
refresh_registers();
|
||||
|
||||
box(win_mem,0,0);
|
||||
mvwprintw(win_mem, 0, 2, " MEMORY: ");
|
||||
mvwprintw(win_mem, 1, 2, "%ix%i", w, h);
|
||||
wrefresh(win_mem);
|
||||
|
||||
box(win_code,0,0);
|
||||
//wattron(win_code, COLOR_PAIR(1));
|
||||
//mvwprintw(win_code, 1, 1, "Hello world %s !!!", "hola");
|
||||
//wattroff(win_code, COLOR_PAIR(1));
|
||||
wrefresh(win_code);
|
||||
SDL_Init(SDL_INIT_EVERYTHING);
|
||||
z80debug::show();
|
||||
|
||||
bool should_exit = false;
|
||||
int linea=1;
|
||||
char old_line[256];
|
||||
old_line[0]=0;
|
||||
while(!should_exit)
|
||||
SDL_Event e;
|
||||
|
||||
while (!should_exit)
|
||||
{
|
||||
uint16_t PC = z80::getPC();
|
||||
if (old_line[0]!=0) {
|
||||
wattron(win_code, COLOR_PAIR(1));
|
||||
mvwprintw(win_code, linea-1, 1, old_line);
|
||||
wattroff(win_code, COLOR_PAIR(1));
|
||||
while (SDL_PollEvent(&e))
|
||||
{
|
||||
if (e.type == SDL_QUIT) { should_exit=true; break; }
|
||||
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_RETURN) {
|
||||
//uint16_t PC = z80::getPC();
|
||||
//z80dis::getAsm(&memory[PC]);
|
||||
t += z80::step();
|
||||
z80debug::refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
sprintf(old_line, "[%04x] ", PC);
|
||||
strcat(old_line, z80dis::getAsm(&memory[PC]));
|
||||
wattron(win_code, COLOR_PAIR(2));
|
||||
mvwprintw(win_code, linea, 1, old_line);
|
||||
wattron(win_code, COLOR_PAIR(2));
|
||||
wrefresh(win_code);
|
||||
linea++;
|
||||
t += z80::step();
|
||||
refresh_registers();
|
||||
getch();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
9
z80.cpp
9
z80.cpp
@@ -211,13 +211,13 @@ namespace z80
|
||||
void INC16(uint16_t *reg)
|
||||
{
|
||||
t+=2;
|
||||
*reg++;
|
||||
(*reg)++;
|
||||
}
|
||||
|
||||
void DEC16(uint16_t *reg)
|
||||
{
|
||||
t+=2;
|
||||
*reg--;
|
||||
(*reg)--;
|
||||
}
|
||||
|
||||
void ADD16(uint16_t* a, uint16_t b)
|
||||
@@ -891,7 +891,8 @@ namespace z80
|
||||
void reset(uint8_t* mem)
|
||||
{
|
||||
memory = mem;
|
||||
rPC = 0;
|
||||
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)
|
||||
{
|
||||
@@ -2557,6 +2558,8 @@ namespace z80
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *getMem() { return memory; }
|
||||
|
||||
uint16_t getAF(const bool alt) { return alt?rAF2:rAF; }
|
||||
uint16_t getBC(const bool alt) { return alt?rBC2:rBC; }
|
||||
uint16_t getDE(const bool alt) { return alt?rDE2:rDE; }
|
||||
|
||||
2
z80.h
2
z80.h
@@ -8,6 +8,8 @@ namespace z80
|
||||
void connect_port(int num, int (*in_ptr)(), void (*out_ptr)(int));
|
||||
uint32_t step();
|
||||
|
||||
uint8_t *getMem();
|
||||
|
||||
uint16_t getAF(const bool alt=false);
|
||||
uint16_t getBC(const bool alt=false);
|
||||
uint16_t getDE(const bool alt=false);
|
||||
|
||||
214
z80debug.cpp
Normal file
214
z80debug.cpp
Normal file
@@ -0,0 +1,214 @@
|
||||
#include "z80debug.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include "z80.h"
|
||||
#include "z80dis.h"
|
||||
|
||||
namespace z80debug
|
||||
{
|
||||
#define CHR_W 6
|
||||
#define CHR_H 13
|
||||
|
||||
#define COLOR_BLACK 0
|
||||
#define COLOR_DARK_BLUE 1
|
||||
#define COLOR_GREEN 2
|
||||
#define COLOR_TEAL 3
|
||||
#define COLOR_BROWN 4
|
||||
#define COLOR_PURPLE 5
|
||||
#define COLOR_ORANGE 6
|
||||
#define COLOR_GRAY 7
|
||||
#define COLOR_DARK 8
|
||||
#define COLOR_BLUE 9
|
||||
#define COLOR_LIME 10
|
||||
#define COLOR_CYAN 11
|
||||
#define COLOR_RED 12
|
||||
#define COLOR_MAGENTA 13
|
||||
#define COLOR_YELLOW 14
|
||||
#define COLOR_WHITE 15
|
||||
|
||||
uint8_t colors[16][3] = {
|
||||
{0,0,0},
|
||||
{0,0,128},
|
||||
{0,128,0},
|
||||
{0,128,128},
|
||||
{128,0,0},
|
||||
{128,0,128},
|
||||
{255,128,0},
|
||||
{128,128,128},
|
||||
{30,30,30},
|
||||
{0,0,255},
|
||||
{0,255,0},
|
||||
{0,255,255},
|
||||
{255,0,0},
|
||||
{255,0,255},
|
||||
{255,255,0},
|
||||
{255,255,255},
|
||||
};
|
||||
|
||||
uint8_t offset_x = 0;
|
||||
uint8_t offset_y = 0;
|
||||
|
||||
SDL_Window *win = nullptr;
|
||||
SDL_Renderer *ren = nullptr;
|
||||
SDL_Texture *tex = nullptr;
|
||||
|
||||
uint16_t mem_viewer_pos = 0;
|
||||
|
||||
char temp[256];
|
||||
const char *tohex(int value, int numdigits)
|
||||
{
|
||||
if (numdigits==2) sprintf(temp, "%02X", value);
|
||||
else if (numdigits==4) sprintf(temp, "%04X", value);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void show()
|
||||
{
|
||||
if (win) return;
|
||||
win = SDL_CreateWindow("Z80 Debugger", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 71*CHR_W, 28*CHR_H, SDL_WINDOW_SHOWN);
|
||||
ren = SDL_CreateRenderer(win, -1, 0);
|
||||
tex = SDL_CreateTextureFromSurface(ren, SDL_LoadBMP("font.bmp"));
|
||||
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND);
|
||||
|
||||
z80debug::refresh();
|
||||
}
|
||||
|
||||
void box(int x, int y, int w, int h, uint8_t color)
|
||||
{
|
||||
SDL_Rect rect {((offset_x+x)*CHR_W)+3, ((offset_y+y)*CHR_H)+6, w*CHR_W-6, h*CHR_H-13};
|
||||
SDL_SetRenderDrawColor(ren, colors[color][0], colors[color][1], colors[color][2], 255);
|
||||
SDL_RenderDrawRect(ren, &rect);
|
||||
}
|
||||
|
||||
void printrect(int x, int y, int w, int h, uint8_t color)
|
||||
{
|
||||
SDL_Rect rect {(offset_x+x)*CHR_W, (offset_y+y)*CHR_H, w*CHR_W, h*CHR_H};
|
||||
SDL_SetRenderDrawColor(ren, colors[color][0], colors[color][1], colors[color][2], 255);
|
||||
SDL_RenderFillRect(ren, &rect);
|
||||
}
|
||||
|
||||
void printchar(int x, int y, char chr, uint8_t color=255)
|
||||
{
|
||||
if (color != 255) SDL_SetRenderDrawColor(ren, colors[color][0], colors[color][1], colors[color][2], 255);
|
||||
if (chr==32) return;
|
||||
if (chr<32 || chr>127) chr = '.';
|
||||
SDL_Rect src {((chr-32)&0xf)*CHR_W, ((chr-32)>>4)*CHR_H, CHR_W, CHR_H};
|
||||
SDL_Rect dst {(offset_x+x)*CHR_W, (offset_y+y)*CHR_H, CHR_W, CHR_H};
|
||||
SDL_RenderCopy(ren, tex, &src, &dst);
|
||||
}
|
||||
|
||||
void printtxt(int x, int y, const char *text, uint8_t color)
|
||||
{
|
||||
SDL_SetTextureColorMod(tex, colors[color][0], colors[color][1], colors[color][2]);
|
||||
for (int i=0; i<strlen(text);++i) if (text[i]!=32) printchar(x+i, y, text[i]);
|
||||
}
|
||||
|
||||
uint16_t find_previous_opcode(uint16_t pc)
|
||||
{
|
||||
pc-=4;
|
||||
if (z80dis::getOpcodeSize(&z80::getMem()[pc]) != 4) {
|
||||
pc++;
|
||||
if (z80dis::getOpcodeSize(&z80::getMem()[pc]) != 3) {
|
||||
pc++;
|
||||
if (z80dis::getOpcodeSize(&z80::getMem()[pc]) != 2) {
|
||||
pc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pc;
|
||||
}
|
||||
|
||||
void refresh()
|
||||
{
|
||||
SDL_SetRenderDrawColor(ren, 30, 30, 30, 255);
|
||||
SDL_RenderClear(ren);
|
||||
|
||||
offset_x = offset_y = 0;
|
||||
|
||||
box(0,0,46,20,COLOR_WHITE);
|
||||
printrect(2,0, 12,1, COLOR_DARK);
|
||||
printtxt(3,0, "ASSEMBLER:", COLOR_WHITE);
|
||||
|
||||
offset_x=1; offset_y=1;
|
||||
/*printtxt(1,0, "19C4:", COLOR_CYAN);
|
||||
printtxt(7,0, "10 EE", COLOR_GRAY);
|
||||
printtxt(19,0, "DJNZ 0x19B4", COLOR_WHITE);
|
||||
printrect(0,1, 44,1, COLOR_BLUE);
|
||||
printtxt(1,1, "19C6:", COLOR_YELLOW);
|
||||
printtxt(7,1, "01 3C 00", COLOR_YELLOW);
|
||||
printtxt(19,1, "LD BC,0x003C", COLOR_YELLOW);*/
|
||||
|
||||
printrect(0,8, 44,1, COLOR_BLUE);
|
||||
uint16_t pc = z80::getPC();
|
||||
uint8_t *memory = z80::getMem();
|
||||
printtxt(1,8,tohex(pc,4), COLOR_YELLOW);
|
||||
printtxt(7,8, z80dis::getOpcode(&memory[pc]), COLOR_YELLOW);
|
||||
printtxt(19,8, z80dis::getAsm(&memory[pc]), COLOR_YELLOW);
|
||||
|
||||
uint16_t pos = pc;
|
||||
for (int i=9;i<18;++i) {
|
||||
pos += z80dis::getOpcodeSize(&memory[pos]);
|
||||
printtxt(1,i,tohex(pos,4), COLOR_CYAN);
|
||||
printtxt(7,i, z80dis::getOpcode(&memory[pos]), COLOR_GRAY);
|
||||
printtxt(19,i, z80dis::getAsm(&memory[pos]), COLOR_WHITE);
|
||||
}
|
||||
|
||||
pos = pc;
|
||||
for (int i=7;i>=0;--i) {
|
||||
pos = find_previous_opcode(pos);
|
||||
printtxt(1,i,tohex(pos,4), COLOR_CYAN);
|
||||
printtxt(7,i, z80dis::getOpcode(&memory[pos]), COLOR_GRAY);
|
||||
printtxt(19,i, z80dis::getAsm(&memory[pos]), COLOR_WHITE);
|
||||
}
|
||||
//for (int i=0;i<20;++i) printtxt(1,i,tohex(pc,4), COLOR_CYAN);
|
||||
|
||||
offset_x = offset_y = 0;
|
||||
box(46,0,25,8,COLOR_WHITE);
|
||||
printrect(48,0, 12,1, COLOR_DARK);
|
||||
printtxt(49,0, "REGISTERS:", COLOR_WHITE);
|
||||
|
||||
offset_x=47;
|
||||
offset_y=1;
|
||||
printtxt(0,0, "AF AF' IX ", COLOR_WHITE);
|
||||
printtxt(0,1, "BC BC' IY ", COLOR_WHITE);
|
||||
printtxt(0,2, "DE DE' SP ", COLOR_WHITE);
|
||||
printtxt(0,3, "HL HL' PC ", COLOR_WHITE);
|
||||
printtxt(0,5, "(BC) (DE) (HL) ", COLOR_WHITE);
|
||||
|
||||
printtxt(3,0, tohex(z80::getAF(), 4), COLOR_GRAY);
|
||||
printtxt(11,0, tohex(z80::getAF(true), 4), COLOR_GRAY);
|
||||
printtxt(19,0, tohex(z80::getIX(), 4), COLOR_GRAY);
|
||||
printtxt(3,1, tohex(z80::getBC(), 4), COLOR_GRAY);
|
||||
printtxt(11,1, tohex(z80::getBC(true), 4), COLOR_GRAY);
|
||||
printtxt(19,1, tohex(z80::getIY(), 4), COLOR_GRAY);
|
||||
printtxt(3,2, tohex(z80::getDE(), 4), COLOR_GRAY);
|
||||
printtxt(11,2, tohex(z80::getDE(true), 4), COLOR_GRAY);
|
||||
printtxt(19,2, tohex(z80::getSP(), 4), COLOR_GRAY);
|
||||
printtxt(3,3, tohex(z80::getHL(), 4), COLOR_GRAY);
|
||||
printtxt(11,3, tohex(z80::getHL(true), 4), COLOR_GRAY);
|
||||
printtxt(19,3, tohex(z80::getPC(), 4), COLOR_GRAY);
|
||||
|
||||
printtxt(5,5, tohex(memory[z80::getBC()], 2), COLOR_GRAY);
|
||||
printtxt(13,5, tohex(memory[z80::getDE()], 2), COLOR_GRAY);
|
||||
printtxt(21,5, tohex(memory[z80::getHL()], 2), COLOR_GRAY);
|
||||
|
||||
offset_x=offset_y=0;
|
||||
box(0,20,71,8,COLOR_WHITE);
|
||||
printrect(2,20, 9,1, COLOR_DARK);
|
||||
printtxt(3,20, "MEMORY:", COLOR_WHITE);
|
||||
|
||||
offset_x=1; offset_y=21;
|
||||
|
||||
uint16_t mem_viewer_cursor = mem_viewer_pos;
|
||||
for (int i=0; i<6; ++i) {
|
||||
printtxt(0,i, tohex(mem_viewer_cursor, 4), COLOR_CYAN);
|
||||
for (int j=0; j<16; ++j) {
|
||||
printtxt(5+j*3, i, tohex(memory[mem_viewer_cursor++],2), COLOR_WHITE);
|
||||
printchar(53+j, i, memory[mem_viewer_cursor++], COLOR_GRAY);
|
||||
}
|
||||
//printtxt(5,0, "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", COLOR_WHITE);
|
||||
//printtxt(53,0, "0123456789AB\tDEF", COLOR_GRAY);
|
||||
}
|
||||
|
||||
SDL_RenderPresent(ren);
|
||||
}
|
||||
}
|
||||
7
z80debug.h
Normal file
7
z80debug.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
namespace z80debug
|
||||
{
|
||||
void show();
|
||||
void refresh();
|
||||
}
|
||||
48
z80dis.cpp
48
z80dis.cpp
@@ -69,36 +69,58 @@ namespace z80dis
|
||||
}
|
||||
}
|
||||
|
||||
const char *getAsm(const uint8_t *memory, const bool include_opcode)
|
||||
const char *getAsm(const uint8_t *memory)
|
||||
{
|
||||
opcode_size = 0;
|
||||
buffer[0]=0;
|
||||
char txt[20];
|
||||
const char *base = getBase(memory);
|
||||
|
||||
if (strstr(base, "4x")) {
|
||||
opcode_size+=2;
|
||||
printOpcode(memory);
|
||||
const uint16_t word = *(uint16_t*)(memory+1);
|
||||
sprintf(txt, base, word);
|
||||
sprintf(buffer, base, word);
|
||||
} else if (strstr(base, "2x")) {
|
||||
opcode_size+=1;
|
||||
printOpcode(memory);
|
||||
sprintf(txt, base, *(memory+1));
|
||||
sprintf(buffer, base, *(memory+1));
|
||||
} else if (strstr(base, "hhd")) {
|
||||
opcode_size+=1;
|
||||
printOpcode(memory);
|
||||
if (opcode_size>4) {
|
||||
opcode_size=4;
|
||||
sprintf(txt, base, (int8_t)*(memory+2));
|
||||
sprintf(buffer, base, (int8_t)*(memory+2));
|
||||
} else {
|
||||
sprintf(txt, base, (int8_t)*(memory+1));
|
||||
sprintf(buffer, base, (int8_t)*(memory+1));
|
||||
}
|
||||
} else {
|
||||
printOpcode(memory);
|
||||
sprintf(txt, base);
|
||||
sprintf(buffer, base);
|
||||
}
|
||||
strcat(buffer, txt);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const char *getOpcode(const uint8_t *memory)
|
||||
{
|
||||
opcode_size = 0;
|
||||
buffer[0]=0;
|
||||
const char *base = getBase(memory);
|
||||
|
||||
if (strstr(base, "4x")) {
|
||||
opcode_size+=2;
|
||||
} else if (strstr(base, "2x") || strstr(base, "hhd")) {
|
||||
opcode_size+=1;
|
||||
}
|
||||
printOpcode(memory);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const int getOpcodeSize(const uint8_t *memory)
|
||||
{
|
||||
opcode_size = 0;
|
||||
const char *base = getBase(memory);
|
||||
|
||||
if (strstr(base, "4x")) {
|
||||
opcode_size+=2;
|
||||
} else if (strstr(base, "2x") || strstr(base, "hhd")) {
|
||||
opcode_size+=1;
|
||||
}
|
||||
return opcode_size;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user