ca65 jsr/jmp/rts will not promote to jsl/jml/rtl by default, but can still be enabled with new feature long_jsr_jmp_rts
This commit is contained in:
@@ -66,6 +66,7 @@ static const char* const FeatureKeys[FEAT_COUNT] = {
|
||||
"addrsize",
|
||||
"bracket_as_indirect",
|
||||
"string_escapes",
|
||||
"long_jsr_jmp_rts",
|
||||
};
|
||||
|
||||
|
||||
@@ -125,6 +126,7 @@ feature_t SetFeature (const StrBuf* Key)
|
||||
case FEAT_ADDRSIZE: AddrSize = 1; break;
|
||||
case FEAT_BRACKET_AS_INDIRECT: BracketAsIndirect = 1; break;
|
||||
case FEAT_STRING_ESCAPES: StringEscapes = 1; break;
|
||||
case FEAT_LONG_JSR_JMP_RTS: LongJsrJmpRts = 1; break;
|
||||
default: /* Keep gcc silent */ break;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ typedef enum {
|
||||
FEAT_ADDRSIZE,
|
||||
FEAT_BRACKET_AS_INDIRECT,
|
||||
FEAT_STRING_ESCAPES,
|
||||
FEAT_LONG_JSR_JMP_RTS,
|
||||
|
||||
/* Special value: Number of features available */
|
||||
FEAT_COUNT
|
||||
|
||||
@@ -67,6 +67,7 @@ unsigned char LineCont = 0; /* Allow line continuation */
|
||||
unsigned char LargeAlignment = 0; /* Don't warn about large alignments */
|
||||
unsigned char RelaxChecks = 0; /* Relax a few assembler checks */
|
||||
unsigned char StringEscapes = 0; /* Allow C-style escapes in strings */
|
||||
unsigned char LongJsrJmpRts = 0; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */
|
||||
|
||||
/* Emulation features */
|
||||
unsigned char DollarIsPC = 0; /* Allow the $ symbol as current PC */
|
||||
|
||||
@@ -69,6 +69,7 @@ extern unsigned char LineCont; /* Allow line continuation */
|
||||
extern unsigned char LargeAlignment; /* Don't warn about large alignments */
|
||||
extern unsigned char RelaxChecks; /* Relax a few assembler checks */
|
||||
extern unsigned char StringEscapes; /* Allow C-style escapes in strings */
|
||||
extern unsigned char LongJsrJmpRts; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */
|
||||
|
||||
/* Emulation features */
|
||||
extern unsigned char DollarIsPC; /* Allow the $ symbol as current PC */
|
||||
|
||||
@@ -120,9 +120,21 @@ static void PutJMP (const InsDesc* Ins);
|
||||
** to check for this case and is otherwise identical to PutAll.
|
||||
*/
|
||||
|
||||
static void PutJMP816 (const InsDesc* Ins);
|
||||
/* Handle the JMP instruction for the 816.
|
||||
** Allowing the long_jsr_jmp_rts feature to permit a long JMP.
|
||||
** Note that JMP [abs] and JML [abs] are always both permitted for instruction $DC,
|
||||
** because the [] notation for long indirection makes the generated instruction unambiguous.
|
||||
*/
|
||||
|
||||
static void PutJSR816 (const InsDesc* Ins);
|
||||
/* Handle the JSR instruction for the 816.
|
||||
** Allowing the long_jsr_jmp_rts feature to permit a long JSR.
|
||||
*/
|
||||
|
||||
static void PutRTS (const InsDesc* Ins attribute ((unused)));
|
||||
/* Handle the RTS instruction for the 816. In smart mode emit a RTL opcode if
|
||||
** the enclosing scope is FAR.
|
||||
** the enclosing scope is FAR, but only if the long_jsr_jmp_rts feature applies.
|
||||
*/
|
||||
|
||||
static void PutAll (const InsDesc* Ins);
|
||||
@@ -758,9 +770,9 @@ static const struct {
|
||||
{ "INX", 0x0000001, 0xe8, 0, PutAll },
|
||||
{ "INY", 0x0000001, 0xc8, 0, PutAll },
|
||||
{ "JML", 0x4000010, 0x5c, 1, PutAll },
|
||||
{ "JMP", 0x4010818, 0x4c, 6, PutAll },
|
||||
{ "JMP", 0x4010818, 0x4c, 6, PutJMP816 },
|
||||
{ "JSL", 0x0000010, 0x20, 7, PutAll },
|
||||
{ "JSR", 0x0010018, 0x20, 7, PutAll },
|
||||
{ "JSR", 0x0010018, 0x20, 7, PutJSR816 },
|
||||
{ "LDA", 0x0b8f6fc, 0xa0, 0, PutAll },
|
||||
{ "LDX", 0x0c0030c, 0xa2, 1, PutAll },
|
||||
{ "LDY", 0x0c0006c, 0xa0, 1, PutAll },
|
||||
@@ -1627,12 +1639,46 @@ static void PutJMP (const InsDesc* Ins)
|
||||
|
||||
|
||||
|
||||
static void PutRTS (const InsDesc* Ins attribute ((unused)))
|
||||
/* Handle the RTS instruction for the 816. In smart mode emit a RTL opcode if
|
||||
** the enclosing scope is FAR.
|
||||
static void PutJMP816 (const InsDesc* Ins)
|
||||
/* Handle the JMP instruction for the 816.
|
||||
** Allowing the long_jsr_jmp_rts feature to permit a long JMP.
|
||||
** Note that JMP [abs] and JML [abs] are always both permitted for instruction $DC,
|
||||
** because the [] notation for long indirection makes the generated instruction unambiguous.
|
||||
*/
|
||||
{
|
||||
if (SmartMode && CurrentScope->AddrSize == ADDR_SIZE_FAR) {
|
||||
if (LongJsrJmpRts) {
|
||||
PutJMP (Ins);
|
||||
} else {
|
||||
InsDesc InsAbs = *Ins;
|
||||
InsAbs.AddrMode &= ~(AM65_ABS_LONG);
|
||||
PutJMP (&InsAbs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void PutJSR816 (const InsDesc* Ins)
|
||||
/* Handle the JSR instruction for the 816.
|
||||
** Allowing the long_jsr_jmp_rts feature to permit a long JSR.
|
||||
*/
|
||||
{
|
||||
if (LongJsrJmpRts) {
|
||||
PutAll (Ins);
|
||||
} else {
|
||||
InsDesc InsAbs = *Ins;
|
||||
InsAbs.AddrMode &= ~(AM65_ABS_LONG);
|
||||
PutJMP (&InsAbs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void PutRTS (const InsDesc* Ins attribute ((unused)))
|
||||
/* Handle the RTS instruction for the 816. In smart mode emit a RTL opcode if
|
||||
** the enclosing scope is FAR, but only if the long_jsr_jmp_rts feature applies.
|
||||
*/
|
||||
{
|
||||
if (LongJsrJmpRts && SmartMode && CurrentScope->AddrSize == ADDR_SIZE_FAR) {
|
||||
Emit0 (0x6B); /* RTL */
|
||||
} else {
|
||||
Emit0 (0x60); /* RTS */
|
||||
|
||||
Reference in New Issue
Block a user