1
0
mirror of https://github.com/cc65/cc65.git synced 2025-04-09 10:39:40 +00:00

Merge pull request #681 from shinra-jp/voperand

Support for "inline parameters" of subroutines
This commit is contained in:
Oliver Schmidt 2018-06-13 14:41:24 +02:00 committed by GitHub
commit 6c320f7d65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 78 additions and 12 deletions

View File

@ -542,6 +542,18 @@ code. The following attributes are recognized:
range, where <tt/label/ is the label name given with the <tt/NAME/
attribute, and <tt/offs/ is the offset within the data.
<tag><tt>PARAMSIZE</tt></tag>
This optional attribute is followed by a numerical value. It tells the
assembler that subroutine calls to this label are followed by
"inline parameters" with the given number of bytes, like this:
<tscreen><verb>
JSR LabelWithParamSize2
.byte $00, $10
(return here)
code...
</verb></tscreen>
</descrip>

View File

@ -51,6 +51,8 @@
static unsigned short SubroutineParamSize[0x10000];
/*****************************************************************************/
/* Helper functions */
/*****************************************************************************/
@ -741,3 +743,35 @@ void OH_JmpAbsoluteXIndirect (const OpcDesc* D)
}
SeparatorLine ();
}
void OH_JsrAbsolute (const OpcDesc* D)
{
unsigned ParamSize = SubroutineParamSize[GetCodeWord (PC+1)];
OH_Absolute (D);
if (ParamSize > 0) {
unsigned RemainingBytes;
unsigned BytesLeft;
PC += D->Size;
RemainingBytes = GetRemainingBytes ();
if (RemainingBytes < ParamSize) {
ParamSize = RemainingBytes;
}
BytesLeft = ParamSize;
while (BytesLeft > 0) {
unsigned Chunk = (BytesLeft > BytesPerLine) ? BytesPerLine : BytesLeft;
DataByteLine (Chunk);
BytesLeft -= Chunk;
PC += Chunk;
}
PC -= D->Size;
}
}
void SetSubroutineParamSize (unsigned Addr, unsigned Size)
{
SubroutineParamSize[Addr] = Size;
}

View File

@ -104,7 +104,9 @@ void OH_Rts (const OpcDesc*);
void OH_JmpAbsolute (const OpcDesc*);
void OH_JmpAbsoluteIndirect (const OpcDesc* D);
void OH_JmpAbsoluteXIndirect (const OpcDesc* D);
void OH_JsrAbsolute (const OpcDesc*);
void SetSubroutineParamSize (unsigned Addr, unsigned Size);
/* End of handler.h */

View File

@ -59,6 +59,7 @@
#include "opctable.h"
#include "scanner.h"
#include "segment.h"
#include "handler.h"
@ -376,17 +377,19 @@ static void LabelSection (void)
/* Parse a label section */
{
static const IdentTok LabelDefs[] = {
{ "COMMENT", INFOTOK_COMMENT },
{ "ADDR", INFOTOK_ADDR },
{ "NAME", INFOTOK_NAME },
{ "SIZE", INFOTOK_SIZE },
{ "COMMENT", INFOTOK_COMMENT },
{ "ADDR", INFOTOK_ADDR },
{ "NAME", INFOTOK_NAME },
{ "SIZE", INFOTOK_SIZE },
{ "PARAMSIZE", INFOTOK_PARAMSIZE },
};
/* Locals - initialize to avoid gcc warnings */
char* Name = 0;
char* Comment = 0;
long Value = -1;
long Size = -1;
char* Name = 0;
char* Comment = 0;
long Value = -1;
long Size = -1;
long ParamSize = -1;
/* Skip the token */
InfoNextTok ();
@ -448,6 +451,17 @@ static void LabelSection (void)
InfoNextTok ();
break;
case INFOTOK_PARAMSIZE:
InfoNextTok ();
if (ParamSize >= 0) {
InfoError ("ParamSize already given");
}
InfoAssureInt ();
InfoRangeCheck (1, 0x10000);
ParamSize = InfoIVal;
InfoNextTok ();
break;
default:
Internal ("Unexpected token: %u", InfoTok);
}
@ -484,6 +498,9 @@ static void LabelSection (void)
} else {
AddExtLabelRange ((unsigned) Value, Name, Size);
}
if (ParamSize >= 0) {
SetSubroutineParamSize ((unsigned) Value, (unsigned) ParamSize);
}
/* Define the comment */
if (Comment) {

View File

@ -79,7 +79,7 @@ const OpcDesc OpcTable_6502[256] = {
{ "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */
{ "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */
{ "", 1, flIllegal, OH_Illegal, }, /* $1f */
{ "jsr", 3, flLabel, OH_Absolute }, /* $20 */
{ "jsr", 3, flLabel, OH_JsrAbsolute }, /* $20 */
{ "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */
{ "", 1, flIllegal, OH_Illegal, }, /* $22 */
{ "", 1, flIllegal, OH_Illegal, }, /* $23 */

View File

@ -79,7 +79,7 @@ const OpcDesc OpcTable_65816[256] = {
{ "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */
{ "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */
{ "ora", 4, flUseLabel, OH_AbsoluteLongX }, /* $1f */
{ "jsr", 3, flLabel, OH_Absolute }, /* $20 */
{ "jsr", 3, flLabel, OH_JsrAbsolute }, /* $20 */
{ "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */
{ "jsl", 3, flLabel, OH_AbsoluteLong }, /* $22 */
{ "and", 2, flNone, OH_StackRelative }, /* $23 */

View File

@ -79,7 +79,7 @@ const OpcDesc OpcTable_65C02[256] = {
{ "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */
{ "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */
{ "bbr1", 3, flUseLabel, OH_BitBranch }, /* $1f */
{ "jsr", 3, flLabel, OH_Absolute }, /* $20 */
{ "jsr", 3, flLabel, OH_JsrAbsolute }, /* $20 */
{ "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */
{ "", 1, flIllegal, OH_Illegal, }, /* $22 */
{ "", 1, flIllegal, OH_Illegal, }, /* $23 */

View File

@ -79,7 +79,7 @@ const OpcDesc OpcTable_65SC02[256] = {
{ "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */
{ "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */
{ "", 1, flIllegal, OH_Illegal, }, /* $1f */
{ "jsr", 3, flLabel, OH_Absolute }, /* $20 */
{ "jsr", 3, flLabel, OH_JsrAbsolute }, /* $20 */
{ "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */
{ "", 1, flIllegal, OH_Illegal, }, /* $22 */
{ "", 1, flIllegal, OH_Illegal, }, /* $23 */

View File

@ -105,6 +105,7 @@ typedef enum token_t {
INFOTOK_COMMENT,
INFOTOK_ADDR,
INFOTOK_SIZE,
INFOTOK_PARAMSIZE,
/* ASMINC section */
INFOTOK_FILE,