diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..df0482a5a 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1568,6 +1568,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1670,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -2101,10 +2124,12 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ @@ -2183,4 +2208,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..0452bb368 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -260,10 +260,12 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..a94254bfd 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -231,10 +231,12 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..af5bdf725 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -76,6 +81,8 @@ static unsigned char Tab[256] = { + + void TgtTranslateInit (void) /* Initialize the translation tables */ { @@ -127,3 +134,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */