From f1de771d882ae3848b500b6f558f7307b740b3cd Mon Sep 17 00:00:00 2001
From: ryo <ryo@nopwd.lol>
Date: Mon, 30 Dec 2024 16:15:09 +0000
Subject: Initial commit

---
 demos/add.asm  | 11 +++++++
 demos/inp.asm  |  9 ++++++
 demos/test.asm | 22 ++++++++++++++
 mmasm.py       | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 132 insertions(+)
 create mode 100644 demos/add.asm
 create mode 100644 demos/inp.asm
 create mode 100644 demos/test.asm
 create mode 100644 mmasm.py

diff --git a/demos/add.asm b/demos/add.asm
new file mode 100644
index 0000000..0185625
--- /dev/null
+++ b/demos/add.asm
@@ -0,0 +1,11 @@
+	ORG 30
+	LDA X I
+	ADD Y	/simple comment
+	STA S	/ another one
+	HLT
+
+X,	HEX 1A
+Y,	DEC -23
+S,	DEC 0
+
+	END
diff --git a/demos/inp.asm b/demos/inp.asm
new file mode 100644
index 0000000..bdec386
--- /dev/null
+++ b/demos/inp.asm
@@ -0,0 +1,9 @@
+        ORG 12
+LINP,   SKI         / check input flag
+        BUN LINP
+        inp
+        OUT         /output character
+        sta CHR i
+        HLT
+CHR,
+        HEX B42
diff --git a/demos/test.asm b/demos/test.asm
new file mode 100644
index 0000000..2b03cc2
--- /dev/null
+++ b/demos/test.asm
@@ -0,0 +1,22 @@
+		org 38
+
+		lda num1 i
+lop,	add num2		/ add in loop
+		isz ctr
+		bun lop
+		sta sum			/ save ac to sum
+
+		hlt
+
+ctr,	dec -5
+num1,	hex a1
+sum,	hex 0
+
+num2,	dec 21
+		org 9f
+		hex c4b5
+		dec -70
+		hex 43
+		hex d89a
+
+		end
diff --git a/mmasm.py b/mmasm.py
new file mode 100644
index 0000000..973aafa
--- /dev/null
+++ b/mmasm.py
@@ -0,0 +1,90 @@
+import sys
+
+if len(sys.argv) != 2:
+	print("no source file")
+	sys.exit(1)
+
+lines = []
+with open(sys.argv[1], 'r') as file:
+	lines = file.readlines()
+
+opcodes = {
+	"AND": 0, "ADD": 1, "LDA": 2, "STA": 3, "BUN": 4, "BSA": 5, "ISZ": 6,
+	"CLA": 0x7800, "CLE": 0x7400, "CMA": 0x7200, "CME": 0x7100, "CIR": 0x7080,
+	"CIL": 0x7040, "INC": 0x7020, "SPA": 0x7010, "SNA": 0x7008, "SZA": 0x7004,
+	"SZE": 0x7002, "HLT": 0x7001, "INP": 0xF800, "OUT": 0xF400, "SKI": 0xF200,
+	"SKO": 0xF100, "ION": 0xF080, "IOF": 0xF040
+}
+labels = {}
+
+# collect all labels in the file
+lc = 0
+for i, line in enumerate(lines):
+	comment_index = line.find('/')
+	if (comment_index != -1):
+		line = line[:comment_index]
+		lines[i] = lines[i][:comment_index]
+
+	parts = line.split()
+
+	if (len(parts) == 0):
+		continue
+
+	if (parts[0][-1] == ','):
+		labels[parts[0][:-1]] = lc
+		k = line.find(',')
+		lines[i] = lines[i][k+1:]
+
+	lines[i] = lines[i].strip()
+
+	if (parts[0].upper() == "ORG"):
+		lc = int(parts[1], 16)
+		continue
+
+	lc += 1
+
+print(labels)
+# print hex equivalent line by line
+lc = 0
+for line in lines:
+	parts = line.split()
+	n = len(parts)
+	if (n == 0): continue
+	ins = -1
+
+	parts[0] = parts[0].upper()
+	match parts[0]:
+		case "ORG":
+			lc = int(parts[1], 16)
+			continue
+		case "HEX":
+			ins = int(parts[1], 16)
+			n = 0
+		case "DEC":
+			ins = int(parts[1])
+			n = 0
+		case "END":
+			break
+
+	if n > 0:
+		if parts[0] not in opcodes:
+			print(f"line {lines.index(line)}: {line}")
+			print("error: wrong mnemonic")
+			break;
+		ins = opcodes[parts[0]]
+	if n > 2:
+		parts[2] = parts[2].upper()
+		if parts[2] == 'I': ins += 8;
+	if n > 1:
+		if parts[1] not in labels:
+			print(f"line {lines.index(line)}: {line}")
+			print("error: label not found")
+			break;
+		ins = ins << 12
+		ins = ins | labels[parts[1]]
+
+	if ins != -1:
+		print(f"{lc:03x}: {ins & 0xffff:04x}")
+
+	lc += 1
+
-- 
cgit v1.2.3