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