Added .chksm directive that inserts rom header checksum into the rom
authorLukas Krickl <lukas@krickl.dev>
Sun, 10 Dec 2023 17:33:30 +0000 (18:33 +0100)
committerLukas Krickl <lukas@krickl.dev>
Sun, 10 Dec 2023 17:33:30 +0000 (18:33 +0100)
include/ulas.h
src/ulas.c
tests/t0.bin
tests/t0.s

index 34c68388a337dea7d855b7df3207f7415b10135d..e220cf6bcdc66314e958d25930fb94ad395a0b62 100644 (file)
@@ -44,6 +44,7 @@
 #define ULAS_ASMSTR_PAD ".pad"
 #define ULAS_ASMSTR_INCBIN ".incbin"
 #define ULAS_ASMSTR_DEF ".def"
+#define ULAS_ASMSTR_CHKSM ".chksm"
 
 // configurable tokens
 #define ULAS_TOK_COMMENT ';'
@@ -77,7 +78,7 @@
 // this is a bit of a hack to get the int expression to evaluate anyway
 // because expressions only work in the final pass
 // Beware that this can cause unforseen writes to the file and should really
-// only be uesd to evalulate an expression that needs to be evaled during 
+// only be uesd to evalulate an expression that needs to be evaled during
 // all passes and nothing else!
 #define ULAS_EVALEXPRS(...)                                                    \
   {                                                                            \
@@ -251,6 +252,8 @@ struct ulas {
   // internal counter
   // used whenever a new unique number might be needed
   int icntr;
+
+  char chksm;
 };
 
 extern struct ulas ulas;
@@ -365,6 +368,8 @@ enum ulas_asmdir {
   ULAS_ASMDIR_INCBIN,
   // .def name = value
   ULAS_ASMDIR_DEF,
+  // inserts checksum into rom
+  ULAS_ASMDIR_CHKSM,
 };
 
 // amount of registers
index 2815dc6622ac6851e43a34bc7686621075a602d0..23921f47b8a201d6634aa91871866775f755ee0c 100644 (file)
@@ -51,6 +51,7 @@ void ulas_nextpass(void) {
   ulas.line = 0;
   ulas.icntr = 0;
   ulas.address = 0;
+  ulas.chksm = 0;
   ulas.filename = ulas.initial_filename;
 }
 
@@ -2198,6 +2199,12 @@ void ulas_asmout(FILE *dst, const char *outbuf, unsigned long n) {
   if (ulas.pass == ULAS_PASS_FINAL) {
     fwrite(outbuf, 1, n, dst);
   }
+
+  if (ulas.address < 0x14C) {
+    for (int i =0; i < n; i++) {
+      ulas.chksm = ulas.chksm - outbuf[i] - 1;
+    }
+  }
 }
 
 int ulas_asmdirbyte(FILE *dst, const char **line, unsigned long n, int *rc) {
@@ -2411,13 +2418,15 @@ 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,  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,  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_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};
 
     enum ulas_asmdir dir = ULAS_ASMDIR_NONE;
 
@@ -2459,6 +2468,10 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
     case ULAS_ASMDIR_INCBIN:
       other_writes += ulas_asmdirincbin(dst, &line, n, &rc);
       break;
+    case ULAS_ASMDIR_CHKSM:
+      ulas_asmout(dst, &ulas.chksm, 1);
+      other_writes += 1;
+      break;
     case ULAS_ASMDIR_PAD:
       // TODO: pad is the same as .fill n, $ - n
     case ULAS_ASMDIR_NONE:
index 42b91e311f874b7f4b6119f758a33098ef2efba0..c4ede5e0c800a5f9d83336d81069f0021d254441 100644 (file)
Binary files a/tests/t0.bin and b/tests/t0.bin differ
index 60f35048560ee2227c30b43e7526c4436b55a43c..5e75e9932bf8c3aa5cbec29014cc9fad2ae5f0d9 100644 (file)
@@ -100,3 +100,4 @@ l2:
   jp j1
 j1:
   jp j1
+.chksm