shithub: rgbds

Download patch

ref: b76567e7d17f70671b08097465b679777afe564d
parent: f2be601a137a145e7b56bb8c40768820d8cdd536
parent: 652db60ad6520e359dab92ef1aa53e907641666c
author: Eldred Habert <[email protected]>
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