mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
@@ -13,6 +13,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "linkdefs.h"
|
||||
#include "platform.h" // NONNULL
|
||||
|
||||
extern uint8_t fillByte;
|
||||
|
||||
@@ -76,4 +77,6 @@ void sect_BinaryFileSlice(char const *s, int32_t start_pos, int32_t length);
|
||||
void sect_PushSection(void);
|
||||
void sect_PopSection(void);
|
||||
|
||||
bool sect_IsSizeKnown(struct Section const NONNULL(name));
|
||||
|
||||
#endif
|
||||
|
||||
@@ -49,8 +49,10 @@
|
||||
/* MSVC doesn't support `[static N]` for array arguments from C99 */
|
||||
#ifdef _MSC_VER
|
||||
# define MIN_NB_ELMS(N)
|
||||
# define NONNULL(ptr) *ptr
|
||||
#else
|
||||
# define MIN_NB_ELMS(N) static (N)
|
||||
# define NONNULL(ptr) ptr[static 1]
|
||||
#endif
|
||||
|
||||
// MSVC uses a different name for O_RDWR, and needs an additional _O_BINARY flag
|
||||
|
||||
@@ -205,28 +205,40 @@ void rpn_SizeOfSection(struct Expression *expr, char const *sectionName)
|
||||
{
|
||||
rpn_Init(expr);
|
||||
|
||||
makeUnknown(expr, "Section \"%s\"'s size is not known", sectionName);
|
||||
struct Section *section = sect_FindSectionByName(sectionName);
|
||||
|
||||
size_t nameLen = strlen(sectionName) + 1; /* Room for NUL! */
|
||||
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
|
||||
if (section && sect_IsSizeKnown(section)) {
|
||||
expr->val = section->size;
|
||||
} else {
|
||||
makeUnknown(expr, "Section \"%s\"'s size is not known", sectionName);
|
||||
|
||||
expr->rpnPatchSize += nameLen + 1;
|
||||
*ptr++ = RPN_SIZEOF_SECT;
|
||||
memcpy(ptr, sectionName, nameLen);
|
||||
size_t nameLen = strlen(sectionName) + 1; /* Room for NUL! */
|
||||
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
|
||||
|
||||
expr->rpnPatchSize += nameLen + 1;
|
||||
*ptr++ = RPN_SIZEOF_SECT;
|
||||
memcpy(ptr, sectionName, nameLen);
|
||||
}
|
||||
}
|
||||
|
||||
void rpn_StartOfSection(struct Expression *expr, char const *sectionName)
|
||||
{
|
||||
rpn_Init(expr);
|
||||
|
||||
makeUnknown(expr, "Section \"%s\"'s start is not known", sectionName);
|
||||
struct Section *section = sect_FindSectionByName(sectionName);
|
||||
|
||||
size_t nameLen = strlen(sectionName) + 1; /* Room for NUL! */
|
||||
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
|
||||
if (section && section->org != (uint32_t)-1) {
|
||||
expr->val = section->org;
|
||||
} else {
|
||||
makeUnknown(expr, "Section \"%s\"'s start is not known", sectionName);
|
||||
|
||||
expr->rpnPatchSize += nameLen + 1;
|
||||
*ptr++ = RPN_STARTOF_SECT;
|
||||
memcpy(ptr, sectionName, nameLen);
|
||||
size_t nameLen = strlen(sectionName) + 1; /* Room for NUL! */
|
||||
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
|
||||
|
||||
expr->rpnPatchSize += nameLen + 1;
|
||||
*ptr++ = RPN_STARTOF_SECT;
|
||||
memcpy(ptr, sectionName, nameLen);
|
||||
}
|
||||
}
|
||||
|
||||
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src)
|
||||
|
||||
@@ -1016,3 +1016,22 @@ void sect_PopSection(void)
|
||||
sectionStack = entry->next;
|
||||
free(entry);
|
||||
}
|
||||
|
||||
bool sect_IsSizeKnown(struct Section const NONNULL(sect))
|
||||
{
|
||||
// SECTION UNION and SECTION FRAGMENT can still grow
|
||||
if (sect->modifier != SECTION_NORMAL)
|
||||
return false;
|
||||
|
||||
// The current section (or current load section if within one) is still growing
|
||||
if (sect == currentSection || sect == currentLoadSection)
|
||||
return false;
|
||||
|
||||
// Any section on the stack is still growing
|
||||
for (struct SectionStackEntry *stack = sectionStack; stack; stack = stack->next) {
|
||||
if (stack->section && !strcmp(sect->name, stack->section->name))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,33 @@
|
||||
SECTION "sect", ROMX[$4567], BANK[$23]
|
||||
ds 42
|
||||
|
||||
W = BANK("sect")
|
||||
X = SIZEOF("sect") ; unknown
|
||||
Y = STARTOF("sect")
|
||||
|
||||
println "sect1: {W} {X} {Y}"
|
||||
|
||||
SECTION "sect2", ROMX
|
||||
|
||||
W = BANK("sect")
|
||||
X = SIZEOF("sect")
|
||||
Y = STARTOF("sect")
|
||||
|
||||
println "{W} {X} {Y}"
|
||||
println "sect1: {W} {X} {Y}"
|
||||
|
||||
PUSHS
|
||||
SECTION FRAGMENT "sect3", ROMX[$4567], BANK[$12]
|
||||
|
||||
W = BANK("sect2") ; unknown
|
||||
X = SIZEOF("sect2") ; unknown
|
||||
Y = STARTOF("sect2") ; unknown
|
||||
|
||||
println "sect2: {W} {X} {Y}"
|
||||
|
||||
POPS
|
||||
|
||||
W = BANK("sect3")
|
||||
X = SIZEOF("sect3") ; unknown
|
||||
Y = STARTOF("sect3")
|
||||
|
||||
println "sect3: {W} {X} {Y}"
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
ERROR: section-sizeof-startof.asm(5):
|
||||
Expected constant expression: Section "sect"'s size is not known
|
||||
ERROR: section-sizeof-startof.asm(6):
|
||||
Expected constant expression: Section "sect"'s start is not known
|
||||
error: Assembly aborted (2 errors)!
|
||||
ERROR: section-sizeof-startof.asm(21):
|
||||
Expected constant expression: Section "sect2"'s bank is not known
|
||||
ERROR: section-sizeof-startof.asm(22):
|
||||
Expected constant expression: Section "sect2"'s size is not known
|
||||
ERROR: section-sizeof-startof.asm(23):
|
||||
Expected constant expression: Section "sect2"'s start is not known
|
||||
ERROR: section-sizeof-startof.asm(30):
|
||||
Expected constant expression: Section "sect3"'s size is not known
|
||||
error: Assembly aborted (5 errors)!
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
$23 $0 $0
|
||||
sect1: $23 $0 $4567
|
||||
sect1: $23 $2A $4567
|
||||
sect2: $0 $0 $0
|
||||
sect3: $12 $0 $4567
|
||||
|
||||
Reference in New Issue
Block a user