shithub: rgbds

Download patch

ref: d3db5f0d76db501dfda123d1606ffbb6dfe5a6b7
parent: 461ef6cea5225ec252293216011d070d65626ea0
author: dbrotz <43593771+dbrotz@users.noreply.github.com>
date: Fri Aug 30 15:36:23 EDT 2019

Add pushc and popc directives

--- a/include/asm/charmap.h
+++ b/include/asm/charmap.h
@@ -35,6 +35,8 @@
 void charmap_InitMain(void);
 struct Charmap *charmap_New(const char *name, const char *baseName);
 void charmap_Set(const char *name);
+void charmap_Push(void);
+void charmap_Pop(void);
 int32_t charmap_Add(char *input, uint8_t output);
 int32_t charmap_Convert(char **input);
 
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -621,6 +621,8 @@
 %token	T_POP_CHARMAP
 %token	T_POP_NEWCHARMAP
 %token	T_POP_SETCHARMAP
+%token	T_POP_PUSHC
+%token	T_POP_POPC
 %token	T_POP_SHIFT
 %token	T_POP_ENDR
 %token	T_POP_FAIL
@@ -776,6 +778,8 @@
 		| charmap
 		| newcharmap
 		| setcharmap
+		| pushc
+		| popc
 		| rept
 		| shift
 		| fail
@@ -1047,11 +1051,19 @@
 		{
 			charmap_New($2, $4);
 		}
+;
 
 setcharmap	: T_POP_SETCHARMAP T_ID
 		{
 			charmap_Set($2);
 		}
+;
+
+pushc		: T_POP_PUSHC	{ charmap_Push(); }
+;
+
+popc		: T_POP_POPC	{ charmap_Pop(); }
+;
 
 printt		: T_POP_PRINTT string
 		{
--- a/src/asm/charmap.c
+++ b/src/asm/charmap.c
@@ -20,11 +20,18 @@
 
 #define CHARMAP_HASH_SIZE (1 << 9)
 
+struct CharmapStackEntry {
+	struct Charmap *charmap;
+	struct CharmapStackEntry *next;
+};
+
 static struct Charmap *tHashedCharmaps[CHARMAP_HASH_SIZE];
 
 static struct Charmap *mainCharmap;
 static struct Charmap *currentCharmap;
 
+struct CharmapStackEntry *charmapStack;
+
 static void warnSectionCharmap(void)
 {
 	static bool warned = false;
@@ -117,6 +124,32 @@
 	}
 
 	currentCharmap = *ppCharmap;
+}
+
+void charmap_Push(void)
+{
+	struct CharmapStackEntry *stackEntry;
+
+	stackEntry = malloc(sizeof(struct CharmapStackEntry));
+	if (stackEntry == NULL)
+		fatalerror("No memory for charmap stack");
+
+	stackEntry->charmap = currentCharmap;
+	stackEntry->next = charmapStack;
+
+	charmapStack = stackEntry;
+}
+
+void charmap_Pop(void)
+{
+	if (charmapStack == NULL)
+		fatalerror("No entries in the charmap stack");
+
+	struct CharmapStackEntry *top = charmapStack;
+
+	currentCharmap = top->charmap;
+	charmapStack = top->next;
+	free(top);
 }
 
 void charmap_InitMain(void)
--- a/src/asm/globlex.c
+++ b/src/asm/globlex.c
@@ -481,6 +481,8 @@
 	{"charmap", T_POP_CHARMAP},
 	{"newcharmap", T_POP_NEWCHARMAP},
 	{"setcharmap", T_POP_SETCHARMAP},
+	{"pushc", T_POP_PUSHC},
+	{"popc", T_POP_POPC},
 
 	{"fail", T_POP_FAIL},
 	{"warn", T_POP_WARN},
--- a/src/asm/rgbasm.5
+++ b/src/asm/rgbasm.5
@@ -1146,7 +1146,8 @@
 one character map called
 .Sy main
 and it is automatically selected as the current character map from the
-beginning.
+beginning. There is also a character map stack that can be used to save and
+restore which character map is currently active.
 .Bl -column "NEWCHARMAP name, basename"
 .It Sy Command Ta Sy Meaning
 .It Ic NEWCHARMAP Ar name Ta Creates a new, empty character map called
@@ -1156,6 +1157,8 @@
 copied from character map
 .Ic basename .
 .It Ic SETCHARMAP Ar name Ta Switch to character map Ic name .
+.It Ic PUSHC Ta Push the current character map onto the stack.
+.It Ic POPC Ta Pop a character map off the stack and switch to it.
 .El
 .Pp
 .Sy Note:
