- [NEW] Modul sm83dis per a mostrar el desensamblat del codi completat - [NEW] Afegits moduls ui, ui_menu i ui_window, i el font.bmp, quasi tal qual des del projecte z80
173 lines
9.6 KiB
C++
173 lines
9.6 KiB
C++
#include "sm83dis.h"
|
|
#include "sm83.h"
|
|
#include "mem.h"
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <vector>
|
|
#include <bits/stdc++.h>
|
|
|
|
namespace sm83dis
|
|
{
|
|
char buffer[256];
|
|
int opcode_size = 0;
|
|
char symbols[65536][15];
|
|
std::vector<uint16_t> 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];
|
|
}
|
|
|
|
|
|
}
|