Added new .scc (set char code) directive to map ascii to a custom format
authorLukas Krickl <lukas@krickl.dev>
Thu, 21 Dec 2023 19:17:38 +0000 (20:17 +0100)
committerLukas Krickl <lukas@krickl.dev>
Thu, 21 Dec 2023 19:17:38 +0000 (20:17 +0100)
include/ulas.h
src/test.c
src/ulas.c
tests/t0.bin
tests/t0.s

index aa4dfc471d4a9234fcba12b385ebfe12db49e798..dd48937422c297f2d08eca2b31c500bf2309ae1e 100644 (file)
@@ -9,6 +9,8 @@
 #define ULAS_STDFILEPATH "-"
 #define ULAS_PATHSEP "/"
 
+#define ULAS_CHARCODEMAPLEN 256
+
 #define ULAS_SYMNAMEMAX 256
 #define ULAS_PATHMAX 4096
 #define ULAS_LINEMAX 4096
@@ -48,6 +50,7 @@
 #define ULAS_ASMSTR_ADV ".adv"
 #define ULAS_ASMSTR_SET_ENUM_DEF ".se"
 #define ULAS_ASMSTR_DEFINE_ENUM ".de"
+#define ULAS_ASMSTR_SETCHRCODE ".scc"
 
 // configurable tokens
 #define ULAS_TOK_COMMENT ';'
@@ -263,6 +266,11 @@ struct ulas {
   int icntr;
 
   char chksm;
+
+  // character code map
+  // defaults to just x=x mapping
+  // but cna be set with a directive
+  char charcodemap[ULAS_CHARCODEMAPLEN];
 };
 
 extern struct ulas ulas;
@@ -389,12 +397,17 @@ enum ulas_asmdir {
   // acts like .def but sets the value to the current _ENUM counter
   // and increments it by size
   ULAS_ASMDIR_DEFINE_ENUM,
+  // .scc '<char>'=<value>
+  // allows to set custom encoding for char codes
+  // when using .str
+  ULAS_ASMDIR_SETCHRCODE
 };
 
 // amount of registers
 #define ULAS_NR8 7
 #define ULAS_NR16 3
 