--- a/test/asm/multiple-charmaps.asm
+++ b/test/asm/multiple-charmaps.asm
@@ -1,88 +1,104 @@
+new_: MACRO
+	IF _NARG > 1
+	printt "newcharmap \1, \2\n"
+	newcharmap \1, \2
+	ELSE
+	printt "newcharmap \1\n"
+	newcharmap \1
+	ENDC
+ENDM
+
+set_: MACRO
+	printt "setcharmap \1\n"
+	setcharmap \1
+ENDM
+
+push_: MACRO
+	printt "pushc\n"
+	pushc
+ENDM
+
+pop_: MACRO
+	printt "popc\n"
+	popc
+ENDM
+
+print: MACRO
+x = \1
+printt "{x}\n"
+ENDM
+
 printt "main charmap\n"
 
 charmap "ab", $0
 
-x = "ab"
-printt "{x}\n"
+	print "ab"
 
-printt "newcharmap map1\n"
-newcharmap map1
+	new_ map1
 
-x = "ab"
-printt "{x}\n"
+	print "ab"
 
-printt "newcharmap map2, main\n"
-newcharmap map2, main
+	new_ map2, main
 
-x = "ab"
-printt "{x}\n"
+	print "ab"
 
-printt "setcharmap map1\n"
-setcharmap map1
+	set_ map1
 
-x = "ab"
-printt "{x}\n"
+	print "ab"
 
-printt "newcharmap map3\n"
-newcharmap map3
+	new_ map3
 
 charmap "ab", $1
 
-x = "ab"
-printt "{x}\n"
+	print "ab"
 
-printt "newcharmap map4, map3\n"
-newcharmap map4, map3
+	new_ map4, map3
 
 charmap "ab", $1
 charmap "cd", $2
 
-x = "ab"
-printt "{x}\n"
+	print "ab"
+	print "cd"
 
-x = "cd"
-printt "{x}\n"
+	set_ map3
 
-printt "setcharmap map3\n"
-setcharmap map3
+	print "ab"
+	print "cd"
 
-x = "ab"
-printt "{x}\n"
+	set_ main
 
-x = "cd"
-printt "{x}\n"
-
-printt "setcharmap main\n"
-setcharmap main
-
 SECTION "sec0", ROM0
 
-x = "ab"
-printt "{x}\n"
+	print "ab"
 
 printt "override main charmap\n"
 charmap "ef", $3
 
-x = "ab"
-printt "{x}\n"
+	print "ab"
+	print "ef"
 
-x = "ef"
-printt "{x}\n"
+	set_ map1
 
-printt "setcharmap map3\n"
-setcharmap map3
+	push_
+	set_ map2
+	push_
 
-x = "ab"
-printt "{x}\n"
+	set_ map3
 
-x = "cd"
-printt "{x}\n"
+	print "ab"
+	print "cd"
+	print "ef"
 
-x = "ef"
-printt "{x}\n"
+	pop_
 
-printt "newcharmap map1\n"
-newcharmap map1
+	print "ab"
 
-printt "setcharmap map5\n"
-setcharmap map5
+	pop_
+
+	print "ab"
+
+	new_ map1
+
+	set_ map5
+
+	pop_
--- a/test/asm/multiple-charmaps.out
+++ b/test/asm/multiple-charmaps.out
@@ -1,10 +1,11 @@
-warning: multiple-charmaps.asm(64):
+warning: multiple-charmaps.asm(75):
     Using 'charmap' within a section when the current charmap is 'main' is deprecated
-ERROR: multiple-charmaps.asm(85):
+ERROR: multiple-charmaps.asm(100) -> new_(5):
     Charmap 'map1' already exists
-ERROR: multiple-charmaps.asm(88):
+ERROR: multiple-charmaps.asm(102) -> set_(2):
     Charmap 'map5' doesn't exist
-error: Assembly aborted (2 errors)!
+ERROR: multiple-charmaps.asm(104) -> pop_(2):
+    No entries in the charmap stack
 main charmap
 $0
 newcharmap map1
@@ -26,9 +27,18 @@
 override main charmap
 $6162
 $3
+setcharmap map1
+pushc
+setcharmap map2
+pushc
 setcharmap map3
 $1
 $6364
 $6566
+popc
+$0
+popc
+$6162
 newcharmap map1
 setcharmap map5
+popc
--- a/test/asm/multiple-charmaps.out.pipe
+++ b/test/asm/multiple-charmaps.out.pipe
@@ -1,10 +1,11 @@
-warning: -(64):
+warning: -(75):
     Using 'charmap' within a section when the current charmap is 'main' is deprecated
-ERROR: -(85):
+ERROR: -(100) -> new_(5):
     Charmap 'map1' already exists
-ERROR: -(88):
+ERROR: -(102) -> set_(2):
     Charmap 'map5' doesn't exist
-error: Assembly aborted (2 errors)!
+ERROR: -(104) -> pop_(2):
+    No entries in the charmap stack
 main charmap
 $0
 newcharmap map1
@@ -26,9 +27,18 @@
 override main charmap
 $6162
 $3
+setcharmap map1
+pushc
+setcharmap map2
+pushc
 setcharmap map3
 $1
 $6364
 $6566
+popc
+$0
+popc
+$6162
 newcharmap map1
 setcharmap map5
+popc