Start work on preprocessor
diff --git a/as/CMakeLists.txt b/as/CMakeLists.txt
index f5e3989..e3ed969 100644
--- a/as/CMakeLists.txt
+++ b/as/CMakeLists.txt
@@ -13,6 +13,6 @@
endif()
-add_executable(6502-as main.c as.h as.c map.h map.c hash.c hash.c)
+add_executable(6502-as main.c as.h as.c pp.c map.h map.c hash.c hash.c)
install(TARGETS 6502-as)
diff --git a/as/as.c b/as/as.c
index 989b83c..f85bc21 100644
--- a/as/as.c
+++ b/as/as.c
@@ -20,9 +20,6 @@
ARG_IMP, /* Implied argument */
};
-#define ERR "\033[31m"
-#define GREEN "\033[32m"
-#define RESET "\033[0m"
#define MAX_LEN (0xFFFF - 0x600)
#define MAX_INSTS (MAX_LEN / 2)
@@ -583,7 +580,8 @@
uint16_t lbl;
if (!(lbl = ll_find(last_node, insts[i]->label)))
{
- printf(ERR "Error on line %d: label '%s' is not defined" RESET "\n", insts[i]->line, insts[i]->label);
+ printf(ERR "Error on line %d: label '%s' is not defined" RESET "\n",
+ insts[i]->line, insts[i]->label);
goto cleanup;
}
curr_pc += 3;
@@ -596,7 +594,8 @@
uint16_t lbl;
if (!(lbl = ll_find(last_node, insts[i]->label)))
{
- printf(ERR "Error on line %d: label '%s' is not defined" RESET "\n", insts[i]->line, insts[i]->label);
+ printf(ERR "Error on line %d: label '%s' is not defined" RESET "\n",
+ insts[i]->line, insts[i]->label);
goto cleanup;
}
curr_pc += 2;
@@ -604,7 +603,8 @@
printf("ARG_REL, pc (after) == %x, diff = %hx\n", curr_pc, (uint8_t) diff);
if ((diff < 0 ? -diff : diff) > 0xFF)
{
- printf(ERR "Error on line %d: label '%s' is too far away for a relative jump" RESET "\n", insts[i]->line, insts[i]->label);
+ printf(ERR "Error on line %d: label '%s' is too far away for a relative jump" RESET "\n",
+ insts[i]->line, insts[i]->label);
printf("pc == %hx, label is at %hx\n", curr_pc, lbl);
goto cleanup;
}
diff --git a/as/as.h b/as/as.h
index 4e167dd..a04ef79 100644
--- a/as/as.h
+++ b/as/as.h
@@ -1,9 +1,26 @@
#pragma once
+#include "map.h"
+
#include <stdio.h>
#include <stdint.h>
+#include <stdbool.h>
-/*
+#define ERR "\033[31m"
+#define GREEN "\033[32m"
+#define RESET "\033[0m"
+
+char *strtok_fix(char *string, const char *token);
+uint32_t skip_ws(char **code);
+char *parse_label_name(char **code);
+bool ws_end(char **code);
+
+/**
+ * @returns 0 on success, error code otherwise
+ */
+int preproc(char *code, FILE *out, map_t *macros, int flags);
+
+/**
* @returns NULL on failure, printing info to stderr
*/
uint32_t assemble(char *code, FILE *out);
diff --git a/as/main.c b/as/main.c
index cf966f8..8c2b577 100644
--- a/as/main.c
+++ b/as/main.c
@@ -1,10 +1,12 @@
#include "as.h"
+#include "map.h"
#include <stdio.h>
#include <stdlib.h>
#include <bits/getopt_core.h>
#include <unistd.h>
+// TODO: handle all the possible IO errors
int main(int argc, char **argv)
{
char c;
@@ -38,7 +40,22 @@
fread(text, len, 1, in);
text[len] = 0;
- uint32_t built = assemble(text, out);
+ FILE *temp = tmpfile();
+
+ map_t *macros = new_map();
+ uint32_t processed = preproc(text, temp, macros, 0);
+ free_map_items(macros);
+
+ fseek(temp, 0, SEEK_END);
+ ssize_t temp_len = ftell(in);
+ fseek(temp, 0, SEEK_SET);
+
+ char *processed_text = malloc(len + 1);
+ fread(processed_text, len, 1, in);
+ text[temp_len] = 0;
+
+ uint32_t built = assemble(processed_text, out);
free(text);
+ free(processed_text);
}
diff --git a/as/pp.c b/as/pp.c
new file mode 100644
index 0000000..03936a7
--- /dev/null
+++ b/as/pp.c
@@ -0,0 +1,77 @@
+#include "as.h"
+#include "map.h"
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+enum /* State */
+{
+ NORMAL, /* Default State */
+ MACRO_DEF /* In Macro Definition */
+};
+
+enum /* Flags */
+{
+ PRESERVE_MACRO_ARGS,
+};
+
+int preproc(char *in, FILE *out, map_t *macros, int flags)
+{
+ int line_no = 1,
+ err = 0,
+ state = NORMAL;
+ char *line = strtok_fix(in, "\n"),
+ *macro_name = NULL;
+
+ while (line)
+ {
+ skip_ws(&line);
+
+ if (*line == '%')
+ {
+ // Line is preprocessor directive
+
+ char *directive = parse_label_name(&line);
+ if (!directive)
+ {
+ fprintf(stderr, ERR "Expected preprocessor directive on line %d\n" RESET,
+ line_no);
+ err = EINVAL;
+ goto cleanup;
+ }
+ else
+ {
+ if (!strcasecmp(directive, "macro"))
+ {
+ skip_ws(&line);
+ macro_name = parse_label_name(&line);
+ if (!macro_name)
+ {
+ fprintf(stderr, ERR "Expected name after %%macro on line %d\n" RESET,
+ line_no);
+ err = EINVAL;
+ goto cleanup;
+ }
+
+ if (!ws_end(&line))
+ {
+ fprintf(stderr, ERR "Expected new line after macro definition\n" RESET);
+ err = EINVAL;
+ goto cleanup;
+ }
+
+ state = MACRO_DEF;
+ }
+ }
+ }
+
+ fprintf(out, "%s\n", line);
+
+ line = strtok_fix(NULL, "\n");
+ line_no++;
+ }
+
+cleanup:
+ return err;
+}
diff --git a/as/test/test-abs-jump.s b/as/test/test-abs-jump.s
new file mode 100644
index 0000000..07441cc
--- /dev/null
+++ b/as/test/test-abs-jump.s
@@ -0,0 +1,16 @@
+;;; This program should test for a bug involving endianness.
+
+start:
+ lda #$FF
+ sta $200 ; Put something on the screen, just to see
+ jmp second-pixel
+ brk
+
+second-pixel:
+ lda #$E0 ; Red
+ sta $201
+ sta $220
+ sta $221 ; Draw a box around the white pixel
+
+loop: ; Infinite loop
+ jmp loop
diff --git a/docs/.sass-cache/e3a0acadbd5d6bc6cf7ba6a2321a4fa55d361330/styles.scssc b/docs/.sass-cache/e3a0acadbd5d6bc6cf7ba6a2321a4fa55d361330/styles.scssc
new file mode 100644
index 0000000..f47ca89
--- /dev/null
+++ b/docs/.sass-cache/e3a0acadbd5d6bc6cf7ba6a2321a4fa55d361330/styles.scssc
Binary files differ
diff --git a/docs/build.lua b/docs/build.lua
index c7a50e1..e27125a 100644
--- a/docs/build.lua
+++ b/docs/build.lua
@@ -4,7 +4,7 @@
-- site.processors.md = markdownProcessor
site.processors.scss = {
- process = cmdProcessor("sass -"),
+ process = cmdProcessor("sass"),
extension = "css"
}
site.processors.webm = {
diff --git a/docs/content/demo.webm b/docs/content/demo.webm
index fba477a..01d6961 100644
--- a/docs/content/demo.webm
+++ b/docs/content/demo.webm
Binary files differ
diff --git a/docs/templates/page.html b/docs/templates/page.html
index 9bcf2b4..e074116 100644
--- a/docs/templates/page.html
+++ b/docs/templates/page.html
@@ -14,7 +14,7 @@
</p>
<ul>
- <li><a href="https://github.com/swissChili/6502">Git</a></li>
+ <li><a href="https://git.sr.ht/~swisschili/toolchain-6502">Git</a></li>
<li><a href="https://builds.sr.ht/~swisschili/6502">
<img src="https://builds.sr.ht/~swisschili/6502.svg"></a>
</li>
diff --git a/test-abs-jump.bin b/test-abs-jump.bin
new file mode 100644
index 0000000..02aff09
--- /dev/null
+++ b/test-abs-jump.bin
Binary files differ