diff --git a/doc/da65.sgml b/doc/da65.sgml index a8e32e1c8..c2d87ac92 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -542,6 +542,18 @@ code. The following attributes are recognized: range, where VOPERAND + This optional attribute is followed by a numerical value. It tells the + assembler that subroutine calls to this label follow "virtual operands" + of the given bytes like this: + + + JSR LabelWith2BytesOfVoperand + .byte $00, $10 ; virtual operands + ; return here + BIT $0F + + diff --git a/src/da65/handler.c b/src/da65/handler.c index 624952363..19b8946de 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -51,6 +51,8 @@ +static unsigned short SubroutineVOperandSize[0x10000]; + /*****************************************************************************/ /* Helper functions */ /*****************************************************************************/ @@ -741,3 +743,31 @@ void OH_JmpAbsoluteXIndirect (const OpcDesc* D) } SeparatorLine (); } + + + +void OH_JsrAbsolute (const OpcDesc* D) +{ + unsigned VOperandSize = SubroutineVOperandSize[GetCodeWord(PC+1)]; + OH_Absolute (D); + if (VOperandSize > 0) { + unsigned RemainingBytes; + PC += D->Size; + RemainingBytes = GetRemainingBytes(); + if (RemainingBytes < VOperandSize) { + VOperandSize = RemainingBytes; + } + if (VOperandSize > 0) { + DataByteLine (VOperandSize); /* FIXME: follow BytesPerLine */ + PC += VOperandSize; + } + PC -= D->Size; + } +} + + + +void SetSubroutineVOperand (unsigned Addr, unsigned Size) +{ + SubroutineVOperandSize[Addr] = Size; +} diff --git a/src/da65/handler.h b/src/da65/handler.h index c0fa68e56..96b73f2c7 100644 --- a/src/da65/handler.h +++ b/src/da65/handler.h @@ -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 SetSubroutineVOperand (unsigned Addr, unsigned Size); /* End of handler.h */ diff --git a/src/da65/infofile.c b/src/da65/infofile.c index e8ce66cf7..3bfa15f51 100644 --- a/src/da65/infofile.c +++ b/src/da65/infofile.c @@ -59,6 +59,7 @@ #include "opctable.h" #include "scanner.h" #include "segment.h" +#include "handler.h" @@ -380,6 +381,7 @@ static void LabelSection (void) { "ADDR", INFOTOK_ADDR }, { "NAME", INFOTOK_NAME }, { "SIZE", INFOTOK_SIZE }, + { "VOPERAND", INFOTOK_VOPERAND }, }; /* Locals - initialize to avoid gcc warnings */ @@ -387,6 +389,7 @@ static void LabelSection (void) char* Comment = 0; long Value = -1; long Size = -1; + long VOperand = -1; /* Skip the token */ InfoNextTok (); @@ -448,6 +451,17 @@ static void LabelSection (void) InfoNextTok (); break; + case INFOTOK_VOPERAND: + InfoNextTok (); + if (VOperand >= 0) { + InfoError ("VOperand already given"); + } + InfoAssureInt (); + InfoRangeCheck (1, 0x10000); + VOperand = InfoIVal; + InfoNextTok (); + break; + default: Internal ("Unexpected token: %u", InfoTok); } @@ -484,6 +498,9 @@ static void LabelSection (void) } else { AddExtLabelRange ((unsigned) Value, Name, Size); } + if (VOperand >= 0) { + SetSubroutineVOperand ((unsigned) Value, (unsigned) VOperand); + } /* Define the comment */ if (Comment) { diff --git a/src/da65/opc6502.c b/src/da65/opc6502.c index 27f734d56..8fc6f6aea 100644 --- a/src/da65/opc6502.c +++ b/src/da65/opc6502.c @@ -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 */ diff --git a/src/da65/opc65816.c b/src/da65/opc65816.c index 2cd2aaee8..b7775d2e2 100644 --- a/src/da65/opc65816.c +++ b/src/da65/opc65816.c @@ -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 */ diff --git a/src/da65/opc65c02.c b/src/da65/opc65c02.c index 8133bccae..b69558f2a 100644 --- a/src/da65/opc65c02.c +++ b/src/da65/opc65c02.c @@ -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 */ diff --git a/src/da65/opc65sc02.c b/src/da65/opc65sc02.c index 90549d00f..82e10bd96 100644 --- a/src/da65/opc65sc02.c +++ b/src/da65/opc65sc02.c @@ -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 */ diff --git a/src/da65/scanner.h b/src/da65/scanner.h index f7f090fad..14a3ef679 100644 --- a/src/da65/scanner.h +++ b/src/da65/scanner.h @@ -105,6 +105,7 @@ typedef enum token_t { INFOTOK_COMMENT, INFOTOK_ADDR, INFOTOK_SIZE, + INFOTOK_VOPERAND, /* ASMINC section */ INFOTOK_FILE,