diff --git a/include/asm/rpn.h b/include/asm/rpn.h index 4ca3cdd9..8711ef31 100644 --- a/include/asm/rpn.h +++ b/include/asm/rpn.h @@ -57,6 +57,8 @@ void rpn_BankSection(struct Expression *expr, char const *sectionName); void rpn_BankSelf(struct Expression *expr); void rpn_SizeOfSection(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_CheckHRAM(struct Expression *expr, const struct Expression *src); void rpn_CheckRST(struct Expression *expr, const struct Expression *src); diff --git a/include/linkdefs.h b/include/linkdefs.h index 3926c990..c08fe254 100644 --- a/include/linkdefs.h +++ b/include/linkdefs.h @@ -56,6 +56,8 @@ enum RPNCommand { RPN_BANK_SELF = 0x52, RPN_SIZEOF_SECT = 0x53, RPN_STARTOF_SECT = 0x54, + RPN_SIZEOF_SECTTYPE = 0x55, + RPN_STARTOF_SECTTYPE = 0x56, RPN_HRAM = 0x60, RPN_RST = 0x61, diff --git a/man/rgbasm.5 b/man/rgbasm.5 index ba02e1a0..3afc942b 100644 --- a/man/rgbasm.5 +++ b/man/rgbasm.5 @@ -487,11 +487,21 @@ is able to compute it. is in. .Ar symbol 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 . +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. -.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 . +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. .It Fn DEF symbol Ta Returns TRUE (1) if .Ar symbol diff --git a/man/rgbds.5 b/man/rgbds.5 index 6126ee4e..466a8fb4 100644 --- a/man/rgbds.5 +++ b/man/rgbds.5 @@ -349,23 +349,33 @@ after it. .It Li $40 Ta Left 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 $50 Ta Fn BANK symbol , +.It Li $50 Ta Fn BANK symbol ; followed by the .Ar symbol Ap s Cm LONG ID. -.It Li $51 Ta Fn BANK section , +.It Li $51 Ta Fn BANK section ; followed by the .Ar section Ap s Cm STRING name. .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 .Ar section Ap s Cm STRING name. -.It Li $54 Ta Fn STARTOF section , +.It Li $54 Ta Fn STARTOF section ; followed by the .Ar section Ap s Cm STRING 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 check. 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. The value is then ORed with $C7 .Pq Ql \&| $C7 . -.It Li $80 Ta Integer literal. -Followed by the +.It Li $80 Ta Integer literal; followed by the .Cm LONG integer. -.It Li $81 Ta A symbol's value. -Followed by the symbol's +.It Li $81 Ta A symbol's value; followed by the symbol's .Cm LONG ID. .El diff --git a/src/asm/parser.y b/src/asm/parser.y index 08286a6c..b4f69fe2 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -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_SIZEOF T_LPAREN string T_RPAREN { rpn_SizeOfSection(&$$, $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 { lexer_ToggleStringExpansion(false); } T_LPAREN scoped_anon_id T_RPAREN { diff --git a/src/asm/rpn.c b/src/asm/rpn.c index b233ecbf..6424e0e6 100644 --- a/src/asm/rpn.c +++ b/src/asm/rpn.c @@ -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) { *expr = *src; @@ -508,6 +532,8 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr, case RPN_BANK_SELF: case RPN_SIZEOF_SECT: case RPN_STARTOF_SECT: + case RPN_SIZEOF_SECTTYPE: + case RPN_STARTOF_SECTTYPE: case RPN_HRAM: case RPN_RST: case RPN_CONST: diff --git a/src/link/patch.c b/src/link/patch.c index f71fc27e..9ac86bd0 100644 --- a/src/link/patch.c +++ b/src/link/patch.c @@ -360,6 +360,30 @@ static int32_t computeRPNExpr(struct Patch const *patch, } 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: value = popRPN(); if (!isError && (value < 0 diff --git a/test/link/sizeof-startof.asm b/test/link/sizeof-startof.asm index ae1a49f9..3f340a71 100644 --- a/test/link/sizeof-startof.asm +++ b/test/link/sizeof-startof.asm @@ -3,5 +3,14 @@ SECTION "meta", ROM0[0] dw STARTOF("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] ds 42 diff --git a/test/link/sizeof-startof.out.bin b/test/link/sizeof-startof.out.bin index b00e9df0..1f5d7a1b 100644 Binary files a/test/link/sizeof-startof.out.bin and b/test/link/sizeof-startof.out.bin differ