aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--asm/ext_string_io.py47
-rw-r--r--asm/text_mode.atk1659
-rw-r--r--digital/atk16_mem.dig12
-rw-r--r--src/asm_pass0.py5
-rw-r--r--src/asm_pass1.py3
-rw-r--r--src/charmem.py2
-rw-r--r--src/tokenizer.py32
7 files changed, 100 insertions, 60 deletions
diff --git a/asm/ext_string_io.py b/asm/ext_string_io.py
new file mode 100644
index 0000000..cf7d598
--- /dev/null
+++ b/asm/ext_string_io.py
@@ -0,0 +1,47 @@
+from asm_ops import *
+from ext_std import expand_addi
+
+def to_char_code(c: str):
+ if c == " " or c == "%SPACE": return 0
+ else: return ord(c) - 64
+
+_counter = 0
+def get_unique_name(prefix: str):
+ global _counter
+ ret = f"{prefix}_{_counter}"
+ _counter += 1
+ return ret
+
+def expand_put_char(cursor_reg: str, scratch_reg: str, c: str) -> ExpandResult:
+ return [
+ ["ldi", str(to_char_code(c)), scratch_reg],
+ ["str", scratch_reg, cursor_reg],
+ *expand_addi("RA", "1", "RA"),
+ ]
+
+def expand_put_string(cursor_reg: str, scratch_reg: str, *rest: str) -> ExpandResult:
+ string = " ".join(rest)
+ result: ExpandResult = []
+ for c in string:
+ result += expand_put_char(cursor_reg, scratch_reg, c)
+
+ return result
+
+def expand_cursor_to_line(cursor_reg: str, line: int) -> ExpandResult:
+ lbl_data = get_unique_name("cursor_to_line_data")
+ lbl_jmpover = get_unique_name("cursor_to_line_jmpover")
+ line_width = 64
+ return [
+ ["jpi", lbl_jmpover],
+ ["@label", lbl_data],
+ [f"text_mem + {line} * {line_width}"],
+ ["@label", lbl_jmpover],
+ ["ldi", lbl_data, cursor_reg],
+ ["ldr", cursor_reg, cursor_reg],
+ ]
+
+expansions: OpExpansionDict = {
+ "put_char": expand_put_char,
+ "cursor_to_line": expand_cursor_to_line,
+ "put_string": expand_put_string,
+} \ No newline at end of file
diff --git a/asm/text_mode.atk16 b/asm/text_mode.atk16
index ff84156..f4d84ae 100644
--- a/asm/text_mode.atk16
+++ b/asm/text_mode.atk16
@@ -1,61 +1,19 @@
@opt stack_pointer RF
@opt csr_scratch RH
@use ext_std:*
+@use ext_string_io:*
; bootstrap code (must be called to set up mandatory data)
; will jump to label main
@include bootstrap
@label main
- ldi vt_text_mem RA
- ldr RA RA
- ldi 8 RB ; letter H
- str RB RA
- addi RA 1 RA
- ldi 5 RB ; letter E
- str RB RA
- addi RA 1 RA
- ldi 12 RB ; letter L
- str RB RA
- addi RA 1 RA
- ldi 12 RB ; letter L
- str RB RA
- addi RA 1 RA
- ldi 15 RB ; letter O
- str RB RA
- addi RA 1 RA
- ldi 0 RB ; space
- str RB RA
- addi RA 1 RA
- ldi 3 RB ; letter C
- str RB RA
- addi RA 1 RA
- ldi 15 RB ; letter O
- str RB RA
- addi RA 1 RA
- ldi 18 RB ; letter R
- str RB RA
- addi RA 1 RA
- ldi 5 RB ; letter E
- str RB RA
- addi RA 1 RA
- ldi 3 RB ; letter C
- str RB RA
- addi RA 1 RA
- ldi 1 RB ; letter A
- str RB RA
- addi RA 1 RA
- ldi 13 RB ; letter M
- str RB RA
- addi RA 1 RA
- ldi 16 RB ; letter P
- str RB RA
- ldi offset RC
- ldr RC RC
- add RA RC RA
- ; ldi 20 RB ; letter A
- ; str RB RA
- ; addi RA 1 RA
+ cursor_to_line RA 1
+ put_char RA RB %SPACE
+ put_string RA RB HELLO CORECAMP
+ cursor_to_line RA 3
+ put_char RA RB %SPACE
+ put_string RA RB BY JAN
; set graphics mode to sprite mode
; set_graphics_mode gr_sprite_mode
@@ -63,6 +21,3 @@
@label loop
jpi loop
-
-@label offset
- 51
diff --git a/digital/atk16_mem.dig b/digital/atk16_mem.dig
index c3663e3..31fe276 100644
--- a/digital/atk16_mem.dig
+++ b/digital/atk16_mem.dig
@@ -37,11 +37,13 @@
<string>Data</string>
<data>4014,2a00,6029,13*8000,1c,1a,1a,1a,8000,e000,e001,e002,e800,f800
,4855,f000,3140,1b48,3148,1b48,4016,2000,2000,4215,2240,3040,1800
-,3148,1b48,3140,1b48,e000,4017,2000,4200,3008,6000,4019,2000,4208
-,3008,1008,4205,3008,1008,420c,3008,1008,420c,3008,1008,420f,3008
-,1008,4200,3008,1008,4203,3008,1008,420f,3008,1008,4212,3008,1008
-,4205,3008,1008,4203,3008,1008,4201,3008,1008,420d,3008,1008,4210
-,3008,4464,2480,10,4017,2000,4201,3008,61ff,33</data>
+,3148,1b48,3140,1b48,e000,4017,2000,4200,3008,6000,6001,f840,4032
+,2000,4200,3008,1008,4208,3008,1008,4205,3008,1008,420c,3008,1008
+,420c,3008,1008,420f,3008,1008,4200,3008,1008,4203,3008,1008,420f
+,3008,1008,4212,3008,1008,4205,3008,1008,4203,3008,1008,4201,3008
+,1008,420d,3008,1008,4210,3008,1008,6001,f8c0,4063,2000,4200,3008
+,1008,4202,3008,1008,4219,3008,1008,4200,3008,1008,420a,3008,1008
+,4201,3008,1008,420e,3008,1008,4017,2000,4201,3008,61ff</data>
</entry>
</elementAttributes>
<pos x="740" y="100"/>
diff --git a/src/asm_pass0.py b/src/asm_pass0.py
index 4913e4b..f5b6b0b 100644
--- a/src/asm_pass0.py
+++ b/src/asm_pass0.py
@@ -2,6 +2,7 @@ from dataclasses import dataclass
import os.path
from asm_ops import *
from asm_eval import *
+from tokenizer import *
@dataclass
class Result0Line:
@@ -19,7 +20,9 @@ def pass_0(lines: list[str], file_name: str) -> Result0:
for (line_num, line) in enumerate(lines):
line = line.split(";")[0].strip()
if line == "": continue
- keyword, *args = line.lower().split()
+
+ keyword, *args = tokenize(line)
+
match keyword:
case "@include":
asm_file_name = args[0]
diff --git a/src/asm_pass1.py b/src/asm_pass1.py
index d462526..5e6213a 100644
--- a/src/asm_pass1.py
+++ b/src/asm_pass1.py
@@ -5,6 +5,7 @@ from dataclasses import dataclass
from asm_ops import *
from asm_eval import *
from asm_pass0 import *
+from tokenizer import tokenize
@dataclass
class Result1Line:
@@ -24,7 +25,7 @@ def pass_1(result0: Result0) -> Result1:
operations: OpExpansionDict = default_expansions.copy()
for line in result0.lines:
- keyword, *args = line.line.lower().split()
+ keyword, *args = tokenize(line.line)
match keyword:
case "@opt":
opt_name, opt_value = args
diff --git a/src/charmem.py b/src/charmem.py
index 9b19864..551ba85 100644
--- a/src/charmem.py
+++ b/src/charmem.py
@@ -43,7 +43,7 @@ def string_to_byte(input_string: str):
# Check if the string contains only '0' or '1'
if not all(c in '01' for c in binary_string):
- raise ValueError("Input string must contain only spaces and '#' characters.")
+ raise ValueError("Input string must contain only spaces and '█' characters.")
# Convert the binary string to an unsigned integer byte
return int(binary_string[::-1], 2)
diff --git a/src/tokenizer.py b/src/tokenizer.py
new file mode 100644
index 0000000..2049461
--- /dev/null
+++ b/src/tokenizer.py
@@ -0,0 +1,32 @@
+def tokenize(line: str) -> list[str]:
+ cur: str = ""
+ result: list[str] = []
+ is_py_expr = False
+ idx = 0
+ while idx < len(line):
+ c = line[idx]
+ if not is_py_expr and c == "$":
+ is_py_expr = True
+ idx += 1
+ elif is_py_expr and c == "$":
+ raise Exception("Unexpected start of python expr while already parsing a python expression:\n" + line)
+ elif not is_py_expr and c == "}":
+ raise Exception("Unexpected end of python expr while not parsing a python expression:\n" + line)
+ elif is_py_expr and c == "}":
+ is_py_expr = False
+ result.append(cur)
+ cur = ""
+ elif is_py_expr:
+ cur += c
+ elif c == " " or c == "\t":
+ result.append(cur)
+ cur = ""
+ else:
+ cur += c
+
+ idx += 1
+
+ if len(cur) > 0:
+ result.append(cur)
+
+ return [r for r in result if r != ""] \ No newline at end of file