shithub: rgbds

Download patch

ref: 4cc24f436947890f41a3e16392a3c7ec7e8949ba
parent: cfe21876e5d1793fbcf1c8544f1e27c4fc234919
author: ISSOtm <[email protected]>
date: Sun Feb 23 17:43:50 EST 2020

Add `ds cnt, byte` syntax

As suggested by https://github.com/rednex/rgbds/issues/350#issuecomment-498030458
The order `count` then `byte` was decided after some discussion:
- First argument consistent with single-arg syntax
- Intuitive at least to some people other than myself
- Consistent with other assemblers, at least ca65

--- a/include/asm/section.h
+++ b/include/asm/section.h
@@ -46,6 +46,7 @@
 void out_Skip(int32_t skip);
 void out_String(char const *s);
 void out_RelByte(struct Expression *expr);
+void out_RelBytes(struct Expression *expr, int32_t n);
 void out_RelWord(struct Expression *expr);
 void out_RelLong(struct Expression *expr);
 void out_PCRelByte(struct Expression *expr);
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -884,6 +884,10 @@
 		{
 			out_Skip($2);
 		}
+		| T_POP_DS uconst comma reloc_8bit
+		{
+			out_RelBytes(&$4, $2);
+		}
 ;
 
 db		: T_POP_DB constlist_8bit_entry comma constlist_8bit {
--- a/src/asm/rgbasm.5
+++ b/src/asm/rgbasm.5
@@ -799,6 +799,14 @@
 DB 1,2,3,4,"This is a string"
 .Ed
 .Pp
+.Ic DS
+can also be used to fill a region of memory with some value.
+The following produces 42 times the byte $FF:
+.Pp
+.Bd -literal -offset indent
+DS 42, $FF
+.Ed
+.Pp
 Alternatively, you can use
 .Ic DW
 to store a list of words (16-bit) or
--- a/src/asm/section.c
+++ b/src/asm/section.c
@@ -295,11 +295,7 @@
 		absByteBypassCheck(*s++);
 }
 
-/*
- * Output a relocatable byte. Checking will be done to see if it
- * is an absolute value in disguise.
- */
-void out_RelByte(struct Expression *expr)
+static void outputExpression(struct Expression const *expr)
 {
 	if (!rpn_isKnown(expr)) {
 		out_CreatePatch(PATCHTYPE_BYTE, expr);
@@ -307,6 +303,26 @@
 	} else {
 		out_AbsByte(expr->nVal);
 	}
+}
+
+/*
+ * Output a relocatable byte. Checking will be done to see if it
+ * is an absolute value in disguise.
+ */
+void out_RelByte(struct Expression *expr)
+{
+	outputExpression(expr);
+	rpn_Free(expr);
+}
+
+/*
+ * Output several copies of a relocatable byte. Checking will be done to see if
+ * it is an absolute value in disguise.
+ */
+void out_RelBytes(struct Expression *expr, int32_t n)
+{
+	while (n--)
+		outputExpression(expr);
 	rpn_Free(expr);
 }
 
--- /dev/null
+++ b/test/asm/ds-bad.asm
@@ -1,0 +1,4 @@
+SECTION "test", ROM0[0]
+
+	ds unknown, 0
+	ds 1, $100
--- /dev/null
+++ b/test/asm/ds-bad.err
@@ -1,0 +1,5 @@
+ERROR: ds-bad.asm(3):
+    Expected constant expression: 'unknown' is not constant at assembly time
+warning: ds-bad.asm(4): [-Wtruncation]
+    Expression must be 8-bit
+error: Assembly aborted (1 errors)!
--- /dev/null
+++ b/test/asm/ds-byte.asm
@@ -1,0 +1,8 @@
+SECTION "test", ROM0[0]
+
+Label:
+	ds 4, 42
+.other
+	ds 5, .other - Label - 5 ; Expressions should work...
+	ds 60, .last - Label     ; ...even if not constant
+.last
--- /dev/null
+++ b/test/asm/ds-byte.out.bin
@@ -1,0 +1,1 @@
+****�����EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
\ No newline at end of file