shithub: rgbds

Download patch

ref: 136446fccb5412ccc70cd2331a5ea0c7d369af35
parent: 49bca8d588f1060367fc53d9ee8d668febc5faf7
author: ISSOtm <[email protected]>
date: Sun Mar 15 11:19:05 EDT 2020

Improve checking of RST and LDH values at assembly time

--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -1535,21 +1535,13 @@
 z80_ldio	: T_Z80_LDIO T_MODE_A ',' op_mem_ind {
 			rpn_CheckHRAM(&$4, &$4);
 
-			if ((rpn_isKnown(&$4)) && ($4.nVal < 0 || ($4.nVal > 0xFF && $4.nVal < 0xFF00) || $4.nVal > 0xFFFF))
-				yyerror("Source address $%x not in $FF00 to $FFFF", $4.nVal);
-
 			out_AbsByte(0xF0);
-			$4.nVal &= 0xFF;
 			out_RelByte(&$4);
 		}
 		| T_Z80_LDIO op_mem_ind ',' T_MODE_A {
 			rpn_CheckHRAM(&$2, &$2);
 
-			if ((rpn_isKnown(&$2)) && ($2.nVal < 0 || ($2.nVal > 0xFF && $2.nVal < 0xFF00) || $2.nVal > 0xFFFF))
-				yyerror("Destination address $%x not in $FF00 to $FFFF", $2.nVal);
-
 			out_AbsByte(0xE0);
-			$2.nVal &= 0xFF;
 			out_RelByte(&$2);
 		}
 		| T_Z80_LDIO T_MODE_A ',' T_MODE_C_IND {
@@ -1737,14 +1729,11 @@
 ;
 
 z80_rst		: T_Z80_RST reloc_8bit {
-			if (!rpn_isKnown(&$2)) {
-				rpn_CheckRST(&$2, &$2);
+			rpn_CheckRST(&$2, &$2);
+			if (!rpn_isKnown(&$2))
 				out_RelByte(&$2);
-			} else if (($2.nVal & 0x38) != $2.nVal) {
-				yyerror("Invalid address $%x for RST", $2.nVal);
-			} else {
+			else
 				out_AbsByte(0xC7 | $2.nVal);
-			}
 			rpn_Free(&$2);
 		}
 ;
--- a/src/asm/rpn.c
+++ b/src/asm/rpn.c
@@ -208,11 +208,14 @@
 	*expr = *src;
 	expr->isSymbol = false;
 
-	if (rpn_isKnown(expr)) {
-		/* TODO */
-	} else {
+	if (!rpn_isKnown(expr)) {
 		expr->nRPNPatchSize++;
 		*reserveSpace(expr, 1) = RPN_HRAM;
+	} else if (expr->nVal >= 0xFF00 && expr->nVal <= 0xFFFF) {
+		/* That range is valid, but only keep the lower byte */
+		expr->nVal &= 0xFF;
+	} else if (expr->nVal < 0 || expr->nVal > 0xFF) {
+		yyerror("Source address $%x not in $FF00 to $FFFF", expr->nVal);
 	}
 }
 
@@ -221,7 +224,11 @@
 	*expr = *src;
 
 	if (rpn_isKnown(expr)) {
-		/* TODO */
+		/* A valid RST address must be masked with 0x38 */
+		if (expr->nVal & ~0x38)
+			yyerror("Invalid address $%x for RST", expr->nVal);
+		/* The target is in the "0x38" bits, all other bits are set */
+		expr->nVal |= 0xC7;
 	} else {
 		expr->nRPNPatchSize++;
 		*reserveSpace(expr, 1) = RPN_RST;