mirror of
https://github.com/ksherlock/x65.git
synced 2025-08-05 05:24:43 +00:00
Cycle timing listing for 65816
- XREF blocked linking with same name label - REPT also works as a symbols for repeat counter to reduce need for extra counting labels. - "<<" got interpreted as a right shift - Added LONG keyword to declare 32 bit values
This commit is contained in:
21
README.md
21
README.md
@@ -143,6 +143,7 @@ Directives are assembler commands that control the code generation but that does
|
|||||||
* [**EVAL**](#eval) Log an expression during assembly.
|
* [**EVAL**](#eval) Log an expression during assembly.
|
||||||
* [**BYTES**](#bytes) Insert comma separated bytes at this address (same as **BYTE** or **DC.B**)
|
* [**BYTES**](#bytes) Insert comma separated bytes at this address (same as **BYTE** or **DC.B**)
|
||||||
* [**WORDS**](#words) Insert comma separated 16 bit values at this address (same as **WORD** or **DC.W**)
|
* [**WORDS**](#words) Insert comma separated 16 bit values at this address (same as **WORD** or **DC.W**)
|
||||||
|
* [**LONG**](#long) Insert comma separated 32 bit values at this address
|
||||||
* [**TEXT**](#text) Insert text at this address
|
* [**TEXT**](#text) Insert text at this address
|
||||||
* [**INCLUDE**](#include) Include another source file and assemble at this address
|
* [**INCLUDE**](#include) Include another source file and assemble at this address
|
||||||
* [**INCBIN**](#incbin) Include a binary file at this address
|
* [**INCBIN**](#incbin) Include a binary file at this address
|
||||||
@@ -311,6 +312,10 @@ RandomBytes:
|
|||||||
|
|
||||||
Adds comma separated 16 bit values similar to how **BYTES** work. **word** or **dc.w** are also recognized.
|
Adds comma separated 16 bit values similar to how **BYTES** work. **word** or **dc.w** are also recognized.
|
||||||
|
|
||||||
|
<a name="long">**LONGS**
|
||||||
|
|
||||||
|
Adds comma separated 32 bit values similar to how **WORDS** work.
|
||||||
|
|
||||||
<a name="text">**TEXT**
|
<a name="text">**TEXT**
|
||||||
|
|
||||||
Copies the string in quotes on the same line. The plan is to do a petscii conversion step. Use the modifier 'petscii' or 'petscii_shifted' to convert alphabetic characters to range.
|
Copies the string in quotes on the same line. The plan is to do a petscii conversion step. Use the modifier 'petscii' or 'petscii_shifted' to convert alphabetic characters to range.
|
||||||
@@ -493,11 +498,9 @@ Example:
|
|||||||
```
|
```
|
||||||
columns = 40
|
columns = 40
|
||||||
rows = 25
|
rows = 25
|
||||||
screen_col = $400
|
|
||||||
height_buf = $1000
|
|
||||||
rept columns {
|
rept columns {
|
||||||
screen_addr = screen_col
|
screen_addr = $400 + rept ; rept is the repeat counter
|
||||||
ldx height_buf
|
ldx $1000+rept
|
||||||
dest = screen_addr
|
dest = screen_addr
|
||||||
remainder = 3
|
remainder = 3
|
||||||
rept (rows+remainder)/4 {
|
rept (rows+remainder)/4 {
|
||||||
@@ -514,8 +517,6 @@ rept columns {
|
|||||||
dest = dest + 4*40
|
dest = dest + 4*40
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
screen_col = screen_col+1
|
|
||||||
height_buf = height_buf+1
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -527,6 +528,9 @@ Note that if the -endm command line option is used (macros are not defined with
|
|||||||
.ENDREPEAT
|
.ENDREPEAT
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The symbol 'REPT' is the current repeat count within a REPT (0 outside of repeat blocks).
|
||||||
|
|
||||||
|
|
||||||
<a name="incdir">**INCDIR**
|
<a name="incdir">**INCDIR**
|
||||||
|
|
||||||
Adds a folder to search for INCLUDE, INCBIN, etc. files in
|
Adds a folder to search for INCLUDE, INCBIN, etc. files in
|
||||||
@@ -821,6 +825,11 @@ Fish food! Assembler has all important features and switching to make a 6502 pro
|
|||||||
* irp (indefinite repeat)
|
* irp (indefinite repeat)
|
||||||
|
|
||||||
**FIXED**
|
**FIXED**
|
||||||
|
* XREF prevented linking with same name symbol included from .x65 object causing a linker failure
|
||||||
|
* << was mistakenly interpreted as shift right
|
||||||
|
* REPT is also a value that can be used in expressions as a repeat counter
|
||||||
|
* LONG allows for adding 4 byte values like BYTE/WORD
|
||||||
|
* Cycle listing for 65816 - required more complex visualization due to more than 1 cycle extra
|
||||||
* Enabled EXT and CYC directive for merlin, accumulating cycle timing within scope (Hierarchical cycle timing in list file) / CYC...CYC (6502 only for now)
|
* Enabled EXT and CYC directive for merlin, accumulating cycle timing within scope (Hierarchical cycle timing in list file) / CYC...CYC (6502 only for now)
|
||||||
* First pass cycle timing in listing file for 6502 targets
|
* First pass cycle timing in listing file for 6502 targets
|
||||||
* Enums can have comments
|
* Enums can have comments
|
||||||
|
164
x65.cpp
164
x65.cpp
@@ -69,6 +69,7 @@
|
|||||||
// minor variation of 65C02
|
// minor variation of 65C02
|
||||||
#define NUM_WDC_65C02_SPECIFIC_OPS 18
|
#define NUM_WDC_65C02_SPECIFIC_OPS 18
|
||||||
|
|
||||||
|
|
||||||
// To simplify some syntax disambiguation the preferred
|
// To simplify some syntax disambiguation the preferred
|
||||||
// ruleset can be specified on the command line.
|
// ruleset can be specified on the command line.
|
||||||
enum AsmSyntax {
|
enum AsmSyntax {
|
||||||
@@ -756,6 +757,37 @@ const char* aliases_65816[] = {
|
|||||||
|
|
||||||
static const int num_opcodes_65816 = sizeof(opcodes_65816) / sizeof(opcodes_65816[0]);
|
static const int num_opcodes_65816 = sizeof(opcodes_65816) / sizeof(opcodes_65816[0]);
|
||||||
|
|
||||||
|
unsigned char timing_65816[] = {
|
||||||
|
0x4e, 0x1c, 0x4e, 0x28, 0x3a, 0x26, 0x3a, 0x1c, 0x46, 0x24, 0x44, 0x48, 0x4c, 0x28, 0x5c, 0x2a,
|
||||||
|
0x44, 0x1a, 0x1a, 0x2e, 0x3a, 0x18, 0x6c, 0x1c, 0x44, 0x28, 0x44, 0x44, 0x4c, 0x28, 0x5e, 0x2a,
|
||||||
|
0x4c, 0x1c, 0x50, 0x28, 0x16, 0x26, 0x3a, 0x1c, 0x48, 0x24, 0x44, 0x4a, 0x28, 0x28, 0x4c, 0x2a,
|
||||||
|
0x44, 0x1a, 0x1a, 0x2e, 0x18, 0x18, 0x3c, 0x1c, 0x44, 0x28, 0x44, 0x44, 0x28, 0x28, 0x4e, 0x2a,
|
||||||
|
0x4c, 0x1c, 0x42, 0x28, 0x42, 0x16, 0x6a, 0x1c, 0x26, 0x24, 0x44, 0x46, 0x46, 0x28, 0x5c, 0x2a,
|
||||||
|
0x44, 0x1a, 0x1a, 0x2e, 0x42, 0x18, 0x6c, 0x1c, 0x44, 0x28, 0x76, 0x44, 0x48, 0x28, 0x5e, 0x2a,
|
||||||
|
0x4c, 0x1c, 0x4c, 0x28, 0x16, 0x26, 0x3a, 0x1c, 0x28, 0x24, 0x44, 0x4c, 0x4a, 0x28, 0x4c, 0x2a,
|
||||||
|
0x44, 0x1a, 0x1a, 0x2e, 0x28, 0x18, 0x3c, 0x1c, 0x44, 0x28, 0x78, 0x44, 0x4c, 0x28, 0x4e, 0x2a,
|
||||||
|
0x46, 0x1c, 0x48, 0x28, 0x86, 0x16, 0x86, 0x1c, 0x44, 0x24, 0x44, 0x46, 0x78, 0x28, 0x78, 0x2a,
|
||||||
|
0x44, 0x1c, 0x1a, 0x2e, 0x88, 0x18, 0x88, 0x1c, 0x44, 0x2a, 0x44, 0x44, 0x28, 0x2a, 0x2a, 0x2a,
|
||||||
|
0x74, 0x1c, 0x74, 0x28, 0x86, 0x16, 0x86, 0x1c, 0x44, 0x24, 0x44, 0x48, 0x78, 0x28, 0x78, 0x2a,
|
||||||
|
0x44, 0x1a, 0x1a, 0x2e, 0x88, 0x18, 0x88, 0x1c, 0x44, 0x28, 0x44, 0x44, 0x78, 0x28, 0x78, 0x2a,
|
||||||
|
0x74, 0x1c, 0x46, 0x28, 0x86, 0x16, 0x6a, 0x1c, 0x44, 0x24, 0x44, 0x26, 0x78, 0x28, 0x5c, 0x2a,
|
||||||
|
0x44, 0x1a, 0x1a, 0x2e, 0x4c, 0x18, 0x6c, 0x1c, 0x44, 0x28, 0x76, 0x46, 0x4c, 0x28, 0x5e, 0x2a,
|
||||||
|
0x74, 0x3c, 0x46, 0x48, 0x86, 0x36, 0x6a, 0x3c, 0x44, 0x44, 0x44, 0x46, 0x78, 0x48, 0x5c, 0x4a,
|
||||||
|
0x44, 0x3a, 0x3a, 0x4e, 0x4a, 0x38, 0x6c, 0x3c, 0x44, 0x48, 0x78, 0x44, 0x50, 0x48, 0x5e, 0x4a
|
||||||
|
};
|
||||||
|
|
||||||
|
// m=0, i=0, dp!=0
|
||||||
|
unsigned char timing_65816_plus[9][3] = {
|
||||||
|
{ 0, 0, 0 }, // 6502 plus timing check bit 0
|
||||||
|
{ 1, 0, 1 }, // acc 16 bit + dp!=0
|
||||||
|
{ 1, 0, 0 }, // acc 16 bit
|
||||||
|
{ 0, 0, 1 }, // dp != 0
|
||||||
|
{ 0, 0, 0 }, // no plus
|
||||||
|
{ 2, 0, 0 }, // acc 16 bit yields 2+
|
||||||
|
{ 2, 0, 1 }, // acc 16 bit yields 2+ + dp!=0
|
||||||
|
{ 0, 1, 0 }, // idx 16 bit
|
||||||
|
{ 0, 1, 1 } // idx 16 bit + dp!=0
|
||||||
|
};
|
||||||
|
|
||||||
// 65C02
|
// 65C02
|
||||||
// http://6502.org/tutorials/65c02opcodes.html
|
// http://6502.org/tutorials/65c02opcodes.html
|
||||||
@@ -798,7 +830,7 @@ struct CPUDetails {
|
|||||||
{ opcodes_6502, num_opcodes_6502, "6502ill", aliases_6502, timing_6502 },
|
{ opcodes_6502, num_opcodes_6502, "6502ill", aliases_6502, timing_6502 },
|
||||||
{ opcodes_65C02, num_opcodes_65C02 - NUM_WDC_65C02_SPECIFIC_OPS, "65C02", aliases_65C02, nullptr },
|
{ opcodes_65C02, num_opcodes_65C02 - NUM_WDC_65C02_SPECIFIC_OPS, "65C02", aliases_65C02, nullptr },
|
||||||
{ opcodes_65C02, num_opcodes_65C02, "65C02WDC", aliases_65C02, nullptr },
|
{ opcodes_65C02, num_opcodes_65C02, "65C02WDC", aliases_65C02, nullptr },
|
||||||
{ opcodes_65816, num_opcodes_65816, "65816", aliases_65816, nullptr },
|
{ opcodes_65816, num_opcodes_65816, "65816", aliases_65816, timing_65816 },
|
||||||
};
|
};
|
||||||
static const int nCPUs = sizeof(aCPUs) / sizeof(aCPUs[0]);
|
static const int nCPUs = sizeof(aCPUs) / sizeof(aCPUs[0]);
|
||||||
|
|
||||||
@@ -872,6 +904,7 @@ DirectiveName aDirectiveNames[] {
|
|||||||
{ "BYTES", AD_BYTES },
|
{ "BYTES", AD_BYTES },
|
||||||
{ "WORD", AD_WORDS },
|
{ "WORD", AD_WORDS },
|
||||||
{ "WORDS", AD_WORDS },
|
{ "WORDS", AD_WORDS },
|
||||||
|
{ "LONG", AD_ADRL },
|
||||||
{ "DC", AD_DC },
|
{ "DC", AD_DC },
|
||||||
{ "TEXT", AD_TEXT },
|
{ "TEXT", AD_TEXT },
|
||||||
{ "INCLUDE", AD_INCLUDE },
|
{ "INCLUDE", AD_INCLUDE },
|
||||||
@@ -1295,6 +1328,7 @@ typedef struct {
|
|||||||
strref read_source; // current position/length in source file
|
strref read_source; // current position/length in source file
|
||||||
strref next_source; // next position/length in source file
|
strref next_source; // next position/length in source file
|
||||||
short repeat; // how many times to repeat this code segment
|
short repeat; // how many times to repeat this code segment
|
||||||
|
short repeat_total; // initial number of repeats for this code segment
|
||||||
bool scoped_context;
|
bool scoped_context;
|
||||||
void restart() { read_source = code_segment; }
|
void restart() { read_source = code_segment; }
|
||||||
bool complete() { repeat--; return repeat <= 0; }
|
bool complete() { repeat--; return repeat <= 0; }
|
||||||
@@ -1318,6 +1352,7 @@ public:
|
|||||||
context.read_source = code_seg;
|
context.read_source = code_seg;
|
||||||
context.next_source = code_seg;
|
context.next_source = code_seg;
|
||||||
context.repeat = rept;
|
context.repeat = rept;
|
||||||
|
context.repeat_total = rept;
|
||||||
context.scoped_context = false;
|
context.scoped_context = false;
|
||||||
stack.push_back(context);
|
stack.push_back(context);
|
||||||
currContext = &stack[stack.size()-1];
|
currContext = &stack[stack.size()-1];
|
||||||
@@ -2590,6 +2625,7 @@ EvalOperator Asm::RPNToken_Merlin(strref &expression, const struct EvalContext &
|
|||||||
if (ret == STATUS_OK) return EVOP_VAL;
|
if (ret == STATUS_OK) return EVOP_VAL;
|
||||||
if (ret != STATUS_NOT_STRUCT) return EVOP_ERR; // partial struct
|
if (ret != STATUS_NOT_STRUCT) return EVOP_ERR; // partial struct
|
||||||
}
|
}
|
||||||
|
if (!pLabel && label.same_str("rept")) { value = contextStack.curr().repeat_total - contextStack.curr().repeat; return EVOP_VAL; }
|
||||||
if (!pLabel || !pLabel->evaluated) return EVOP_NRY; // this label could not be found (yet)
|
if (!pLabel || !pLabel->evaluated) return EVOP_NRY; // this label could not be found (yet)
|
||||||
value = pLabel->value; section = pLabel->section; return EVOP_VAL;
|
value = pLabel->value; section = pLabel->section; return EVOP_VAL;
|
||||||
} else
|
} else
|
||||||
@@ -2619,7 +2655,7 @@ EvalOperator Asm::RPNToken(strref &exp, const struct EvalContext &etx, EvalOpera
|
|||||||
if (prev_op == EVOP_VAL || prev_op == EVOP_RPR) { ++exp;
|
if (prev_op == EVOP_VAL || prev_op == EVOP_RPR) { ++exp;
|
||||||
if (exp[0] == '=') { ++exp; return EVOP_GTE; } return EVOP_GT; }
|
if (exp[0] == '=') { ++exp; return EVOP_GTE; } return EVOP_GT; }
|
||||||
++exp; return EVOP_HIB;
|
++exp; return EVOP_HIB;
|
||||||
case '<': if (exp.get_len() >= 2 && exp[1] == '<') { exp += 2; return EVOP_SHR; }
|
case '<': if (exp.get_len() >= 2 && exp[1] == '<') { exp += 2; return EVOP_SHL; }
|
||||||
if (prev_op == EVOP_VAL || prev_op == EVOP_RPR) { ++exp;
|
if (prev_op == EVOP_VAL || prev_op == EVOP_RPR) { ++exp;
|
||||||
if (exp[0] == '=') { ++exp; return EVOP_LTE; } return EVOP_LT; }
|
if (exp[0] == '=') { ++exp; return EVOP_LTE; } return EVOP_LT; }
|
||||||
++exp; return EVOP_LOB;
|
++exp; return EVOP_LOB;
|
||||||
@@ -2654,6 +2690,7 @@ EvalOperator Asm::RPNToken(strref &exp, const struct EvalContext &etx, EvalOpera
|
|||||||
if (ret == STATUS_OK) return EVOP_VAL;
|
if (ret == STATUS_OK) return EVOP_VAL;
|
||||||
if (ret != STATUS_NOT_STRUCT) return EVOP_ERR; // partial struct
|
if (ret != STATUS_NOT_STRUCT) return EVOP_ERR; // partial struct
|
||||||
}
|
}
|
||||||
|
if (!pLabel && label.same_str("rept")) { value = contextStack.curr().repeat_total - contextStack.curr().repeat; return EVOP_VAL; }
|
||||||
if (!pLabel || !pLabel->evaluated) return EVOP_NRY; // this label could not be found (yet)
|
if (!pLabel || !pLabel->evaluated) return EVOP_NRY; // this label could not be found (yet)
|
||||||
value = pLabel->value; section = pLabel->section; return pLabel->reference ? EVOP_XRF : EVOP_VAL;
|
value = pLabel->value; section = pLabel->section; return pLabel->reference ? EVOP_XRF : EVOP_VAL;
|
||||||
}
|
}
|
||||||
@@ -4945,6 +4982,45 @@ StatusCode Asm::BuildSegment()
|
|||||||
|
|
||||||
// Produce the assembler listing
|
// Produce the assembler listing
|
||||||
#define MAX_DEPTH_CYCLE_COUNTER 64
|
#define MAX_DEPTH_CYCLE_COUNTER 64
|
||||||
|
|
||||||
|
struct cycleCnt {
|
||||||
|
int base;
|
||||||
|
short plus, a16, x16, dp;
|
||||||
|
void clr() { base = 0; plus = a16 = x16 = dp = 0; }
|
||||||
|
void add(unsigned char c) {
|
||||||
|
if (c != 0xff) {
|
||||||
|
base += (c >> 1) & 7;
|
||||||
|
plus += c & 1;
|
||||||
|
if (c & 0xf0) {
|
||||||
|
int i = c >> 4;
|
||||||
|
if (i <= 8) {
|
||||||
|
a16 += timing_65816_plus[i][0];
|
||||||
|
x16 += timing_65816_plus[i][1];
|
||||||
|
dp += timing_65816_plus[i][2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int plus_acc() {
|
||||||
|
return plus + a16 + x16 + dp;
|
||||||
|
}
|
||||||
|
void combine(const struct cycleCnt &o) {
|
||||||
|
base += o.base; plus += o.plus; a16 += o.a16; x16 += o.x16; dp += o.dp;
|
||||||
|
}
|
||||||
|
bool complex() const { return a16 != 0 || x16 != 0 || dp != 0; }
|
||||||
|
static int get_base(unsigned char c) {
|
||||||
|
return (c & 0xf) >> 1;
|
||||||
|
}
|
||||||
|
static int sum_plus(unsigned char c) {
|
||||||
|
if (c == 0xff)
|
||||||
|
return 0;
|
||||||
|
int i = c >> 4;
|
||||||
|
if (i)
|
||||||
|
return i <= 8 ? (timing_65816_plus[i][0] + timing_65816_plus[i][1] + timing_65816_plus[i][2]) : 0;
|
||||||
|
return c & 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
bool Asm::List(strref filename)
|
bool Asm::List(strref filename)
|
||||||
{
|
{
|
||||||
FILE *f = stdout;
|
FILE *f = stdout;
|
||||||
@@ -4977,11 +5053,9 @@ bool Asm::List(strref filename)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
short cycles[MAX_DEPTH_CYCLE_COUNTER][2];
|
struct cycleCnt cycles[MAX_DEPTH_CYCLE_COUNTER];
|
||||||
short cycles_depth = 0;
|
short cycles_depth = 0;
|
||||||
|
memset(cycles, 0, sizeof(cycles));
|
||||||
cycles[0][0] = 0;
|
|
||||||
cycles[0][1] = 0;
|
|
||||||
|
|
||||||
strref prev_src;
|
strref prev_src;
|
||||||
int prev_offs = 0;
|
int prev_offs = 0;
|
||||||
@@ -5005,7 +5079,7 @@ bool Asm::List(strref filename)
|
|||||||
if (line_fix[pos] == '\t')
|
if (line_fix[pos] == '\t')
|
||||||
line_fix.exchange(pos, 1, pos & 1 ? strref(" ") : strref(" "));
|
line_fix.exchange(pos, 1, pos & 1 ? strref(" ") : strref(" "));
|
||||||
}
|
}
|
||||||
out.append_to(' ', aCPUs[cpu].timing ? 36 : 33);
|
out.append_to(' ', aCPUs[cpu].timing ? 40 : 33);
|
||||||
out.append(line_fix.get_strref());
|
out.append(line_fix.get_strref());
|
||||||
fprintf(f, STRREF_FMT "\n", STRREF_ARG(out));
|
fprintf(f, STRREF_FMT "\n", STRREF_ARG(out));
|
||||||
out.clear();
|
out.clear();
|
||||||
@@ -5024,14 +5098,18 @@ bool Asm::List(strref filename)
|
|||||||
out.sprintf_append("%02x ", si->output[lst.address + b]);
|
out.sprintf_append("%02x ", si->output[lst.address + b]);
|
||||||
}
|
}
|
||||||
if (lst.startClock() && cycles_depth<MAX_DEPTH_CYCLE_COUNTER) {
|
if (lst.startClock() && cycles_depth<MAX_DEPTH_CYCLE_COUNTER) {
|
||||||
cycles_depth++; cycles[cycles_depth][0] = 0; cycles[cycles_depth][1] = 0;
|
cycles_depth++; cycles[cycles_depth].clr();
|
||||||
out.append_to(' ', 25); out.sprintf_append("c>%d", cycles_depth);
|
out.append_to(' ', 6); out.sprintf_append("c>%d", cycles_depth);
|
||||||
}
|
}
|
||||||
if (lst.stopClock()) {
|
if (lst.stopClock()) {
|
||||||
out.append_to(' ', 25); out.sprintf_append("c<%d=%d+%d", cycles_depth, cycles[cycles_depth][0], cycles[cycles_depth][1]);
|
out.append_to(' ', 6);
|
||||||
|
if (cycles[cycles_depth].complex())
|
||||||
|
out.sprintf_append("c<%d = %d + m%d + i%d + d%d", cycles_depth, cycles[cycles_depth].base, cycles[cycles_depth].a16, cycles[cycles_depth].x16, cycles[cycles_depth].dp);
|
||||||
|
else
|
||||||
|
out.sprintf_append("c<%d = %d + %d", cycles_depth, cycles[cycles_depth].base, cycles[cycles_depth].plus_acc());
|
||||||
if (cycles_depth) {
|
if (cycles_depth) {
|
||||||
cycles_depth--; cycles[cycles_depth][0] += cycles[cycles_depth + 1][0];
|
cycles_depth--;
|
||||||
cycles[cycles_depth][1] += cycles[cycles_depth + 1][1];
|
cycles[cycles_depth].combine(cycles[cycles_depth + 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lst.size && lst.wasMnemonic()) {
|
if (lst.size && lst.wasMnemonic()) {
|
||||||
@@ -5064,15 +5142,19 @@ bool Asm::List(strref filename)
|
|||||||
else
|
else
|
||||||
out.sprintf_append(fmt, opcode_table[op].instr, buf[1]);
|
out.sprintf_append(fmt, opcode_table[op].instr, buf[1]);
|
||||||
if (aCPUs[cpu].timing) {
|
if (aCPUs[cpu].timing) {
|
||||||
cycles[cycles_depth][0] += aCPUs[cpu].timing[*buf] / 2;
|
cycles[cycles_depth].add(aCPUs[cpu].timing[*buf]);
|
||||||
cycles[cycles_depth][1] += aCPUs[cpu].timing[*buf] & 1;
|
|
||||||
out.append_to(' ', 33);
|
out.append_to(' ', 33);
|
||||||
out.sprintf_append("%x%s", aCPUs[cpu].timing[*buf] / 2, (aCPUs[cpu].timing[*buf] & 1) ? "+" : "");
|
if (cycleCnt::sum_plus(aCPUs[cpu].timing[*buf])==1)
|
||||||
|
out.sprintf_append("%d+", cycleCnt::get_base(aCPUs[cpu].timing[*buf]));
|
||||||
|
else if (cycleCnt::sum_plus(aCPUs[cpu].timing[*buf]))
|
||||||
|
out.sprintf_append("%d+%d", cycleCnt::get_base(aCPUs[cpu].timing[*buf]), cycleCnt::sum_plus(aCPUs[cpu].timing[*buf]));
|
||||||
|
else
|
||||||
|
out.sprintf_append("%d", cycleCnt::get_base(aCPUs[cpu].timing[*buf]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out.append_to(' ', aCPUs[cpu].timing ? 36 : 33);
|
out.append_to(' ', aCPUs[cpu].timing ? 40 : 33);
|
||||||
strref line = lst.code.get_skipped(lst.line_offs).get_line();
|
strref line = lst.code.get_skipped(lst.line_offs).get_line();
|
||||||
line.clip_trailing_whitespace();
|
line.clip_trailing_whitespace();
|
||||||
strown<128> line_fix(line);
|
strown<128> line_fix(line);
|
||||||
@@ -5354,7 +5436,7 @@ StatusCode Asm::WriteObjectFile(strref filename)
|
|||||||
(si->IsDummySection() ? (1 << ObjFileSection::OFS_DUMMY) : 0) |
|
(si->IsDummySection() ? (1 << ObjFileSection::OFS_DUMMY) : 0) |
|
||||||
(si->IsMergedSection() ? (1 << ObjFileSection::OFS_MERGED) : 0) |
|
(si->IsMergedSection() ? (1 << ObjFileSection::OFS_MERGED) : 0) |
|
||||||
(si->address_assigned ? (1 << ObjFileSection::OFS_FIXED) : 0);
|
(si->address_assigned ? (1 << ObjFileSection::OFS_FIXED) : 0);
|
||||||
if (si->pRelocs && si->pRelocs->size()) {
|
if (si->pRelocs && si->pRelocs->size() && aRelocs) {
|
||||||
for (relocList::iterator ri = si->pRelocs->begin(); ri!=si->pRelocs->end(); ++ri) {
|
for (relocList::iterator ri = si->pRelocs->begin(); ri!=si->pRelocs->end(); ++ri) {
|
||||||
struct ObjFileReloc &r = aRelocs[reloc++];
|
struct ObjFileReloc &r = aRelocs[reloc++];
|
||||||
r.base_value = ri->base_value;
|
r.base_value = ri->base_value;
|
||||||
@@ -5552,32 +5634,34 @@ StatusCode Asm::ReadObjectFile(strref filename)
|
|||||||
struct ObjFileLabel &l = aLabels[li];
|
struct ObjFileLabel &l = aLabels[li];
|
||||||
strref name = l.name.offs >= 0 ? strref(str_pool + l.name.offs) : strref();
|
strref name = l.name.offs >= 0 ? strref(str_pool + l.name.offs) : strref();
|
||||||
Label *lbl = GetLabel(name);
|
Label *lbl = GetLabel(name);
|
||||||
if (!lbl) {
|
short f = l.flags;
|
||||||
short f = l.flags;
|
int external = f & ObjFileLabel::OFL_XDEF;
|
||||||
int external = f & ObjFileLabel::OFL_XDEF;
|
if (external == ObjFileLabel::OFL_XDEF) {
|
||||||
if (external == ObjFileLabel::OFL_XDEF)
|
if (!lbl)
|
||||||
lbl = AddLabel(name.fnv1a()); // insert shared label
|
lbl = AddLabel(name.fnv1a()); // insert shared label
|
||||||
else { // insert protected label
|
else if (!lbl->reference)
|
||||||
while ((file_index + external) >= (int)externals.size()) {
|
continue;
|
||||||
if (externals.size() == externals.capacity())
|
} else { // insert protected label
|
||||||
externals.reserve(externals.size() + 32);
|
while ((file_index + external) >= (int)externals.size()) {
|
||||||
externals.push_back(ExtLabels());
|
if (externals.size() == externals.capacity())
|
||||||
}
|
externals.reserve(externals.size() + 32);
|
||||||
unsigned int hash = name.fnv1a();
|
externals.push_back(ExtLabels());
|
||||||
unsigned int index = FindLabelIndex(hash, externals[file_index].labels.getKeys(), externals[file_index].labels.count());
|
|
||||||
externals[file_index].labels.insert(index, hash);
|
|
||||||
lbl = externals[file_index].labels.getValues() + index;
|
|
||||||
}
|
}
|
||||||
lbl->label_name = name;
|
unsigned int hash = name.fnv1a();
|
||||||
lbl->pool_name.clear();
|
unsigned int index = FindLabelIndex(hash, externals[file_index].labels.getKeys(), externals[file_index].labels.count());
|
||||||
lbl->value = l.value;
|
externals[file_index].labels.insert(index, hash);
|
||||||
lbl->evaluated = !!(f & ObjFileLabel::OFL_EVAL);
|
lbl = externals[file_index].labels.getValues() + index;
|
||||||
lbl->constant = !!(f & ObjFileLabel::OFL_CNST);
|
|
||||||
lbl->pc_relative = !!(f & ObjFileLabel::OFL_ADDR);
|
|
||||||
lbl->external = external == ObjFileLabel::OFL_XDEF;
|
|
||||||
lbl->section = l.section >= 0 ? aSctRmp[l.section] : l.section;
|
|
||||||
lbl->mapIndex = l.mapIndex >= 0 ? (l.mapIndex + (int)map.size()) : -1;
|
|
||||||
}
|
}
|
||||||
|
lbl->label_name = name;
|
||||||
|
lbl->pool_name.clear();
|
||||||
|
lbl->value = l.value;
|
||||||
|
lbl->evaluated = !!(f & ObjFileLabel::OFL_EVAL);
|
||||||
|
lbl->constant = !!(f & ObjFileLabel::OFL_CNST);
|
||||||
|
lbl->pc_relative = !!(f & ObjFileLabel::OFL_ADDR);
|
||||||
|
lbl->external = external == ObjFileLabel::OFL_XDEF;
|
||||||
|
lbl->section = l.section >= 0 ? aSctRmp[l.section] : l.section;
|
||||||
|
lbl->mapIndex = l.mapIndex >= 0 ? (l.mapIndex + (int)map.size()) : -1;
|
||||||
|
lbl->reference = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_index==(int)externals.size())
|
if (file_index==(int)externals.size())
|
||||||
|
Reference in New Issue
Block a user