Merge pull request #2001 from bbbradsmith/ca65_long_jsr_jmp_rts
ca65 jsr/jmp/rts will not promote to jsl/jml/rtl by default, new feature long_jsr_jmp_rts to re-enable this ability
This commit is contained in:
@@ -184,7 +184,7 @@ Here is a description of all the command line options:
|
|||||||
|
|
||||||
Enable an emulation feature. This is identical as using <tt/.FEATURE/
|
Enable an emulation feature. This is identical as using <tt/.FEATURE/
|
||||||
in the source with two exceptions: Feature names must be lower case, and
|
in the source with two exceptions: Feature names must be lower case, and
|
||||||
each feature must be specified by using an extra <tt/--feature/ option,
|
each feature must be specified by using a separate <tt/--feature/ option,
|
||||||
comma separated lists are not allowed.
|
comma separated lists are not allowed.
|
||||||
|
|
||||||
See the discussion of the <tt><ref id=".FEATURE" name=".FEATURE"></tt>
|
See the discussion of the <tt><ref id=".FEATURE" name=".FEATURE"></tt>
|
||||||
@@ -2833,6 +2833,23 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH
|
|||||||
overridden. When using this feature, you may also get into trouble if
|
overridden. When using this feature, you may also get into trouble if
|
||||||
later versions of the assembler define new keywords starting with a dot.
|
later versions of the assembler define new keywords starting with a dot.
|
||||||
|
|
||||||
|
<tag><tt>long_jsr_jmp_rts</tt><label id="long_jsr_jmp_rts"></tag>
|
||||||
|
|
||||||
|
Affects 65816 mode only.
|
||||||
|
|
||||||
|
Allows <tt>jsr</tt> and <tt>jmp</tt> to produce long jumps if the target
|
||||||
|
address has been previously declared in a <tt>far</tt> segment,
|
||||||
|
or imported as <tt>far</tt>.
|
||||||
|
Otherwise <tt>jsl</tt> and <tt>jml</tt> must be used instead.
|
||||||
|
|
||||||
|
Also allows <tt><ref id=".SMART" name=".SMART"></tt> to convert <tt>rts</tt>
|
||||||
|
to a long return <tt>rtl</tt> when the enclosing scope or memory model
|
||||||
|
indicates returning from a <tt>far</tt> procedure.
|
||||||
|
|
||||||
|
This permits compatibility with the old behavior of this assembler, or other
|
||||||
|
assemblers which similarly allowed <tt>jsr</tt> and <tt>jmp</tt> to be used
|
||||||
|
this way.
|
||||||
|
|
||||||
<tag><tt>loose_char_term</tt><label id="loose_char_term"></tag>
|
<tag><tt>loose_char_term</tt><label id="loose_char_term"></tag>
|
||||||
|
|
||||||
Accept single quotes as well as double quotes as terminators for char
|
Accept single quotes as well as double quotes as terminators for char
|
||||||
@@ -4002,7 +4019,9 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE"
|
|||||||
the assembler cannot trace the execution flow this may lead to false
|
the assembler cannot trace the execution flow this may lead to false
|
||||||
results in some cases. If in doubt, use the <tt/.Inn/ and <tt/.Ann/
|
results in some cases. If in doubt, use the <tt/.Inn/ and <tt/.Ann/
|
||||||
instructions to tell the assembler about the current settings.
|
instructions to tell the assembler about the current settings.
|
||||||
<item>In 65816 mode, replace a <tt/RTS/ instruction by <tt/RTL/ if it is
|
<item>In 65816 mode, if the <tt><ref id="long_jsr_jmp_rts"
|
||||||
|
name="long_jsr_jmp_rts"></tt> feature is enabled,
|
||||||
|
smart mode will replace a <tt/RTS/ instruction by <tt/RTL/ if it is
|
||||||
used within a procedure declared as <tt/far/, or if the procedure has
|
used within a procedure declared as <tt/far/, or if the procedure has
|
||||||
no explicit address specification, but it is <tt/far/ because of the
|
no explicit address specification, but it is <tt/far/ because of the
|
||||||
memory model used.
|
memory model used.
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ static const char* const FeatureKeys[FEAT_COUNT] = {
|
|||||||
"addrsize",
|
"addrsize",
|
||||||
"bracket_as_indirect",
|
"bracket_as_indirect",
|
||||||
"string_escapes",
|
"string_escapes",
|
||||||
|
"long_jsr_jmp_rts",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -125,6 +126,7 @@ feature_t SetFeature (const StrBuf* Key)
|
|||||||
case FEAT_ADDRSIZE: AddrSize = 1; break;
|
case FEAT_ADDRSIZE: AddrSize = 1; break;
|
||||||
case FEAT_BRACKET_AS_INDIRECT: BracketAsIndirect = 1; break;
|
case FEAT_BRACKET_AS_INDIRECT: BracketAsIndirect = 1; break;
|
||||||
case FEAT_STRING_ESCAPES: StringEscapes = 1; break;
|
case FEAT_STRING_ESCAPES: StringEscapes = 1; break;
|
||||||
|
case FEAT_LONG_JSR_JMP_RTS: LongJsrJmpRts = 1; break;
|
||||||
default: /* Keep gcc silent */ break;
|
default: /* Keep gcc silent */ break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ typedef enum {
|
|||||||
FEAT_ADDRSIZE,
|
FEAT_ADDRSIZE,
|
||||||
FEAT_BRACKET_AS_INDIRECT,
|
FEAT_BRACKET_AS_INDIRECT,
|
||||||
FEAT_STRING_ESCAPES,
|
FEAT_STRING_ESCAPES,
|
||||||
|
FEAT_LONG_JSR_JMP_RTS,
|
||||||
|
|
||||||
/* Special value: Number of features available */
|
/* Special value: Number of features available */
|
||||||
FEAT_COUNT
|
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 LargeAlignment = 0; /* Don't warn about large alignments */
|
||||||
unsigned char RelaxChecks = 0; /* Relax a few assembler checks */
|
unsigned char RelaxChecks = 0; /* Relax a few assembler checks */
|
||||||
unsigned char StringEscapes = 0; /* Allow C-style escapes in strings */
|
unsigned char StringEscapes = 0; /* Allow C-style escapes in strings */
|
||||||
|
unsigned char LongJsrJmpRts = 0; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */
|
||||||
unsigned char WarningsAsErrors = 0; /* Error if any warnings */
|
unsigned char WarningsAsErrors = 0; /* Error if any warnings */
|
||||||
|
|
||||||
/* Emulation features */
|
/* Emulation features */
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ extern unsigned char LineCont; /* Allow line continuation */
|
|||||||
extern unsigned char LargeAlignment; /* Don't warn about large alignments */
|
extern unsigned char LargeAlignment; /* Don't warn about large alignments */
|
||||||
extern unsigned char RelaxChecks; /* Relax a few assembler checks */
|
extern unsigned char RelaxChecks; /* Relax a few assembler checks */
|
||||||
extern unsigned char StringEscapes; /* Allow C-style escapes in strings */
|
extern unsigned char StringEscapes; /* Allow C-style escapes in strings */
|
||||||
|
extern unsigned char LongJsrJmpRts; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */
|
||||||
extern unsigned char WarningsAsErrors; /* Error if any warnings */
|
extern unsigned char WarningsAsErrors; /* Error if any warnings */
|
||||||
|
|
||||||
/* Emulation features */
|
/* Emulation features */
|
||||||
|
|||||||
@@ -120,9 +120,21 @@ static void PutJMP (const InsDesc* Ins);
|
|||||||
** to check for this case and is otherwise identical to PutAll.
|
** 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)));
|
static void PutRTS (const InsDesc* Ins attribute ((unused)));
|
||||||
/* Handle the RTS instruction for the 816. In smart mode emit a RTL opcode if
|
/* 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);
|
static void PutAll (const InsDesc* Ins);
|
||||||
@@ -758,9 +770,9 @@ static const struct {
|
|||||||
{ "INX", 0x0000001, 0xe8, 0, PutAll },
|
{ "INX", 0x0000001, 0xe8, 0, PutAll },
|
||||||
{ "INY", 0x0000001, 0xc8, 0, PutAll },
|
{ "INY", 0x0000001, 0xc8, 0, PutAll },
|
||||||
{ "JML", 0x4000010, 0x5c, 1, PutAll },
|
{ "JML", 0x4000010, 0x5c, 1, PutAll },
|
||||||
{ "JMP", 0x4010818, 0x4c, 6, PutAll },
|
{ "JMP", 0x4010818, 0x4c, 6, PutJMP816 },
|
||||||
{ "JSL", 0x0000010, 0x20, 7, PutAll },
|
{ "JSL", 0x0000010, 0x20, 7, PutAll },
|
||||||
{ "JSR", 0x0010018, 0x20, 7, PutAll },
|
{ "JSR", 0x0010018, 0x20, 7, PutJSR816 },
|
||||||
{ "LDA", 0x0b8f6fc, 0xa0, 0, PutAll },
|
{ "LDA", 0x0b8f6fc, 0xa0, 0, PutAll },
|
||||||
{ "LDX", 0x0c0030c, 0xa2, 1, PutAll },
|
{ "LDX", 0x0c0030c, 0xa2, 1, PutAll },
|
||||||
{ "LDY", 0x0c0006c, 0xa0, 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)))
|
static void PutJMP816 (const InsDesc* Ins)
|
||||||
/* Handle the RTS instruction for the 816. In smart mode emit a RTL opcode if
|
/* Handle the JMP instruction for the 816.
|
||||||
** the enclosing scope is FAR.
|
** 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 */
|
Emit0 (0x6B); /* RTL */
|
||||||
} else {
|
} else {
|
||||||
Emit0 (0x60); /* RTS */
|
Emit0 (0x60); /* RTS */
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ GLOBAL {
|
|||||||
};
|
};
|
||||||
|
|
||||||
RANGE { START $8000; END $8229; ADDRMODE "MX"; TYPE Code;};
|
RANGE { START $8000; END $8229; ADDRMODE "MX"; TYPE Code;};
|
||||||
RANGE { START $822a; END $824b; ADDRMODE "mx"; TYPE Code;};
|
RANGE { START $822a; END $825b; ADDRMODE "mx"; TYPE Code;};
|
||||||
|
|
||||||
|
|||||||
@@ -151,10 +151,11 @@ BVC LABEL
|
|||||||
BVS LABEL
|
BVS LABEL
|
||||||
BRL LABEL
|
BRL LABEL
|
||||||
JMP $1234
|
JMP $1234
|
||||||
JMP $FEDCBA
|
JML $FEDCBA
|
||||||
JMP ($1234)
|
JMP ($1234)
|
||||||
JMP ($1234,X)
|
JMP ($1234,X)
|
||||||
JMP [$1234]
|
JMP [$1234]
|
||||||
|
JML [$1234] ; alternative to JMP []
|
||||||
JSL $123456
|
JSL $123456
|
||||||
JSR $1234
|
JSR $1234
|
||||||
JSR ($1234,X)
|
JSR ($1234,X)
|
||||||
@@ -271,3 +272,15 @@ BIT #$5432
|
|||||||
LDA #$5432
|
LDA #$5432
|
||||||
LDX #$5432
|
LDX #$5432
|
||||||
LDY #$5432
|
LDY #$5432
|
||||||
|
|
||||||
|
; test of smart and long_jsr_jmp_rts
|
||||||
|
.smart
|
||||||
|
.proc short_rts : far
|
||||||
|
RTS ; not promoted to RTL
|
||||||
|
.endproc
|
||||||
|
.feature long_jsr_jmp_rts
|
||||||
|
JSR $FEDCBA ; promoted to JSL
|
||||||
|
JMP $FEDCBA ; promoted to JML
|
||||||
|
.proc long_rts : far
|
||||||
|
RTS ; promoted to RTL
|
||||||
|
.endproc
|
||||||
|
|||||||
Reference in New Issue
Block a user