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