mirror of
https://github.com/ksherlock/x65.git
synced 2025-01-16 23:30:02 +00:00
Error Fix III, Switching default section to be relative section
- Merlin support broke colon-overrides-directive-as-label trick, fixed. - Relative section fixes - If no section is specified the default section will be relative. If a binary output is requested the default section is applied to address $1000
This commit is contained in:
parent
83ffae8812
commit
d17fbfb710
75
asm6502.cpp
75
asm6502.cpp
@ -820,7 +820,7 @@ void Asm::Cleanup() {
|
|||||||
labels.clear();
|
labels.clear();
|
||||||
macros.clear();
|
macros.clear();
|
||||||
allSections.clear();
|
allSections.clear();
|
||||||
SetSection(strref("default"), 0x1000);
|
SetSection(strref("default"));//, 0x10001);
|
||||||
current_section = &allSections[0];
|
current_section = &allSections[0];
|
||||||
syntax = SYNTAX_SANE;
|
syntax = SYNTAX_SANE;
|
||||||
scope_depth = 0;
|
scope_depth = 0;
|
||||||
@ -911,6 +911,7 @@ void Asm::SetSection(strref name, int address)
|
|||||||
|
|
||||||
void Asm::SetSection(strref name)
|
void Asm::SetSection(strref name)
|
||||||
{
|
{
|
||||||
|
// should same name section within the same file be the same section?
|
||||||
/* if (name) {
|
/* if (name) {
|
||||||
for (std::vector<Section>::iterator i = allSections.begin(); i!=allSections.end(); ++i) {
|
for (std::vector<Section>::iterator i = allSections.begin(); i!=allSections.end(); ++i) {
|
||||||
if (i->name && name.same_str(i->name)) {
|
if (i->name && name.same_str(i->name)) {
|
||||||
@ -955,11 +956,18 @@ void Asm::EndSection() {
|
|||||||
// Return an appropriate section for exporting a binary
|
// Return an appropriate section for exporting a binary
|
||||||
Section& Asm::ExportSection() {
|
Section& Asm::ExportSection() {
|
||||||
std::vector<Section>::iterator i = allSections.end();
|
std::vector<Section>::iterator i = allSections.end();
|
||||||
|
bool hasRelativeSection = false;
|
||||||
while (i != allSections.begin()) {
|
while (i != allSections.begin()) {
|
||||||
--i;
|
--i;
|
||||||
|
hasRelativeSection = hasRelativeSection || i->IsRelativeSection();
|
||||||
if (!i->IsDummySection() && !i->IsMergedSection() && !i->IsRelativeSection())
|
if (!i->IsDummySection() && !i->IsMergedSection() && !i->IsRelativeSection())
|
||||||
return *i;
|
return *i;
|
||||||
}
|
}
|
||||||
|
if (hasRelativeSection) {
|
||||||
|
// no fixed sections, make a new fixed section and return that for exporting.
|
||||||
|
SetSection(strref(), 0x1000);
|
||||||
|
LinkSections(strref());
|
||||||
|
}
|
||||||
return CurrSection();
|
return CurrSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -971,7 +979,7 @@ StatusCode Asm::LinkSections(strref name) {
|
|||||||
|
|
||||||
int section_id = 0;
|
int section_id = 0;
|
||||||
for (std::vector<Section>::iterator i = allSections.begin(); i != allSections.end(); ++i) {
|
for (std::vector<Section>::iterator i = allSections.begin(); i != allSections.end(); ++i) {
|
||||||
if (i->name.same_str_case(name) && i->IsRelativeSection() && !i->IsMergedSection()) {
|
if ((!name || i->name.same_str_case(name)) && i->IsRelativeSection() && !i->IsMergedSection()) {
|
||||||
// found a section to link!
|
// found a section to link!
|
||||||
Section &s = *i;
|
Section &s = *i;
|
||||||
// Get base addresses
|
// Get base addresses
|
||||||
@ -979,6 +987,7 @@ StatusCode Asm::LinkSections(strref name) {
|
|||||||
|
|
||||||
int section_address = CurrSection().GetPC();
|
int section_address = CurrSection().GetPC();
|
||||||
unsigned char *section_out = CurrSection().curr;
|
unsigned char *section_out = CurrSection().curr;
|
||||||
|
if (s.output)
|
||||||
memcpy(section_out, s.output, s.size());
|
memcpy(section_out, s.output, s.size());
|
||||||
CurrSection().address += (int)s.size();
|
CurrSection().address += (int)s.size();
|
||||||
CurrSection().curr += s.size();
|
CurrSection().curr += s.size();
|
||||||
@ -1389,7 +1398,7 @@ EvalOperator Asm::RPNToken_Merlin(strref &expression, int pc, int scope_pc, int
|
|||||||
if (expression[1]=='0' || expression[1]=='1') {
|
if (expression[1]=='0' || expression[1]=='1') {
|
||||||
++expression; value = expression.abinarytoui_skip(); return EVOP_VAL; }
|
++expression; value = expression.abinarytoui_skip(); return EVOP_VAL; }
|
||||||
if (scope_end_pc<0) return EVOP_NRY;
|
if (scope_end_pc<0) return EVOP_NRY;
|
||||||
++expression; value = scope_end_pc; return EVOP_VAL;
|
++expression; value = scope_end_pc; section = CurrSection().IsRelativeSection() ? SectionId() : -1; return EVOP_VAL;
|
||||||
case '|':
|
case '|':
|
||||||
case '.': ++expression; return EVOP_OR; // MERLIN: . is or, | is not used
|
case '.': ++expression; return EVOP_OR; // MERLIN: . is or, | is not used
|
||||||
case '^': ++expression; return EVOP_EOR;
|
case '^': ++expression; return EVOP_EOR;
|
||||||
@ -1404,7 +1413,7 @@ EvalOperator Asm::RPNToken_Merlin(strref &expression, int pc, int scope_pc, int
|
|||||||
if (c == '!' && (prev_op == EVOP_VAL || prev_op == EVOP_RPR)) { ++expression; return EVOP_EOR; }
|
if (c == '!' && (prev_op == EVOP_VAL || prev_op == EVOP_RPR)) { ++expression; return EVOP_EOR; }
|
||||||
else if (c == '!' && !(expression + 1).len_label()) {
|
else if (c == '!' && !(expression + 1).len_label()) {
|
||||||
if (scope_pc < 0) return EVOP_NRY; // ! by itself is current scope, !+label char is a local label
|
if (scope_pc < 0) return EVOP_NRY; // ! by itself is current scope, !+label char is a local label
|
||||||
++expression; value = scope_pc; return EVOP_VAL;
|
++expression; value = scope_pc; section = CurrSection().IsRelativeSection() ? SectionId() : -1; return EVOP_VAL;
|
||||||
} else if (strref::is_number(c)) {
|
} else if (strref::is_number(c)) {
|
||||||
if (prev_op == EVOP_VAL) return EVOP_STP; // value followed by value doesn't make sense, stop
|
if (prev_op == EVOP_VAL) return EVOP_STP; // value followed by value doesn't make sense, stop
|
||||||
value = expression.atoi_skip(); return EVOP_VAL;
|
value = expression.atoi_skip(); return EVOP_VAL;
|
||||||
@ -1450,7 +1459,7 @@ EvalOperator Asm::RPNToken(strref &expression, int pc, int scope_pc, int scope_e
|
|||||||
case '%': // % means both binary and scope closure, disambiguate!
|
case '%': // % means both binary and scope closure, disambiguate!
|
||||||
if (expression[1] == '0' || expression[1] == '1') { ++expression; value = expression.abinarytoui_skip(); return EVOP_VAL; }
|
if (expression[1] == '0' || expression[1] == '1') { ++expression; value = expression.abinarytoui_skip(); return EVOP_VAL; }
|
||||||
if (scope_end_pc<0) return EVOP_NRY;
|
if (scope_end_pc<0) return EVOP_NRY;
|
||||||
++expression; value = scope_end_pc; return EVOP_VAL;
|
++expression; value = scope_end_pc; section = CurrSection().IsRelativeSection() ? SectionId() : -1; return EVOP_VAL;
|
||||||
case '|': ++expression; return EVOP_OR;
|
case '|': ++expression; return EVOP_OR;
|
||||||
case '^': ++expression; return EVOP_EOR;
|
case '^': ++expression; return EVOP_EOR;
|
||||||
case '&': ++expression; return EVOP_AND;
|
case '&': ++expression; return EVOP_AND;
|
||||||
@ -1462,7 +1471,7 @@ EvalOperator Asm::RPNToken(strref &expression, int pc, int scope_pc, int scope_e
|
|||||||
default: { // ! by itself is current scope, !+label char is a local label
|
default: { // ! by itself is current scope, !+label char is a local label
|
||||||
if (c == '!' && !(expression + 1).len_label()) {
|
if (c == '!' && !(expression + 1).len_label()) {
|
||||||
if (scope_pc < 0) return EVOP_NRY;
|
if (scope_pc < 0) return EVOP_NRY;
|
||||||
++expression; value = scope_pc; return EVOP_VAL;
|
++expression; value = scope_pc; section = CurrSection().IsRelativeSection() ? SectionId() : -1; return EVOP_VAL;
|
||||||
} else if (strref::is_number(c)) {
|
} else if (strref::is_number(c)) {
|
||||||
if (prev_op == EVOP_VAL) return EVOP_STP; // value followed by value doesn't make sense, stop
|
if (prev_op == EVOP_VAL) return EVOP_STP; // value followed by value doesn't make sense, stop
|
||||||
value = expression.atoi_skip(); return EVOP_VAL;
|
value = expression.atoi_skip(); return EVOP_VAL;
|
||||||
@ -1718,19 +1727,20 @@ void Asm::AddLateEval(strref label, int pc, int scope_pc, strref expression, Lat
|
|||||||
// any related late label evaluators that can now be evaluated.
|
// any related late label evaluators that can now be evaluated.
|
||||||
StatusCode Asm::CheckLateEval(strref added_label, int scope_end)
|
StatusCode Asm::CheckLateEval(strref added_label, int scope_end)
|
||||||
{
|
{
|
||||||
std::vector<LateEval>::iterator i = lateEval.begin();
|
|
||||||
bool evaluated_label = true;
|
bool evaluated_label = true;
|
||||||
strref new_labels[MAX_LABELS_EVAL_ALL];
|
strref new_labels[MAX_LABELS_EVAL_ALL];
|
||||||
int num_new_labels = 0;
|
int num_new_labels = 0;
|
||||||
if (added_label)
|
if (added_label)
|
||||||
new_labels[num_new_labels++] = added_label;
|
new_labels[num_new_labels++] = added_label;
|
||||||
|
|
||||||
|
bool all = !added_label;
|
||||||
|
std::vector<LateEval>::iterator i = lateEval.begin();
|
||||||
while (evaluated_label) {
|
while (evaluated_label) {
|
||||||
evaluated_label = false;
|
evaluated_label = false;
|
||||||
while (i != lateEval.end()) {
|
while (i != lateEval.end()) {
|
||||||
int value = 0;
|
int value = 0;
|
||||||
// check if this expression is related to the late change (new label or end of scope)
|
// check if this expression is related to the late change (new label or end of scope)
|
||||||
bool check = num_new_labels==MAX_LABELS_EVAL_ALL;
|
bool check = all || num_new_labels==MAX_LABELS_EVAL_ALL;
|
||||||
for (int l=0; l<num_new_labels && !check; l++)
|
for (int l=0; l<num_new_labels && !check; l++)
|
||||||
check = i->expression.find(new_labels[l]) >= 0;
|
check = i->expression.find(new_labels[l]) >= 0;
|
||||||
if (!check && scope_end>0) {
|
if (!check && scope_end>0) {
|
||||||
@ -1747,9 +1757,9 @@ StatusCode Asm::CheckLateEval(strref added_label, int scope_end)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (check) {
|
if (check) {
|
||||||
int ret = EvalExpression(i->expression, i->address, i->scope, scope_end,
|
StatusCode ret = EvalExpression(i->expression, i->address, i->scope, scope_end,
|
||||||
i->type==LateEval::LET_BRANCH ? SectionId() : -1, value);
|
i->type==LateEval::LET_BRANCH ? SectionId() : -1, value);
|
||||||
if (ret == STATUS_OK) {
|
if (ret == STATUS_OK || ret==STATUS_RELATIVE_SECTION) {
|
||||||
// Check if target section merged with another section
|
// Check if target section merged with another section
|
||||||
size_t trg = i->target;
|
size_t trg = i->target;
|
||||||
int sec = i->section;
|
int sec = i->section;
|
||||||
@ -1759,18 +1769,36 @@ StatusCode Asm::CheckLateEval(strref added_label, int scope_end)
|
|||||||
sec = allSections[sec].merged_section;
|
sec = allSections[sec].merged_section;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool resolved = true;
|
||||||
switch (i->type) {
|
switch (i->type) {
|
||||||
case LateEval::LET_BRANCH:
|
case LateEval::LET_BRANCH:
|
||||||
value -= i->address+1;
|
value -= i->address+1;
|
||||||
if (value<-128 || value>127)
|
if (value<-128 || value>127)
|
||||||
return ERROR_BRANCH_OUT_OF_RANGE;
|
return ERROR_BRANCH_OUT_OF_RANGE;
|
||||||
|
if (ret==STATUS_RELATIVE_SECTION)
|
||||||
allSections[sec].SetByte(trg, value);
|
allSections[sec].SetByte(trg, value);
|
||||||
break;
|
break;
|
||||||
case LateEval::LET_BYTE:
|
case LateEval::LET_BYTE:
|
||||||
|
if (ret==STATUS_RELATIVE_SECTION) {
|
||||||
|
if (i->section<0)
|
||||||
|
resolved = false;
|
||||||
|
else {
|
||||||
|
allSections[i->section].AddReloc(lastEvalValue, i->address, lastEvalSection,
|
||||||
|
lastEvalPart==Reloc::HI_BYTE ? Reloc::HI_BYTE : Reloc::LO_BYTE);
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
allSections[sec].SetByte(trg, value);
|
allSections[sec].SetByte(trg, value);
|
||||||
break;
|
break;
|
||||||
case LateEval::LET_ABS_REF:
|
case LateEval::LET_ABS_REF:
|
||||||
|
if (ret==STATUS_RELATIVE_SECTION) {
|
||||||
|
if (i->section<0)
|
||||||
|
resolved = false;
|
||||||
|
else {
|
||||||
|
allSections[i->section].AddReloc(lastEvalValue, i->address, lastEvalSection, lastEvalPart);
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
allSections[sec].SetWord(trg, value);
|
allSections[sec].SetWord(trg, value);
|
||||||
break;
|
break;
|
||||||
case LateEval::LET_LABEL: {
|
case LateEval::LET_LABEL: {
|
||||||
@ -1789,12 +1817,14 @@ StatusCode Asm::CheckLateEval(strref added_label, int scope_end)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (resolved)
|
||||||
i = lateEval.erase(i);
|
i = lateEval.erase(i);
|
||||||
} else
|
} else
|
||||||
++i;
|
++i;
|
||||||
} else
|
} else
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
all = false;
|
||||||
added_label.clear();
|
added_label.clear();
|
||||||
}
|
}
|
||||||
return STATUS_OK;
|
return STATUS_OK;
|
||||||
@ -2311,6 +2341,7 @@ DirectiveName aDirectiveNames[] {
|
|||||||
{ "ORG", AD_ORG },
|
{ "ORG", AD_ORG },
|
||||||
{ "LOAD", AD_LOAD },
|
{ "LOAD", AD_LOAD },
|
||||||
{ "SECTION", AD_SECTION },
|
{ "SECTION", AD_SECTION },
|
||||||
|
// { "SEG", AD_SECTION }, // DASM version of SECTION
|
||||||
{ "LINK", AD_LINK },
|
{ "LINK", AD_LINK },
|
||||||
{ "ALIGN", AD_ALIGN },
|
{ "ALIGN", AD_ALIGN },
|
||||||
{ "MACRO", AD_MACRO },
|
{ "MACRO", AD_MACRO },
|
||||||
@ -2386,6 +2417,13 @@ StatusCode Asm::ApplyDirective(AssemblerDirective dir, strref line, strref sourc
|
|||||||
error = error == STATUS_NOT_READY ? ERROR_TARGET_ADDRESS_MUST_EVALUATE_IMMEDIATELY : error;
|
error = error == STATUS_NOT_READY ? ERROR_TARGET_ADDRESS_MUST_EVALUATE_IMMEDIATELY : error;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Section immediately followed by ORG reassigns that section to be fixed
|
||||||
|
if (CurrSection().size()==0 && !CurrSection().IsDummySection()) {
|
||||||
|
CurrSection().start_address = addr;
|
||||||
|
CurrSection().load_address = addr;
|
||||||
|
CurrSection().address = addr;
|
||||||
|
CurrSection().address_assigned = true;
|
||||||
|
} else
|
||||||
SetSection(strref(), addr);
|
SetSection(strref(), addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2463,14 +2501,14 @@ StatusCode Asm::ApplyDirective(AssemblerDirective dir, strref line, strref sourc
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AD_WORDS: // words: add words (16 bit values) by comma separated values
|
case AD_WORDS: // words: add words (16 bit values) by comma separated values
|
||||||
while (strref exp = line.split_token_trim(',')) {
|
while (strref exp_w = line.split_token_trim(',')) {
|
||||||
int value = 0;
|
int value = 0;
|
||||||
if (!CurrSection().IsDummySection()) {
|
if (!CurrSection().IsDummySection()) {
|
||||||
error = EvalExpression(exp, CurrSection().GetPC(), scope_address[scope_depth], -1, -1, value);
|
error = EvalExpression(exp_w, CurrSection().GetPC(), scope_address[scope_depth], -1, -1, value);
|
||||||
if (error>STATUS_NOT_READY)
|
if (error>STATUS_NOT_READY)
|
||||||
break;
|
break;
|
||||||
else if (error==STATUS_NOT_READY)
|
else if (error==STATUS_NOT_READY)
|
||||||
AddLateEval(CurrSection().GetPC(), scope_address[scope_depth], exp, source_file, LateEval::LET_ABS_REF);
|
AddLateEval(CurrSection().GetPC(), scope_address[scope_depth], exp_w, source_file, LateEval::LET_ABS_REF);
|
||||||
else if (error == STATUS_RELATIVE_SECTION) {
|
else if (error == STATUS_RELATIVE_SECTION) {
|
||||||
CurrSection().AddReloc(lastEvalValue, CurrSection().GetPC(), lastEvalSection, lastEvalPart);
|
CurrSection().AddReloc(lastEvalValue, CurrSection().GetPC(), lastEvalSection, lastEvalPart);
|
||||||
value = 0;
|
value = 0;
|
||||||
@ -2491,14 +2529,14 @@ StatusCode Asm::ApplyDirective(AssemblerDirective dir, strref line, strref sourc
|
|||||||
++line;
|
++line;
|
||||||
line.skip_whitespace();
|
line.skip_whitespace();
|
||||||
}
|
}
|
||||||
while (strref exp = line.split_token_trim(',')) {
|
while (strref exp_dc = line.split_token_trim(',')) {
|
||||||
int value = 0;
|
int value = 0;
|
||||||
if (!CurrSection().IsDummySection()) {
|
if (!CurrSection().IsDummySection()) {
|
||||||
error = EvalExpression(exp, CurrSection().GetPC(), scope_address[scope_depth], -1, -1, value);
|
error = EvalExpression(exp_dc, CurrSection().GetPC(), scope_address[scope_depth], -1, -1, value);
|
||||||
if (error > STATUS_NOT_READY)
|
if (error > STATUS_NOT_READY)
|
||||||
break;
|
break;
|
||||||
else if (error == STATUS_NOT_READY)
|
else if (error == STATUS_NOT_READY)
|
||||||
AddLateEval(CurrSection().GetPC(), scope_address[scope_depth], exp, source_file, LateEval::LET_BYTE);
|
AddLateEval(CurrSection().GetPC(), scope_address[scope_depth], exp_dc, source_file, words ? LateEval::LET_ABS_REF : LateEval::LET_BYTE);
|
||||||
else if (error == STATUS_RELATIVE_SECTION) {
|
else if (error == STATUS_RELATIVE_SECTION) {
|
||||||
value = 0;
|
value = 0;
|
||||||
if (words)
|
if (words)
|
||||||
@ -3125,7 +3163,8 @@ StatusCode Asm::BuildLine(OP_ID *pInstr, int numInstructions, strref line)
|
|||||||
bool force_label = charE==':' || charE=='$';
|
bool force_label = charE==':' || charE=='$';
|
||||||
if (!force_label && syntax==SYNTAX_MERLIN && line) // MERLIN fixes and PoP does some naughty stuff like 'and = 0'
|
if (!force_label && syntax==SYNTAX_MERLIN && line) // MERLIN fixes and PoP does some naughty stuff like 'and = 0'
|
||||||
force_label = !strref::is_ws(char0) || char1==']' || charE=='?';
|
force_label = !strref::is_ws(char0) || char1==']' || charE=='?';
|
||||||
|
else if (!force_label && syntax!=SYNTAX_MERLIN && line[0]==':')
|
||||||
|
force_label = true;
|
||||||
if (!operation && !force_label) {
|
if (!operation && !force_label) {
|
||||||
if (ConditionalAsm()) {
|
if (ConditionalAsm()) {
|
||||||
// scope open / close
|
// scope open / close
|
||||||
|
Loading…
x
Reference in New Issue
Block a user