ref: 165bd8cb71c5ebe4f5cf79ed4179f9302834aa07
parent: e54e02dc77ae4e412905e168ff11e3017a481127
author: Rangi <remy.oukaour+rangi42@gmail.com>
date: Wed Dec 9 10:04:54 EST 2020
Allow 'dw' and 'dl' to apply to characters of strings Fixes #568 The old behavior of `dw "string"` can be replicated with `dw ("string")`; likewise for dl
--- a/include/asm/section.h
+++ b/include/asm/section.h
@@ -56,6 +56,8 @@
void out_AbsByte(uint8_t b);
void out_AbsByteGroup(uint8_t const *s, int32_t length);
+void out_AbsWordGroup(uint8_t const *s, int32_t length);
+void out_AbsLongGroup(uint8_t const *s, int32_t length);
void out_Skip(int32_t skip, bool ds);
void out_String(char const *s);
void out_RelByte(struct Expression *expr);
--- a/src/asm/parser.y
+++ b/src/asm/parser.y
@@ -202,6 +202,7 @@
%type <sVal> reloc_8bit
%type <sVal> reloc_8bit_no_str
%type <sVal> reloc_16bit
+%type <sVal> reloc_16bit_no_str
%type <nConstValue> sectiontype
%type <tzString> string
@@ -842,7 +843,14 @@
out_Skip(2, false);
nListCountEmpty++;
}
- | reloc_16bit { out_RelWord(&$1); }
+ | reloc_16bit_no_str { out_RelWord(&$1); }
+ | string {
+ uint8_t *output = malloc(strlen($1)); /* Cannot be larger than that */
+ int32_t length = charmap_Convert($1, output);
+
+ out_AbsWordGroup(output, length);
+ free(output);
+ }
;
constlist_32bit : constlist_32bit_entry
@@ -853,7 +861,14 @@
out_Skip(4, false);
nListCountEmpty++;
}
- | relocexpr { out_RelLong(&$1); }
+ | relocexpr_no_str { out_RelLong(&$1); }
+ | string {
+ uint8_t *output = malloc(strlen($1)); /* Cannot be larger than that */
+ int32_t length = charmap_Convert($1, output);
+
+ out_AbsLongGroup(output, length);
+ free(output);
+ }
;
reloc_8bit : relocexpr {
@@ -873,6 +888,14 @@
;
reloc_16bit : relocexpr {
+ if (rpn_isKnown(&$1)
+ && ($1.nVal < -32768 || $1.nVal > 65535))
+ warning(WARNING_TRUNCATION, "Expression must be 16-bit\n");
+ $$ = $1;
+ }
+;
+
+reloc_16bit_no_str : relocexpr_no_str {
if (rpn_isKnown(&$1)
&& ($1.nVal < -32768 || $1.nVal > 65535))
warning(WARNING_TRUNCATION, "Expression must be 16-bit\n");
--- a/src/asm/section.c
+++ b/src/asm/section.c
@@ -506,6 +506,24 @@
writebyte(*s++);
}
+void out_AbsWordGroup(uint8_t const *s, int32_t length)
+{
+ checkcodesection();
+ reserveSpace(length * 2);
+
+ while (length--)
+ writeword(*s++);
+}
+
+void out_AbsLongGroup(uint8_t const *s, int32_t length)
+{
+ checkcodesection();
+ reserveSpace(length * 4);
+
+ while (length--)
+ writelong(*s++);
+}
+
/*
* Skip this many bytes
*/
--- /dev/null
+++ b/test/asm/db-dw-dl-string.asm
@@ -1,0 +1,17 @@
+SECTION "Test", ROM0
+
+ db "ABC"
+ dw "ABC"
+ dl "ABC"
+
+ db 0, "DEF", -1
+ dw 0, "DEF", -1
+ dl 0, "DEF", -1
+
+ db "A" + 1
+ dw "A" + 1
+ dl "A" + 1
+
+ db 1, ("UVWXYZ") & $ff, -1
+ dw 1, ("UVWXYZ") & $ffff, -1
+ dl 1, ("UVWXYZ"), -1
binary files /dev/null b/test/asm/db-dw-dl-string.out.bin differ