diff --git a/font.bmp b/font.bmp new file mode 100644 index 0000000..b68787a Binary files /dev/null and b/font.bmp differ diff --git a/sm83.cpp b/sm83.cpp index 8cfcf5b..c4ecb5b 100644 --- a/sm83.cpp +++ b/sm83.cpp @@ -967,15 +967,15 @@ namespace sm83 case 0xDE: SBC8(READ_MEM_8()); break; case 0xDF: RST(0x18); break; - case 0xE0: WRITE_MEM_8(READ_MEM_8()|0x00ff, rA);break; + case 0xE0: WRITE_MEM_8(READ_MEM_8()|0xff00, rA);break; case 0xE1: POP(_rHL); break; - case 0xE2: WRITE_MEM_8(rC|0x00ff, rA); break; + case 0xE2: WRITE_MEM_8(rC|0xff00, rA); break; case 0xE3: IgnoreOpcode(); break; case 0xE4: IgnoreOpcode(); break; case 0xE5: PUSH(rHL); break; case 0xE6: AND(READ_MEM_8()); break; case 0xE7: RST(0x20); break; - case 0xE8: ADD16(_rSP, READ_MEM_8()); break; /*[TODO] es correcte? ha de ser signed*/ + case 0xE8: ADD16(_rSP, (int8_t)READ_MEM_8());break; /*[TODO] es correcte? ha de ser signed*/ case 0xE9: JP(cUnconditional, rHL, true); break; case 0xEA: WRITE_MEM_8(READ_MEM_16(), rA); break; case 0xEB: IgnoreOpcode(); break; @@ -984,15 +984,15 @@ namespace sm83 case 0xEE: XOR(READ_MEM_8()); break; case 0xEF: RST(0x28); break; - case 0xF0: rA = READ_MEM_8(READ_MEM_8()|0x00ff);break; + case 0xF0: rA = READ_MEM_8(READ_MEM_8()|0xff00);break; case 0xF1: POP(_rAF); break; - case 0xF2: rA = READ_MEM_8(rC|0x00ff); break; + case 0xF2: rA = READ_MEM_8(rC|0xff00); break; case 0xF3: DI(); break; case 0xF4: IgnoreOpcode(); break; case 0xF5: PUSH(rAF); break; case 0xF6: OR(READ_MEM_8()); break; case 0xF7: RST(0x30); break; - case 0xF8: rHL = rSP + READ_MEM_8(); break; /*[TODO] es correcte? ha de ser signed*/ + case 0xF8: rHL = rSP + (int8_t)READ_MEM_8();break; /*[TODO] es correcte? ha de ser signed*/ case 0xF9: rSP = rHL; t+=2; break; case 0xFA: rA = READ_MEM_8(READ_MEM_16()); break; case 0xFB: EI(); break; diff --git a/sm83dis.cpp b/sm83dis.cpp new file mode 100644 index 0000000..f5a288b --- /dev/null +++ b/sm83dis.cpp @@ -0,0 +1,172 @@ +#include "sm83dis.h" +#include "sm83.h" +#include "mem.h" +#include +#include +#include +#include + +namespace sm83dis +{ + char buffer[256]; + int opcode_size = 0; + char symbols[65536][15]; + std::vector used_symbols; + +// $%04x +// $%02x +// %hhd + + const char *base_opcodes[256] = {"nop", "ld bc,$%04x", "ld (bc),a", "inc bc", "inc b", "dec b", "ld b,$%02x", "rlca", "ld ($%04x), sp", "add hl,bc", "ld a,(bc)", "dec bc", "inc c", "dec c", "ld c,$%02x", "rrca", "stop $%02x", "ld de,$%04x", "ld (de),a", "inc de", "inc d", "dec d", "ld d,$%02x", "rla", "jr $%Xx", "add hl,de", "ld a,(de)", "dec de", "inc e", "dec e", "ld e,$%02x", "rra", "jr nz,$%Xx", "ld hl,$%04x", "ld (hl+),a", "inc hl", "inc h", "dec h", "ld h,$%02x", "daa", "jr z,$%Xx", "add hl,hl", "ld a, (hl+)", "dec hl", "inc l", "dec l", "ld l,$%02x", "cpl", "jr nc,$%Xx", "ld sp,$%04x", "ld (hl-),a", "inc sp", "inc (hl)", "dec (hl)", "ld (hl),$%02x", "scf", "jr c,$%Xx", "add hl,sp", "ld a,(hl-)", "dec sp", "inc a", "dec a", "ld a,$%02x", "ccf", "ld b,b", "ld b,c", "ld b,d", "ld b,e", "ld b,h", "ld b,l", "ld b,(hl)", "ld b,a", "ld c,b", "ld c,c", "ld c,d", "ld c,e", "ld c,h", "ld c,l", "ld c,(hl)", "ld c,a", "ld d,b", "ld d,c", "ld d,d", "ld d,e", "ld d,h", "ld d,l", "ld d,(hl)", "ld d,a", "ld e,b", "ld e,c", "ld e,d", "ld e,e", "ld e,h", "ld e,l", "ld e,(hl)", "ld e,a", "ld h,b", "ld h,c", "ld h,d", "ld h,e", "ld h,h", "ld h,l", "ld h,(hl)", "ld h,a", "ld l,b", "ld l,c", "ld l,d", "ld l,e", "ld l,h", "ld l,l", "ld l,(hl)", "ld l,a", "ld (hl),b", "ld (hl),c", "ld (hl),d", "ld (hl),e", "ld (hl),h", "ld (hl),l", "halt", "ld (hl),a", "ld a,b", "ld a,c", "ld a,d", "ld a,e", "ld a,h", "ld a,l", "ld a,(hl)", "ld a,a", "add a,b", "add a,c", "add a,d", "add a,e", "add a,h", "add a,l", "add a,(hl)", "add a,a", "adc a,b", "adc a,c", "adc a,d", "adc a,e", "adc a,h", "adc a,l", "adc a,(hl)", "adc a,a", "sub b", "sub c", "sub d", "sub e", "sub h", "sub l", "sub (hl)", "sub a", "sbc a,b", "sbc a,c", "sbc a,d", "sbc a,e", "sbc a,h", "sbc a,l", "sbc a,(hl)", "sbc a,a", "and b", "and c", "and d", "and e", "and h", "and l", "and (hl)", "and a", "xor b", "xor c", "xor d", "xor e", "xor h", "xor l", "xor (hl)", "xor a", "or b", "or c", "or d", "or e", "or h", "or l", "or (hl)", "or a", "cp b", "cp c", "cp d", "cp e", "cp h", "cp l", "cp (hl)", "cp a", "ret nz", "pop bc", "jp nz,$%04x", "jp $%04x", "call nz,$%04x", "push bc", "add a,$%02x", "rst &00", "ret z", "ret", "jp z,$%04x", "_Bit_", "call z,$%04x", "call $%04x", "adc a,$%02x", "rst $08", "ret nc", "pop de", "jp nc,$%04x", "---", "call nc,$%04x", "push de", "sub a,$%02x", "rst $10", "ret c", "reti", "jp c,$%04x", "---", "call c,$%04x", "---", "sbc a,$%02x", "rst $18", "ldh ($%02x),a", "pop hl", "ldh (c),a", "---", "---", "push hl", "and a,$%02x", "rst $20", "add sp,$%Xx", "jp hl", "ld ($%04x),a", "---", "---", "---", "xor a,$%02x", "rst $28", "ldh a,($%02x)", "pop af", "ld a,(c)", "di", "---", "push af", "or a,$%02x", "rst $30", "ld hl,sp+$%Xx", "ld sp,hl", "ld a,($%04x)", "ei", "---", "---", "cp a,$%02x", "rst $38"}; + const char *bit_opcodes[256] = {"rlc b", "rlc c", "rlc d", "rlc e", "rlc h", "rlc l", "rlc (hl)", "rlc a", "rrc b", "rrc c", "rrc d", "rrc e", "rrc h", "rrc l", "rrc (hl)", "rrc a", "rl b", "rl c", "rl d", "rl e", "rl h", "rl l", "rl (hl)", "rl a", "rr b", "rr c", "rr d", "rr e", "rr h", "rr l", "rr (hl)", "rr a", "sla b", "sla c", "sla d", "sla e", "sla h", "sla l", "sla (hl)", "sla a", "sra b", "sra c", "sra d", "sra e", "sra h", "sra l", "sra (hl)", "sra a", "swap b", "swap c", "swap d", "swap e", "swap h", "swap l", "swap (hl)", "swap a", "srl b", "srl c", "srl d", "srl e", "srl h", "srl l", "srl (hl)", "srl a", "bit 0,b", "bit 0,c", "bit 0,d", "bit 0,e", "bit 0,h", "bit 0,l", "bit 0,(hl)", "bit 0,a", "bit 1,b", "bit 1,c", "bit 1,d", "bit 1,e", "bit 1,h", "bit 1,l", "bit 1,(hl)", "bit 1,a", "bit 2,b", "bit 2,c", "bit 2,d", "bit 2,e", "bit 2,h", "bit 2,l", "bit 2,(hl)", "bit 2,a", "bit 3,b", "bit 3,c", "bit 3,d", "bit 3,e", "bit 3,h", "bit 3,l", "bit 3,(hl)", "bit 3,a", "bit 4,b", "bit 4,c", "bit 4,d", "bit 4,e", "bit 4,h", "bit 4,l", "bit 4,(hl)", "bit 4,a", "bit 5,b", "bit 5,c", "bit 5,d", "bit 5,e", "bit 5,h", "bit 5,l", "bit 5,(hl)", "bit 5,a", "bit 6,b", "bit 6,c", "bit 6,d", "bit 6,e", "bit 6,h", "bit 6,l", "bit 6,(hl)", "bit 6,a", "bit 7,b", "bit 7,c", "bit 7,d", "bit 7,e", "bit 7,h", "bit 7,l", "bit 7,(hl)", "bit 7,a", "res 0,b", "res 0,c", "res 0,d", "res 0,e", "res 0,h", "res 0,l", "res 0,(hl)", "res 0,a", "res 1,b", "res 1,c", "res 1,d", "res 1,e", "res 1,h", "res 1,l", "res 1,(hl)", "res 1,a", "res 2,b", "res 2,c", "res 2,d", "res 2,e", "res 2,h", "res 2,l", "res 2,(hl)", "res 2,a", "res 3,b", "res 3,c", "res 3,d", "res 3,e", "res 3,h", "res 3,l", "res 3,(hl)", "res 3,a", "res 4,b", "res 4,c", "res 4,d", "res 4,e", "res 4,h", "res 4,l", "res 4,(hl)", "res 4,a", "res 5,b", "res 5,c", "res 5,d", "res 5,e", "res 5,h", "res 5,l", "res 5,(hl)", "res 5,a", "res 6,b", "res 6,c", "res 6,d", "res 6,e", "res 6,h", "res 6,l", "res 6,(hl)", "res 6,a", "res 7,b", "res 7,c", "res 7,d", "res 7,e", "res 7,h", "res 7,l", "res 7,(hl)", "res 7,a", "set 0,b", "set 0,c", "set 0,d", "set 0,e", "set 0,h", "set 0,l", "set 0,(hl)", "set 0,a", "set 1,b", "set 1,c", "set 1,d", "set 1,e", "set 1,h", "set 1,l", "set 1,(hl)", "set 1,a", "set 2,b", "set 2,c", "set 2,d", "set 2,e", "set 2,h", "set 2,l", "set 2,(hl)", "set 2,a", "set 3,b", "set 3,c", "set 3,d", "set 3,e", "set 3,h", "set 3,l", "set 3,(hl)", "set 3,a", "set 4,b", "set 4,c", "set 4,d", "set 4,e", "set 4,h", "set 4,l", "set 4,(hl)", "set 4,a", "set 5,b", "set 5,c", "set 5,d", "set 5,e", "set 5,h", "set 5,l", "set 5,(hl)", "set 5,a", "set 6,b", "set 6,c", "set 6,d", "set 6,e", "set 6,h", "set 6,l", "set 6,(hl)", "set 6,a", "set 7,b", "set 7,c", "set 7,d", "set 7,e", "set 7,h", "set 7,l", "set 7,(hl)", "set 7,a"}; + + void loadSymbols() + { + used_symbols.clear(); + for (int i=0; i<65536; ++i) symbols[i][0] = 0; + FILE *f = fopen("symbols.txt", "r"); + if (!f) return; + while (true) { + uint16_t address; + char tmp[15]; + const int result = fscanf(f, "%x %s", &address, tmp); + if (result != 2) break; + strcpy(symbols[address], tmp); + used_symbols.push_back(address); + } + fclose(f); + } + + void saveSymbols() + { + FILE *f = fopen("symbols.txt", "w"); + for (auto sym_addr : used_symbols) + { + fprintf(f, "0x%x %s\n", sym_addr, symbols[sym_addr]); + } + fclose(f); + } + + const char *getBase(const uint16_t pos) + { + if (mem::readMem(pos) == 0xCB) { + opcode_size=2; + return bit_opcodes[mem::readMem(pos+1)]; + } else { + opcode_size=1; + return base_opcodes[mem::readMem(pos)]; + } + } + + void printOpcode(const uint16_t pos) + { + char hex[4]; + for (int i=0; i<4;++i) + { + if (opcode_size>i) + sprintf(hex, "%02x ", mem::readMem(pos+i)); + else + sprintf(hex, " "); + strcat(buffer, hex); + } + } + + const char *getAsm(const uint16_t pos) + { + opcode_size = 0; + char base[256]; + strcpy(buffer, getBase(pos)); + + if (strstr(buffer, "4x")) + { + opcode_size+=2; + //const uint8_t memvalue = mem::readMem(pos); + //const uint16_t address = pos + 1; + const uint16_t word = mem::readMem(pos+1) + (mem::readMem(pos+2)<<8); + if (symbols[word][0]!=0) { + char *p = strstr(buffer, "$"); + (*p)='%'; p++; + (*p)='s'; p++; + while (*(p-1) != 0) { + *p = *(p+3); + p++; + } + strcpy(base, buffer); + sprintf(buffer, base, symbols[word]); + } else { + strcpy(base, buffer); + sprintf(buffer, base, word); + } + } + + if (strstr(buffer, "2x")) + { + opcode_size+=1; + strcpy(base, buffer); + sprintf(buffer, base, mem::readMem(pos+1)); + } + + if (strstr(buffer, "Xx")) + { + strcpy(base, buffer); + *strstr(base, "Xx") = '4'; + opcode_size+=1; + sprintf(buffer, base, pos + opcode_size + (int8_t)mem::readMem(pos+1)); + } + + return buffer; + } + + const char *getOpcode(const uint16_t pos) + { + opcode_size = 0; + buffer[0]=0; + const char *base = getBase(pos); + + if (strstr(base, "4x")) opcode_size+=2; + if (strstr(base, "2x")) opcode_size+=1; + if (strstr(base, "Xx")) opcode_size+=1; + printOpcode(pos); + return buffer; + } + + const int getOpcodeSize(const uint16_t pos) + { + opcode_size = 0; + const char *base = getBase(pos); + + if (strstr(base, "4x")) opcode_size+=2; + if (strstr(base, "2x")) opcode_size+=1; + if (strstr(base, "Xx")) opcode_size+=1; + return opcode_size; + } + + const char *getSymbol(const uint16_t pos) + { + return symbols[pos]; + } + + void setSymbol(const uint16_t pos, const char *sym) + { + if (sym) { + strcpy(symbols[pos], sym); + } else { + symbols[pos][0] = 0; + } + used_symbols.clear(); + for (int i=0; i<65536; ++i) if (symbols[i][0]!=0) used_symbols.push_back(i); + saveSymbols(); + } + + const int getNumSymbols() + { + return used_symbols.size(); + } + + const uint16_t getSymbolAddress(const int pos) + { + return used_symbols[pos]; + } + + +} diff --git a/sm83dis.h b/sm83dis.h new file mode 100644 index 0000000..7e1a359 --- /dev/null +++ b/sm83dis.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +namespace sm83dis +{ + void loadSymbols(); + void saveSymbols(); + const char *getAsm(const uint16_t pos); + const char *getOpcode(const uint16_t pos); + const int getOpcodeSize(const uint16_t pos); + const char *getSymbol(const uint16_t pos); + void setSymbol(const uint16_t pos, const char *sym); + + const int getNumSymbols(); + const uint16_t getSymbolAddress(const int pos); +} diff --git a/ui.cpp b/ui.cpp new file mode 100644 index 0000000..abbda53 --- /dev/null +++ b/ui.cpp @@ -0,0 +1,101 @@ +#include "ui.h" +#include + +namespace ui +{ + 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}, + }; + + SDL_Renderer *ren = nullptr; + SDL_Texture *tex = nullptr; + + uint8_t offset_x = 0; + uint8_t offset_y = 0; + + bool clicked = false; + + SDL_Texture * createtexture(SDL_Renderer *renderer) + { + SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, SDL_LoadBMP("font.bmp")); + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + return texture; + } + + void setrenderer(SDL_Renderer *renderer, SDL_Texture *texture) + { + if (ren==renderer) return; + ren = renderer; + tex = texture; + offset_x = offset_y = 0; + } + + void setoffset(uint8_t x, uint8_t y) + { + offset_x = x; + offset_y = y; + } + + 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 printvoidrect(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_RenderDrawRect(ren, &rect); + } + + void printchar(int x, int y, char chr, uint8_t color) + { + 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 + +namespace ui +{ + #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 + + SDL_Texture * createtexture(SDL_Renderer *renderer); + void setrenderer(SDL_Renderer *renderer, SDL_Texture *texture); + void setoffset(uint8_t x, uint8_t y); + + void box(int x, int y, int w, int h, uint8_t color); + void printrect(int x, int y, int w, int h, uint8_t color); + void printvoidrect(int x, int y, int w, int h, uint8_t color); + void printchar(int x, int y, char chr, uint8_t color=255); + void printtxt(int x, int y, const char *text, uint8_t color); + + void setClicked(const bool value); + const bool getClicked(); +} diff --git a/ui_menu.cpp b/ui_menu.cpp new file mode 100644 index 0000000..e0e02e9 --- /dev/null +++ b/ui_menu.cpp @@ -0,0 +1,142 @@ +#include "ui_menu.h" +#include "ui.h" +#include +#include + +namespace ui +{ + namespace menu + { + #define OPTION_TYPE_NORMAL 0 + #define OPTION_TYPE_SEPARATOR 1 + #define OPTION_TYPE_BOOLEAN 2 + + struct option_t + { + std::string label; + int type; + int value; + int (*callback)(int); + }; + + struct menu_t + { + std::string label; + SDL_Rect rect; + std::vector options; + }; + + void(*exit_callback)(void) = nullptr; + std::vector menus; + int visible_menu = -1; + int menu_x = 0; + + void init() + { + // No se si hi ha algo que fer acĂ­... + } + + void show() + { + int mx, my; + Uint32 mb = SDL_GetMouseState(&mx, &my); + mx=mx/CHR_W; my=my/CHR_H; + int w; + ui::printrect(0, 0, 320, 1, COLOR_BLACK); + int opt_pos=1; + int index=0; + for (auto &menu : menus) + { + const int text_size = (menu.label.size()+2); + uint8_t text_color = COLOR_WHITE; + if (my<1 && mx>=opt_pos && mx=menu_x && mx + +namespace ui +{ + namespace window + { + struct window_t + { + Uint32 window; + bool (*callback)(SDL_Event*); + }; + std::vector windows; + + void registerWindow(Uint32 window, bool(*callback)(SDL_Event*)) + { + for (auto win : windows) if (win.window == window) return; + windows.push_back((window_t){window, callback}); + } + + void unregisterWindow(Uint32 window) + { + for (auto win = windows.begin(); win != windows.end(); win++) if ((*win).window == window) { windows.erase(win); return; } + } + + bool sendEvent(Uint32 window, SDL_Event *e) + { + for (auto win : windows) if (win.window == window) return win.callback(e); + return true; + } + + } +} diff --git a/ui_window.h b/ui_window.h new file mode 100644 index 0000000..1ff0983 --- /dev/null +++ b/ui_window.h @@ -0,0 +1,12 @@ +#pragma once +#include + +namespace ui +{ + namespace window + { + void registerWindow(Uint32 window, bool(*callback)(SDL_Event *e)); + void unregisterWindow(Uint32 window); + bool sendEvent(Uint32 window, SDL_Event *e); + } +}