ref: 959bfe2a9dd5ee8d30f740c557502f7d9cd2efff
parent: d24cf11ad43b30e0e9b5e28d39b3baad945ba1cf
author: Antonio Niño Díaz <[email protected]>
date: Sat Jan 6 21:05:05 EST 2018
Allow to request BANK() of sections and PC The bank of a section can be requested with `BANK("Section Name")`, and the bank of the current section with `BANK(@)`. In both cases, the bank number is resolved by the linker. New commands have been added to the list of RPN commands of object files, and the rest has been moved so that new additions don't force a new change in the number of the enumerations. Increase object file version, as it is now incompatible with the old format. Update manpages to reflect the new ways of using `BANK()` and the new format of the object files. Signed-off-by: Antonio Niño Díaz <[email protected]>
--- a/include/asm/rpn.h
+++ b/include/asm/rpn.h
@@ -58,7 +58,9 @@
void rpn_UNNEG(struct Expression *expr, const struct Expression *src);
void rpn_UNNOT(struct Expression *expr, const struct Expression *src);
uint16_t rpn_PopByte(struct Expression *expr);
-void rpn_Bank(struct Expression *expr, char *tzSym);
+void rpn_BankSymbol(struct Expression *expr, char *tzSym);
+void rpn_BankSection(struct Expression *expr, char *tzSectionName);
+void rpn_BankSelf(struct Expression *expr);
void rpn_Reset(struct Expression *expr);
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src);
--- a/include/common.h
+++ b/include/common.h
@@ -1,6 +1,6 @@
#ifndef RGBDS_COMMON_H
#define RGBDS_COMMON_H
-#define RGBDS_OBJECT_VERSION_STRING "RGB5"
+#define RGBDS_OBJECT_VERSION_STRING "RGB6"
#endif /* RGBDS_COMMON_H */
--- a/include/link/assign.h
+++ b/include/link/assign.h
@@ -38,6 +38,7 @@
int32_t area_Avail(int32_t bank);
void AssignSections(void);
void CreateSymbolTable(void);
+struct sSection *GetSectionByName(const char *name);
int32_t IsSectionNameInUse(const char *name);
void SetLinkerscriptName(char *tzLinkerscriptFile);
int32_t IsSectionSameTypeBankAndFloating(const char *name,
--- a/include/linkdefs.h
+++ b/include/linkdefs.h
@@ -2,61 +2,63 @@
#define RGBDS_LINKDEFS_H
enum eRpnData {
- RPN_ADD = 0,
- RPN_SUB,
- RPN_MUL,
- RPN_DIV,
- RPN_MOD,
- RPN_UNSUB,
+ RPN_ADD = 0x00,
+ RPN_SUB = 0x01,
+ RPN_MUL = 0x02,
+ RPN_DIV = 0x03,
+ RPN_MOD = 0x04,
+ RPN_UNSUB = 0x05,
- RPN_OR,
- RPN_AND,
- RPN_XOR,
- RPN_UNNOT,
+ RPN_OR = 0x10,
+ RPN_AND = 0x11,
+ RPN_XOR = 0x12,
+ RPN_UNNOT = 0x13,
- RPN_LOGAND,
- RPN_LOGOR,
- RPN_LOGUNNOT,
+ RPN_LOGAND = 0x21,
+ RPN_LOGOR = 0x22,
+ RPN_LOGUNNOT = 0x23,
- RPN_LOGEQ,
- RPN_LOGNE,
- RPN_LOGGT,
- RPN_LOGLT,
- RPN_LOGGE,
- RPN_LOGLE,
+ RPN_LOGEQ = 0x30,
+ RPN_LOGNE = 0x31,
+ RPN_LOGGT = 0x32,
+ RPN_LOGLT = 0x33,
+ RPN_LOGGE = 0x34,
+ RPN_LOGLE = 0x35,
- RPN_SHL,
- RPN_SHR,
+ RPN_SHL = 0x40,
+ RPN_SHR = 0x41,
- RPN_BANK,
+ RPN_BANK_SYM = 0x50,
+ RPN_BANK_SECT = 0x51,
+ RPN_BANK_SELF = 0x52,
- RPN_HRAM,
+ RPN_HRAM = 0x60,
- RPN_CONST = 0x80,
- RPN_SYM = 0x81
+ RPN_CONST = 0x80,
+ RPN_SYM = 0x81
};
enum eSectionType {
- SECT_WRAM0 = 0,
- SECT_VRAM,
- SECT_ROMX,
- SECT_ROM0,
- SECT_HRAM,
- SECT_WRAMX,
- SECT_SRAM,
- SECT_OAM
+ SECT_WRAM0 = 0x00,
+ SECT_VRAM = 0x01,
+ SECT_ROMX = 0x02,
+ SECT_ROM0 = 0x03,
+ SECT_HRAM = 0x04,
+ SECT_WRAMX = 0x05,
+ SECT_SRAM = 0x06,
+ SECT_OAM = 0x07
};
enum eSymbolType {
- SYM_LOCAL = 0,
- SYM_IMPORT,
- SYM_EXPORT
+ SYM_LOCAL = 0x00,
+ SYM_IMPORT = 0x01,
+ SYM_EXPORT = 0x02
};
enum ePatchType {
- PATCH_BYTE = 0,
- PATCH_WORD_L,
- PATCH_LONG_L
+ PATCH_BYTE = 0x00,
+ PATCH_WORD_L = 0x01,
+ PATCH_LONG_L = 0x02
};
#endif /* RGBDS_LINKDEFS_H */
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -1173,7 +1173,13 @@
| T_OP_LOW '(' relocconst ')' { rpn_LOW(&$$, &$3); }
| T_OP_BANK '(' T_ID ')'
{
- rpn_Bank(&$$, $3);
+ /* '@' is also a T_ID, it is handled here. */
+ rpn_BankSymbol(&$$, $3);
+ $$.nVal = 0;
+ }
+ | T_OP_BANK '(' string ')'
+ {
+ rpn_BankSection(&$$, $3);
$$.nVal = 0;
}
| T_OP_DEF {
--- a/src/asm/output.c
+++ b/src/asm/output.c
@@ -419,7 +419,7 @@
rpnexpr[rpnptr++] = symptr >> 24;
}
break;
- case RPN_BANK:
+ case RPN_BANK_SYM:
{
struct sSymbol *sym;
@@ -432,11 +432,23 @@
break;
symptr = addsymbol(sym);
- rpnexpr[rpnptr++] = RPN_BANK;
+ rpnexpr[rpnptr++] = RPN_BANK_SYM;
rpnexpr[rpnptr++] = symptr & 0xFF;
rpnexpr[rpnptr++] = symptr >> 8;
rpnexpr[rpnptr++] = symptr >> 16;
rpnexpr[rpnptr++] = symptr >> 24;
+ break;
+ }
+ case RPN_BANK_SECT:
+ {
+ uint16_t b;
+
+ rpnexpr[rpnptr++] = RPN_BANK_SECT;
+
+ do {
+ b = rpn_PopByte(expr);
+ rpnexpr[rpnptr++] = b & 0xFF;
+ } while (b != 0);
break;
}
default:
--- a/src/asm/rgbasm.5
+++ b/src/asm/rgbasm.5
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2017 Antonio Nino Diaz <[email protected]>
+.\" Copyright (c) 2017-2018 Antonio Nino Diaz <[email protected]>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd July 22, 2017
+.Dd January 7, 2018
.Dt RGBASM 5
.Os RGBDS Manual
.Sh NAME
@@ -969,9 +969,15 @@
.Pp
.Bl -column ".Sy String" ".Sy String"
.It Sy Name Ta Ta Ta Sy Operation
-.It Li BANK(label) Ta Returns the bank number label is in.
-The linker will have to resolve this so it can't be used when the expression has
-to be constant.
+.It Li BANK(\@/str/lbl) Ta Returns a bank number.
+If the argument is the symbol
+.Ic \@,
+this function returns the bank of the current section.
+If the argument is a string, it returns the bank of the section that has that
+name.
+If the argument is a label, it returns the bank number the label is in.
+For labels, as the linker has to resolve this, it can't be used when the
+expression has to be constant.
.It Li DEF(label) Ta Returns TRUE if label has been defined.
.It Li HIGH(r16/cnst/lbl) Ta Returns the top 8 bits of the operand if it is a
label or constant, or the top 8-bit register if it is a 16-bit register.
--- a/src/asm/rpn.c
+++ b/src/asm/rpn.c
@@ -108,8 +108,27 @@
}
}
-void rpn_Bank(struct Expression *expr, char *tzSym)
+void rpn_BankSelf(struct Expression *expr)
{
+ rpn_Reset(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;
+
+ pushbyte(expr, RPN_BANK_SELF);
+}
+
+void rpn_BankSymbol(struct Expression *expr, char *tzSym)
+{
+ /* The @ symbol is treated differently. */
+ if (sym_FindSymbol(tzSym) == pPCSymbol) {
+ rpn_BankSelf(expr);
+ return;
+ }
+
if (!sym_isConstant(tzSym)) {
rpn_Reset(expr);
@@ -120,7 +139,7 @@
sym_GetValue(tzSym);
expr->isReloc = 1;
- pushbyte(expr, RPN_BANK);
+ pushbyte(expr, RPN_BANK_SYM);
while (*tzSym)
pushbyte(expr, *tzSym++);
pushbyte(expr, 0);
@@ -127,6 +146,22 @@
} else {
yyerror("BANK argument must be a relocatable identifier");
}
+}
+
+void rpn_BankSection(struct Expression *expr, char *tzSectionName)
+{
+ rpn_Reset(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;
+
+ pushbyte(expr, RPN_BANK_SECT);
+ while (*tzSectionName)
+ pushbyte(expr, *tzSectionName++);
+ pushbyte(expr, 0);
}
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src)
--- a/src/link/assign.c
+++ b/src/link/assign.c
@@ -247,6 +247,20 @@
return 0;
}
+struct sSection *GetSectionByName(const char *name)
+{
+ struct sSection *pSection = pSections;
+
+ while (pSection) {
+ if (strcmp(pSection->pzName, name) == 0)
+ return pSection;
+
+ pSection = pSection->pNext;
+ }
+
+ return NULL;
+}
+
int32_t IsSectionSameTypeBankAndFloating(const char *name,
enum eSectionType type, int32_t bank)
{
--- a/src/link/patch.c
+++ b/src/link/patch.c
@@ -27,7 +27,7 @@
return rpnstack[rpnp];
}
-int32_t getsymvalue(int32_t symid)
+static int32_t getsymvalue(int32_t symid)
{
const struct sSymbol *tSymbol = pCurrentSection->tSymbols[symid];
@@ -49,26 +49,14 @@
errx(1, "%s: Unknown symbol type", __func__);
}
-int32_t getsymbank(int32_t symid)
-{
- int32_t n;
- const struct sSymbol *tSymbol = pCurrentSection->tSymbols[symid];
- switch (tSymbol->Type) {
- case SYM_IMPORT:
- n = sym_GetBank(tSymbol->pzName);
- break;
- case SYM_EXPORT:
- case SYM_LOCAL:
- n = tSymbol->pSection->nBank;
- break;
- default:
- errx(1, "%s: Unknown symbol type", __func__);
- }
-
+static int32_t getrealbankfrominternalbank(int32_t n)
+{
if ((n == BANK_WRAM0) || (n == BANK_ROM0) || (n == BANK_OAM) ||
(n == BANK_HRAM)) {
return 0;
+ } else if ((n >= BANK_ROMX) && (n < (BANK_ROMX + BANK_COUNT_ROMX))) {
+ return n - BANK_ROMX + 1;
} else if ((n >= BANK_WRAMX) && (n < (BANK_WRAMX + BANK_COUNT_WRAMX))) {
return n - BANK_WRAMX + 1;
} else if ((n >= BANK_VRAM) && (n < (BANK_VRAM + BANK_COUNT_VRAM))) {
@@ -77,13 +65,37 @@
return n - BANK_SRAM;
}
+ errx(1, "%s: Unknown bank %d", __func__, n);
+
return n;
}
+static int32_t getsymbank(int32_t symid)
+{
+ int32_t nBank;
+ const struct sSymbol *tSymbol = pCurrentSection->tSymbols[symid];
+
+ switch (tSymbol->Type) {
+ case SYM_IMPORT:
+ nBank = sym_GetBank(tSymbol->pzName);
+ break;
+ case SYM_EXPORT:
+ case SYM_LOCAL:
+ nBank = tSymbol->pSection->nBank;
+ break;
+ default:
+ errx(1, "%s: Unknown symbol type", __func__);
+ }
+
+ return getrealbankfrominternalbank(nBank);
+}
+
int32_t calcrpn(struct sPatch *pPatch)
{
int32_t t, size;
uint8_t *rpn;
+ uint8_t rpn_cmd;
+ int32_t nBank;
rpnp = 0;
@@ -93,7 +105,9 @@
while (size > 0) {
size -= 1;
- switch (*rpn++) {
+ rpn_cmd = *rpn++;
+
+ switch (rpn_cmd) {
case RPN_ADD:
rpnpush(rpnpop() + rpnpop());
break;
@@ -194,7 +208,7 @@
pPatch->oRelocPatch |= (getsymbank(t) != -1);
size -= 4;
break;
- case RPN_BANK:
+ case RPN_BANK_SYM:
/* symbol */
t = (*rpn++);
t |= (*rpn++) << 8;
@@ -202,6 +216,34 @@
t |= (*rpn++) << 24;
rpnpush(getsymbank(t));
size -= 4;
+ break;
+ case RPN_BANK_SECT:
+ {
+ char *name = (char *)rpn;
+
+ struct sSection *pSection = GetSectionByName(name);
+
+ if (pSection == NULL) {
+ errx(1, "Requested BANK() of section \"%s\", which was not found.\n",
+ name);
+ }
+
+ nBank = pSection->nBank;
+ rpnpush(getrealbankfrominternalbank(nBank));
+
+ int len = strlen(name);
+
+ size -= len + 1;
+ rpn += len + 1;
+ break;
+ }
+ case RPN_BANK_SELF:
+ nBank = pCurrentSection->nBank;
+ rpnpush(getrealbankfrominternalbank(nBank));
+ break;
+ default:
+ errx(1, "%s: Invalid command %d\n", __func__,
+ rpn_cmd);
break;
}
}
--- a/src/rgbds.5
+++ b/src/rgbds.5
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2017 Antonio Nino Diaz <[email protected]>
+.\" Copyright (c) 2017-2018 Antonio Nino Diaz <[email protected]>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd July 22, 2017
+.Dd January 7, 2018
.Dt RGBDS 5
.Os RGBDS Manual
.Sh NAME
@@ -42,7 +42,7 @@
.Bd -literal
; Header
-BYTE ID[4] ; "RGB5"
+BYTE ID[4] ; "RGB6"
LONG NumberOfSymbols ; The number of symbols used in this file
LONG NumberOfSections ; The number of sections used in this file
@@ -155,25 +155,29 @@
.It Li $03 Ta Li / operator
.It Li $04 Ta Li % operator
.It Li $05 Ta Li unary -
-.It Li $06 Ta Li | operator
-.It Li $07 Ta Li & operator
-.It Li $08 Ta Li ^ operator
-.It Li $09 Ta Li unary ~
-.It Li $0A Ta Li && comparison
-.It Li $0B Ta Li || comparison
-.It Li $0C Ta Li unary !
-.It Li $0D Ta Li == comparison
-.It Li $0E Ta Li != comparison
-.It Li $0F Ta Li > comparison
-.It Li $10 Ta Li < comparison
-.It Li $11 Ta Li >= comparison
-.It Li $12 Ta Li <= comparison
-.It Li $13 Ta Li << comparison
-.It Li $14 Ta Li >> comparison
-.It Li $15 Ta Li BANK()
-function.
-A symbol ID follows.
-.It Li $16 Ta Li HRAMCheck.
+.It Li $10 Ta Li | operator
+.It Li $11 Ta Li & operator
+.It Li $12 Ta Li ^ operator
+.It Li $13 Ta Li unary ~
+.It Li $21 Ta Li && comparison
+.It Li $22 Ta Li || comparison
+.It Li $23 Ta Li unary !
+.It Li $30 Ta Li == comparison
+.It Li $31 Ta Li != comparison
+.It Li $32 Ta Li > comparison
+.It Li $33 Ta Li < comparison
+.It Li $34 Ta Li >= comparison
+.It Li $35 Ta Li <= comparison
+.It Li $40 Ta Li << comparison
+.It Li $41 Ta Li >> comparison
+.It Li $50 Ta Li BANK(symbol),
+a
+.Ar LONG
+Symbol ID follows.
+.It Li $51 Ta Li BANK(section_name),
+a null-terminated string follows.
+.It Li $52 Ta Li Current BANK() .
+.It Li $60 Ta Li HRAMCheck.
Check if the value is in HRAM, AND it with 0xFF.
.It Li $80 Ta Ar LONG
integer follows.