Merge pull request #430 from ISSOtm/known_selfbank

Make `BANK(@)` and `BANK("section")` known to RGBASM
This commit is contained in:
Eldred Habert
2020-01-08 18:56:28 +01:00
committed by GitHub
8 changed files with 131 additions and 37 deletions

View File

@@ -20,6 +20,8 @@ struct ConstExpression {
}; };
void constexpr_Symbol(struct ConstExpression *expr, char *tzSym); void constexpr_Symbol(struct ConstExpression *expr, char *tzSym);
void constexpr_BanksSymbol(struct ConstExpression *expr, char *tzSym);
void constexpr_BankSection(struct ConstExpression *expr, char *tzSym);
void constexpr_Number(struct ConstExpression *expr, int32_t i); void constexpr_Number(struct ConstExpression *expr, int32_t i);
void constexpr_UnaryOp(struct ConstExpression *expr, void constexpr_UnaryOp(struct ConstExpression *expr,
int32_t op, int32_t op,

View File

@@ -29,6 +29,7 @@ extern char *tzObjectname;
void out_PrepPass2(void); void out_PrepPass2(void);
void out_SetFileName(char *s); void out_SetFileName(char *s);
struct Section *out_FindSectionByName(const char *pzName);
void out_NewSection(char *pzName, uint32_t secttype); void out_NewSection(char *pzName, uint32_t secttype);
void out_NewAbsSection(char *pzName, uint32_t secttype, int32_t org, void out_NewAbsSection(char *pzName, uint32_t secttype, int32_t org,
int32_t bank); int32_t bank);

View File

@@ -1394,6 +1394,14 @@ const : T_ID { constexpr_Symbol(&$$, $1); }
| T_NUMBER { constexpr_Number(&$$, $1); } | T_NUMBER { constexpr_Number(&$$, $1); }
| T_OP_HIGH '(' const ')' { constexpr_UnaryOp(&$$, $1, &$3); } | T_OP_HIGH '(' const ')' { constexpr_UnaryOp(&$$, $1, &$3); }
| T_OP_LOW '(' const ')' { constexpr_UnaryOp(&$$, $1, &$3); } | T_OP_LOW '(' const ')' { constexpr_UnaryOp(&$$, $1, &$3); }
| T_OP_BANK '(' T_ID ')'
{
constexpr_BankSymbol(&$$, $3);
}
| T_OP_BANK '(' string ')'
{
constexpr_BankSection(&$$, $3);
}
| string | string
{ {
char *s = $1; char *s = $1;

View File

@@ -15,6 +15,7 @@
#include "asm/lexer.h" #include "asm/lexer.h"
#include "asm/main.h" #include "asm/main.h"
#include "asm/mymath.h" #include "asm/mymath.h"
#include "asm/output.h"
#include "asm/rpn.h" #include "asm/rpn.h"
#include "asm/symbol.h" #include "asm/symbol.h"
#include "asm/warning.h" #include "asm/warning.h"
@@ -37,6 +38,42 @@ void constexpr_Symbol(struct ConstExpression *expr, char *tzSym)
} }
} }
void constexpr_BankSymbol(struct ConstExpression *expr, char *tzSym)
{
if (sym_FindSymbol(tzSym) == pPCSymbol) {
if (pCurrentSection->nBank == -1)
yyerror("%s's bank is not known yet", tzSym);
else
constexpr_Number(expr, pCurrentSection->nBank);
return;
}
if (sym_isConstant(tzSym)) {
yyerror("BANK argument must be a relocatable identifier");
} else {
struct sSymbol *pSymbol = sym_FindSymbol(tzSym);
if (!pSymbol)
yyerror("BANK argument doesn't exist");
else if (!pSymbol->pSection || pSymbol->pSection->nBank == -1)
yyerror("BANK argument must be a relocatable identifier");
else
constexpr_Number(expr, pSymbol->pSection->nBank);
}
}
void constexpr_BankSection(struct ConstExpression *expr, char *tzSectionName)
{
struct Section *pSection = out_FindSectionByName(tzSectionName);
if (!pSection)
yyerror("Section \"%s\" doesn't exist");
else if (pSection->nBank == -1)
yyerror("Section \"%s\"'s bank is not known yet");
else
constexpr_Number(expr, pSection->nBank);
}
void constexpr_Number(struct ConstExpression *expr, int32_t i) void constexpr_Number(struct ConstExpression *expr, int32_t i)
{ {
expr->u.nVal = i; expr->u.nVal = i;

View File

@@ -599,48 +599,52 @@ void out_SetFileName(char *s)
printf("Output filename %s\n", s); printf("Output filename %s\n", s);
} }
struct Section *out_FindSectionByName(const char *pzName)
{
struct Section *pSect = pSectionList;
while (pSect) {
if (strcmp(pzName, pSect->pzName) == 0)
return pSect;
pSect = pSect->pNext;
}
return NULL;
}
/* /*
* 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
*/ */
struct Section *out_FindSection(char *pzName, uint32_t secttype, int32_t org, struct Section *out_FindSection(char *pzName, uint32_t secttype, int32_t org,
int32_t bank, int32_t alignment) int32_t bank, int32_t alignment)
{ {
struct Section *pSect, **ppSect; struct Section *pSect = out_FindSectionByName(pzName);
ppSect = &pSectionList; if (pSect) {
pSect = pSectionList;
while (pSect) {
if (strcmp(pzName, pSect->pzName) == 0) {
if (secttype == pSect->nType if (secttype == pSect->nType
&& ((uint32_t)org) == pSect->nOrg && ((uint32_t)org) == pSect->nOrg
&& ((uint32_t)bank) == pSect->nBank && ((uint32_t)bank) == pSect->nBank
&& ((uint32_t)alignment == pSect->nAlign)) { && ((uint32_t)alignment == pSect->nAlign)) {
return pSect; return pSect;
} }
fatalerror("Section already exists but with a different type"); fatalerror("Section already exists but with a different type");
} }
ppSect = &(pSect->pNext);
pSect = pSect->pNext;
}
pSect = malloc(sizeof(struct Section)); pSect = malloc(sizeof(struct Section));
*ppSect = pSect;
if (pSect == NULL) if (pSect == NULL)
fatalerror("Not enough memory for section"); fatalerror("Not enough memory for section");
pSect->pzName = malloc(strlen(pzName) + 1); pSect->pzName = strdup(pzName);
if (pSect->pzName == NULL) if (pSect->pzName == NULL)
fatalerror("Not enough memory for sectionname"); fatalerror("Not enough memory for sectionname");
strcpy(pSect->pzName, pzName);
pSect->nType = secttype; pSect->nType = secttype;
pSect->nPC = 0; pSect->nPC = 0;
pSect->nOrg = org; pSect->nOrg = org;
pSect->nBank = bank; pSect->nBank = bank;
pSect->nAlign = alignment; pSect->nAlign = alignment;
pSect->pNext = NULL; pSect->pNext = pSectionList;
pSect->pPatches = NULL; pSect->pPatches = NULL;
/* It is only needed to allocate memory for ROM sections. */ /* It is only needed to allocate memory for ROM sections. */
@@ -655,7 +659,13 @@ struct Section *out_FindSection(char *pzName, uint32_t secttype, int32_t org,
pSect->tData = NULL; pSect->tData = NULL;
} }
return (pSect); /*
* Add the new section to the list
* at the beginning because order doesn't matter
*/
pSectionList = pSect;
return pSect;
} }
/* /*

View File

@@ -19,6 +19,7 @@
#include "asm/main.h" #include "asm/main.h"
#include "asm/rpn.h" #include "asm/rpn.h"
#include "asm/symbol.h" #include "asm/symbol.h"
#include "asm/output.h"
#include "asm/warning.h" #include "asm/warning.h"
#include "linkdefs.h" #include "linkdefs.h"
@@ -160,11 +161,14 @@ void rpn_BankSelf(struct Expression *expr)
{ {
rpn_Init(expr); rpn_Init(expr);
if (pCurrentSection->nBank == -1)
/* /*
* This symbol is not really relocatable, but this makes the assembler * This is not really relocatable, but this makes the assembler
* write this expression as a RPN patch to the object file. * write this expression as a RPN patch to the object file.
*/ */
expr->isReloc = 1; expr->isReloc = 1;
else
expr->nVal = pCurrentSection->nBank;
pushbyte(expr, RPN_BANK_SELF); pushbyte(expr, RPN_BANK_SELF);
expr->nRPNPatchSize++; expr->nRPNPatchSize++;
@@ -178,17 +182,25 @@ void rpn_BankSymbol(struct Expression *expr, char *tzSym)
return; return;
} }
if (!sym_isConstant(tzSym)) { if (sym_isConstant(tzSym)) {
yyerror("BANK argument must be a relocatable identifier");
} else {
rpn_Init(expr); rpn_Init(expr);
sym_Ref(tzSym); sym_Ref(tzSym);
expr->isReloc = 1;
pushbyte(expr, RPN_BANK_SYM); pushbyte(expr, RPN_BANK_SYM);
while (*tzSym) for (unsigned int i = 0; tzSym[i]; i++)
pushbyte(expr, *tzSym++); pushbyte(expr, tzSym[i]);
pushbyte(expr, 0); pushbyte(expr, 0);
expr->nRPNPatchSize += 5; expr->nRPNPatchSize += 5;
} else {
yyerror("BANK argument must be a relocatable identifier"); /* If the symbol didn't exist, `sym_Ref` created it */
struct sSymbol *pSymbol = sym_FindSymbol(tzSym);
if (pSymbol->pSection && pSymbol->pSection->nBank != -1)
/* Symbol's section is known and bank's fixed */
expr->nVal = pSymbol->pSection->nBank;
else
expr->isReloc = 1;
} }
} }
@@ -196,8 +208,13 @@ void rpn_BankSection(struct Expression *expr, char *tzSectionName)
{ {
rpn_Init(expr); rpn_Init(expr);
struct Section *pSection = out_FindSectionByName(tzSectionName);
if (pSection && pSection->nBank != -1)
expr->nVal = pSection->nBank;
else
/* /*
* This symbol is not really relocatable, but this makes the assembler * This is not really relocatable, but this makes the assembler
* write this expression as a RPN patch to the object file. * write this expression as a RPN patch to the object file.
*/ */
expr->isReloc = 1; expr->isReloc = 1;

11
test/asm/pc-bank.asm Normal file
View File

@@ -0,0 +1,11 @@
SECTION "Fixed bank", ROMX,BANK[42]
ldh a, [BANK(@) * 256] ; This should be complained about at assembly time
X = BANK(@)
SECTION "Something else", ROMX
Y = BANK("Fixed bank")
PRINTT "@: {X}\nStr: {Y}\n"
ERR = BANK(@)

8
test/asm/pc-bank.out Normal file
View File

@@ -0,0 +1,8 @@
ERROR: pc-bank.asm(2):
Source address $2a00 not in $FF00 to $FFFF
ERROR: pc-bank.asm(11):
@'s bank is not known yet
ERROR: pc-bank.asm(11):
Non-constant expression
@: $2A
Str: $2A