ref: b76567e7d17f70671b08097465b679777afe564d
parent: f2be601a137a145e7b56bb8c40768820d8cdd536
parent: 652db60ad6520e359dab92ef1aa53e907641666c
author: Eldred Habert <eldredhabert0@gmail.com>
date: Mon Feb 3 20:26:06 EST 2020
Merge pull request #470 from ISSOtm/rst Allow using labels as argument to `rst`
--- a/include/asm/rpn.h
+++ b/include/asm/rpn.h
@@ -74,5 +74,6 @@
void rpn_Init(struct Expression *expr);
void rpn_Free(struct Expression *expr);
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src);
+void rpn_CheckRST(struct Expression *expr, const struct Expression *src);
#endif /* RGBDS_ASM_RPN_H */
--- a/include/linkdefs.h
+++ b/include/linkdefs.h
@@ -13,7 +13,8 @@
#include <stdint.h>
#define RGBDS_OBJECT_VERSION_STRING "RGB%1hhu"
-#define RGBDS_OBJECT_VERSION_NUMBER (uint8_t)6
+#define RGBDS_OBJECT_VERSION_NUMBER (uint8_t)9
+#define RGBDS_OBJECT_REV 0
enum RPNCommand {
RPN_ADD = 0x00,
@@ -47,6 +48,7 @@
RPN_BANK_SELF = 0x52,
RPN_HRAM = 0x60,
+ RPN_RST = 0x61,
RPN_CONST = 0x80,
RPN_SYM = 0x81
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -2065,9 +2065,10 @@
z80_rst : T_Z80_RST const_8bit
{
- if (rpn_isReloc(&$2))
- yyerror("Address for RST must be absolute");
- else if (($2.nVal & 0x38) != $2.nVal)
+ if (rpn_isReloc(&$2)) {
+ rpn_CheckRST(&$2, &$2);
+ out_RelByte(&$2);
+ } else if (($2.nVal & 0x38) != $2.nVal)
yyerror("Invalid address $%x for RST", $2.nVal);
else
out_AbsByte(0xC7 | $2.nVal);
--- a/src/asm/output.c
+++ b/src/asm/output.c
@@ -542,6 +542,7 @@
fatalerror("Couldn't write file '%s'\n", tzObjectname);
fprintf(f, RGBDS_OBJECT_VERSION_STRING, RGBDS_OBJECT_VERSION_NUMBER);
+ fputlong(RGBDS_OBJECT_REV, f);
fputlong(countsymbols(), f);
fputlong(countsections(), f);
--- a/src/asm/rpn.c
+++ b/src/asm/rpn.c
@@ -242,6 +242,13 @@
expr->nRPNPatchSize++;
}
+void rpn_CheckRST(struct Expression *expr, const struct Expression *src)
+{
+ *expr = *src;
+ pushbyte(expr, RPN_RST);
+ expr->nRPNPatchSize++;
+}
+
void rpn_LOGNOT(struct Expression *expr, const struct Expression *src)
{
*expr = *src;
--- a/src/link/object.c
+++ b/src/link/object.c
@@ -334,12 +334,39 @@
}
/**
- * Reads a RGB6 object file.
- * @param file The file to read from
- * @param fileName The filename to report in errors
+ * Reads an object file of any supported format
+ * @param fileName The filename to report for errors
*/
-static void readRGB6File(FILE *file, char const *fileName)
+void obj_ReadFile(char const *fileName)
{
+ FILE *file = strcmp("-", fileName) ? fopen(fileName, "rb") : stdin;
+
+ if (!file)
+ err(1, "Could not open file %s", fileName);
+
+ /* Begin by reading the magic bytes and version number */
+ uint8_t versionNumber;
+ int matchedElems = fscanf(file, RGBDS_OBJECT_VERSION_STRING,
+ &versionNumber);
+
+ if (matchedElems != 1)
+ errx(1, "\"%s\" is not a RGBDS object file", fileName);
+
+ verbosePrint("Reading object file %s, version %hhu\n",
+ fileName, versionNumber);
+
+ if (versionNumber != RGBDS_OBJECT_VERSION_NUMBER)
+ errx(1, "\"%s\" is an incompatible version %hhu object file",
+ fileName, versionNumber);
+
+ uint32_t revNum;
+
+ tryReadlong(revNum, file, "%s: Cannot read revision number: %s",
+ fileName);
+ if (revNum != RGBDS_OBJECT_REV)
+ errx(1, "%s is a revision 0x%04x object file, only 0x%04x is supported",
+ fileName, revNum, RGBDS_OBJECT_REV);
+
uint32_t nbSymbols;
uint32_t nbSections;
@@ -424,37 +451,6 @@
linkSymToSect(fileSymbols[i], fileSections[sectionID]);
}
}
-}
-
-/**
- * Reads an object file of any supported format
- * @param fileName The filename to report for errors
- */
-void obj_ReadFile(char const *fileName)
-{
- FILE *file = strcmp("-", fileName) ? fopen(fileName, "rb") : stdin;
-
- if (!file) {
- err(1, "Could not open file %s", fileName);
- return;
- }
-
- /* Begin by reading the magic bytes and version number */
- uint8_t versionNumber;
- int matchedElems = fscanf(file, RGBDS_OBJECT_VERSION_STRING,
- &versionNumber);
-
- if (matchedElems != 1)
- errx(1, "\"%s\" is not a RGBDS object file", fileName);
- /* TODO: support other versions? */
- if (versionNumber != 6)
- errx(1, "\"%s\" is an incompatible version %hhu object file",
- fileName, versionNumber);
-
- verbosePrint("Reading object file %s, version %hhu\n",
- fileName, versionNumber);
-
- readRGB6File(file, fileName);
fclose(file);
}
--- a/src/link/patch.c
+++ b/src/link/patch.c
@@ -284,6 +284,17 @@
value &= 0xFF;
break;
+ case RPN_RST:
+ value = popRPN();
+ /* Acceptable values are 0x00, 0x08, 0x10, ..., 0x38
+ * They can be easily checked with a bitmask
+ */
+ if (value & ~0x38)
+ errx(1, "%s(%d): Value %d is not a RST vector",
+ patch->fileName, patch->lineNo, value);
+ value |= 0xC7;
+ break;
+
case RPN_CONST:
value = 0;
for (uint8_t shift = 0; shift < 32; shift += 8)
--- a/src/rgbds.5
+++ b/src/rgbds.5
@@ -33,7 +33,8 @@
.Bd -literal
; Header
-BYTE ID[4] ; "RGB6"
+BYTE ID[4] ; "RGB9"
+LONG RevisionNumber ; The format's revision number this file uses
LONG NumberOfSymbols ; The number of symbols used in this file
LONG NumberOfSections ; The number of sections used in this file
@@ -170,7 +171,9 @@
a null-terminated string follows.
.It Li $52 Ta Li Current BANK()
.It Li $60 Ta Li HRAMCheck .
-Checks if the value is in HRAM, AND it with 0xFF.
+Checks if the value is in HRAM, ANDs it with 0xFF.
+.It Li $61 Ta Li RSTCheck .
+Checks if the value is a RST vector, ORs it with 0xC7.
.It Li $80 Ta Ar LONG
integer follows.
.It Li $81 Ta Ar LONG
--- /dev/null
+++ b/test/asm/rst.asm
@@ -1,0 +1,35 @@
+
+SECTION "calls", ROM0[0]
+
+; The values are not known at this point, forcing the assembler to emit an
+; expression
+ rst rst00
+ rst rst08
+ rst rst10
+ rst rst18
+ rst rst20
+ rst rst28
+ rst rst30
+ rst rst38
+
+ rst rst2A
+
+
+defRST: MACRO
+; FIXME: This is required, otherwise the lexer does not paste the two tokens
+ADDR equs "$\1"
+SECTION "rst\1", ROM0[ADDR]
+
+rst\1:
+ PURGE ADDR
+ENDM
+ defRST 00
+ defRST 08
+ defRST 10
+ defRST 18
+ defRST 20
+ defRST 28
+ defRST 30
+ defRST 38
+
+ defRST 2A ; Define a nonsensical RST, because RGBASM cannot catch it
--- /dev/null
+++ b/test/link/rst-bad.asm
@@ -1,0 +1,3 @@
+SECTION "bad", ROM0[0]
+ rst bad
+bad: ; This is not at a RST vector!
--- /dev/null
+++ b/test/link/rst-bad.out
@@ -1,0 +1,1 @@
+error: rst-bad.asm(2): Value 1 is not a RST vector
--- /dev/null
+++ b/test/link/rst.asm
@@ -1,0 +1,31 @@
+
+SECTION "calls", ROM0[0]
+
+; The values are not known at this point, forcing the assembler to emit an
+; expression
+ rst rst00
+ rst rst08
+ rst rst10
+ rst rst18
+ rst rst20
+ rst rst28
+ rst rst30
+ rst rst38
+
+
+defRST: MACRO
+; FIXME: This is required, otherwise the lexer does not paste the two tokens
+ADDR equs "$\1"
+SECTION "rst\1", ROM0[ADDR]
+
+rst\1:
+ PURGE ADDR
+ENDM
+ defRST 00
+ defRST 08
+ defRST 10
+ defRST 18
+ defRST 20
+ defRST 28
+ defRST 30
+ defRST 38
--- /dev/null
+++ b/test/link/rst.out.bin
@@ -1,0 +1,1 @@
+������
\ No newline at end of file