aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Tuomi <jans.tuomi@gmail.com>2023-04-11 14:05:41 +0300
committerJan Tuomi <jans.tuomi@gmail.com>2023-04-11 14:05:41 +0300
commitda14e7ca7f31cb4b9a975dbe349fb4d385592b9c (patch)
treeea60a83ccb64af33a48f13839e6145b7c97236d2 /src
parent9a6001ad380e83a545188b58145387593b117b48 (diff)
Fix bugs
Diffstat (limited to 'src')
-rw-r--r--src/asm_pass2.py8
-rw-r--r--src/asm_pass3.py2
-rw-r--r--src/asm_pass4.py6
-rwxr-xr-xsrc/assembler.py5
-rw-r--r--src/assembler_eval.py24
-rw-r--r--src/assembler_ops.py16
-rw-r--r--src/ext_std.py19
-rw-r--r--src/test.atk162
-rw-r--r--src/test_fibo.atk1672
-rwxr-xr-xsrc/ucode.py8
10 files changed, 103 insertions, 59 deletions
diff --git a/src/asm_pass2.py b/src/asm_pass2.py
index 77b8fa6..261ba06 100644
--- a/src/asm_pass2.py
+++ b/src/asm_pass2.py
@@ -7,6 +7,7 @@ from asm_pass1 import *
class Result2Line:
line_num: int
parts: list[str]
+ original_parts: list[str]
@dataclass
class Result2:
@@ -20,16 +21,17 @@ def pass_2(result1: Result1) -> Result2:
for line in result1.lines:
keyword, *args = line.parts
- if not keyword.startswith("@"):
+ if keyword in result1.operations:
fn = result1.operations[keyword]
output: list[list[str]] = fn(*args)
else:
output = [line.parts]
- for parts in output:
+ for (idx, parts) in enumerate(output):
result_lines.append(Result2Line(
line_num=line.line_num,
- parts=parts
+ parts=parts,
+ original_parts=line.parts if idx == 0 else ["..."]
))
return Result2(
diff --git a/src/asm_pass3.py b/src/asm_pass3.py
index 5365e3b..e8e44d3 100644
--- a/src/asm_pass3.py
+++ b/src/asm_pass3.py
@@ -8,6 +8,7 @@ class Result3Line:
line_num: int
address: int
parts: list[str]
+ original_parts: list[str]
@dataclass
class Result3:
@@ -35,6 +36,7 @@ def pass_3(result2: Result2) -> Result3:
line_num=line.line_num,
parts=line.parts,
address=address,
+ original_parts=line.original_parts,
))
address += 1
diff --git a/src/asm_pass4.py b/src/asm_pass4.py
index 96d9e65..926b354 100644
--- a/src/asm_pass4.py
+++ b/src/asm_pass4.py
@@ -9,6 +9,7 @@ class Result4Line:
address: int
word: int
text: str
+ original_text: str
@dataclass
class Result4:
@@ -35,6 +36,7 @@ def pass_4(result3: Result3) -> Result4:
args = list(map(lambda a: translate_opt(a, result3.options), args))
text = " ".join([keyword, *args])
+ original_text = " ".join(line.original_parts)
if keyword in operations:
fn = operations[keyword]
@@ -44,6 +46,7 @@ def pass_4(result3: Result3) -> Result4:
address=line.address,
word=word,
text=text,
+ original_text=original_text,
))
else:
try:
@@ -52,10 +55,13 @@ def pass_4(result3: Result3) -> Result4:
address=line.address,
word=eval_expr(result3.labels, keyword),
text=text,
+ original_text=original_text,
))
except:
raise Exception(f"Invalid assembly at {line.line_num + 1}\n\n{line}")
+ address += 1
+
return Result4(
operations=result3.operations,
labels=result3.labels,
diff --git a/src/assembler.py b/src/assembler.py
index fc7bc45..4e82deb 100755
--- a/src/assembler.py
+++ b/src/assembler.py
@@ -67,7 +67,10 @@ for line in result4.lines:
if len(result) < 2 * line.address + 1:
result.extend((2 * line.address + 1 - len(result)) * nop)
- print(f"{line.address:>08x} 0x{line.word:>04x} {line.text}")
+ out_line = f"{line.address:>08x} 0x{line.word:>04x} {line.text}"
+ out_spaces_n = (42 - len(out_line))
+ out_spaces = out_spaces_n * " " if out_spaces_n > 0 else 4 * " "
+ print(f"{out_line}{out_spaces}{line.original_text}")
result[2 * line.address + 0] = ((line.word >> 8) & 0xff)
result[2 * line.address + 1] = ((line.word >> 0) & 0xff)
diff --git a/src/assembler_eval.py b/src/assembler_eval.py
index 7cfe336..691e4eb 100644
--- a/src/assembler_eval.py
+++ b/src/assembler_eval.py
@@ -1,13 +1,13 @@
constants: dict[str, str] = {
# Registers
- "rz": "0",
- "ra": "1",
- "rb": "2",
- "rc": "3",
- "rd": "4",
- "re": "5",
- "rf": "6",
- "rg": "7",
+ "ra": "0",
+ "rb": "1",
+ "rc": "2",
+ "rd": "3",
+ "re": "4",
+ "rf": "5",
+ "rg": "6",
+ "rh": "7",
# ALU instructions
"al_plus": "0",
"al_minus": "1",
@@ -18,10 +18,10 @@ constants: dict[str, str] = {
"al_sar": "6",
"al_sll": "7",
# ALU flags
- "f_carry": "0",
- "f_overflow": "1",
- "f_zero": "2",
- "f_sign": "3",
+ "carry": "0",
+ "overflow": "1",
+ "zero": "2",
+ "sign": "3",
}
Labels = dict[str, int]
diff --git a/src/assembler_ops.py b/src/assembler_ops.py
index e4eeac4..b55927b 100644
--- a/src/assembler_ops.py
+++ b/src/assembler_ops.py
@@ -4,8 +4,8 @@ from dataclasses import dataclass
@dataclass
class Options:
- stack_pointer = "rg"
- csr_scratch = "rf"
+ stack_pointer = "rf"
+ csr_scratch = "rh"
@dataclass
class Meta:
@@ -37,7 +37,7 @@ def make_ali(meta: Meta, labels: Labels, alu_op: str, left: str, imm: str, targe
alu_op_e
return word
-def make_ldr(meta: Meta, labels: Labels, to_reg: str, addr_reg: str) -> int:
+def make_ldr(meta: Meta, labels: Labels, addr_reg: str, to_reg: str) -> int:
"""LDR 0010 TTTR RRXX XXXX"""
to_reg_e = eval_expr(labels, to_reg, bits=3)
addr_reg_e = eval_expr(labels, addr_reg, bits=3)
@@ -47,15 +47,15 @@ def make_ldr(meta: Meta, labels: Labels, to_reg: str, addr_reg: str) -> int:
return word
def make_str(meta: Meta, labels: Labels, from_reg: str, addr_reg: str) -> int:
- """STR 0011 TTTR RRXX XXXX"""
+ """STR 0011 XXXL LLRR RXXX"""
from_reg_e = eval_expr(labels, from_reg, bits=3)
addr_reg_e = eval_expr(labels, addr_reg, bits=3)
word = (0b0011 << 12) + \
- (from_reg_e << 9) + \
- (addr_reg_e << 6)
+ (addr_reg_e << 6) + \
+ (from_reg_e << 3)
return word
-def make_ldi(meta: Meta, labels: Labels, to_reg: str, imm: str) -> int:
+def make_ldi(meta: Meta, labels: Labels, imm: str, to_reg: str) -> int:
"""LDI 0100 TTTI IIII IIII"""
to_reg_e = eval_expr(labels, to_reg, bits=3)
imm_e = eval_expr(labels, imm, bits=9)
@@ -75,6 +75,7 @@ def make_jpi(meta: Meta, labels: Labels, imm: str) -> int:
"""JPI 0110 XXXI IIII IIII"""
imm_e = eval_expr(labels, imm, bits=9)
imm_e = imm_e - meta.address - 1
+ imm_e = imm_e & (0b111111111)
word = (0b0110 << 12) + \
imm_e
return word
@@ -93,6 +94,7 @@ def make_bri(meta: Meta, labels: Labels, flag_s: str, imm: str) -> int:
flag_s_e = eval_expr(labels, flag_s, bits=2)
imm_e = eval_expr(labels, imm, bits=9)
imm_e = imm_e - meta.address - 1
+ imm_e = imm_e & (0b111111111)
word = (0b1000 << 12) + \
(flag_s_e << 9) + \
imm_e
diff --git a/src/ext_std.py b/src/ext_std.py
index a6b175a..5f41f60 100644
--- a/src/ext_std.py
+++ b/src/ext_std.py
@@ -52,16 +52,25 @@ def expand_spu(reg: str) -> ExpandResult:
return [["str", reg, "__STACK_POINTER"]] + expand_inc("__STACK_POINTER")
def expand_spo(reg: str):
- return expand_dec("__STACK_POINTER") + [["ldr", reg, "__STACK_POINTER"]]
+ return expand_dec("__STACK_POINTER") + [["ldr", "__STACK_POINTER", reg]]
def expand_csr(addr_reg: str):
- return [["lpc", "__STACK_POINTER"]] + expand_spu("__STACK_POINTER") + [["jpr", addr_reg]]
+ return [
+ ["lpc", "__CSR_SCRATCH"],
+ *expand_addi("__CSR_SCRATCH", "4", "__CSR_SCRATCH"),
+ *expand_spu("__CSR_SCRATCH"),
+ ["jpr", addr_reg]
+ ]
def expand_csi(addr_imm: str):
- return [["lpc", "__STACK_POINTER"]] + expand_spu("__STACK_POINTER") + [["jpr", addr_imm]]
-
+ return [
+ ["lpc", "__CSR_SCRATCH"],
+ *expand_addi("__CSR_SCRATCH", "4", "__CSR_SCRATCH"),
+ *expand_spu("__CSR_SCRATCH"),
+ ["jpi", addr_imm]
+ ]
def expand_rsr():
- return expand_spo("__STACK_POINTER") + [["jpr", "__CSR_SCRATCH"]]
+ return expand_spo("__CSR_SCRATCH") + [["jpr", "__CSR_SCRATCH"]]
expansions: OpExpansionDict = {
"add": expand_add,
diff --git a/src/test.atk16 b/src/test.atk16
index 8e48892..3f2d378 100644
--- a/src/test.atk16
+++ b/src/test.atk16
@@ -22,7 +22,7 @@
mov RC RA ; RA := result of sum
ldi RB 30 ; RB := 30
sub RA RB RC ; RC := RA - RB
- bri f_zero @success ; if result is zero, jump to success
+ bri zero @success ; if result is zero, jump to success
ldi RA 2 ; RA := 2 to signal failure
hlt
diff --git a/src/test_fibo.atk16 b/src/test_fibo.atk16
index a03f14b..8bb7a6e 100644
--- a/src/test_fibo.atk16
+++ b/src/test_fibo.atk16
@@ -1,46 +1,66 @@
-@opt stack_pointer RG
-@opt csr_scratch RF
-
+@opt stack_pointer RF
+@opt csr_scratch RH
@use ext_std:*
+; jump over data segment
+ jpi program
+
+; data segment
+@label ram_offset
+ 0x8000
+
@label program
- ; call fibo subroutine with parameter 10
- ldi RA 10
+; set up stack pointer to point to beginning of RAM
+ ldi ram_offset RA
+ ldr RA RF
+
+; call fibo subroutine with parameter 10
+ ldi 10 RA
csi fibo
hlt
@label fibo
- ; function fibo
- ; parameters:
- ; RA n : u16
- ; return value:
- ; RA fibo(n) : u16
+; function fibo
+; parameters:
+; RA n : u16
+; return value:
+; RA fibo(n) : u16
- spu RB ; prelude
+; store RB, RC on stack
+ spu RB
spu RC
-
- subi RA 2 RA ; if n < 2, return n
- bri f_sign fibo_early
-
- spu RD ; prelude
-
- ldi RB 0 ; a = 0
- ldi RC 1 ; b = 1
+; if n < 2, return n
+ subi RA 2 RA
+ bri sign fibo_early
+; store also RD on stack
+ spu RD
+; a = 0
+ ldi 0 RB
+; b = 1
+ ldi 1 RC
@label fibo_loop
- add RB RC RD ; v = a + b
- mov RC RB ; a = b
- mov RD RC ; b = v
- dec RA ; n -= 1
- bri f_zero fibo_done ; loop while n > 0
+; v = a + b
+ add RB RC RD
+; a = b
+ mov RC RB
+; b = v
+ mov RD RC
+; n -= 1
+ dec RA
+; loop while n > 0
+ bri zero fibo_done
jpi fibo_loop
-
@label fibo_early
+; restore used registers
spo RC
spo RB
+; return from subroutine
rsr
@label fibo_done
mov RD RA
- spo RD ; restore registers
+; restore used registers
+ spo RD
spo RC
spo RB
+; return from subroutine
rsr
diff --git a/src/ucode.py b/src/ucode.py
index 9745a7e..1d050c8 100755
--- a/src/ucode.py
+++ b/src/ucode.py
@@ -20,9 +20,9 @@ MEM_IE = 0b0000_0000_0001_0000
MEM_OE = 0b0000_0000_0010_0000
RW_IE = 0b0000_0000_0100_0000
R1_OE = 0b0000_0000_1000_0000
-IM_M = 0b0000_0001_0000_0000
+R2_OE = 0b0000_0001_0000_0000
IR_IE = 0b0000_0010_0000_0000
-unused = 0b0000_0100_0000_0000
+IM_M = 0b0000_0100_0000_0000
LI_OE = 0b0000_1000_0000_0000
ALU_OE = 0b0001_0000_0000_0000
FR_IE = 0b0010_0000_0000_0000
@@ -51,8 +51,8 @@ ucode = [
not_branch([*fetch, IM_M|ALU_OE|FR_IE|RW_IE, US_RS, 0, 0, 0, 0]),
# LDR 0010 TTTR RRXX XXXX
not_branch([*fetch, R1_OE|MAR_IE, MEM_OE|RW_IE, US_RS, 0, 0, 0]),
- # STR 0011 TTTR RRXX XXXX
- not_branch([*fetch, R1_OE|MAR_IE, R1_OE|MEM_IE, US_RS, 0, 0, 0]),
+ # STR 0011 XXXL LLRR RXXX
+ not_branch([*fetch, R1_OE|MAR_IE, R2_OE|MEM_IE, US_RS, 0, 0, 0]),
# LDI 0100 TTTI IIII IIII
not_branch([*fetch, LI_OE|RW_IE, US_RS, 0, 0, 0, 0]),
# JPR 0101 XXXR RRXX XXXX