mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
@@ -17,7 +17,7 @@ enum FormatState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class FormatSpec {
|
class FormatSpec {
|
||||||
enum FormatState state;
|
FormatState state;
|
||||||
int sign;
|
int sign;
|
||||||
bool prefix;
|
bool prefix;
|
||||||
bool alignLeft;
|
bool alignLeft;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#include "asm/lexer.hpp"
|
#include "asm/lexer.hpp"
|
||||||
|
|
||||||
struct FileStackNode {
|
struct FileStackNode {
|
||||||
enum FileStackNodeType type;
|
FileStackNodeType type;
|
||||||
std::variant<
|
std::variant<
|
||||||
std::vector<uint32_t>, // NODE_REPT
|
std::vector<uint32_t>, // NODE_REPT
|
||||||
std::string // NODE_FILE, NODE_MACRO
|
std::string // NODE_FILE, NODE_MACRO
|
||||||
@@ -39,9 +39,7 @@ struct FileStackNode {
|
|||||||
std::string &name();
|
std::string &name();
|
||||||
std::string const &name() const;
|
std::string const &name() const;
|
||||||
|
|
||||||
FileStackNode(
|
FileStackNode(FileStackNodeType type_, std::variant<std::vector<uint32_t>, std::string> data_)
|
||||||
enum FileStackNodeType type_, std::variant<std::vector<uint32_t>, std::string> data_
|
|
||||||
)
|
|
||||||
: type(type_), data(data_) {};
|
: type(type_), data(data_) {};
|
||||||
|
|
||||||
void dump(uint32_t curLineNo) const;
|
void dump(uint32_t curLineNo) const;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ struct BufferedLexerState {
|
|||||||
struct LexerState {
|
struct LexerState {
|
||||||
char const *path;
|
char const *path;
|
||||||
|
|
||||||
enum LexerMode mode;
|
LexerMode mode;
|
||||||
bool atLineStart;
|
bool atLineStart;
|
||||||
uint32_t lineNo;
|
uint32_t lineNo;
|
||||||
uint32_t colNo;
|
uint32_t colNo;
|
||||||
@@ -122,7 +122,7 @@ void lexer_OpenFileView(
|
|||||||
void lexer_RestartRept(uint32_t lineNo);
|
void lexer_RestartRept(uint32_t lineNo);
|
||||||
void lexer_CleanupState(LexerState &state);
|
void lexer_CleanupState(LexerState &state);
|
||||||
void lexer_Init();
|
void lexer_Init();
|
||||||
void lexer_SetMode(enum LexerMode mode);
|
void lexer_SetMode(LexerMode mode);
|
||||||
void lexer_ToggleStringExpansion(bool enable);
|
void lexer_ToggleStringExpansion(bool enable);
|
||||||
|
|
||||||
uint32_t lexer_GetIFDepth();
|
uint32_t lexer_GetIFDepth();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ void out_ReplaceNode(FileStackNode *node);
|
|||||||
void out_SetFileName(char *s);
|
void out_SetFileName(char *s);
|
||||||
void out_CreatePatch(uint32_t type, Expression const &expr, uint32_t ofs, uint32_t pcShift);
|
void out_CreatePatch(uint32_t type, Expression const &expr, uint32_t ofs, uint32_t pcShift);
|
||||||
void out_CreateAssert(
|
void out_CreateAssert(
|
||||||
enum AssertionType type, Expression const &expr, char const *message, uint32_t ofs
|
AssertionType type, Expression const &expr, char const *message, uint32_t ofs
|
||||||
);
|
);
|
||||||
void out_WriteObject();
|
void out_WriteObject();
|
||||||
|
|
||||||
|
|||||||
@@ -27,9 +27,7 @@ struct Expression {
|
|||||||
void rpn_Number(Expression &expr, uint32_t val);
|
void rpn_Number(Expression &expr, uint32_t val);
|
||||||
void rpn_Symbol(Expression &expr, char const *symName);
|
void rpn_Symbol(Expression &expr, char const *symName);
|
||||||
void rpn_LOGNOT(Expression &expr, const Expression &src);
|
void rpn_LOGNOT(Expression &expr, const Expression &src);
|
||||||
void rpn_BinaryOp(
|
void rpn_BinaryOp(RPNCommand op, Expression &expr, const Expression &src1, const Expression &src2);
|
||||||
enum RPNCommand op, Expression &expr, const Expression &src1, const Expression &src2
|
|
||||||
);
|
|
||||||
void rpn_HIGH(Expression &expr, const Expression &src);
|
void rpn_HIGH(Expression &expr, const Expression &src);
|
||||||
void rpn_LOW(Expression &expr, const Expression &src);
|
void rpn_LOW(Expression &expr, const Expression &src);
|
||||||
void rpn_ISCONST(Expression &expr, const Expression &src);
|
void rpn_ISCONST(Expression &expr, const Expression &src);
|
||||||
@@ -40,8 +38,8 @@ void rpn_BankSection(Expression &expr, char const *sectionName);
|
|||||||
void rpn_BankSelf(Expression &expr);
|
void rpn_BankSelf(Expression &expr);
|
||||||
void rpn_SizeOfSection(Expression &expr, char const *sectionName);
|
void rpn_SizeOfSection(Expression &expr, char const *sectionName);
|
||||||
void rpn_StartOfSection(Expression &expr, char const *sectionName);
|
void rpn_StartOfSection(Expression &expr, char const *sectionName);
|
||||||
void rpn_SizeOfSectionType(Expression &expr, enum SectionType type);
|
void rpn_SizeOfSectionType(Expression &expr, SectionType type);
|
||||||
void rpn_StartOfSectionType(Expression &expr, enum SectionType type);
|
void rpn_StartOfSectionType(Expression &expr, SectionType type);
|
||||||
|
|
||||||
void rpn_Free(Expression &expr);
|
void rpn_Free(Expression &expr);
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ struct Patch {
|
|||||||
|
|
||||||
struct Section {
|
struct Section {
|
||||||
std::string name;
|
std::string name;
|
||||||
enum SectionType type;
|
SectionType type;
|
||||||
enum SectionModifier modifier;
|
SectionModifier modifier;
|
||||||
FileStackNode const *src; // Where the section was defined
|
FileStackNode const *src; // Where the section was defined
|
||||||
uint32_t fileLine; // Line where the section was defined
|
uint32_t fileLine; // Line where the section was defined
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
@@ -53,18 +53,10 @@ extern Section *currentSection;
|
|||||||
|
|
||||||
Section *sect_FindSectionByName(char const *name);
|
Section *sect_FindSectionByName(char const *name);
|
||||||
void sect_NewSection(
|
void sect_NewSection(
|
||||||
char const *name,
|
char const *name, SectionType type, uint32_t org, SectionSpec const &attrs, SectionModifier mod
|
||||||
enum SectionType type,
|
|
||||||
uint32_t org,
|
|
||||||
SectionSpec const &attrs,
|
|
||||||
enum SectionModifier mod
|
|
||||||
);
|
);
|
||||||
void sect_SetLoadSection(
|
void sect_SetLoadSection(
|
||||||
char const *name,
|
char const *name, SectionType type, uint32_t org, SectionSpec const &attrs, SectionModifier mod
|
||||||
enum SectionType type,
|
|
||||||
uint32_t org,
|
|
||||||
SectionSpec const &attrs,
|
|
||||||
enum SectionModifier mod
|
|
||||||
);
|
);
|
||||||
void sect_EndLoadSection();
|
void sect_EndLoadSection();
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ bool sym_IsPC(Symbol const *sym); // For the inline `getSection` method
|
|||||||
|
|
||||||
struct Symbol {
|
struct Symbol {
|
||||||
std::string name;
|
std::string name;
|
||||||
enum SymbolType type;
|
SymbolType type;
|
||||||
bool isExported; // Whether the symbol is to be exported
|
bool isExported; // Whether the symbol is to be exported
|
||||||
bool isBuiltin; // Whether the symbol is a built-in
|
bool isBuiltin; // Whether the symbol is a built-in
|
||||||
Section *section;
|
Section *section;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ enum WarningID {
|
|||||||
#define NB_META_WARNINGS (NB_WARNINGS - META_WARNINGS_START)
|
#define NB_META_WARNINGS (NB_WARNINGS - META_WARNINGS_START)
|
||||||
};
|
};
|
||||||
|
|
||||||
extern enum WarningState warningStates[NB_PLAIN_AND_PARAM_WARNINGS];
|
extern WarningState warningStates[NB_PLAIN_AND_PARAM_WARNINGS];
|
||||||
extern bool warningsAreErrors;
|
extern bool warningsAreErrors;
|
||||||
|
|
||||||
void processWarningFlag(char const *flag);
|
void processWarningFlag(char const *flag);
|
||||||
@@ -63,7 +63,7 @@ void processWarningFlag(char const *flag);
|
|||||||
* Used to warn the user about problems that don't prevent the generation of
|
* Used to warn the user about problems that don't prevent the generation of
|
||||||
* valid code.
|
* valid code.
|
||||||
*/
|
*/
|
||||||
void warning(enum WarningID id, char const *fmt, ...) format_(printf, 2, 3);
|
void warning(WarningID id, char const *fmt, ...) format_(printf, 2, 3);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used for errors that compromise the whole assembly process by affecting the
|
* Used for errors that compromise the whole assembly process by affecting the
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ extern bool disablePadding;
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
struct FileStackNode {
|
struct FileStackNode {
|
||||||
enum FileStackNodeType type;
|
FileStackNodeType type;
|
||||||
std::variant<
|
std::variant<
|
||||||
std::monostate, // Default constructed; `.type` and `.data` must be set manually
|
std::monostate, // Default constructed; `.type` and `.data` must be set manually
|
||||||
std::vector<uint32_t>, // NODE_REPT
|
std::vector<uint32_t>, // NODE_REPT
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ struct Patch {
|
|||||||
Section const *pcSection;
|
Section const *pcSection;
|
||||||
uint32_t pcSectionID;
|
uint32_t pcSectionID;
|
||||||
uint32_t pcOffset;
|
uint32_t pcOffset;
|
||||||
enum PatchType type;
|
PatchType type;
|
||||||
std::vector<uint8_t> rpnExpression;
|
std::vector<uint8_t> rpnExpression;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -34,8 +34,8 @@ struct Section {
|
|||||||
std::string name;
|
std::string name;
|
||||||
uint16_t size;
|
uint16_t size;
|
||||||
uint16_t offset;
|
uint16_t offset;
|
||||||
enum SectionType type;
|
SectionType type;
|
||||||
enum SectionModifier modifier;
|
SectionModifier modifier;
|
||||||
bool isAddressFixed;
|
bool isAddressFixed;
|
||||||
// This `struct`'s address in ROM.
|
// This `struct`'s address in ROM.
|
||||||
// Importantly for fragments, this does not include `offset`!
|
// Importantly for fragments, this does not include `offset`!
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ struct Label {
|
|||||||
struct Symbol {
|
struct Symbol {
|
||||||
// Info contained in the object files
|
// Info contained in the object files
|
||||||
std::string name;
|
std::string name;
|
||||||
enum ExportLevel type;
|
ExportLevel type;
|
||||||
char const *objFileName;
|
char const *objFileName;
|
||||||
FileStackNode const *src;
|
FileStackNode const *src;
|
||||||
int32_t lineNo;
|
int32_t lineNo;
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ extern struct SectionTypeInfo {
|
|||||||
* @param type The section's type
|
* @param type The section's type
|
||||||
* @return `true` if the section's definition includes data
|
* @return `true` if the section's definition includes data
|
||||||
*/
|
*/
|
||||||
static inline bool sect_HasData(enum SectionType type) {
|
static inline bool sect_HasData(SectionType type) {
|
||||||
assert(type != SECTTYPE_INVALID);
|
assert(type != SECTTYPE_INVALID);
|
||||||
return type == SECTTYPE_ROM0 || type == SECTTYPE_ROMX;
|
return type == SECTTYPE_ROM0 || type == SECTTYPE_ROMX;
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ static inline bool sect_HasData(enum SectionType type) {
|
|||||||
* Computes a memory region's end address (last byte), eg. 0x7FFF
|
* Computes a memory region's end address (last byte), eg. 0x7FFF
|
||||||
* @return The address of the last byte in that memory region
|
* @return The address of the last byte in that memory region
|
||||||
*/
|
*/
|
||||||
static inline uint16_t endaddr(enum SectionType type) {
|
static inline uint16_t endaddr(SectionType type) {
|
||||||
return sectionTypeInfo[type].startAddr + sectionTypeInfo[type].size - 1;
|
return sectionTypeInfo[type].startAddr + sectionTypeInfo[type].size - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ static inline uint16_t endaddr(enum SectionType type) {
|
|||||||
* Computes a memory region's number of banks
|
* Computes a memory region's number of banks
|
||||||
* @return The number of banks, 1 for regions without banking
|
* @return The number of banks, 1 for regions without banking
|
||||||
*/
|
*/
|
||||||
static inline uint32_t nbbanks(enum SectionType type) {
|
static inline uint32_t nbbanks(SectionType type) {
|
||||||
return sectionTypeInfo[type].lastBank - sectionTypeInfo[type].firstBank + 1;
|
return sectionTypeInfo[type].lastBank - sectionTypeInfo[type].firstBank + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
#include <winbase.h> // CreateFileMappingA
|
#include <winbase.h> // CreateFileMappingA
|
||||||
#include <memoryapi.h> // MapViewOfFile
|
#include <memoryapi.h> // MapViewOfFile
|
||||||
#include <handleapi.h> // CloseHandle
|
#include <handleapi.h> // CloseHandle
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
#define MAP_FAILED nullptr
|
#define MAP_FAILED nullptr
|
||||||
|
|
||||||
@@ -491,7 +491,7 @@ void lexer_CleanupState(LexerState &state) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lexer_SetMode(enum LexerMode mode) {
|
void lexer_SetMode(LexerMode mode) {
|
||||||
lexerState->mode = mode;
|
lexerState->mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1825,9 +1825,8 @@ static Token yylex_NORMAL() {
|
|||||||
// Local symbols cannot be string expansions
|
// Local symbols cannot be string expansions
|
||||||
if (token.type == T_(ID) && lexerState->expandStrings) {
|
if (token.type == T_(ID) && lexerState->expandStrings) {
|
||||||
// Attempt string expansion
|
// Attempt string expansion
|
||||||
Symbol const *sym = sym_FindExactSymbol(
|
Symbol const *sym =
|
||||||
std::get<std::string>(token.value).c_str()
|
sym_FindExactSymbol(std::get<std::string>(token.value).c_str());
|
||||||
);
|
|
||||||
|
|
||||||
if (sym && sym->type == SYM_EQUS) {
|
if (sym && sym->type == SYM_EQUS) {
|
||||||
char const *str = sym->getEqus()->c_str();
|
char const *str = sym->getEqus()->c_str();
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ struct OptStackEntry {
|
|||||||
bool warnOnLdOpt;
|
bool warnOnLdOpt;
|
||||||
bool warningsAreErrors;
|
bool warningsAreErrors;
|
||||||
size_t maxRecursionDepth;
|
size_t maxRecursionDepth;
|
||||||
enum WarningState warningStates[numWarningStates];
|
WarningState warningStates[numWarningStates];
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::stack<OptStackEntry> stack;
|
static std::stack<OptStackEntry> stack;
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ void out_CreatePatch(uint32_t type, Expression const &expr, uint32_t ofs, uint32
|
|||||||
|
|
||||||
// Creates an assert that will be written to the object file
|
// Creates an assert that will be written to the object file
|
||||||
void out_CreateAssert(
|
void out_CreateAssert(
|
||||||
enum AssertionType type, Expression const &expr, char const *message, uint32_t ofs
|
AssertionType type, Expression const &expr, char const *message, uint32_t ofs
|
||||||
) {
|
) {
|
||||||
Assertion &assertion = assertions.emplace_front();
|
Assertion &assertion = assertions.emplace_front();
|
||||||
|
|
||||||
|
|||||||
@@ -78,9 +78,9 @@
|
|||||||
char *dest, size_t destLen, char const *spec,
|
char *dest, size_t destLen, char const *spec,
|
||||||
std::vector<std::variant<uint32_t, std::string>> &args
|
std::vector<std::variant<uint32_t, std::string>> &args
|
||||||
);
|
);
|
||||||
static void compoundAssignment(const char *symName, enum RPNCommand op, int32_t constValue);
|
static void compoundAssignment(const char *symName, RPNCommand op, int32_t constValue);
|
||||||
static void failAssert(enum AssertionType type);
|
static void failAssert(AssertionType type);
|
||||||
static void failAssertMsg(enum AssertionType type, char const *msg);
|
static void failAssertMsg(AssertionType type, char const *msg);
|
||||||
void yyerror(char const *str);
|
void yyerror(char const *str);
|
||||||
|
|
||||||
// The CPU encodes instructions in a logical way, so most instructions actually follow patterns.
|
// The CPU encodes instructions in a logical way, so most instructions actually follow patterns.
|
||||||
@@ -838,7 +838,7 @@ shift:
|
|||||||
|
|
||||||
load:
|
load:
|
||||||
POP_LOAD sectmod string COMMA sectiontype sectorg sectattrs {
|
POP_LOAD sectmod string COMMA sectiontype sectorg sectattrs {
|
||||||
sect_SetLoadSection($3.string, (enum SectionType)$5, $6, $7, $2);
|
sect_SetLoadSection($3.string, (SectionType)$5, $6, $7, $2);
|
||||||
}
|
}
|
||||||
| POP_ENDL {
|
| POP_ENDL {
|
||||||
sect_EndLoadSection();
|
sect_EndLoadSection();
|
||||||
@@ -1402,10 +1402,10 @@ relocexpr_no_str:
|
|||||||
rpn_StartOfSection($$, $3.string);
|
rpn_StartOfSection($$, $3.string);
|
||||||
}
|
}
|
||||||
| OP_SIZEOF LPAREN sectiontype RPAREN {
|
| OP_SIZEOF LPAREN sectiontype RPAREN {
|
||||||
rpn_SizeOfSectionType($$, (enum SectionType)$3);
|
rpn_SizeOfSectionType($$, (SectionType)$3);
|
||||||
}
|
}
|
||||||
| OP_STARTOF LPAREN sectiontype RPAREN {
|
| OP_STARTOF LPAREN sectiontype RPAREN {
|
||||||
rpn_StartOfSectionType($$, (enum SectionType)$3);
|
rpn_StartOfSectionType($$, (SectionType)$3);
|
||||||
}
|
}
|
||||||
| OP_DEF {
|
| OP_DEF {
|
||||||
lexer_ToggleStringExpansion(false);
|
lexer_ToggleStringExpansion(false);
|
||||||
@@ -1611,7 +1611,7 @@ strfmt_va_args:
|
|||||||
|
|
||||||
section:
|
section:
|
||||||
POP_SECTION sectmod string COMMA sectiontype sectorg sectattrs {
|
POP_SECTION sectmod string COMMA sectiontype sectorg sectattrs {
|
||||||
sect_NewSection($3.string, (enum SectionType)$5, $6, $7, $2);
|
sect_NewSection($3.string, (SectionType)$5, $6, $7, $2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -2730,7 +2730,7 @@ static void strfmt(
|
|||||||
dest[i] = '\0';
|
dest[i] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compoundAssignment(const char *symName, enum RPNCommand op, int32_t constValue) {
|
static void compoundAssignment(const char *symName, RPNCommand op, int32_t constValue) {
|
||||||
Expression oldExpr, constExpr, newExpr;
|
Expression oldExpr, constExpr, newExpr;
|
||||||
int32_t newValue;
|
int32_t newValue;
|
||||||
|
|
||||||
@@ -2741,7 +2741,7 @@ static void compoundAssignment(const char *symName, enum RPNCommand op, int32_t
|
|||||||
sym_AddVar(symName, newValue);
|
sym_AddVar(symName, newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void failAssert(enum AssertionType type) {
|
static void failAssert(AssertionType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ASSERT_FATAL:
|
case ASSERT_FATAL:
|
||||||
fatalerror("Assertion failed\n");
|
fatalerror("Assertion failed\n");
|
||||||
@@ -2754,7 +2754,7 @@ static void failAssert(enum AssertionType type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void failAssertMsg(enum AssertionType type, char const *msg) {
|
static void failAssertMsg(AssertionType type, char const *msg) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ASSERT_FATAL:
|
case ASSERT_FATAL:
|
||||||
fatalerror("Assertion failed: %s\n", msg);
|
fatalerror("Assertion failed: %s\n", msg);
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ void rpn_StartOfSection(Expression &expr, char const *sectionName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpn_SizeOfSectionType(Expression &expr, enum SectionType type) {
|
void rpn_SizeOfSectionType(Expression &expr, SectionType type) {
|
||||||
initExpression(expr);
|
initExpression(expr);
|
||||||
makeUnknown(expr, "Section type's size is not known");
|
makeUnknown(expr, "Section type's size is not known");
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ void rpn_SizeOfSectionType(Expression &expr, enum SectionType type) {
|
|||||||
*ptr++ = type;
|
*ptr++ = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpn_StartOfSectionType(Expression &expr, enum SectionType type) {
|
void rpn_StartOfSectionType(Expression &expr, SectionType type) {
|
||||||
initExpression(expr);
|
initExpression(expr);
|
||||||
makeUnknown(expr, "Section type's start is not known");
|
makeUnknown(expr, "Section type's start is not known");
|
||||||
|
|
||||||
@@ -343,9 +343,7 @@ static int32_t tryConstMask(Expression const &lhs, Expression const &rhs) {
|
|||||||
return (symbolOfs + sect.alignOfs) & ~unknownBits;
|
return (symbolOfs + sect.alignOfs) & ~unknownBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpn_BinaryOp(
|
void rpn_BinaryOp(RPNCommand op, Expression &expr, const Expression &src1, const Expression &src2) {
|
||||||
enum RPNCommand op, Expression &expr, const Expression &src1, const Expression &src2
|
|
||||||
) {
|
|
||||||
initExpression(expr);
|
initExpression(expr);
|
||||||
expr.isSymbol = false;
|
expr.isSymbol = false;
|
||||||
int32_t constMaskVal;
|
int32_t constMaskVal;
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ Section *sect_FindSectionByName(char const *name) {
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static unsigned int mergeSectUnion(
|
static unsigned int mergeSectUnion(
|
||||||
Section §, enum SectionType type, uint32_t org, uint8_t alignment, uint16_t alignOffset
|
Section §, SectionType type, uint32_t org, uint8_t alignment, uint16_t alignOffset
|
||||||
) {
|
) {
|
||||||
assert(alignment < 16); // Should be ensured by the caller
|
assert(alignment < 16); // Should be ensured by the caller
|
||||||
unsigned int nbSectErrors = 0;
|
unsigned int nbSectErrors = 0;
|
||||||
@@ -240,12 +240,12 @@ static unsigned int
|
|||||||
|
|
||||||
static void mergeSections(
|
static void mergeSections(
|
||||||
Section §,
|
Section §,
|
||||||
enum SectionType type,
|
SectionType type,
|
||||||
uint32_t org,
|
uint32_t org,
|
||||||
uint32_t bank,
|
uint32_t bank,
|
||||||
uint8_t alignment,
|
uint8_t alignment,
|
||||||
uint16_t alignOffset,
|
uint16_t alignOffset,
|
||||||
enum SectionModifier mod
|
SectionModifier mod
|
||||||
) {
|
) {
|
||||||
unsigned int nbSectErrors = 0;
|
unsigned int nbSectErrors = 0;
|
||||||
|
|
||||||
@@ -296,12 +296,12 @@ static void mergeSections(
|
|||||||
// Create a new section, not yet in the list.
|
// Create a new section, not yet in the list.
|
||||||
static Section *createSection(
|
static Section *createSection(
|
||||||
char const *name,
|
char const *name,
|
||||||
enum SectionType type,
|
SectionType type,
|
||||||
uint32_t org,
|
uint32_t org,
|
||||||
uint32_t bank,
|
uint32_t bank,
|
||||||
uint8_t alignment,
|
uint8_t alignment,
|
||||||
uint16_t alignOffset,
|
uint16_t alignOffset,
|
||||||
enum SectionModifier mod
|
SectionModifier mod
|
||||||
) {
|
) {
|
||||||
// Add the new section to the list (order doesn't matter)
|
// Add the new section to the list (order doesn't matter)
|
||||||
Section § = sectionList.emplace_front();
|
Section § = sectionList.emplace_front();
|
||||||
@@ -326,11 +326,7 @@ static Section *createSection(
|
|||||||
|
|
||||||
// Find a section by name and type. If it doesn't exist, create it.
|
// Find a section by name and type. If it doesn't exist, create it.
|
||||||
static Section *getSection(
|
static Section *getSection(
|
||||||
char const *name,
|
char const *name, SectionType type, uint32_t org, SectionSpec const &attrs, SectionModifier mod
|
||||||
enum SectionType type,
|
|
||||||
uint32_t org,
|
|
||||||
SectionSpec const &attrs,
|
|
||||||
enum SectionModifier mod
|
|
||||||
) {
|
) {
|
||||||
uint32_t bank = attrs.bank;
|
uint32_t bank = attrs.bank;
|
||||||
uint8_t alignment = attrs.alignment;
|
uint8_t alignment = attrs.alignment;
|
||||||
@@ -445,11 +441,7 @@ bool Section::isSizeKnown() const {
|
|||||||
|
|
||||||
// Set the current section by name and type
|
// Set the current section by name and type
|
||||||
void sect_NewSection(
|
void sect_NewSection(
|
||||||
char const *name,
|
char const *name, SectionType type, uint32_t org, SectionSpec const &attrs, SectionModifier mod
|
||||||
enum SectionType type,
|
|
||||||
uint32_t org,
|
|
||||||
SectionSpec const &attrs,
|
|
||||||
enum SectionModifier mod
|
|
||||||
) {
|
) {
|
||||||
if (currentLoadSection)
|
if (currentLoadSection)
|
||||||
fatalerror("Cannot change the section within a `LOAD` block\n");
|
fatalerror("Cannot change the section within a `LOAD` block\n");
|
||||||
@@ -469,11 +461,7 @@ void sect_NewSection(
|
|||||||
|
|
||||||
// Set the current section by name and type
|
// Set the current section by name and type
|
||||||
void sect_SetLoadSection(
|
void sect_SetLoadSection(
|
||||||
char const *name,
|
char const *name, SectionType type, uint32_t org, SectionSpec const &attrs, SectionModifier mod
|
||||||
enum SectionType type,
|
|
||||||
uint32_t org,
|
|
||||||
SectionSpec const &attrs,
|
|
||||||
enum SectionModifier mod
|
|
||||||
) {
|
) {
|
||||||
// Important info: currently, UNION and LOAD cannot interact, since UNION is prohibited in
|
// Important info: currently, UNION and LOAD cannot interact, since UNION is prohibited in
|
||||||
// "code" sections, whereas LOAD is restricted to them.
|
// "code" sections, whereas LOAD is restricted to them.
|
||||||
@@ -612,7 +600,7 @@ static void writelong(uint32_t b) {
|
|||||||
writebyte(b >> 24);
|
writebyte(b >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void createPatch(enum PatchType type, Expression const &expr, uint32_t pcShift) {
|
static void createPatch(PatchType type, Expression const &expr, uint32_t pcShift) {
|
||||||
out_CreatePatch(type, expr, sect_GetOutputOffset(), pcShift);
|
out_CreatePatch(type, expr, sect_GetOutputOffset(), pcShift);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
unsigned int nbErrors = 0;
|
unsigned int nbErrors = 0;
|
||||||
unsigned int maxErrors = 0;
|
unsigned int maxErrors = 0;
|
||||||
|
|
||||||
static const enum WarningState defaultWarnings[ARRAY_SIZE(warningStates)] = {
|
static const WarningState defaultWarnings[ARRAY_SIZE(warningStates)] = {
|
||||||
WARNING_ENABLED, // WARNING_ASSERT
|
WARNING_ENABLED, // WARNING_ASSERT
|
||||||
WARNING_DISABLED, // WARNING_BACKWARDS_FOR
|
WARNING_DISABLED, // WARNING_BACKWARDS_FOR
|
||||||
WARNING_DISABLED, // WARNING_BUILTIN_ARG
|
WARNING_DISABLED, // WARNING_BUILTIN_ARG
|
||||||
@@ -45,17 +45,17 @@ static const enum WarningState defaultWarnings[ARRAY_SIZE(warningStates)] = {
|
|||||||
WARNING_DISABLED, // WARNING_UNMAPPED_CHAR_2
|
WARNING_DISABLED, // WARNING_UNMAPPED_CHAR_2
|
||||||
};
|
};
|
||||||
|
|
||||||
enum WarningState warningStates[ARRAY_SIZE(warningStates)];
|
WarningState warningStates[ARRAY_SIZE(warningStates)];
|
||||||
|
|
||||||
bool warningsAreErrors; // Set if `-Werror` was specified
|
bool warningsAreErrors; // Set if `-Werror` was specified
|
||||||
|
|
||||||
static enum WarningState warningState(enum WarningID id) {
|
static WarningState warningState(WarningID id) {
|
||||||
// Check if warnings are globally disabled
|
// Check if warnings are globally disabled
|
||||||
if (!warnings)
|
if (!warnings)
|
||||||
return WARNING_DISABLED;
|
return WARNING_DISABLED;
|
||||||
|
|
||||||
// Get the actual state
|
// Get the actual state
|
||||||
enum WarningState state = warningStates[id];
|
WarningState state = warningStates[id];
|
||||||
|
|
||||||
if (state == WARNING_DEFAULT)
|
if (state == WARNING_DEFAULT)
|
||||||
// The state isn't set, grab its default state
|
// The state isn't set, grab its default state
|
||||||
@@ -109,8 +109,8 @@ static const struct {
|
|||||||
{"unmapped-char", 2, 1},
|
{"unmapped-char", 2, 1},
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool tryProcessParamWarning(char const *flag, uint8_t param, enum WarningState state) {
|
static bool tryProcessParamWarning(char const *flag, uint8_t param, WarningState state) {
|
||||||
enum WarningID baseID = PARAM_WARNINGS_START;
|
WarningID baseID = PARAM_WARNINGS_START;
|
||||||
|
|
||||||
for (size_t i = 0; i < ARRAY_SIZE(paramWarnings); i++) {
|
for (size_t i = 0; i < ARRAY_SIZE(paramWarnings); i++) {
|
||||||
uint8_t maxParam = paramWarnings[i].nbLevels;
|
uint8_t maxParam = paramWarnings[i].nbLevels;
|
||||||
@@ -142,7 +142,7 @@ static bool tryProcessParamWarning(char const *flag, uint8_t param, enum Warning
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
baseID = (enum WarningID)(baseID + maxParam);
|
baseID = (WarningID)(baseID + maxParam);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -214,7 +214,7 @@ void processWarningFlag(char const *flag) {
|
|||||||
static bool setError = false;
|
static bool setError = false;
|
||||||
|
|
||||||
// First, try to match against a "meta" warning
|
// First, try to match against a "meta" warning
|
||||||
for (enum WarningID id : EnumSeq(META_WARNINGS_START, NB_WARNINGS)) {
|
for (WarningID id : EnumSeq(META_WARNINGS_START, NB_WARNINGS)) {
|
||||||
// TODO: improve the matching performance?
|
// TODO: improve the matching performance?
|
||||||
if (!strcmp(flag, warningFlags[id])) {
|
if (!strcmp(flag, warningFlags[id])) {
|
||||||
// We got a match!
|
// We got a match!
|
||||||
@@ -256,10 +256,10 @@ void processWarningFlag(char const *flag) {
|
|||||||
|
|
||||||
// Well, it's either a normal warning or a mistake
|
// Well, it's either a normal warning or a mistake
|
||||||
|
|
||||||
enum WarningState state = setError ? WARNING_ERROR
|
WarningState state = setError ? WARNING_ERROR
|
||||||
// Not an error, then check if this is a negation
|
// Not an error, then check if this is a negation
|
||||||
: strncmp(flag, "no-", strlen("no-")) ? WARNING_ENABLED
|
: strncmp(flag, "no-", strlen("no-")) ? WARNING_ENABLED
|
||||||
: WARNING_DISABLED;
|
: WARNING_DISABLED;
|
||||||
char const *rootFlag = state == WARNING_DISABLED ? flag + strlen("no-") : flag;
|
char const *rootFlag = state == WARNING_DISABLED ? flag + strlen("no-") : flag;
|
||||||
|
|
||||||
// Is this a "parametric" warning?
|
// Is this a "parametric" warning?
|
||||||
@@ -312,7 +312,7 @@ void processWarningFlag(char const *flag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to match the flag against a "normal" flag
|
// Try to match the flag against a "normal" flag
|
||||||
for (enum WarningID id : EnumSeq(NB_PLAIN_WARNINGS)) {
|
for (WarningID id : EnumSeq(NB_PLAIN_WARNINGS)) {
|
||||||
if (!strcmp(rootFlag, warningFlags[id])) {
|
if (!strcmp(rootFlag, warningFlags[id])) {
|
||||||
// We got a match!
|
// We got a match!
|
||||||
warningStates[id] = state;
|
warningStates[id] = state;
|
||||||
@@ -368,7 +368,7 @@ void error(char const *fmt, ...) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void warning(enum WarningID id, char const *fmt, ...) {
|
void warning(WarningID id, char const *fmt, ...) {
|
||||||
char const *flag = warningFlags[id];
|
char const *flag = warningFlags[id];
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ static bool readMBCSlice(char const *&name, char const *expected) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum MbcType parseMBC(char const *name) {
|
static MbcType parseMBC(char const *name) {
|
||||||
if (!strcasecmp(name, "help")) {
|
if (!strcasecmp(name, "help")) {
|
||||||
fputs("Accepted MBC names:\n", stderr);
|
fputs("Accepted MBC names:\n", stderr);
|
||||||
printAcceptedMBCNames();
|
printAcceptedMBCNames();
|
||||||
@@ -226,7 +226,7 @@ static enum MbcType parseMBC(char const *name) {
|
|||||||
return MBC_BAD;
|
return MBC_BAD;
|
||||||
if (mbc > 0xFF)
|
if (mbc > 0xFF)
|
||||||
return MBC_BAD_RANGE;
|
return MBC_BAD_RANGE;
|
||||||
return (enum MbcType)mbc;
|
return (MbcType)mbc;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Begin by reading the MBC type:
|
// Begin by reading the MBC type:
|
||||||
@@ -567,11 +567,11 @@ static enum MbcType parseMBC(char const *name) {
|
|||||||
if (*ptr)
|
if (*ptr)
|
||||||
return MBC_BAD;
|
return MBC_BAD;
|
||||||
|
|
||||||
return (enum MbcType)mbc;
|
return (MbcType)mbc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char const *mbcName(enum MbcType type) {
|
static char const *mbcName(MbcType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ROM:
|
case ROM:
|
||||||
return "ROM";
|
return "ROM";
|
||||||
@@ -669,7 +669,7 @@ static char const *mbcName(enum MbcType type) {
|
|||||||
unreachable_();
|
unreachable_();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasRAM(enum MbcType type) {
|
static bool hasRAM(MbcType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ROM:
|
case ROM:
|
||||||
case MBC1:
|
case MBC1:
|
||||||
@@ -760,7 +760,7 @@ static bool japanese = true;
|
|||||||
static const char *newLicensee = nullptr;
|
static const char *newLicensee = nullptr;
|
||||||
static uint8_t newLicenseeLen;
|
static uint8_t newLicenseeLen;
|
||||||
static uint16_t oldLicensee = UNSPECIFIED;
|
static uint16_t oldLicensee = UNSPECIFIED;
|
||||||
static enum MbcType cartridgeType = MBC_NONE;
|
static MbcType cartridgeType = MBC_NONE;
|
||||||
static uint16_t romVersion = UNSPECIFIED;
|
static uint16_t romVersion = UNSPECIFIED;
|
||||||
static bool overwriteRom = false; // If false, warn when overwriting non-zero non-identical bytes
|
static bool overwriteRom = false; // If false, warn when overwriting non-zero non-identical bytes
|
||||||
static uint16_t padValue = UNSPECIFIED;
|
static uint16_t padValue = UNSPECIFIED;
|
||||||
@@ -1232,9 +1232,7 @@ static void parseByte(uint16_t &output, char name) {
|
|||||||
}
|
}
|
||||||
if (*endptr) {
|
if (*endptr) {
|
||||||
report(
|
report(
|
||||||
"error: Expected number as argument to option '%c', got %s\n",
|
"error: Expected number as argument to option '%c', got %s\n", name, musl_optarg
|
||||||
name,
|
|
||||||
musl_optarg
|
|
||||||
);
|
);
|
||||||
} else if (value > 0xFF) {
|
} else if (value > 0xFF) {
|
||||||
report("error: Argument to option '%c' is larger than 255: %lu\n", name, value);
|
report("error: Argument to option '%c' is larger than 255: %lu\n", name, value);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ uint64_t nbSectionsToAssign;
|
|||||||
|
|
||||||
// Init the free space-modelling structs
|
// Init the free space-modelling structs
|
||||||
static void initFreeSpace() {
|
static void initFreeSpace() {
|
||||||
for (enum SectionType type : EnumSeq(SECTTYPE_INVALID)) {
|
for (SectionType type : EnumSeq(SECTTYPE_INVALID)) {
|
||||||
memory[type].resize(nbbanks(type));
|
memory[type].resize(nbbanks(type));
|
||||||
for (std::deque<FreeSpace> &bankMem : memory[type]) {
|
for (std::deque<FreeSpace> &bankMem : memory[type]) {
|
||||||
bankMem.push_back({
|
bankMem.push_back({
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ static void parseScrambleSpec(char const *spec) {
|
|||||||
size_t regionNameLen = strcspn(spec, "=, \t");
|
size_t regionNameLen = strcspn(spec, "=, \t");
|
||||||
// Length of region name string slice for printing, truncated if too long
|
// Length of region name string slice for printing, truncated if too long
|
||||||
int regionNamePrintLen = regionNameLen > INT_MAX ? INT_MAX : (int)regionNameLen;
|
int regionNamePrintLen = regionNameLen > INT_MAX ? INT_MAX : (int)regionNameLen;
|
||||||
enum ScrambledRegion region = SCRAMBLE_UNK;
|
ScrambledRegion region = SCRAMBLE_UNK;
|
||||||
|
|
||||||
// If this trips, `spec` must be pointing at a ',' or '=' (or NUL) due to the assert
|
// If this trips, `spec` must be pointing at a ',' or '=' (or NUL) due to the assert
|
||||||
if (regionNameLen == 0) {
|
if (regionNameLen == 0) {
|
||||||
@@ -262,7 +262,7 @@ static void parseScrambleSpec(char const *spec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now, determine which region type this is
|
// Now, determine which region type this is
|
||||||
for (enum ScrambledRegion r : EnumSeq(SCRAMBLE_UNK)) {
|
for (ScrambledRegion r : EnumSeq(SCRAMBLE_UNK)) {
|
||||||
// If the strings match (case-insensitively), we got it!
|
// If the strings match (case-insensitively), we got it!
|
||||||
// `strncasecmp` must be used here since `regionName` points
|
// `strncasecmp` must be used here since `regionName` points
|
||||||
// to the entire remaining argument.
|
// to the entire remaining argument.
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ static void readFileStackNode(
|
|||||||
node.lineNo, file, "%s: Cannot read node #%" PRIu32 "'s line number: %s", fileName, i
|
node.lineNo, file, "%s: Cannot read node #%" PRIu32 "'s line number: %s", fileName, i
|
||||||
);
|
);
|
||||||
tryGetc(
|
tryGetc(
|
||||||
enum FileStackNodeType,
|
FileStackNodeType,
|
||||||
node.type,
|
node.type,
|
||||||
file,
|
file,
|
||||||
"%s: Cannot read node #%" PRIu32 "'s type: %s",
|
"%s: Cannot read node #%" PRIu32 "'s type: %s",
|
||||||
@@ -186,7 +186,7 @@ static void readSymbol(
|
|||||||
) {
|
) {
|
||||||
tryReadstring(symbol.name, file, "%s: Cannot read symbol name: %s", fileName);
|
tryReadstring(symbol.name, file, "%s: Cannot read symbol name: %s", fileName);
|
||||||
tryGetc(
|
tryGetc(
|
||||||
enum ExportLevel,
|
ExportLevel,
|
||||||
symbol.type,
|
symbol.type,
|
||||||
file,
|
file,
|
||||||
"%s: Cannot read \"%s\"'s type: %s",
|
"%s: Cannot read \"%s\"'s type: %s",
|
||||||
@@ -250,7 +250,7 @@ static void readPatch(
|
|||||||
std::vector<FileStackNode> const &fileNodes
|
std::vector<FileStackNode> const &fileNodes
|
||||||
) {
|
) {
|
||||||
uint32_t nodeID, rpnSize;
|
uint32_t nodeID, rpnSize;
|
||||||
enum PatchType type;
|
PatchType type;
|
||||||
|
|
||||||
tryReadlong(
|
tryReadlong(
|
||||||
nodeID,
|
nodeID,
|
||||||
@@ -294,7 +294,7 @@ static void readPatch(
|
|||||||
i
|
i
|
||||||
);
|
);
|
||||||
tryGetc(
|
tryGetc(
|
||||||
enum PatchType,
|
PatchType,
|
||||||
type,
|
type,
|
||||||
file,
|
file,
|
||||||
"%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s type: %s",
|
"%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s type: %s",
|
||||||
@@ -354,7 +354,7 @@ static void readSection(
|
|||||||
tryGetc(
|
tryGetc(
|
||||||
uint8_t, byte, file, "%s: Cannot read \"%s\"'s type: %s", fileName, section.name.c_str()
|
uint8_t, byte, file, "%s: Cannot read \"%s\"'s type: %s", fileName, section.name.c_str()
|
||||||
);
|
);
|
||||||
section.type = (enum SectionType)(byte & 0x3F);
|
section.type = (SectionType)(byte & 0x3F);
|
||||||
if (byte >> 7)
|
if (byte >> 7)
|
||||||
section.modifier = SECTION_UNION;
|
section.modifier = SECTION_UNION;
|
||||||
else if (byte >> 6)
|
else if (byte >> 6)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ struct SortedSections {
|
|||||||
static std::deque<SortedSections> sections[SECTTYPE_INVALID];
|
static std::deque<SortedSections> sections[SECTTYPE_INVALID];
|
||||||
|
|
||||||
// Defines the order in which types are output to the sym and map files
|
// Defines the order in which types are output to the sym and map files
|
||||||
static enum SectionType typeMap[SECTTYPE_INVALID] = {
|
static SectionType typeMap[SECTTYPE_INVALID] = {
|
||||||
SECTTYPE_ROM0,
|
SECTTYPE_ROM0,
|
||||||
SECTTYPE_ROMX,
|
SECTTYPE_ROMX,
|
||||||
SECTTYPE_VRAM,
|
SECTTYPE_VRAM,
|
||||||
@@ -315,7 +315,7 @@ static int compareSymbols(SortedSymbol const &sym1, SortedSymbol const &sym2) {
|
|||||||
* Write a bank's contents to the sym file
|
* Write a bank's contents to the sym file
|
||||||
* @param bankSections The bank's sections
|
* @param bankSections The bank's sections
|
||||||
*/
|
*/
|
||||||
static void writeSymBank(SortedSections const &bankSections, enum SectionType type, uint32_t bank) {
|
static void writeSymBank(SortedSections const &bankSections, SectionType type, uint32_t bank) {
|
||||||
#define forEachSortedSection(sect, ...) \
|
#define forEachSortedSection(sect, ...) \
|
||||||
do { \
|
do { \
|
||||||
for (auto it = bankSections.zeroLenSections.begin(); \
|
for (auto it = bankSections.zeroLenSections.begin(); \
|
||||||
@@ -383,7 +383,7 @@ static void writeEmptySpace(uint16_t begin, uint16_t end) {
|
|||||||
/*
|
/*
|
||||||
* Write a bank's contents to the map file
|
* Write a bank's contents to the map file
|
||||||
*/
|
*/
|
||||||
static void writeMapBank(SortedSections const §List, enum SectionType type, uint32_t bank) {
|
static void writeMapBank(SortedSections const §List, SectionType type, uint32_t bank) {
|
||||||
fprintf(
|
fprintf(
|
||||||
mapFile,
|
mapFile,
|
||||||
"\n%s bank #%" PRIu32 ":\n",
|
"\n%s bank #%" PRIu32 ":\n",
|
||||||
@@ -474,7 +474,7 @@ static void writeMapSummary() {
|
|||||||
fputs("SUMMARY:\n", mapFile);
|
fputs("SUMMARY:\n", mapFile);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < SECTTYPE_INVALID; i++) {
|
for (uint8_t i = 0; i < SECTTYPE_INVALID; i++) {
|
||||||
enum SectionType type = typeMap[i];
|
SectionType type = typeMap[i];
|
||||||
uint32_t nbBanks = sections[type].size();
|
uint32_t nbBanks = sections[type].size();
|
||||||
|
|
||||||
// Do not output used space for VRAM or OAM
|
// Do not output used space for VRAM or OAM
|
||||||
@@ -539,7 +539,7 @@ static void writeSym() {
|
|||||||
fputs("; File generated by rgblink\n", symFile);
|
fputs("; File generated by rgblink\n", symFile);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < SECTTYPE_INVALID; i++) {
|
for (uint8_t i = 0; i < SECTTYPE_INVALID; i++) {
|
||||||
enum SectionType type = typeMap[i];
|
SectionType type = typeMap[i];
|
||||||
|
|
||||||
for (uint32_t bank = 0; bank < sections[type].size(); bank++)
|
for (uint32_t bank = 0; bank < sections[type].size(); bank++)
|
||||||
writeSymBank(sections[type][bank], type, bank);
|
writeSymBank(sections[type][bank], type, bank);
|
||||||
@@ -565,7 +565,7 @@ static void writeMap() {
|
|||||||
writeMapSummary();
|
writeMapSummary();
|
||||||
|
|
||||||
for (uint8_t i = 0; i < SECTTYPE_INVALID; i++) {
|
for (uint8_t i = 0; i < SECTTYPE_INVALID; i++) {
|
||||||
enum SectionType type = typeMap[i];
|
SectionType type = typeMap[i];
|
||||||
|
|
||||||
for (uint32_t bank = 0; bank < sections[type].size(); bank++)
|
for (uint32_t bank = 0; bank < sections[type].size(); bank++)
|
||||||
writeMapBank(sections[type][bank], type, bank);
|
writeMapBank(sections[type][bank], type, bank);
|
||||||
|
|||||||
@@ -75,15 +75,13 @@ static Symbol const *getSymbol(std::vector<Symbol> const &symbolList, uint32_t i
|
|||||||
* errors caused by the value should be suppressed.
|
* errors caused by the value should be suppressed.
|
||||||
*/
|
*/
|
||||||
static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fileSymbols) {
|
static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fileSymbols) {
|
||||||
|
|
||||||
uint8_t const *expression = patch.rpnExpression.data();
|
uint8_t const *expression = patch.rpnExpression.data();
|
||||||
int32_t size = (int32_t)patch.rpnExpression.size();
|
int32_t size = (int32_t)patch.rpnExpression.size();
|
||||||
|
|
||||||
rpnStack.clear();
|
rpnStack.clear();
|
||||||
|
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
enum RPNCommand command =
|
RPNCommand command = (RPNCommand)getRPNByte(expression, size, patch);
|
||||||
(enum RPNCommand)getRPNByte(expression, size, patch);
|
|
||||||
int32_t value;
|
int32_t value;
|
||||||
|
|
||||||
isError = false;
|
isError = false;
|
||||||
@@ -418,7 +416,7 @@ void patch_CheckAssertions(std::deque<Assertion> &assertions) {
|
|||||||
|
|
||||||
for (Assertion &assert : assertions) {
|
for (Assertion &assert : assertions) {
|
||||||
int32_t value = computeRPNExpr(assert.patch, *assert.fileSymbols);
|
int32_t value = computeRPNExpr(assert.patch, *assert.fileSymbols);
|
||||||
enum AssertionType type = (enum AssertionType)assert.patch.type;
|
AssertionType type = (AssertionType)assert.patch.type;
|
||||||
|
|
||||||
if (!isError && !value) {
|
if (!isError && !value) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t readNumber(char const *str, char const *&endptr, enum NumberType base) {
|
static uint32_t readNumber(char const *str, char const *&endptr, NumberType base) {
|
||||||
uint32_t res = 0;
|
uint32_t res = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -93,9 +93,8 @@ static uint32_t readNumber(char const *str, char const *&endptr, enum NumberType
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t parseNumber(
|
static uint32_t
|
||||||
FileStackNode const &where, uint32_t lineNo, char const *str, enum NumberType base
|
parseNumber(FileStackNode const &where, uint32_t lineNo, char const *str, NumberType base) {
|
||||||
) {
|
|
||||||
if (str[0] == '\0')
|
if (str[0] == '\0')
|
||||||
fatal(&where, lineNo, "Expected number, got empty string");
|
fatal(&where, lineNo, "Expected number, got empty string");
|
||||||
|
|
||||||
@@ -108,7 +107,7 @@ static uint32_t parseNumber(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
parseByte(FileStackNode const &where, uint32_t lineNo, char const *str, enum NumberType base) {
|
parseByte(FileStackNode const &where, uint32_t lineNo, char const *str, NumberType base) {
|
||||||
uint32_t num = parseNumber(where, lineNo, str, base);
|
uint32_t num = parseNumber(where, lineNo, str, base);
|
||||||
|
|
||||||
if (num > UINT8_MAX)
|
if (num > UINT8_MAX)
|
||||||
@@ -173,7 +172,7 @@ void sdobj_ReadFile(FileStackNode const &where, FILE *file, std::vector<Symbol>
|
|||||||
|
|
||||||
uint32_t lineNo = 0;
|
uint32_t lineNo = 0;
|
||||||
int lineType = nextLine(line, lineNo, where, file);
|
int lineType = nextLine(line, lineNo, where, file);
|
||||||
enum NumberType numberType;
|
NumberType numberType;
|
||||||
|
|
||||||
// The first letter (thus, the line type) identifies the integer type
|
// The first letter (thus, the line type) identifies the integer type
|
||||||
switch (lineType) {
|
switch (lineType) {
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ static void checkFragmentCompat(Section &target, Section &other) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mergeSections(Section &target, Section &other, enum SectionModifier mod) {
|
static void mergeSections(Section &target, Section &other, SectionModifier mod) {
|
||||||
// Common checks
|
// Common checks
|
||||||
|
|
||||||
if (target.type != other.type)
|
if (target.type != other.type)
|
||||||
|
|||||||
Reference in New Issue
Block a user