From 54ed050ecf9a164ecb9cf368bbdedd524f23560a Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Sun, 8 Sep 2019 22:28:28 +0200 Subject: [PATCH 1/6] Make `BANK(@)` known at assembling time when possible If the current section's bank is fixed, this means this value is known prior to linking. --- src/asm/rpn.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/asm/rpn.c b/src/asm/rpn.c index dff5613c..fc6e228f 100644 --- a/src/asm/rpn.c +++ b/src/asm/rpn.c @@ -19,6 +19,7 @@ #include "asm/main.h" #include "asm/rpn.h" #include "asm/symbol.h" +#include "asm/output.h" #include "asm/warning.h" #include "linkdefs.h" @@ -160,11 +161,14 @@ void rpn_BankSelf(struct Expression *expr) { rpn_Init(expr); - /* - * This symbol is not really relocatable, but this makes the assembler - * write this expression as a RPN patch to the object file. - */ - expr->isReloc = 1; + if (pCurrentSection->nBank == -1) + /* + * This is not really relocatable, but this makes the assembler + * write this expression as a RPN patch to the object file. + */ + expr->isReloc = 1; + else + expr->nVal = pCurrentSection->nBank; pushbyte(expr, RPN_BANK_SELF); expr->nRPNPatchSize++; From 74f43d4e094d6ed6048d784a9275f0a7a26a7097 Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Sun, 8 Sep 2019 23:40:16 +0200 Subject: [PATCH 2/6] Add a way to seek a SECTION by name without creating one --- include/asm/output.h | 1 + src/asm/output.c | 52 ++++++++++++++++++++++++++------------------ 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/include/asm/output.h b/include/asm/output.h index be396b16..46fffb3b 100644 --- a/include/asm/output.h +++ b/include/asm/output.h @@ -29,6 +29,7 @@ extern char *tzObjectname; void out_PrepPass2(void); void out_SetFileName(char *s); +struct Section *out_FindSectionByName(const char *pzName); void out_NewSection(char *pzName, uint32_t secttype); void out_NewAbsSection(char *pzName, uint32_t secttype, int32_t org, int32_t bank); diff --git a/src/asm/output.c b/src/asm/output.c index 21aa0ead..c319a153 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -599,48 +599,52 @@ void out_SetFileName(char *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 */ struct Section *out_FindSection(char *pzName, uint32_t secttype, int32_t org, int32_t bank, int32_t alignment) { - struct Section *pSect, **ppSect; + struct Section *pSect = out_FindSectionByName(pzName); - ppSect = &pSectionList; - pSect = pSectionList; - - while (pSect) { - if (strcmp(pzName, pSect->pzName) == 0) { - if (secttype == pSect->nType - && ((uint32_t)org) == pSect->nOrg - && ((uint32_t)bank) == pSect->nBank - && ((uint32_t)alignment == pSect->nAlign)) { - return pSect; - } - - fatalerror("Section already exists but with a different type"); + if (pSect) { + if (secttype == pSect->nType + && ((uint32_t)org) == pSect->nOrg + && ((uint32_t)bank) == pSect->nBank + && ((uint32_t)alignment == pSect->nAlign)) { + return pSect; } - ppSect = &(pSect->pNext); - pSect = pSect->pNext; + fatalerror("Section already exists but with a different type"); } pSect = malloc(sizeof(struct Section)); - *ppSect = pSect; if (pSect == NULL) fatalerror("Not enough memory for section"); - pSect->pzName = malloc(strlen(pzName) + 1); + pSect->pzName = strdup(pzName); if (pSect->pzName == NULL) fatalerror("Not enough memory for sectionname"); - strcpy(pSect->pzName, pzName); pSect->nType = secttype; pSect->nPC = 0; pSect->nOrg = org; pSect->nBank = bank; pSect->nAlign = alignment; - pSect->pNext = NULL; + pSect->pNext = pSectionList; pSect->pPatches = NULL; /* 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; } - return (pSect); + /* + * Add the new section to the list + * at the beginning because order doesn't matter + */ + pSectionList = pSect; + + return pSect; } /* From 02fe73d1f38b702b7a94a8b4934eb9e829eb4278 Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Thu, 19 Sep 2019 15:06:48 +0200 Subject: [PATCH 3/6] Make `BANK("Section")` known at assembling time when possible If the target section is in the current file and its bank is known, this means this value is known prior to linking. --- src/asm/rpn.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/asm/rpn.c b/src/asm/rpn.c index fc6e228f..0d45829a 100644 --- a/src/asm/rpn.c +++ b/src/asm/rpn.c @@ -182,17 +182,25 @@ void rpn_BankSymbol(struct Expression *expr, char *tzSym) return; } - if (!sym_isConstant(tzSym)) { + if (sym_isConstant(tzSym)) { + yyerror("BANK argument must be a relocatable identifier"); + } else { rpn_Init(expr); sym_Ref(tzSym); - expr->isReloc = 1; pushbyte(expr, RPN_BANK_SYM); - while (*tzSym) - pushbyte(expr, *tzSym++); + for (unsigned int i = 0; tzSym[i]; i++) + pushbyte(expr, tzSym[i]); pushbyte(expr, 0); 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; } } @@ -200,11 +208,16 @@ void rpn_BankSection(struct Expression *expr, char *tzSectionName) { rpn_Init(expr); - /* - * This symbol is not really relocatable, but this makes the assembler - * write this expression as a RPN patch to the object file. - */ - expr->isReloc = 1; + struct Section *pSection = out_FindSectionByName(tzSectionName); + + if (pSection && pSection->nBank != -1) + expr->nVal = pSection->nBank; + else + /* + * This is not really relocatable, but this makes the assembler + * write this expression as a RPN patch to the object file. + */ + expr->isReloc = 1; pushbyte(expr, RPN_BANK_SECT); expr->nRPNPatchSize++; From e4f4706508307f1a1f7b0efb545a82cad53ade2f Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Fri, 27 Sep 2019 09:34:29 +0200 Subject: [PATCH 4/6] Add tests for new "known self-bank" --- test/asm/pc-bank.asm | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 test/asm/pc-bank.asm diff --git a/test/asm/pc-bank.asm b/test/asm/pc-bank.asm new file mode 100644 index 00000000..118e5da5 --- /dev/null +++ b/test/asm/pc-bank.asm @@ -0,0 +1,7 @@ +SECTION "Fixed bank", ROMX,BANK[42] +X = BANK(@) + +SECTION "Something else", OAM +Y = BANK("Fixed bank") + + PRINTT "@: {X}\nStr: {Y}\n" From b49e025703e43088e7376231474bb546a0ba1093 Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Sat, 7 Dec 2019 23:43:02 +0100 Subject: [PATCH 5/6] Allow BANK() in constexpr expressions --- include/asm/constexpr.h | 2 ++ src/asm/asmy.y | 8 ++++++++ src/asm/constexpr.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/include/asm/constexpr.h b/include/asm/constexpr.h index c1dd21b2..79bad465 100644 --- a/include/asm/constexpr.h +++ b/include/asm/constexpr.h @@ -20,6 +20,8 @@ struct ConstExpression { }; 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_UnaryOp(struct ConstExpression *expr, int32_t op, diff --git a/src/asm/asmy.y b/src/asm/asmy.y index ba6dbe9c..22d27da6 100644 --- a/src/asm/asmy.y +++ b/src/asm/asmy.y @@ -1394,6 +1394,14 @@ const : T_ID { constexpr_Symbol(&$$, $1); } | T_NUMBER { constexpr_Number(&$$, $1); } | T_OP_HIGH '(' 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 { char *s = $1; diff --git a/src/asm/constexpr.c b/src/asm/constexpr.c index cec13b9d..ace38524 100644 --- a/src/asm/constexpr.c +++ b/src/asm/constexpr.c @@ -15,6 +15,7 @@ #include "asm/lexer.h" #include "asm/main.h" #include "asm/mymath.h" +#include "asm/output.h" #include "asm/rpn.h" #include "asm/symbol.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) { expr->u.nVal = i; From d23401316e460336400d7c7bc0e302ca924bfa02 Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Sat, 7 Dec 2019 23:43:55 +0100 Subject: [PATCH 6/6] Improve pc-bank test --- test/asm/pc-bank.asm | 6 +++++- test/asm/pc-bank.out | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 test/asm/pc-bank.out diff --git a/test/asm/pc-bank.asm b/test/asm/pc-bank.asm index 118e5da5..aec0fce6 100644 --- a/test/asm/pc-bank.asm +++ b/test/asm/pc-bank.asm @@ -1,7 +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", OAM +SECTION "Something else", ROMX Y = BANK("Fixed bank") PRINTT "@: {X}\nStr: {Y}\n" + +ERR = BANK(@) diff --git a/test/asm/pc-bank.out b/test/asm/pc-bank.out new file mode 100644 index 00000000..de66200b --- /dev/null +++ b/test/asm/pc-bank.out @@ -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