mirror of
https://github.com/ksherlock/x65.git
synced 2024-12-27 13:29:18 +00:00
Disassembler improvements and c64 labels file
- Adding a labels file with all the c64 hardware addresses - Labels are tracked outside of the binary file range - Zero page tracking - Improved code vs data tracking a bit
This commit is contained in:
parent
6cbf7f8754
commit
9cdfeeb0ca
@ -26,6 +26,9 @@ x65dsasm binary disasm.txt [$skip[-$end]] [addr=$xxxx] [cpu=6502/65C02/65816]
|
||||
|
||||
### Updates
|
||||
|
||||
* c64.lbl file defining all c64 hardware addresses
|
||||
* Tracking label references outside of the code including zero page
|
||||
* Data / Code distinction improvements
|
||||
* **Local labels** to improve code readability
|
||||
* Improvements to code vs data determination
|
||||
* Instrument labels through labels text file
|
||||
|
75
disassembler/c64.lbl
Normal file
75
disassembler/c64.lbl
Normal file
@ -0,0 +1,75 @@
|
||||
6510_Port_Data_Direction = 0 data
|
||||
6510_Port_Data = 1 data
|
||||
C64_System_Interrupt = $314-$316 data
|
||||
C64_System_NMI = $318-$31a data
|
||||
Vic_Sprite_Pos = $d000-$d011 data
|
||||
Vic_Screen_Ctrl = $d011 data
|
||||
Vic_Raster_Line = $d012 data
|
||||
Vic_Light_Pen = $d013-$d015 data
|
||||
Vic_Sprite_Enable = $d015 data
|
||||
Vic_Sprite_Ctrl = $d016 data
|
||||
Vic_Sprite_Height_Dbl = $d017 data
|
||||
Vic_Memory_Setup = $d018 data
|
||||
Vic_Int_Status = $d019-$d01b data
|
||||
Vic_Sprite_Pri = $d01b data
|
||||
Vic_Sprite_MultiCol = $d01C data
|
||||
Vic_Sprite_Width_Dbl = $d01d data
|
||||
Vic_Sprite_Sprite_Coll = $d01e data
|
||||
Vic_Sprite_Background_Coll = $d01f data
|
||||
Vic_Border_Color = $d020 data
|
||||
Vic_Back_Color = $d021-$d025 data
|
||||
Vic_Sprite_Color_Extra = $d025-$d027 data
|
||||
Vic_Sprite_Color = $d027-$d02f data
|
||||
Vic = $d02f-$d400 data
|
||||
SID_Voice1_Freq = $d400-$d402 data
|
||||
SID_Voice1_Pulse = $d402-$d404 data
|
||||
SID_Voice1_Ctrl = $d404 data
|
||||
SID_Voice1_AttackDecay = $d405 data
|
||||
SID_Voice1_SustainRelease = $d406 data
|
||||
SID_Voice2_Freq = $d407-$d409 data
|
||||
SID_Voice2_Pulse = $d409-$d40b data
|
||||
SID_Voice2_Ctrl = $d40b data
|
||||
SID_Voice2_AttackDecay = $d40c data
|
||||
SID_Voice2_SustainRelease = $d40d data
|
||||
SID_Voice3_Freq = $d40e-$d410 data
|
||||
SID_Voice3_Pulse = $d410-$d412 data
|
||||
SID_Voice3_Ctrl = $d412 data
|
||||
SID_Voice3_AttackDecay = $d413 data
|
||||
SID_Voice3_SustainRelease = $d414 data
|
||||
SID_Filter_Cutoff = $d415-$d417 data
|
||||
SID_Filter_Ctrl = $d417 data
|
||||
SID_Volume_Filter_Mode = $d418 data
|
||||
SID_Paddles = $d419-$d41b data
|
||||
SID_Voice3_Wave_Out = $d41b data
|
||||
SID_Voice3_ADSR_Out = $d41c data
|
||||
SID = $D41d-$D800 data
|
||||
ColorRam = $D800-$DC00 data
|
||||
CIA1_PortA_KBD_Joy2 = $dc00 data
|
||||
CIA1_PortB_KBD_Joy1 = $dc01 data
|
||||
CIA1_PortA_Data_Dir = $dc02 data
|
||||
CIA1_PortB_Data_Dir = $dc03 data
|
||||
CIA1_TimerA = $dc04-$dc06 data
|
||||
CIA1_TimerB = $dc06-$dc08 data
|
||||
CIA1_TimeOfDay = $dc08-$dc0c data
|
||||
CIA1_Serial_Shift = $dc0c data
|
||||
CIA1_Interrupt_Ctrl_Status = $dc0d data
|
||||
CIA1_TimerA_Ctrl = $dc0e data
|
||||
CIA1_TimerB_Ctrl = $dc0f data
|
||||
CIA1 = $DC10-$DD00 data
|
||||
CIA2_PortA_Serial = $dd00 data
|
||||
CIA2_PortB_RS232 = $dd01 data
|
||||
CIA2_PortA_Data_Dir = $dd02 data
|
||||
CIA2_PortB_Data_Dir = $dd03 data
|
||||
CIA2_TimerA = $dd04-$dd06 data
|
||||
CIA2_TimerB = $dd06-$dd08 data
|
||||
CIA2_TimeOfDay = $dd08-$dd0c data
|
||||
CIA2_Serial_Shift = $dd0c data
|
||||
CIA1_Interrupt_Ctrl_Status = $dd0d data
|
||||
CIA2_TimerA_Ctrl = $dd0e data
|
||||
CIA2_TimerB_Ctrl = $dd0f data
|
||||
CIA2 = $dd10-$de00 data
|
||||
IO_Area1 = $de00-$df00 data
|
||||
IO_Area2 = $df00-$e000 data
|
||||
Interrupt_NMI_Address = $fffa-$fffc data
|
||||
Reset_Address = $fffc-$fffe data
|
||||
Interrupt_Address = $fffe-$10000 data
|
@ -1,6 +1,5 @@
|
||||
|
||||
//
|
||||
// x65.cpp
|
||||
//
|
||||
// x65dsasm.cpp
|
||||
//
|
||||
//
|
||||
// Created by Carl-Henrik Skårstedt on 9/23/15.
|
||||
@ -944,6 +943,7 @@ enum RefType {
|
||||
RT_JUMP, // jmp
|
||||
RT_JSR, // jsr
|
||||
RT_DATA, // lda $...
|
||||
RT_ZP, // using a zero page / direct page instruction
|
||||
RT_COUNT
|
||||
};
|
||||
|
||||
@ -953,7 +953,7 @@ enum DataType {
|
||||
DT_PTRS
|
||||
};
|
||||
|
||||
const char *aRefNames[RT_COUNT] = { "???", "branch", "long branch", "jump", "subroutine", "data" };
|
||||
const char *aRefNames[RT_COUNT] = { "???", "branch", "long branch", "jump", "subroutine", "data", "zp" };
|
||||
|
||||
struct RefLink {
|
||||
int instr_addr;
|
||||
@ -1127,9 +1127,13 @@ void GetReferences(unsigned char *mem, size_t bytes, bool acc_16, bool ind_16, i
|
||||
type = RT_JUMP;
|
||||
else
|
||||
type = RT_DATA;
|
||||
} else if (mode == AM_ZP || mode == AM_ZP_REL || mode == AM_ZP_REL_L || mode == AM_ZP_REL_X || mode == AM_ZP_REL_Y ||
|
||||
mode == AM_ZP_X || mode == AM_ZP_Y || mode == AM_ZP_REL_L || mode == AM_ZP_REL_Y_L) {
|
||||
reference = mem[0];
|
||||
type = RT_ZP;
|
||||
}
|
||||
|
||||
if (reference >= start_addr && reference <= end_addr && type != RT_NONE) {
|
||||
if (/*reference >= start_addr && reference <= end_addr &&*/ reference>=0 && type != RT_NONE) {
|
||||
bool found = false;
|
||||
for (std::vector<RefAddr>::iterator i = refs.begin(); i != refs.end(); ++i) {
|
||||
if (i->address == reference || (reference>i->address && (reference-i->size)<i->address)) {
|
||||
@ -1163,16 +1167,24 @@ void GetReferences(unsigned char *mem, size_t bytes, bool acc_16, bool ind_16, i
|
||||
mem = mem_orig;
|
||||
bytes = bytes_orig;
|
||||
addr = addr_orig;
|
||||
int curr_label = init_data ? 1 : 0;
|
||||
int curr_label = 0;
|
||||
int prev_addr = -1;
|
||||
bool was_data = init_data>0;
|
||||
refs[curr_label].data = DT_CODE;
|
||||
bool separator = false;
|
||||
int prev_op = 0xff;
|
||||
addr += init_data;
|
||||
bytes -= init_data;
|
||||
mem += init_data;
|
||||
bool cutoff = false;
|
||||
|
||||
while (curr_label<(int)refs.size() && refs[curr_label].address<addr) {
|
||||
refs[curr_label].data = DT_DATA;
|
||||
++curr_label;
|
||||
}
|
||||
|
||||
if (curr_label<(int)refs.size())
|
||||
refs[curr_label].data = init_data ? DT_DATA : DT_CODE;
|
||||
|
||||
while (bytes && curr_label<(int)refs.size()) {
|
||||
unsigned char op = *mem++;
|
||||
int curr = addr;
|
||||
@ -1232,28 +1244,45 @@ void GetReferences(unsigned char *mem, size_t bytes, bool acc_16, bool ind_16, i
|
||||
} else {
|
||||
bool prev_data = was_data;
|
||||
was_data = separator && !(!was_data && ((op==0x4c || op==0x6c) && (prev_op==0x4c || prev_op==0x6c)));
|
||||
for (size_t j = 0; j<pRefs.size(); ++j) {
|
||||
RefType type = pRefs[j].type;
|
||||
if (!(pRefs[j].instr_addr>curr && type == RT_BRANCH) && type != RT_DATA) {
|
||||
was_data = false;
|
||||
prev_data = false;
|
||||
break;
|
||||
if (!prev_data) {
|
||||
for (size_t j = 0; j<pRefs.size(); ++j) {
|
||||
RefType type = pRefs[j].type;
|
||||
if (!(pRefs[j].instr_addr>curr && type == RT_BRANCH) && type != RT_DATA) {
|
||||
was_data = false;
|
||||
prev_data = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!was_data && prev_data) {
|
||||
bool only_data_ref = pRefs.size() ? true : false;
|
||||
if (!curr_label || refs[curr_label-1].data == DT_CODE) {
|
||||
for (size_t j = 0; j<pRefs.size(); ++j) {
|
||||
RefType type = pRefs[j].type;
|
||||
int ref_addr = pRefs[j].instr_addr;
|
||||
if (type != RT_DATA && (type != RT_BRANCH || ref_addr<addr)) {
|
||||
only_data_ref = false;
|
||||
if (type != RT_BRANCH)
|
||||
separator = false;
|
||||
}
|
||||
}
|
||||
was_data = only_data_ref;
|
||||
} else
|
||||
was_data = true;
|
||||
}
|
||||
|
||||
// check all references
|
||||
if (was_data) {
|
||||
for (size_t j = 0; j<pRefs.size(); ++j) {
|
||||
RefType type = pRefs[j].type;
|
||||
int ref_addr = pRefs[j].instr_addr;
|
||||
if (type != RT_DATA && (type != RT_BRANCH || ref_addr<addr)) {
|
||||
only_data_ref = false;
|
||||
if (type != RT_BRANCH)
|
||||
separator = false;
|
||||
RefLink &rl = pRefs[j];
|
||||
if (rl.type == RT_BRA_L || rl.type == RT_JSR || rl.type == RT_JUMP) {
|
||||
was_data = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
was_data = only_data_ref;
|
||||
}
|
||||
|
||||
refs[curr_label].separator = separator;
|
||||
refs[curr_label].data = was_data ? DT_DATA : DT_CODE;
|
||||
}
|
||||
@ -1271,6 +1300,12 @@ void GetReferences(unsigned char *mem, size_t bytes, bool acc_16, bool ind_16, i
|
||||
}
|
||||
}
|
||||
}
|
||||
if (refs[curr_label].pRefs->size()==0) {
|
||||
int lbl = curr_label;
|
||||
while (lbl && refs[lbl].pRefs->size()==0)
|
||||
lbl--;
|
||||
was_data = refs[lbl].data != DT_CODE;
|
||||
}
|
||||
}
|
||||
curr_label++;
|
||||
}
|
||||
@ -1323,13 +1358,8 @@ void GetReferences(unsigned char *mem, size_t bytes, bool acc_16, bool ind_16, i
|
||||
}
|
||||
|
||||
std::vector<RefAddr>::iterator k = refs.begin();
|
||||
if (k != refs.end()) {
|
||||
++k; // don't delete the initial label
|
||||
if (init_data && k != refs.end())
|
||||
++k; // don't delete the initial label
|
||||
}
|
||||
while (k!=refs.end()) {
|
||||
if (k->pRefs && k->pRefs->size()==0 && !k->label && !k->separator) {
|
||||
if (k->pRefs && k->pRefs->size()==0 && !k->label && !k->separator && k->address!=addr_orig) {
|
||||
delete k->pRefs;
|
||||
k = refs.erase(k);
|
||||
} else
|
||||
@ -1451,9 +1481,9 @@ void Disassemble(strref filename, unsigned char *mem, size_t bytes, bool acc_16,
|
||||
prv_addr = refs[k].address;
|
||||
}
|
||||
if (refs[lbl].label)
|
||||
out.sprintf("%s; Referenced from " STRREF_FMT " + $%x (%s)\n", spc,
|
||||
out.sprintf("%s; Referenced from " STRREF_FMT " + $%x (%s, $%02x)\n", spc,
|
||||
STRREF_ARG(refs[lbl].label), ref_addr - prv_addr,
|
||||
aRefNames[(*ref.pRefs)[j].type]);
|
||||
aRefNames[(*ref.pRefs)[j].type], ref_addr);
|
||||
else {
|
||||
out.sprintf("%s; Referenced from", spc);
|
||||
if (refs[lbl].local) {
|
||||
@ -1462,11 +1492,14 @@ void Disassemble(strref filename, unsigned char *mem, size_t bytes, bool acc_16,
|
||||
lbl_glb--;
|
||||
if (refs[lbl].label)
|
||||
out.append(refs[lbl].label);
|
||||
else
|
||||
out.sprintf_append(" %s_%d /", refs[lbl_glb].local ? ".l" : (refs[lbl_glb].data==DT_CODE ? "Code" : "Data"), refs[lbl_glb].number);
|
||||
else {
|
||||
RefAddr &ra = refs[lbl_glb];
|
||||
out.sprintf_append(" %s_%d /", ra.local ? ".l" : (ra.data==DT_CODE ? "Code" : (ra.address>=0 && ra.address<0x100 ? "zp" : "Data")), ra.number);
|
||||
}
|
||||
}
|
||||
out.sprintf_append(" %s_%d + $%x (%s)\n", refs[lbl].local ? ".l" : (refs[lbl].data==DT_CODE ? "Code" : "Data"),
|
||||
refs[lbl].number, ref_addr - prv_addr, aRefNames[(*ref.pRefs)[j].type]);
|
||||
RefAddr &ra = refs[lbl];
|
||||
out.sprintf_append(" %s_%d + $%x (%s, $%02x)\n", ra.local ? ".l" : (ra.data==DT_CODE ? "Code" : (ra.address>=0 && ra.address<0x100 ? "zp" : "Data")),
|
||||
ra.number, ref_addr - prv_addr, aRefNames[(*ref.pRefs)[j].type], ra.address);
|
||||
}
|
||||
} else
|
||||
out.sprintf("%s; Referenced from $%04x (%s)\n", spc, (*ref.pRefs)[j].instr_addr,
|
||||
@ -1474,19 +1507,27 @@ void Disassemble(strref filename, unsigned char *mem, size_t bytes, bool acc_16,
|
||||
fputs(out.c_str(), f);
|
||||
}
|
||||
}
|
||||
out.clear();
|
||||
if (refs[curr_label_index].comment)
|
||||
out.sprintf_append("%s; " STRREF_FMT"\n", spc, STRREF_ARG(refs[curr_label_index].comment));
|
||||
if (refs[curr_label_index].label)
|
||||
out.sprintf_append("%s" STRREF_FMT ": ; $%04x\n", spc,
|
||||
STRREF_ARG(refs[curr_label_index].label), addr);
|
||||
else
|
||||
out.sprintf_append("%s%s_%d: ; $%04x\n", spc,
|
||||
refs[curr_label_index].local ? ".l" : (refs[curr_label_index].data==DT_CODE ? "Code" : "Data"),
|
||||
refs[curr_label_index].number, addr);
|
||||
if (addr>refs[curr_label_index].address) {
|
||||
if (ref.label)
|
||||
out.sprintf(STRREF_FMT " = %02x\n", STRREF_ARG(ref.label), ref.address);
|
||||
else
|
||||
out.sprintf("%s_%d = $%02x\n", ref.local ? ".l" : (ref.data==DT_CODE ? "Code" : (ref.address>=0 && ref.address<0x100 ? "zp" : "Data")),
|
||||
ref.number, ref.address);
|
||||
} else {
|
||||
out.clear();
|
||||
if (ref.comment)
|
||||
out.sprintf_append("%s; " STRREF_FMT"\n", spc, STRREF_ARG(ref.comment));
|
||||
if (ref.label)
|
||||
out.sprintf_append("%s" STRREF_FMT ": ; $%04x\n", spc,
|
||||
STRREF_ARG(ref.label), ref.address);
|
||||
else
|
||||
out.sprintf_append("%s%s_%d: ; $%04x\n", spc,
|
||||
ref.local ? ".l" : (ref.data==DT_CODE ? "Code" : (ref.address>=0 && ref.address<0x100 ? "zp" : "Data")),
|
||||
ref.number, ref.address);
|
||||
}
|
||||
fputs(out.c_str(), f);
|
||||
is_data = !!refs[curr_label_index].data;
|
||||
is_ptrs = is_data && refs[curr_label_index].data==DT_PTRS;
|
||||
is_data = !!ref.data;
|
||||
is_ptrs = is_data && ref.data==DT_PTRS;
|
||||
separator = false;
|
||||
curr_label_index++;
|
||||
}
|
||||
@ -1507,10 +1548,12 @@ void Disassemble(strref filename, unsigned char *mem, size_t bytes, bool acc_16,
|
||||
if (refs[lbl].label) {
|
||||
out.append(refs[lbl].label);
|
||||
out.sprintf_append(" ; $%04x " STRREF_FMT "\n", a, STRREF_ARG(refs[lbl].comment));
|
||||
} else
|
||||
out.sprintf_append("%s%s_%d: ; $%04x%s\n", spc,
|
||||
refs[lbl].local ? ".l" : (refs[lbl].data==DT_CODE ? "Code" : "Data"),
|
||||
refs[lbl].number, a, STRREF_ARG(refs[lbl].comment));
|
||||
} else {
|
||||
RefAddr &ra = refs[lbl];
|
||||
out.sprintf_append("%s%s_%d: ; $%04x" STRREF_FMT "\n", spc,
|
||||
ra.local ? ".l" : (ra.data==DT_CODE ? "Code" : (ra.address>=0 && ra.address<0x100 ? "zp" : "Data")),
|
||||
ra.number, a, STRREF_ARG(ra.comment));
|
||||
}
|
||||
} else
|
||||
out.sprintf_append("$%04x\n", a);
|
||||
fputs(out.c_str(), f);
|
||||
@ -1618,13 +1661,16 @@ void Disassemble(strref filename, unsigned char *mem, size_t bytes, bool acc_16,
|
||||
if (reference == refs[i].address ||
|
||||
(reference>=start_addr &&reference<=end_addr && reference>=refs[i].address)) {
|
||||
if (i==(refs.size()-1) || reference<refs[i+1].address) {
|
||||
if (refs[i].label)
|
||||
lblname.copy(refs[i].label);
|
||||
RefAddr &ra = refs[i];
|
||||
if (ra.label)
|
||||
lblname.copy(ra.label);
|
||||
else
|
||||
lblname.sprintf("%s_%d", refs[i].local ? ".l" : (refs[i].data==DT_CODE ? "Code" : "Data"), refs[i].number);
|
||||
lblcmt = refs[i].comment;
|
||||
if (reference > refs[i].address)
|
||||
lblname.sprintf_append(" + $%x", reference - refs[i].address);
|
||||
lblname.sprintf("%s_%d",
|
||||
ra.local ? ".l" : (ra.data==DT_CODE ? "Code" :
|
||||
(ra.address>=0 && ra.address<0x100 ? "zp" : "Data")), ra.number);
|
||||
lblcmt = ra.comment;
|
||||
if (reference > ra.address)
|
||||
lblname.sprintf_append(" + $%x", reference - ra.address);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user