+
 enum ulas_asmregs {
   // r8
   ULAS_REG_B = 1,
index d8aa4231c1a2f31fdc1db69691e7fd787ffd1359..8ab2c8d4b49f30e2ff02ea87cd69ffa56c82829f 100644 (file)
@@ -127,7 +127,8 @@ void test_preproc(void) {
                  "(verylongmacroinput >> 8) & 0xFF\nld [hl+], a\n",
                  0,
                  "#macro testlonginput\nld a, $1 & 0xFF\nld [hl+], a\nld a, "
-                 "($1 >> 8) & 0xFF\nld [hl+], a\n#endmacro\ntestlonginput verylongmacroinput");
+                 "($1 >> 8) & 0xFF\nld [hl+], a\n#endmacro\ntestlonginput "
+                 "verylongmacroinput");
 
   // ifdef
   assert_preproc(
index a47d74c08fcf34ec3a449304728f46db944b24ea..2c4137850d16abc97f7cfb03905e18f24e4bbe02 100644 (file)
@@ -44,6 +44,10 @@ void ulas_init(struct ulas_config cfg) {
   ulas.syms = ulas_symbuf();
   ulas.pp = ulas_preprocinit();
   ulas.scope = 1;
+
+  for (int i = 0; i < ULAS_CHARCODEMAPLEN; i++) {
+    ulas.charcodemap[i] = i;
+  }
 }
 
 void ulas_nextpass(void) {
@@ -53,6 +57,10 @@ void ulas_nextpass(void) {
   ulas.address = 0;
   ulas.chksm = 0;
   ulas.filename = ulas.initial_filename;
+
+  for (int i = 0; i < ULAS_CHARCODEMAPLEN; i++) {
+    ulas.charcodemap[i] = i;
+  }
 }
 
 void ulas_free(void) {
@@ -1370,7 +1378,7 @@ int ulas_tokexpr(const char **line, unsigned long n) {
     }
 
     // check for any expression terminators here
-    if (tok.type == ',' || tok.type == ']' || ulas_istokend(&ulas.tok)) {
+    if (tok.type == ',' || tok.type == ']' || tok.type == '=' || ulas_istokend(&ulas.tok)) {
       // on terminator we roll back line so that the terminator token
       // is not consumed now
       *line -= tokrc;
@@ -2280,8 +2288,8 @@ int ulas_asmdirbyte(FILE *dst, const char **line, unsigned long n, int *rc) {
       break;
     }
   } while (*rc != -1 && t.type == ',');
-  
-  // go back one byte if the token was a comment 
+
+  // go back one byte if the token was a comment
   if (t.type == ULAS_TOK_COMMENT) {
     *line = *line - strlen(ulas.tok.buf);
   }
@@ -2454,6 +2462,12 @@ int ulas_asmdirstr(FILE *dst, const char **line, unsigned long n, int *rc) {
   do {
     char *s = ulas_strexpr(line, n, rc);
     long len = strlen(s);
+    
+    // apply char code map 
+    for (int i = 0; i < len; i++) {
+      s[i] = ulas.charcodemap[(int)s[i]];
+    }
+
     ulas_asmout(dst, s, len);
 
     written += len;
@@ -2500,6 +2514,30 @@ int ulas_asmdirsetenum(FILE *dst, const char **line, unsigned long n, int *rc) {
   return 0;
 }
 
+int ulas_asmdirsetcharcode(const char **line, unsigned long n) {
+  int rc = 0;
+  int charcode = 0;
+  int setto = 0;
+  ULAS_EVALEXPRS(charcode = ulas_intexpr(line, n, &rc));
+  charcode = charcode & 0xFF;
+
+  ulas_tok(&ulas.tok, line, n);
+  struct ulas_tok t =
+      ulas_totok(ulas.tok.buf, strnlen(ulas.tok.buf, ulas.tok.maxlen), &rc);
+
+  if (rc == -1 || t.type != '=') {
+    ULASERR("Expected =\n");
+    return 0;
+  }
+  
+  ULAS_EVALEXPRS(setto = ulas_intexpr(line, n, &rc));
+  setto = setto & 0xFF;
+
+  ulas.charcodemap[charcode] = setto;
+
+  return rc;
+}
+
 int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
   // this buffer is written both to dst and to verbose output
   char outbuf[ULAS_OUTBUFMAX];
@@ -2534,24 +2572,21 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
   }
 
   if (ulas.tok.buf[0] == ULAS_TOK_ASMDIR_BEGIN) {
-    const char *dirstrs[] = {ULAS_ASMSTR_ORG,
-                             ULAS_ASMSTR_SET,
-                             ULAS_ASMSTR_BYTE,
-                             ULAS_ASMSTR_STR,
-                             ULAS_ASMSTR_FILL,
-                             ULAS_ASMSTR_PAD,
-                             ULAS_ASMSTR_INCBIN,
-                             ULAS_ASMSTR_DEF,
-                             ULAS_ASMSTR_CHKSM,
-                             ULAS_ASMSTR_ADV,
-                             ULAS_ASMSTR_SET_ENUM_DEF,
-                             ULAS_ASMSTR_DEFINE_ENUM,
-                             NULL};
+    const char *dirstrs[] = {ULAS_ASMSTR_ORG,          ULAS_ASMSTR_SET,
+                             ULAS_ASMSTR_BYTE,         ULAS_ASMSTR_STR,
+                             ULAS_ASMSTR_FILL,         ULAS_ASMSTR_PAD,
+                             ULAS_ASMSTR_INCBIN,       ULAS_ASMSTR_DEF,
+                             ULAS_ASMSTR_CHKSM,        ULAS_ASMSTR_ADV,
+                             ULAS_ASMSTR_SET_ENUM_DEF, ULAS_ASMSTR_DEFINE_ENUM,
+                             ULAS_ASMSTR_SETCHRCODE,   NULL};
     enum ulas_asmdir dirs[] = {
-        ULAS_ASMDIR_ORG,    ULAS_ASMDIR_SET,          ULAS_ASMDIR_BYTE,
-        ULAS_ASMDIR_STR,    ULAS_ASMDIR_FILL,         ULAS_ASMDIR_PAD,
-        ULAS_ASMDIR_INCBIN, ULAS_ASMDIR_DEF,          ULAS_ASMDIR_CHKSM,
-        ULAS_ASMDIR_ADV,    ULAS_ASMDIR_SET_ENUM_DEF, ULAS_ASMDIR_DEFINE_ENUM};
+        ULAS_ASMDIR_ORG,          ULAS_ASMDIR_SET,
+        ULAS_ASMDIR_BYTE,         ULAS_ASMDIR_STR,
+        ULAS_ASMDIR_FILL,         ULAS_ASMDIR_PAD,
+        ULAS_ASMDIR_INCBIN,       ULAS_ASMDIR_DEF,
+        ULAS_ASMDIR_CHKSM,        ULAS_ASMDIR_ADV,
+        ULAS_ASMDIR_SET_ENUM_DEF, ULAS_ASMDIR_DEFINE_ENUM,
+        ULAS_ASMDIR_SETCHRCODE};
 
     enum ulas_asmdir dir = ULAS_ASMDIR_NONE;
 
@@ -2606,6 +2641,9 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
     case ULAS_ASMDIR_DEFINE_ENUM:
       rc = ulas_asmdirdefenum(&line, n);
       break;
+    case ULAS_ASMDIR_SETCHRCODE:
+      rc = ulas_asmdirsetcharcode(&line, n);
+      break;
     case ULAS_ASMDIR_PAD:
       // TODO: pad is the same as .fill n, $ - n
     case ULAS_ASMDIR_NONE:
index 8d8083db9bcd0df9cc6868bf2f46e30bcc3ac8d7..47a8d977a1f8092faff96b165ee6cacc332788e1 100644 (file)
Binary files a/tests/t0.bin and b/tests/t0.bin differ
index fcfc3031a9d2cc1447d335fd6e94eedb4f677a93..261dc9f16fa84bf46087634d4fabc83fc7920ed6 100644 (file)
@@ -124,3 +124,7 @@ l3: .db 1
   jp hl
   ld a, 4/2
 .db 1 ; comment
+
+.str "abc"
+.scc 'a' = 'f'
+.str "abc"