mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Implement SIZEOF and STARTOF for section types (#1205)
This commit is contained in:
@@ -57,6 +57,8 @@ void rpn_BankSection(struct Expression *expr, char const *sectionName);
|
|||||||
void rpn_BankSelf(struct Expression *expr);
|
void rpn_BankSelf(struct Expression *expr);
|
||||||
void rpn_SizeOfSection(struct Expression *expr, char const *sectionName);
|
void rpn_SizeOfSection(struct Expression *expr, char const *sectionName);
|
||||||
void rpn_StartOfSection(struct Expression *expr, char const *sectionName);
|
void rpn_StartOfSection(struct Expression *expr, char const *sectionName);
|
||||||
|
void rpn_SizeOfSectionType(struct Expression *expr, enum SectionType type);
|
||||||
|
void rpn_StartOfSectionType(struct Expression *expr, enum SectionType type);
|
||||||
void rpn_Free(struct Expression *expr);
|
void rpn_Free(struct Expression *expr);
|
||||||
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src);
|
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src);
|
||||||
void rpn_CheckRST(struct Expression *expr, const struct Expression *src);
|
void rpn_CheckRST(struct Expression *expr, const struct Expression *src);
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ enum RPNCommand {
|
|||||||
RPN_BANK_SELF = 0x52,
|
RPN_BANK_SELF = 0x52,
|
||||||
RPN_SIZEOF_SECT = 0x53,
|
RPN_SIZEOF_SECT = 0x53,
|
||||||
RPN_STARTOF_SECT = 0x54,
|
RPN_STARTOF_SECT = 0x54,
|
||||||
|
RPN_SIZEOF_SECTTYPE = 0x55,
|
||||||
|
RPN_STARTOF_SECTTYPE = 0x56,
|
||||||
|
|
||||||
RPN_HRAM = 0x60,
|
RPN_HRAM = 0x60,
|
||||||
RPN_RST = 0x61,
|
RPN_RST = 0x61,
|
||||||
|
|||||||
14
man/rgbasm.5
14
man/rgbasm.5
@@ -487,11 +487,21 @@ is able to compute it.
|
|||||||
is in.
|
is in.
|
||||||
.Ar symbol
|
.Ar symbol
|
||||||
must have been defined already.
|
must have been defined already.
|
||||||
.It Fn SIZEOF arg Ta Returns the size of the section named
|
.It Fn SIZEOF arg Ta If
|
||||||
|
.Ar arg
|
||||||
|
is a string, this function returns the size of the section named
|
||||||
.Ar arg .
|
.Ar arg .
|
||||||
|
If
|
||||||
|
.Ar arg
|
||||||
|
is a section type keyword, it returns the size of that section type.
|
||||||
The result is not constant, since only RGBLINK can compute its value.
|
The result is not constant, since only RGBLINK can compute its value.
|
||||||
.It Fn STARTOF arg Ta Returns the starting address of the section named
|
.It Fn STARTOF arg Ta If
|
||||||
|
.Ar arg
|
||||||
|
is a string, this function returns the starting address of the section named
|
||||||
.Ar arg .
|
.Ar arg .
|
||||||
|
If
|
||||||
|
.Ar arg
|
||||||
|
is a section type keyword, it returns the starting address of that section type.
|
||||||
The result is not constant, since only RGBLINK can compute its value.
|
The result is not constant, since only RGBLINK can compute its value.
|
||||||
.It Fn DEF symbol Ta Returns TRUE (1) if
|
.It Fn DEF symbol Ta Returns TRUE (1) if
|
||||||
.Ar symbol
|
.Ar symbol
|
||||||
|
|||||||
24
man/rgbds.5
24
man/rgbds.5
@@ -349,23 +349,33 @@ after it.
|
|||||||
.It Li $40 Ta Left shift operator Pq Ql <<
|
.It Li $40 Ta Left shift operator Pq Ql <<
|
||||||
.It Li $41 Ta Arithmetic/signed right shift operator Pq Ql >>
|
.It Li $41 Ta Arithmetic/signed right shift operator Pq Ql >>
|
||||||
.It Li $42 Ta Logical/unsigned right shift operator Pq Ql >>>
|
.It Li $42 Ta Logical/unsigned right shift operator Pq Ql >>>
|
||||||
.It Li $50 Ta Fn BANK symbol ,
|
.It Li $50 Ta Fn BANK symbol ;
|
||||||
followed by the
|
followed by the
|
||||||
.Ar symbol Ap s Cm LONG
|
.Ar symbol Ap s Cm LONG
|
||||||
ID.
|
ID.
|
||||||
.It Li $51 Ta Fn BANK section ,
|
.It Li $51 Ta Fn BANK section ;
|
||||||
followed by the
|
followed by the
|
||||||
.Ar section Ap s Cm STRING
|
.Ar section Ap s Cm STRING
|
||||||
name.
|
name.
|
||||||
.It Li $52 Ta PC's Fn BANK Pq i.e. Ql BANK(@) .
|
.It Li $52 Ta PC's Fn BANK Pq i.e. Ql BANK(@) .
|
||||||
.It Li $53 Ta Fn SIZEOF section ,
|
.It Li $53 Ta Fn SIZEOF section ;
|
||||||
followed by the
|
followed by the
|
||||||
.Ar section Ap s Cm STRING
|
.Ar section Ap s Cm STRING
|
||||||
name.
|
name.
|
||||||
.It Li $54 Ta Fn STARTOF section ,
|
.It Li $54 Ta Fn STARTOF section ;
|
||||||
followed by the
|
followed by the
|
||||||
.Ar section Ap s Cm STRING
|
.Ar section Ap s Cm STRING
|
||||||
name.
|
name.
|
||||||
|
.It Li $55 Ta Fn SIZEOF sectiontype ;
|
||||||
|
followed by the
|
||||||
|
.Ar sectiontype Ap s Cm BYTE
|
||||||
|
value
|
||||||
|
.Pq see the Ar Type No values in Sx Sections .
|
||||||
|
.It Li $56 Ta Fn STARTOF sectiontype ;
|
||||||
|
followed by the
|
||||||
|
.Ar sectiontype Ap s Cm BYTE
|
||||||
|
value
|
||||||
|
.Pq see the Ar Type No values in Sx Sections .
|
||||||
.It Li $60 Ta Ql ldh
|
.It Li $60 Ta Ql ldh
|
||||||
check.
|
check.
|
||||||
Checks if the value is a valid
|
Checks if the value is a valid
|
||||||
@@ -383,12 +393,10 @@ Checks if the value is a valid
|
|||||||
vector, that is one of $00, $08, $10, $18, $20, $28, $30, or $38.
|
vector, that is one of $00, $08, $10, $18, $20, $28, $30, or $38.
|
||||||
The value is then ORed with $C7
|
The value is then ORed with $C7
|
||||||
.Pq Ql \&| $C7 .
|
.Pq Ql \&| $C7 .
|
||||||
.It Li $80 Ta Integer literal.
|
.It Li $80 Ta Integer literal; followed by the
|
||||||
Followed by the
|
|
||||||
.Cm LONG
|
.Cm LONG
|
||||||
integer.
|
integer.
|
||||||
.It Li $81 Ta A symbol's value.
|
.It Li $81 Ta A symbol's value; followed by the symbol's
|
||||||
Followed by the symbol's
|
|
||||||
.Cm LONG
|
.Cm LONG
|
||||||
ID.
|
ID.
|
||||||
.El
|
.El
|
||||||
|
|||||||
@@ -1538,6 +1538,8 @@ relocexpr_no_str : scoped_anon_id { rpn_Symbol(&$$, $1); }
|
|||||||
| T_OP_BANK T_LPAREN string T_RPAREN { rpn_BankSection(&$$, $3); }
|
| T_OP_BANK T_LPAREN string T_RPAREN { rpn_BankSection(&$$, $3); }
|
||||||
| T_OP_SIZEOF T_LPAREN string T_RPAREN { rpn_SizeOfSection(&$$, $3); }
|
| T_OP_SIZEOF T_LPAREN string T_RPAREN { rpn_SizeOfSection(&$$, $3); }
|
||||||
| T_OP_STARTOF T_LPAREN string T_RPAREN { rpn_StartOfSection(&$$, $3); }
|
| T_OP_STARTOF T_LPAREN string T_RPAREN { rpn_StartOfSection(&$$, $3); }
|
||||||
|
| T_OP_SIZEOF T_LPAREN sectiontype T_RPAREN { rpn_SizeOfSectionType(&$$, $3); }
|
||||||
|
| T_OP_STARTOF T_LPAREN sectiontype T_RPAREN { rpn_StartOfSectionType(&$$, $3); }
|
||||||
| T_OP_DEF {
|
| T_OP_DEF {
|
||||||
lexer_ToggleStringExpansion(false);
|
lexer_ToggleStringExpansion(false);
|
||||||
} T_LPAREN scoped_anon_id T_RPAREN {
|
} T_LPAREN scoped_anon_id T_RPAREN {
|
||||||
|
|||||||
@@ -233,6 +233,30 @@ void rpn_StartOfSection(struct Expression *expr, char const *sectionName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rpn_SizeOfSectionType(struct Expression *expr, enum SectionType type)
|
||||||
|
{
|
||||||
|
rpn_Init(expr);
|
||||||
|
makeUnknown(expr, "Section type's size is not known");
|
||||||
|
|
||||||
|
uint8_t *ptr = reserveSpace(expr, 2);
|
||||||
|
|
||||||
|
expr->rpnPatchSize += 2;
|
||||||
|
*ptr++ = RPN_SIZEOF_SECTTYPE;
|
||||||
|
*ptr++ = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rpn_StartOfSectionType(struct Expression *expr, enum SectionType type)
|
||||||
|
{
|
||||||
|
rpn_Init(expr);
|
||||||
|
makeUnknown(expr, "Section type's start is not known");
|
||||||
|
|
||||||
|
uint8_t *ptr = reserveSpace(expr, 2);
|
||||||
|
|
||||||
|
expr->rpnPatchSize += 2;
|
||||||
|
*ptr++ = RPN_STARTOF_SECTTYPE;
|
||||||
|
*ptr++ = type;
|
||||||
|
}
|
||||||
|
|
||||||
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src)
|
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src)
|
||||||
{
|
{
|
||||||
*expr = *src;
|
*expr = *src;
|
||||||
@@ -508,6 +532,8 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
|||||||
case RPN_BANK_SELF:
|
case RPN_BANK_SELF:
|
||||||
case RPN_SIZEOF_SECT:
|
case RPN_SIZEOF_SECT:
|
||||||
case RPN_STARTOF_SECT:
|
case RPN_STARTOF_SECT:
|
||||||
|
case RPN_SIZEOF_SECTTYPE:
|
||||||
|
case RPN_STARTOF_SECTTYPE:
|
||||||
case RPN_HRAM:
|
case RPN_HRAM:
|
||||||
case RPN_RST:
|
case RPN_RST:
|
||||||
case RPN_CONST:
|
case RPN_CONST:
|
||||||
|
|||||||
@@ -360,6 +360,30 @@ static int32_t computeRPNExpr(struct Patch const *patch,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RPN_SIZEOF_SECTTYPE:
|
||||||
|
value = getRPNByte(&expression, &size, patch->src, patch->lineNo);
|
||||||
|
if (value < 0 || value >= SECTTYPE_INVALID) {
|
||||||
|
error(patch->src, patch->lineNo,
|
||||||
|
"Requested SIZEOF() an invalid section type");
|
||||||
|
isError = true;
|
||||||
|
value = 0;
|
||||||
|
} else {
|
||||||
|
value = sectionTypeInfo[value].size;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPN_STARTOF_SECTTYPE:
|
||||||
|
value = getRPNByte(&expression, &size, patch->src, patch->lineNo);
|
||||||
|
if (value < 0 || value >= SECTTYPE_INVALID) {
|
||||||
|
error(patch->src, patch->lineNo,
|
||||||
|
"Requested STARTOF() an invalid section type");
|
||||||
|
isError = true;
|
||||||
|
value = 0;
|
||||||
|
} else {
|
||||||
|
value = sectionTypeInfo[value].startAddr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case RPN_HRAM:
|
case RPN_HRAM:
|
||||||
value = popRPN();
|
value = popRPN();
|
||||||
if (!isError && (value < 0
|
if (!isError && (value < 0
|
||||||
|
|||||||
@@ -3,5 +3,14 @@ SECTION "meta", ROM0[0]
|
|||||||
dw STARTOF("sect")
|
dw STARTOF("sect")
|
||||||
dw SIZEOF("sect")
|
dw SIZEOF("sect")
|
||||||
|
|
||||||
|
MACRO typemeta
|
||||||
|
rept _NARG
|
||||||
|
dw STARTOF(\1), SIZEOF(\1)
|
||||||
|
shift
|
||||||
|
endr
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
typemeta ROM0, ROMX, VRAM, SRAM, WRAM0, WRAMX, OAM, HRAM
|
||||||
|
|
||||||
SECTION "sect", ROMX[$4567], BANK[$23]
|
SECTION "sect", ROMX[$4567], BANK[$23]
|
||||||
ds 42
|
ds 42
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user