From d3db5f0d76db501dfda123d1606ffbb6dfe5a6b7 Mon Sep 17 00:00:00 2001 From: dbrotz <43593771+dbrotz@users.noreply.github.com> Date: Fri, 30 Aug 2019 19:36:23 -0700 Subject: [PATCH] Add pushc and popc directives --- include/asm/charmap.h | 2 + src/asm/asmy.y | 12 +++ src/asm/charmap.c | 33 ++++++++ src/asm/globlex.c | 2 + src/asm/rgbasm.5 | 5 +- test/asm/multiple-charmaps.asm | 120 ++++++++++++++++------------ test/asm/multiple-charmaps.out | 18 ++++- test/asm/multiple-charmaps.out.pipe | 18 ++++- 8 files changed, 149 insertions(+), 61 deletions(-) diff --git a/include/asm/charmap.h b/include/asm/charmap.h index ae64e875..b6d36501 100644 --- a/include/asm/charmap.h +++ b/include/asm/charmap.h @@ -35,6 +35,8 @@ struct Charmap { 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); diff --git a/src/asm/asmy.y b/src/asm/asmy.y index afb9aa53..3257b8d1 100644 --- a/src/asm/asmy.y +++ b/src/asm/asmy.y @@ -621,6 +621,8 @@ static void strsubUTF8(char *dest, const char *src, uint32_t pos, uint32_t len) %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 @@ simple_pseudoop : include | charmap | newcharmap | setcharmap + | pushc + | popc | rept | shift | fail @@ -1047,11 +1051,19 @@ newcharmap : T_POP_NEWCHARMAP T_ID { 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 { diff --git a/src/asm/charmap.c b/src/asm/charmap.c index 092a4be5..3b29707b 100644 --- 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; @@ -119,6 +126,32 @@ void charmap_Set(const char *name) 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) { mainCharmap = charmap_New("main", NULL); diff --git a/src/asm/globlex.c b/src/asm/globlex.c index c848aff8..40b8a914 100644 --- a/src/asm/globlex.c +++ b/src/asm/globlex.c @@ -481,6 +481,8 @@ const struct sLexInitString lexer_strings[] = { {"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}, diff --git a/src/asm/rgbasm.5 b/src/asm/rgbasm.5 index 9d5ea4fd..e816eedb 100644 --- a/src/asm/rgbasm.5 +++ b/src/asm/rgbasm.5 @@ -1146,7 +1146,8 @@ a different encoding for other purposes, for example. Initially, there is 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 @@ beginning. 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: diff --git a/test/asm/multiple-charmaps.asm b/test/asm/multiple-charmaps.asm index fb4e5f35..0a410652 100644 --- 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" - -x = "cd" -printt "{x}\n" - -printt "setcharmap main\n" -setcharmap main + set_ 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_ diff --git a/test/asm/multiple-charmaps.out b/test/asm/multiple-charmaps.out index 79b502c6..4be67109 100644 --- 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 @@ $0 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 diff --git a/test/asm/multiple-charmaps.out.pipe b/test/asm/multiple-charmaps.out.pipe index 03727000..7d6126a7 100644 --- 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 @@ $0 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