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>VOPERAND</tt></tag>
+ 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:
+
+<tscreen><verb>
+ JSR LabelWith2BytesOfVoperand
+ .byte $00, $10 ; virtual operands
+ ; return here
+ BIT $0F
+</verb></tscreen>
+
</descrip>
+static unsigned short SubroutineVOperandSize[0x10000];
+
/*****************************************************************************/
/* Helper functions */
/*****************************************************************************/
}
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;
+}
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 */
#include "opctable.h"
#include "scanner.h"
#include "segment.h"
+#include "handler.h"
{ "ADDR", INFOTOK_ADDR },
{ "NAME", INFOTOK_NAME },
{ "SIZE", INFOTOK_SIZE },
+ { "VOPERAND", INFOTOK_VOPERAND },
};
/* Locals - initialize to avoid gcc warnings */
char* Comment = 0;
long Value = -1;
long Size = -1;
+ long VOperand = -1;
/* Skip the token */
InfoNextTok ();
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);
}
} else {
AddExtLabelRange ((unsigned) Value, Name, Size);
}
+ if (VOperand >= 0) {
+ SetSubroutineVOperand ((unsigned) Value, (unsigned) VOperand);
+ }
/* Define the comment */
if (Comment) {
{ "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 */
{ "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 */
{ "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 */
{ "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 */
INFOTOK_COMMENT,
INFOTOK_ADDR,
INFOTOK_SIZE,
+ INFOTOK_VOPERAND,
/* ASMINC section */
INFOTOK_FILE,