mirror of
https://github.com/ksherlock/x65.git
synced 2024-12-28 19:32:25 +00:00
Fix reloc data
- changed rigid type of reloc target from byte/word/hi byte/lo byte to number of bytes and bits to shift (Apple II GS OMF format)
This commit is contained in:
parent
89ed6d25cc
commit
97dc0ad5e6
@ -833,6 +833,8 @@ Fish food! Assembler has all important features and switching to make a 6502 pro
|
||||
* irp (indefinite repeat)
|
||||
|
||||
**FIXED**
|
||||
* Changed the data for relocs to better match Apple II GS OMF format which also changes the object file format.
|
||||
* Added a disassembler (disassembler/x65dsasm.s)
|
||||
* % evaluates to the current end of scope instead of whatever scope ends first
|
||||
* rept crash fix if not resolved until assembly completed
|
||||
* rept and symbol reference with forward reference label was not taking section into account
|
||||
|
@ -43,7 +43,7 @@
|
||||
//
|
||||
|
||||
struct ObjFileHeader {
|
||||
short id; // 'o6'
|
||||
short id; // 'x6'
|
||||
short sections;
|
||||
short relocs;
|
||||
short labels;
|
||||
@ -76,7 +76,8 @@ struct ObjFileReloc {
|
||||
int base_value;
|
||||
int section_offset;
|
||||
short target_section;
|
||||
short value_type; // Reloc::Type
|
||||
char bytes;
|
||||
char shift;
|
||||
};
|
||||
|
||||
struct ObjFileLabel {
|
||||
@ -117,6 +118,7 @@ enum ShowFlags {
|
||||
SHOW_LABELS = 4,
|
||||
SHOW_MAP_SYMBOLS = 8,
|
||||
SHOW_LATE_EVAL = 16,
|
||||
SHOW_CODE_RANGE = 32,
|
||||
|
||||
SHOW_DEFAULT = SHOW_SECTIONS
|
||||
};
|
||||
@ -170,13 +172,14 @@ void ReadObjectFile(const char *file, unsigned int show = SHOW_DEFAULT)
|
||||
hdr.relocs * sizeof(struct ObjFileReloc) + hdr.labels * sizeof(struct ObjFileLabel) +
|
||||
hdr.late_evals * sizeof(struct ObjFileLateEval) +
|
||||
hdr.map_symbols * sizeof(struct ObjFileMapSymbol) + hdr.stringdata + hdr.bindata;
|
||||
if (hdr.id == 0x6f36 && sum == size) {
|
||||
if (hdr.id == 0x7836 && sum == size) {
|
||||
struct ObjFileSection *aSect = (struct ObjFileSection*)(&hdr + 1);
|
||||
struct ObjFileReloc *aReloc = (struct ObjFileReloc*)(aSect + hdr.sections);
|
||||
struct ObjFileLabel *aLabels = (struct ObjFileLabel*)(aReloc + hdr.relocs);
|
||||
struct ObjFileLateEval *aLateEval = (struct ObjFileLateEval*)(aLabels + hdr.labels);
|
||||
struct ObjFileMapSymbol *aMapSyms = (struct ObjFileMapSymbol*)(aLateEval + hdr.late_evals);
|
||||
const char *str_orig = (const char*)(aMapSyms + hdr.map_symbols);
|
||||
size_t code_start = sum - hdr.bindata;
|
||||
|
||||
// sections
|
||||
if (show & SHOW_SECTIONS) {
|
||||
@ -212,12 +215,13 @@ void ReadObjectFile(const char *file, unsigned int show = SHOW_DEFAULT)
|
||||
}
|
||||
|
||||
if (show & SHOW_RELOCS) {
|
||||
int curRel = 0;
|
||||
for (int si = 0; si < hdr.sections; si++) {
|
||||
printf("section %d relocs: %d\n", si, aSect[si].relocs);
|
||||
for (int r = 0; r < aSect[si].relocs; r++) {
|
||||
struct ObjFileReloc &rs = aReloc[r];
|
||||
printf("Reloc: section %d offset $%x base $%x type %s\n",
|
||||
rs.target_section, rs.section_offset, rs.target_section, reloc_type[rs.value_type]);
|
||||
struct ObjFileReloc &rs = aReloc[curRel++];
|
||||
printf("Reloc: section %d offset $%x base $%x bytes: %d shift: %d\n",
|
||||
rs.target_section, rs.section_offset, rs.base_value, rs.bytes, rs.shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -265,6 +269,9 @@ void ReadObjectFile(const char *file, unsigned int show = SHOW_DEFAULT)
|
||||
}
|
||||
}
|
||||
|
||||
if (show & SHOW_CODE_RANGE)
|
||||
printf("Code block: $%x - $%x (%d bytes)\n", (size_t)code_start, size, size - hdr.bindata);
|
||||
|
||||
// restore previous section
|
||||
} else
|
||||
printf("Not a valid x65 file\n");
|
||||
@ -276,29 +283,24 @@ int main(int argc, char **argv)
|
||||
{
|
||||
const char *file = nullptr;
|
||||
bool def = true;
|
||||
unsigned int show = SHOW_DEFAULT, prv_show = 0;
|
||||
unsigned int show = 0;
|
||||
for (int a = 1; a<argc; a++) {
|
||||
if (argv[a][0]=='-') {
|
||||
strref arg = argv[a]+1;
|
||||
if (arg.same_str("sections")) {
|
||||
show = prv_show | SHOW_SECTIONS;
|
||||
prv_show = show;
|
||||
} else if (arg.same_str("relocs")) {
|
||||
show = prv_show | SHOW_RELOCS;
|
||||
prv_show = show;
|
||||
} else if (arg.same_str("labels")) {
|
||||
show = prv_show | SHOW_LABELS;
|
||||
prv_show = show;
|
||||
} else if (arg.same_str("map")) {
|
||||
show = prv_show | SHOW_MAP_SYMBOLS;
|
||||
prv_show = show;
|
||||
} else if (arg.same_str("late_eval")) {
|
||||
show = prv_show | SHOW_LATE_EVAL;
|
||||
prv_show = show;
|
||||
} else if (arg.same_str("all")) {
|
||||
show = prv_show | SHOW_SECTIONS | SHOW_RELOCS | SHOW_LABELS | SHOW_MAP_SYMBOLS | SHOW_LATE_EVAL;
|
||||
prv_show = show;
|
||||
}
|
||||
if (arg.same_str("sections"))
|
||||
show = show | SHOW_SECTIONS;
|
||||
else if (arg.same_str("relocs"))
|
||||
show = show | SHOW_RELOCS;
|
||||
else if (arg.same_str("labels"))
|
||||
show = show | SHOW_LABELS;
|
||||
else if (arg.same_str("map"))
|
||||
show = show | SHOW_MAP_SYMBOLS;
|
||||
else if (arg.same_str("late_eval"))
|
||||
show = show | SHOW_LATE_EVAL;
|
||||
else if (arg.same_str("code"))
|
||||
show = show | SHOW_CODE_RANGE;
|
||||
else if (arg.same_str("all"))
|
||||
show = SHOW_SECTIONS | SHOW_RELOCS | SHOW_LABELS | SHOW_MAP_SYMBOLS | SHOW_LATE_EVAL | SHOW_CODE_RANGE;
|
||||
} else if (!file)
|
||||
file = argv[a];
|
||||
}
|
||||
@ -309,6 +311,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (argc>1) {
|
||||
ReadObjectFile(file, show);
|
||||
ReadObjectFile(file, show ? show : SHOW_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
165
x65.cpp
165
x65.cpp
@ -892,6 +892,7 @@ DirectiveName aDirectiveNames[] {
|
||||
{ "EXPORT", AD_EXPORT },
|
||||
{ "SECTION", AD_SECTION },
|
||||
{ "SEG", AD_SECTION }, // DASM version of SECTION
|
||||
{ "SEGMENT", AD_SECTION }, // CA65 version of SECTION
|
||||
{ "LINK", AD_LINK },
|
||||
{ "XDEF", AD_XDEF },
|
||||
{ "XREF", AD_XREF },
|
||||
@ -1091,20 +1092,15 @@ public:
|
||||
// be out of scope at link time.
|
||||
|
||||
struct Reloc {
|
||||
enum Type {
|
||||
NONE,
|
||||
WORD,
|
||||
LO_BYTE,
|
||||
HI_BYTE
|
||||
};
|
||||
int base_value;
|
||||
int section_offset; // offset into this section
|
||||
int target_section; // which section does this reloc target?
|
||||
Type value_type; // byte or word size
|
||||
char bytes; // number of bytes to write
|
||||
char shift; // number of bits to shift to get value
|
||||
|
||||
Reloc() : base_value(0), section_offset(-1), target_section(-1), value_type(NONE) {}
|
||||
Reloc(int base, int offs, int sect, Type t = WORD) :
|
||||
base_value(base), section_offset(offs), target_section(sect), value_type(t) {}
|
||||
Reloc() : base_value(0), section_offset(-1), target_section(-1), bytes(0), shift(0) {}
|
||||
Reloc(int base, int offs, int sect, char num_bytes, char bit_shift) :
|
||||
base_value(base), section_offset(offs), target_section(sect), bytes(num_bytes), shift(bit_shift) {}
|
||||
};
|
||||
typedef std::vector<struct Reloc> relocList;
|
||||
|
||||
@ -1187,7 +1183,7 @@ typedef struct Section {
|
||||
bool IsDummySection() const { return dummySection; }
|
||||
bool IsRelativeSection() const { return address_assigned == false; }
|
||||
bool IsMergedSection() const { return merged_offset >= 0; }
|
||||
void AddReloc(int base, int offset, int section, Reloc::Type type = Reloc::WORD);
|
||||
void AddReloc(int base, int offset, int section, char bytes, char shift);// Reloc::Type type = Reloc::WORD);
|
||||
|
||||
Section() : pRelocs(nullptr), pListing(nullptr) { reset(); }
|
||||
Section(strref _name, int _address) : pRelocs(nullptr), pListing(nullptr) {
|
||||
@ -1414,7 +1410,7 @@ public:
|
||||
// Eval relative result (only valid if EvalExpression returns STATUS_RELATIVE_SECTION)
|
||||
int lastEvalSection;
|
||||
int lastEvalValue;
|
||||
Reloc::Type lastEvalPart;
|
||||
char lastEvalShift;
|
||||
|
||||
strref export_base_name; // binary output name if available
|
||||
strref last_label; // most recently defined label for Merlin macro
|
||||
@ -1957,20 +1953,13 @@ StatusCode Asm::LinkRelocs(int section_id, int section_address)
|
||||
}
|
||||
unsigned char *trg = trg_sect->output + output_offs + i->section_offset;
|
||||
int value = i->base_value + section_address;
|
||||
if (i->value_type == Reloc::WORD) {
|
||||
if ((trg+1) >= (trg_sect->output + trg_sect->size()))
|
||||
return ERROR_SECTION_TARGET_OFFSET_OUT_OF_RANGE;
|
||||
*trg++ = (unsigned char)value;
|
||||
*trg = (unsigned char)(value >> 8);
|
||||
} else if (i->value_type == Reloc::LO_BYTE) {
|
||||
if (trg >= (trg_sect->output + trg_sect->size()))
|
||||
return ERROR_SECTION_TARGET_OFFSET_OUT_OF_RANGE;
|
||||
*trg = (unsigned char)value;
|
||||
} else if (i->value_type == Reloc::HI_BYTE) {
|
||||
if (trg >= (trg_sect->output + trg_sect->size()))
|
||||
return ERROR_SECTION_TARGET_OFFSET_OUT_OF_RANGE;
|
||||
*trg = (unsigned char)(value >> 8);
|
||||
}
|
||||
if (i->shift<0)
|
||||
value >>= -i->shift;
|
||||
else if (i->shift)
|
||||
value <<= i->shift;
|
||||
|
||||
for (int b = 0; b<i->bytes; b++)
|
||||
*trg++ = (unsigned char)(value>>(b*8));
|
||||
i = pList->erase(i);
|
||||
if (i != pList->end())
|
||||
++i;
|
||||
@ -2152,13 +2141,13 @@ void Section::AddText(strref line, strref text_prefix) {
|
||||
}
|
||||
|
||||
// Add a relocation marker to a section
|
||||
void Section::AddReloc(int base, int offset, int section, Reloc::Type type)
|
||||
void Section::AddReloc(int base, int offset, int section, char bytes, char shift)
|
||||
{
|
||||
if (!pRelocs)
|
||||
pRelocs = new relocList;
|
||||
if (pRelocs->size() == pRelocs->capacity())
|
||||
pRelocs->reserve(pRelocs->size() + 32);
|
||||
pRelocs->push_back(Reloc(base, offset, section, type));
|
||||
pRelocs->push_back(Reloc(base, offset, section, bytes, shift));
|
||||
}
|
||||
|
||||
// Make sure there is room to assemble in
|
||||
@ -2740,6 +2729,17 @@ EvalOperator Asm::RPNToken(strref &exp, const struct EvalContext &etx, EvalOpera
|
||||
// Max number of unresolved sections to evaluate in a single expression
|
||||
#define MAX_EVAL_SECTIONS 4
|
||||
|
||||
// determine if a scalar can be a shift
|
||||
static int mul_as_shift(int scalar)
|
||||
{
|
||||
int shift = 0;
|
||||
while (scalar > 1 && (scalar & 1) == 0) {
|
||||
shift++;
|
||||
scalar >>= 1;
|
||||
}
|
||||
return scalar == 1 ? shift : 0;
|
||||
}
|
||||
|
||||
StatusCode Asm::EvalExpression(strref expression, const struct EvalContext &etx, int &result)
|
||||
{
|
||||
int numValues = 0;
|
||||
@ -2838,10 +2838,13 @@ StatusCode Asm::EvalExpression(strref expression, const struct EvalContext &etx,
|
||||
{
|
||||
int valIdx = 0;
|
||||
int ri = 0; // RPN index (value)
|
||||
int preByteVal = 0; // special case for relative reference to low byte / high byte
|
||||
int prev_val = values[0];
|
||||
int shift_bits = 0; // special case for relative reference to low byte / high byte
|
||||
short section_counts[MAX_EVAL_SECTIONS][MAX_EVAL_VALUES] = { 0 };
|
||||
for (int o = 0; o<numOps; o++) {
|
||||
EvalOperator op = (EvalOperator)ops[o];
|
||||
shift_bits = 0;
|
||||
prev_val = ri ? values[ri-1] : prev_val;
|
||||
if (op!=EVOP_VAL && op!=EVOP_LOB && op!=EVOP_HIB && op!=EVOP_BAB && op!=EVOP_SUB && ri<2)
|
||||
break; // ignore suffix operations that are lacking values
|
||||
switch (op) {
|
||||
@ -2887,12 +2890,16 @@ StatusCode Asm::EvalExpression(strref expression, const struct EvalContext &etx,
|
||||
ri--;
|
||||
for (int i = 0; i<num_sections; i++)
|
||||
section_counts[i][ri-1] |= section_counts[i][ri];
|
||||
shift_bits = mul_as_shift(values[ri]);
|
||||
prev_val = values[ri - 1];
|
||||
values[ri-1] *= values[ri]; break;
|
||||
case EVOP_DIV: // /
|
||||
ri--;
|
||||
for (int i = 0; i<num_sections; i++)
|
||||
section_counts[i][ri-1] |= section_counts[i][ri];
|
||||
values[ri-1] /= values[ri]; break;
|
||||
shift_bits = -mul_as_shift(values[ri]);
|
||||
prev_val = values[ri - 1];
|
||||
values[ri - 1] /= values[ri]; break;
|
||||
case EVOP_AND: // &
|
||||
ri--;
|
||||
for (int i = 0; i<num_sections; i++)
|
||||
@ -2912,30 +2919,37 @@ StatusCode Asm::EvalExpression(strref expression, const struct EvalContext &etx,
|
||||
ri--;
|
||||
for (int i = 0; i<num_sections; i++)
|
||||
section_counts[i][ri-1] |= section_counts[i][ri];
|
||||
values[ri-1] <<= values[ri]; break;
|
||||
shift_bits = values[ri];
|
||||
prev_val = values[ri - 1];
|
||||
values[ri - 1] <<= values[ri]; break;
|
||||
case EVOP_SHR: // >>
|
||||
ri--;
|
||||
for (int i = 0; i<num_sections; i++)
|
||||
section_counts[i][ri-1] |= section_counts[i][ri];
|
||||
values[ri-1] >>= values[ri]; break;
|
||||
shift_bits = -values[ri];
|
||||
prev_val = values[ri - 1];
|
||||
values[ri - 1] >>= values[ri]; break;
|
||||
case EVOP_LOB: // low byte
|
||||
if (ri) {
|
||||
preByteVal = values[ri - 1];
|
||||
if (ri)
|
||||
values[ri-1] &= 0xff;
|
||||
} break;
|
||||
break;
|
||||
case EVOP_HIB:
|
||||
if (ri) {
|
||||
preByteVal = values[ri - 1];
|
||||
values[ri - 1] = (values[ri - 1] >> 8) & 0xff;
|
||||
shift_bits = -8;
|
||||
values[ri - 1] = values[ri - 1] >> 8;
|
||||
} break;
|
||||
case EVOP_BAB:
|
||||
if (ri)
|
||||
values[ri - 1] = (values[ri - 1] >> 16) & 0xff;
|
||||
if (ri) {
|
||||
shift_bits = -16;
|
||||
values[ri - 1] = (values[ri - 1] >> 16);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ERROR_EXPRESSION_OPERATION;
|
||||
break;
|
||||
}
|
||||
if (shift_bits==0 && ri)
|
||||
prev_val = values[ri-1];
|
||||
}
|
||||
int section_index = -1;
|
||||
bool curr_relative = false;
|
||||
@ -2954,8 +2968,8 @@ StatusCode Asm::EvalExpression(strref expression, const struct EvalContext &etx,
|
||||
result = values[0];
|
||||
if (section_index>=0 && !curr_relative) {
|
||||
lastEvalSection = section_ids[section_index];
|
||||
lastEvalValue = (ops[numOps - 1] == EVOP_LOB || ops[numOps - 1] == EVOP_HIB) ? preByteVal : result;
|
||||
lastEvalPart = ops[numOps - 1] == EVOP_LOB ? Reloc::LO_BYTE : (ops[numOps - 1] == EVOP_HIB ? Reloc::HI_BYTE : Reloc::WORD);
|
||||
lastEvalValue = prev_val;
|
||||
lastEvalShift = shift_bits;
|
||||
return STATUS_RELATIVE_SECTION;
|
||||
}
|
||||
}
|
||||
@ -3058,8 +3072,7 @@ StatusCode Asm::CheckLateEval(strref added_label, int scope_end, bool print_miss
|
||||
if (i->section<0)
|
||||
resolved = false;
|
||||
else {
|
||||
allSections[sec].AddReloc(lastEvalValue, trg, lastEvalSection,
|
||||
lastEvalPart==Reloc::HI_BYTE ? Reloc::HI_BYTE : Reloc::LO_BYTE);
|
||||
allSections[sec].AddReloc(lastEvalValue, trg, lastEvalSection, 1, lastEvalShift);
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
@ -3073,7 +3086,7 @@ StatusCode Asm::CheckLateEval(strref added_label, int scope_end, bool print_miss
|
||||
if (i->section<0)
|
||||
resolved = false;
|
||||
else {
|
||||
allSections[sec].AddReloc(lastEvalValue, trg, lastEvalSection, lastEvalPart);
|
||||
allSections[sec].AddReloc(lastEvalValue, trg, lastEvalSection, 2, lastEvalShift);
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
@ -3087,7 +3100,7 @@ StatusCode Asm::CheckLateEval(strref added_label, int scope_end, bool print_miss
|
||||
if (i->section<0)
|
||||
resolved = false;
|
||||
else {
|
||||
allSections[sec].AddReloc(lastEvalValue, trg, lastEvalSection, lastEvalPart);
|
||||
allSections[sec].AddReloc(lastEvalValue, trg, lastEvalSection, 3, lastEvalShift);
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
@ -3101,7 +3114,7 @@ StatusCode Asm::CheckLateEval(strref added_label, int scope_end, bool print_miss
|
||||
if (i->section<0)
|
||||
resolved = false;
|
||||
else {
|
||||
allSections[sec].AddReloc(lastEvalValue, trg, lastEvalSection, lastEvalPart);
|
||||
allSections[sec].AddReloc(lastEvalValue, trg, lastEvalSection, 4, lastEvalShift);
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
@ -4122,8 +4135,7 @@ StatusCode Asm::ApplyDirective(AssemblerDirective dir, strref line, strref sourc
|
||||
else if (error==STATUS_NOT_READY || error == STATUS_XREF_DEPENDENT)
|
||||
AddLateEval(CurrSection().DataOffset(), CurrSection().GetPC(), scope_address[scope_depth], exp, source_file, LateEval::LET_BYTE);
|
||||
else if (error == STATUS_RELATIVE_SECTION)
|
||||
CurrSection().AddReloc(lastEvalValue, CurrSection().DataOffset(), lastEvalSection,
|
||||
lastEvalPart == Reloc::HI_BYTE ? Reloc::HI_BYTE : Reloc::LO_BYTE);
|
||||
CurrSection().AddReloc(lastEvalValue, CurrSection().DataOffset(), lastEvalSection, 1, lastEvalShift);
|
||||
AddByte(value);
|
||||
}
|
||||
break;
|
||||
@ -4139,7 +4151,7 @@ StatusCode Asm::ApplyDirective(AssemblerDirective dir, strref line, strref sourc
|
||||
else if (error==STATUS_NOT_READY || error == STATUS_XREF_DEPENDENT)
|
||||
AddLateEval(CurrSection().DataOffset(), CurrSection().DataOffset(), scope_address[scope_depth], exp_w, source_file, LateEval::LET_ABS_REF);
|
||||
else if (error == STATUS_RELATIVE_SECTION) {
|
||||
CurrSection().AddReloc(lastEvalValue, CurrSection().DataOffset(), lastEvalSection, lastEvalPart);
|
||||
CurrSection().AddReloc(lastEvalValue, CurrSection().DataOffset(), lastEvalSection, 2, lastEvalShift);
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
@ -4160,7 +4172,7 @@ StatusCode Asm::ApplyDirective(AssemblerDirective dir, strref line, strref sourc
|
||||
else if (error==STATUS_NOT_READY || error == STATUS_XREF_DEPENDENT)
|
||||
AddLateEval(CurrSection().DataOffset(), CurrSection().DataOffset(), scope_address[scope_depth], exp_w, source_file, dir==AD_ADR ? LateEval::LET_ABS_L_REF : LateEval::LET_ABS_4_REF);
|
||||
else if (error == STATUS_RELATIVE_SECTION) {
|
||||
CurrSection().AddReloc(lastEvalValue, CurrSection().DataOffset(), lastEvalSection, lastEvalPart);
|
||||
CurrSection().AddReloc(lastEvalValue, CurrSection().DataOffset(), lastEvalSection, dir==AD_ADRL ? 4 : 3, lastEvalShift);
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
@ -4197,10 +4209,9 @@ StatusCode Asm::ApplyDirective(AssemblerDirective dir, strref line, strref sourc
|
||||
else if (error == STATUS_RELATIVE_SECTION) {
|
||||
value = 0;
|
||||
if (words)
|
||||
CurrSection().AddReloc(lastEvalValue, CurrSection().DataOffset(), lastEvalSection, lastEvalPart);
|
||||
CurrSection().AddReloc(lastEvalValue, CurrSection().DataOffset(), lastEvalSection, 2, lastEvalShift);
|
||||
else
|
||||
CurrSection().AddReloc(lastEvalValue, CurrSection().DataOffset(), lastEvalSection,
|
||||
lastEvalPart == Reloc::HI_BYTE ? Reloc::HI_BYTE : Reloc::LO_BYTE);
|
||||
CurrSection().AddReloc(lastEvalValue, CurrSection().DataOffset(), lastEvalSection, 1, lastEvalShift);
|
||||
}
|
||||
}
|
||||
AddByte(value);
|
||||
@ -4580,7 +4591,7 @@ StatusCode Asm::AddOpcode(strref line, int index, strref source_file)
|
||||
int value = 0;
|
||||
int target_section = -1;
|
||||
int target_section_offs = -1;
|
||||
Reloc::Type target_section_type = Reloc::NONE;
|
||||
char target_section_shift = 0;
|
||||
bool evalLater = false;
|
||||
if (expression) {
|
||||
struct EvalContext etx;
|
||||
@ -4594,7 +4605,7 @@ StatusCode Asm::AddOpcode(strref line, int index, strref source_file)
|
||||
} else if (error == STATUS_RELATIVE_SECTION) {
|
||||
target_section = lastEvalSection;
|
||||
target_section_offs = lastEvalValue;
|
||||
target_section_type = lastEvalPart;
|
||||
target_section_shift = lastEvalShift;
|
||||
} else if (error != STATUS_OK)
|
||||
return error;
|
||||
}
|
||||
@ -4719,8 +4730,7 @@ StatusCode Asm::AddOpcode(strref line, int index, strref source_file)
|
||||
if (evalLater)
|
||||
AddLateEval(CurrSection().DataOffset(), CurrSection().GetPC(), scope_address[scope_depth], expression, source_file, LateEval::LET_BYTE);
|
||||
else if (error == STATUS_RELATIVE_SECTION)
|
||||
CurrSection().AddReloc(target_section_offs, CurrSection().DataOffset(), target_section,
|
||||
target_section_type == Reloc::HI_BYTE ? Reloc::HI_BYTE : Reloc::LO_BYTE);
|
||||
CurrSection().AddReloc(target_section_offs, CurrSection().DataOffset(), target_section, 1, target_section_shift);
|
||||
AddByte(value);
|
||||
break;
|
||||
|
||||
@ -4728,8 +4738,7 @@ StatusCode Asm::AddOpcode(strref line, int index, strref source_file)
|
||||
if (evalLater)
|
||||
AddLateEval(CurrSection().DataOffset(), CurrSection().GetPC(), scope_address[scope_depth], expression, source_file, LateEval::LET_ABS_REF);
|
||||
else if (error == STATUS_RELATIVE_SECTION) {
|
||||
CurrSection().AddReloc(target_section_offs, CurrSection().DataOffset(),
|
||||
target_section, target_section_type);
|
||||
CurrSection().AddReloc(target_section_offs, CurrSection().DataOffset(), target_section, 2, target_section_shift);
|
||||
value = 0;
|
||||
}
|
||||
AddWord(value);
|
||||
@ -4739,8 +4748,7 @@ StatusCode Asm::AddOpcode(strref line, int index, strref source_file)
|
||||
if (evalLater)
|
||||
AddLateEval(CurrSection().DataOffset(), CurrSection().GetPC(), scope_address[scope_depth], expression, source_file, LateEval::LET_ABS_L_REF);
|
||||
else if (error == STATUS_RELATIVE_SECTION) {
|
||||
CurrSection().AddReloc(target_section_offs, CurrSection().DataOffset(),
|
||||
target_section, target_section_type);
|
||||
CurrSection().AddReloc(target_section_offs, CurrSection().DataOffset(), target_section, 3, target_section_shift);
|
||||
value = 0;
|
||||
}
|
||||
AddTriple(value);
|
||||
@ -4750,8 +4758,7 @@ StatusCode Asm::AddOpcode(strref line, int index, strref source_file)
|
||||
if (evalLater)
|
||||
AddLateEval(CurrSection().DataOffset(), CurrSection().GetPC(), scope_address[scope_depth], expression, source_file, LateEval::LET_BYTE);
|
||||
else if (error == STATUS_RELATIVE_SECTION) {
|
||||
CurrSection().AddReloc(target_section_offs, CurrSection().DataOffset(), target_section,
|
||||
target_section_type == Reloc::HI_BYTE ? Reloc::HI_BYTE : Reloc::LO_BYTE);
|
||||
CurrSection().AddReloc(target_section_offs, CurrSection().DataOffset(), target_section, 1, target_section_shift);
|
||||
}
|
||||
AddByte(value);
|
||||
struct EvalContext etx;
|
||||
@ -4781,10 +4788,8 @@ StatusCode Asm::AddOpcode(strref line, int index, strref source_file)
|
||||
case CA_BYTE_BRANCH: {
|
||||
if (evalLater)
|
||||
AddLateEval(CurrSection().DataOffset(), CurrSection().GetPC(), scope_address[scope_depth], expression, source_file, LateEval::LET_BYTE);
|
||||
else if (error == STATUS_RELATIVE_SECTION) {
|
||||
CurrSection().AddReloc(target_section_offs, CurrSection().DataOffset(), target_section,
|
||||
target_section_type == Reloc::HI_BYTE ? Reloc::HI_BYTE : Reloc::LO_BYTE);
|
||||
}
|
||||
else if (error == STATUS_RELATIVE_SECTION)
|
||||
CurrSection().AddReloc(target_section_offs, CurrSection().DataOffset(), target_section, 1, target_section_shift);
|
||||
AddByte(value);
|
||||
struct EvalContext etx;
|
||||
SetEvalCtxDefaults(etx);
|
||||
@ -5329,7 +5334,7 @@ void Asm::Assemble(strref source, strref filename, bool obj_target)
|
||||
//
|
||||
|
||||
struct ObjFileHeader {
|
||||
short id; // 'o6'
|
||||
short id; // 'x6'
|
||||
short sections;
|
||||
short relocs;
|
||||
short labels;
|
||||
@ -5362,7 +5367,8 @@ struct ObjFileReloc {
|
||||
int base_value;
|
||||
int section_offset;
|
||||
short target_section;
|
||||
short value_type; // Reloc::Type
|
||||
char bytes;
|
||||
char shift;
|
||||
};
|
||||
|
||||
struct ObjFileLabel {
|
||||
@ -5437,7 +5443,7 @@ StatusCode Asm::WriteObjectFile(strref filename)
|
||||
{
|
||||
if (FILE *f = fopen(strown<512>(filename).c_str(), "wb")) {
|
||||
struct ObjFileHeader hdr = { 0 };
|
||||
hdr.id = 0x6f36;
|
||||
hdr.id = 0x7836;
|
||||
hdr.sections = (short)allSections.size();
|
||||
hdr.relocs = 0;
|
||||
hdr.bindata = 0;
|
||||
@ -5494,7 +5500,8 @@ StatusCode Asm::WriteObjectFile(strref filename)
|
||||
r.base_value = ri->base_value;
|
||||
r.section_offset = ri->section_offset;
|
||||
r.target_section = ri->target_section;
|
||||
r.value_type = ri->value_type;
|
||||
r.bytes = ri->bytes;
|
||||
r.shift = ri->shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5614,7 +5621,7 @@ StatusCode Asm::ReadObjectFile(strref filename)
|
||||
hdr.relocs * sizeof(struct ObjFileReloc) + hdr.labels * sizeof(struct ObjFileLabel) +
|
||||
hdr.late_evals * sizeof(struct ObjFileLateEval) +
|
||||
hdr.map_symbols * sizeof(struct ObjFileMapSymbol) + hdr.stringdata + hdr.bindata;
|
||||
if (hdr.id == 0x6f36 && sum == size) {
|
||||
if (hdr.id == 0x7836 && sum == size) {
|
||||
struct ObjFileSection *aSect = (struct ObjFileSection*)(&hdr + 1);
|
||||
struct ObjFileReloc *aReloc = (struct ObjFileReloc*)(aSect + hdr.sections);
|
||||
struct ObjFileLabel *aLabels = (struct ObjFileLabel*)(aReloc + hdr.relocs);
|
||||
@ -5666,7 +5673,7 @@ StatusCode Asm::ReadObjectFile(strref filename)
|
||||
for (int si = 0; si < hdr.sections; si++) {
|
||||
for (int r = 0; r < aSect[si].relocs; r++) {
|
||||
struct ObjFileReloc &rs = aReloc[r];
|
||||
allSections[aSctRmp[si]].AddReloc(rs.base_value, rs.section_offset, aSctRmp[rs.target_section], Reloc::Type(rs.value_type));
|
||||
allSections[aSctRmp[si]].AddReloc(rs.base_value, rs.section_offset, aSctRmp[rs.target_section], rs.bytes, rs.shift);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5845,19 +5852,19 @@ int main(int argc, char **argv)
|
||||
puts("Usage:\n"
|
||||
" x65 filename.s code.prg [options]\n"
|
||||
" * -i(path) : Add include path\n"
|
||||
" * -D(label)[=<value>] : Define a label with an optional value(otherwise defined as 1)\n"
|
||||
" * -D(label)[=value] : Define a label with an optional value (otherwise defined as 1)\n"
|
||||
" * -cpu=6502/65c02/65c02wdc/65816: assemble with opcodes for a different cpu\n"
|
||||
" * -acc=8/16: set the accumulator mode for 65816 at start, default is 8 bits"
|
||||
" * -xy=8/16: set the index register mode for 65816 at start, default is 8 bits"
|
||||
" * -obj(file.x65) : generate object file for later linking\n"
|
||||
" * -acc=8/16: set the accumulator mode for 65816 at start, default is 8 bits\n"
|
||||
" * -xy=8/16: set the index register mode for 65816 at start, default is 8 bits\n"
|
||||
" * -obj (file.x65) : generate object file for later linking\n"
|
||||
" * -bin : Raw binary\n"
|
||||
" * -c64 : Include load address(default)\n"
|
||||
" * -a2b : Apple II Dos 3.3 Binary\n"
|
||||
" * -sym(file.sym) : symbol file\n"
|
||||
" * -sym (file.sym) : symbol file\n"
|
||||
" * -lst / -lst = (file.lst) : generate disassembly text from result(file or stdout)\n"
|
||||
" * -opcodes / -opcodes = (file.s) : dump all available opcodes(file or stdout)\n"
|
||||
" * -sect: display sections loaded and built\n"
|
||||
" * -vice(file.vs) : export a vice symbol file\n"
|
||||
" * -vice (file.vs) : export a vice symbol file\n"
|
||||
" * -merlin: use Merlin syntax\n"
|
||||
" * -endm : macros end with endm or endmacro instead of scoped('{' - '}')\n");
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user