summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTest_User <hax@andrewyu.org>2023-06-09 20:16:53 -0400
committerTest_User <hax@andrewyu.org>2023-06-09 20:16:53 -0400
commit112cab89fca082b1d77b0682f2bd41794370b3e1 (patch)
tree4b200981f8f5be8cebdf06efe0cf8783c1d2e44b
downloaddevelopment-112cab89fca082b1d77b0682f2bd41794370b3e1.tar.gz
development-112cab89fca082b1d77b0682f2bd41794370b3e1.zip
Start making an assembler for this; using python for the intial version
-rwxr-xr-xassembler/hasm.py43
-rw-r--r--assembler/syntax.txt36
2 files changed, 79 insertions, 0 deletions
diff --git a/assembler/hasm.py b/assembler/hasm.py
new file mode 100755
index 0000000..2eb5fc7
--- /dev/null
+++ b/assembler/hasm.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+import glob
+
+datadir = os.path.abspath(os.path.dirname(__file__)+"/../cpu")
+
+paths = glob.glob(datadir+"/instructions/*/*")
+
+paths.sort()
+
+instructions = {}
+
+num_instructions = 0
+for file in paths:
+ if os.path.isfile(file) and not os.path.basename(file).endswith("notes.txt"):
+ name = os.path.splitext(os.path.basename(file))[0]
+ try:
+ _ = instructions[name]
+ raise Exception("Instruction name conflict")
+ except KeyError:
+ pass
+ instructions[name] = {"path": file, "id": num_instructions}
+ num_instructions += 1
+
+for ins in instructions:
+ info = instructions[ins]
+ f = open(info["path"], "r")
+ line = f.readline()
+ f.close()
+
+ header, num = line.rsplit(maxsplit=1)
+ if header != "Number of parameters:":
+ print("Unable to read file "+info["path"]+": does not look like an instruction. ignoring...")
+
+ if type(int(num)) != int:
+ raise Exception("Invalid number: "+num)
+
+ info["params"] = int(num)
+
+print(instructions)
+print(num_instructions)
diff --git a/assembler/syntax.txt b/assembler/syntax.txt
new file mode 100644
index 0000000..a3bfc9a
--- /dev/null
+++ b/assembler/syntax.txt
@@ -0,0 +1,36 @@
+TODO: possibly simplify this to make it less of a pain to write
+
+Leading and trailing whitespace is ignored
+Comments start with ; and must not be inside "", '', or ``
+\ is used for escaping; only applies to ", ', `, and itself when outside of quotations
+
+Data-at-address is indicated by [value], where value is anything valid to be used as an indirect reference
+
+Size of operand is specified by a {number} preceeding its reference, and number is to be specified as the size in bytes
+
+Format for each instruction is <instruction> <param0>, ...
+ Whitespace here can be any amount of either spaces or tabs
+ Commas seperating parameters is optional
+
+Instruction queues are surrounded by { and }:
+{
+ add a, b, c
+ add b, a, c
+}
+
+{ and } must be on their own in the line (aside for whitespace and comments)
+
+Labels are any combination of non-whitespace from the start of the line to a ':', and not followed by any non-comment non-whitespace
+Labels must not be declared inside instruction queues
+If a label includes { or }, it must start with {, then a number, then }, to be used as its default size; all other uses of these characters are invalid
+
+Using the value of the label in a parameter will be '<name of label>:' as the operand, like so:
+ add a, my_data:, b
+ jmp {8}[my_data:]
+
+Constants will have a default size of the minimum amount required to represent it in full, as will labels without a default size explicitly set
+
+The "declare" keyword is to be used like an instruction, but not within an instruction queue
+ It will place the following constant's or label's data into the binary output, for an unlimited number of parameters
+ You may use "<data>" to place the literal value of its contents in the output; \ will only apply to " and itself when within these quotes
+ You may use `<data>` to place an evaluated string into the output; for example \n will be translated into a newline