aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Tuomi <jans.tuomi@gmail.com>2023-04-13 14:48:34 +0300
committerJan Tuomi <jans.tuomi@gmail.com>2023-04-13 14:49:59 +0300
commit9d4c6fc299294ac36f7082599edce19286fa0f99 (patch)
treee7601bb1cd9950482f125377d25b6d5d40b72e62
parentafd5f32e56d3d30bfa98fb35deff51febf50e594 (diff)
Add @let directive, start pondering interrupt control
-rw-r--r--asm/bootstrap.atk1623
-rw-r--r--asm/ext_std.py4
-rw-r--r--asm/fibo.atk1614
-rw-r--r--asm/ram_offset.atk162
-rw-r--r--atk16-syntax/atk16-syntax-0.0.1.vsixbin4383 -> 4351 bytes
-rw-r--r--atk16-syntax/extension.js16
-rw-r--r--atk16-syntax/package.json2
-rw-r--r--atk16-syntax/syntaxes/atk16.tmLanguage.json20
-rw-r--r--digital/atk16.dig203
-rw-r--r--digital/atk16_irc.dig341
-rw-r--r--digital/atk16_mem.dig8
-rw-r--r--src/asm_eval.py16
-rw-r--r--src/asm_ops.py66
-rw-r--r--src/asm_pass0.py21
-rw-r--r--src/asm_pass3.py20
-rw-r--r--src/asm_pass4.py13
-rwxr-xr-xsrc/assembler.py6
17 files changed, 617 insertions, 158 deletions
diff --git a/asm/bootstrap.atk16 b/asm/bootstrap.atk16
new file mode 100644
index 0000000..c7ab63e
--- /dev/null
+++ b/asm/bootstrap.atk16
@@ -0,0 +1,23 @@
+@let stack_segment 0x8000
+@let vector_table 0x10
+
+@address vector_table
+ hlt_isr ; 0x10 ISR0
+ hlt_isr ; 0x11 ISR1
+ hlt_isr ; 0x12 ISR2
+ hlt_isr ; 0x13 ISR3
+ stack_segment ; 0x14 Stack address
+
+@label hlt_isr
+ ldi 0x55 RA
+ hlt
+@label program_segment
+
+@address 0x0
+; set up stack pointer to point to beginning of stack segment
+ ldi 0x14 RA
+ ldr RA RF
+ jpi main
+
+@address program_segment
+; set up address for program code
diff --git a/asm/ext_std.py b/asm/ext_std.py
index 11da8aa..de7cd43 100644
--- a/asm/ext_std.py
+++ b/asm/ext_std.py
@@ -48,6 +48,9 @@ def expand_dec(reg: str) -> ExpandResult:
def expand_mov(from_reg: str, to_reg: str) -> ExpandResult:
return [["ali", "al_plus", from_reg, "0", to_reg]]
+def expand_nop() -> ExpandResult:
+ return [["ali", "al_plus", "RA", "0", "RA"]]
+
def expand_spu(reg: str) -> ExpandResult:
return [["str", reg, "__STACK_POINTER"]] + expand_inc("__STACK_POINTER")
@@ -89,6 +92,7 @@ expansions: OpExpansionDict = {
"inc": expand_inc,
"dec": expand_dec,
"mov": expand_mov,
+ "nop": expand_nop,
"spu": expand_spu,
"spo": expand_spo,
"csr": expand_csr,
diff --git a/asm/fibo.atk16 b/asm/fibo.atk16
index cae5f5d..fb375b3 100644
--- a/asm/fibo.atk16
+++ b/asm/fibo.atk16
@@ -2,17 +2,11 @@
@opt csr_scratch RH
@use ext_std:*
-; jump over data segment
- jpi program
-
-; data segment
-@include ram_offset
-
-@label program
-; set up stack pointer to point to beginning of RAM
- ldi ram_offset_addr RA
- ldr RA RF
+; bootstrap code (must be called to setup mandatory data)
+; will jump to label main
+@include bootstrap
+@label main
; call fibo subroutine with parameter 10
ldi 10 RA
csi fibo
diff --git a/asm/ram_offset.atk16 b/asm/ram_offset.atk16
deleted file mode 100644
index e8c9255..0000000
--- a/asm/ram_offset.atk16
+++ /dev/null
@@ -1,2 +0,0 @@
-@label ram_offset_addr
- 0x8000
diff --git a/atk16-syntax/atk16-syntax-0.0.1.vsix b/atk16-syntax/atk16-syntax-0.0.1.vsix
index 342049e..253d326 100644
--- a/atk16-syntax/atk16-syntax-0.0.1.vsix
+++ b/atk16-syntax/atk16-syntax-0.0.1.vsix
Binary files differ
diff --git a/atk16-syntax/extension.js b/atk16-syntax/extension.js
index 2c8e294..26b4d9d 100644
--- a/atk16-syntax/extension.js
+++ b/atk16-syntax/extension.js
@@ -85,9 +85,9 @@ class ATK16DefinitionProvider {
}
} else {
const labelText = document.getText(range);
- let labelLocation = await findLabelInDocument(document, labelText);
- if (labelLocation) {
- return labelLocation;
+ let definitionLocation = await findDefinitionInDocument(document, labelText);
+ if (definitionLocation) {
+ return definitionLocation;
}
// Search for labels in included files
@@ -104,9 +104,9 @@ class ATK16DefinitionProvider {
const includedDocument = await vscode.workspace.openTextDocument(
includedFilePath
);
- labelLocation = await findLabelInDocument(includedDocument, labelText);
- if (labelLocation) {
- return labelLocation;
+ definitionLocation = await findDefinitionInDocument(includedDocument, labelText);
+ if (definitionLocation) {
+ return definitionLocation;
}
}
}
@@ -117,10 +117,10 @@ class ATK16DefinitionProvider {
}
}
-async function findLabelInDocument(document, labelText) {
+async function findDefinitionInDocument(document, labelText) {
for (let i = 0; i < document.lineCount; i++) {
const line = document.lineAt(i);
- if (line.text.includes(`@label ${labelText}`)) {
+ if (line.text.includes(`@label ${labelText}`) || line.text.includes(`@let ${labelText}`)) {
return new vscode.Location(document.uri, line.range.start);
}
}
diff --git a/atk16-syntax/package.json b/atk16-syntax/package.json
index 5fd48e6..6a64b6c 100644
--- a/atk16-syntax/package.json
+++ b/atk16-syntax/package.json
@@ -4,6 +4,8 @@
"description": "Syntax highlighting and support for ATK16 assembly language",
"version": "0.0.1",
"publisher": "JanTuomi",
+ "license": "MIT",
+ "repository": "",
"engines": {
"vscode": "^1.60.0"
},
diff --git a/atk16-syntax/syntaxes/atk16.tmLanguage.json b/atk16-syntax/syntaxes/atk16.tmLanguage.json
index b12f596..6dcf0ea 100644
--- a/atk16-syntax/syntaxes/atk16.tmLanguage.json
+++ b/atk16-syntax/syntaxes/atk16.tmLanguage.json
@@ -16,31 +16,23 @@
},
{
"name": "variable.other.register.atk16",
- "match": "R\\w+"
+ "match": "\\bR[A-H]\\b"
},
{
"name": "constant.numeric.hex.atk16",
- "match": "0x[0-9a-fA-F]+"
+ "match": "\\b0x[0-9a-fA-F]+\\b"
},
{
"name": "constant.numeric.binary.atk16",
- "match": "0b[01]+"
+ "match": "\\b0b[01]+\\b"
},
{
"name": "constant.numeric.decimal.atk16",
- "match": "[0-9]+"
+ "match": "\\b[0-9]+\\b"
},
{
- "name": "entity.name.function.atk16",
- "match": "\\w+(?=\\s*\\()"
- },
- {
- "name": "entity.name.label.atk16",
- "match": "\\w+(?=\\s*:)"
- },
- {
- "name": "keyword.control.instruction.atk16",
- "match": "^\\s+[a-zA-Z]+"
+ "name": "keyword.control.symbol.atk16",
+ "match": "^\\s+[a-zA-Z_-]+"
},
{
"name": "constant.language.flag.atk16",
diff --git a/digital/atk16.dig b/digital/atk16.dig
index ca4aa6d..056fbb0 100644
--- a/digital/atk16.dig
+++ b/digital/atk16.dig
@@ -104,30 +104,6 @@
<pos x="280" y="340"/>
</visualElement>
<visualElement>
- <elementName>Driver</elementName>
- <elementAttributes>
- <entry>
- <string>Bits</string>
- <int>16</int>
- </entry>
- </elementAttributes>
- <pos x="140" y="-240"/>
- </visualElement>
- <visualElement>
- <elementName>Tunnel</elementName>
- <elementAttributes>
- <entry>
- <string>rotation</string>
- <rotation rotation="1"/>
- </entry>
- <entry>
- <string>NetName</string>
- <string>PC_OE</string>
- </entry>
- </elementAttributes>
- <pos x="140" y="-260"/>
- </visualElement>
- <visualElement>
<elementName>Tunnel</elementName>
<elementAttributes>
<entry>
@@ -258,7 +234,7 @@
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation reference="../../../../visualElement[14]/elementAttributes/entry/rotation"/>
+ <rotation reference="../../../../visualElement[12]/elementAttributes/entry/rotation"/>
</entry>
</elementAttributes>
<pos x="0" y="-180"/>
@@ -320,16 +296,6 @@
<pos x="280" y="300"/>
</visualElement>
<visualElement>
- <elementName>Probe</elementName>
- <elementAttributes>
- <entry>
- <string>Label</string>
- <string>Bus</string>
- </entry>
- </elementAttributes>
- <pos x="200" y="-280"/>
- </visualElement>
- <visualElement>
<elementName>atk16_mem.dig</elementName>
<elementAttributes/>
<pos x="580" y="-220"/>
@@ -993,7 +959,7 @@ program(0x4051, 0x40a2, 0x029b)
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation reference="../../../../visualElement[77]/elementAttributes/entry/rotation"/>
+ <rotation reference="../../../../visualElement[74]/elementAttributes/entry/rotation"/>
</entry>
</elementAttributes>
<pos x="740" y="740"/>
@@ -1031,6 +997,103 @@ program(0x4051, 0x40a2, 0x029b)
<elementAttributes/>
<pos x="680" y="-380"/>
</visualElement>
+ <visualElement>
+ <elementName>atk16_irc.dig</elementName>
+ <elementAttributes/>
+ <pos x="160" y="-280"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Probe</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Label</string>
+ <string>Bus</string>
+ </entry>
+ </elementAttributes>
+ <pos x="320" y="-320"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Tunnel</elementName>
+ <elementAttributes>
+ <entry>
+ <string>rotation</string>
+ <rotation rotation="2"/>
+ </entry>
+ <entry>
+ <string>NetName</string>
+ <string>PC_OE</string>
+ </entry>
+ </elementAttributes>
+ <pos x="160" y="-200"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Tunnel</elementName>
+ <elementAttributes>
+ <entry>
+ <string>rotation</string>
+ <rotation reference="../../../../visualElement[4]/elementAttributes/entry/rotation"/>
+ </entry>
+ <entry>
+ <string>NetName</string>
+ <string>MAR_IE</string>
+ </entry>
+ </elementAttributes>
+ <pos x="160" y="-220"/>
+ </visualElement>
+ <visualElement>
+ <elementName>DipSwitch</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Label</string>
+ <string>IRQ0</string>
+ </entry>
+ </elementAttributes>
+ <pos x="-160" y="-480"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Ground</elementName>
+ <elementAttributes>
+ <entry>
+ <string>rotation</string>
+ <rotation rotation="1"/>
+ </entry>
+ </elementAttributes>
+ <pos x="-180" y="-460"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Ground</elementName>
+ <elementAttributes>
+ <entry>
+ <string>rotation</string>
+ <rotation reference="../../../../visualElement[85]/elementAttributes/entry/rotation"/>
+ </entry>
+ </elementAttributes>
+ <pos x="-180" y="-440"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Ground</elementName>
+ <elementAttributes>
+ <entry>
+ <string>rotation</string>
+ <rotation reference="../../../../visualElement[85]/elementAttributes/entry/rotation"/>
+ </entry>
+ </elementAttributes>
+ <pos x="-180" y="-420"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Splitter</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Input Splitting</string>
+ <string>1*4</string>
+ </entry>
+ <entry>
+ <string>Output Splitting</string>
+ <string>4</string>
+ </entry>
+ </elementAttributes>
+ <pos x="-140" y="-480"/>
+ </visualElement>
</visualElements>
<wires>
<wire>
@@ -1070,6 +1133,10 @@ program(0x4051, 0x40a2, 0x029b)
<p2 x="20" y="-260"/>
</wire>
<wire>
+ <p1 x="100" y="-260"/>
+ <p2 x="160" y="-260"/>
+ </wire>
+ <wire>
<p1 x="40" y="260"/>
<p2 x="60" y="260"/>
</wire>
@@ -1111,6 +1178,10 @@ program(0x4051, 0x40a2, 0x029b)
</wire>
<wire>
<p1 x="200" y="-140"/>
+ <p2 x="300" y="-140"/>
+ </wire>
+ <wire>
+ <p1 x="300" y="-140"/>
<p2 x="480" y="-140"/>
</wire>
<wire>
@@ -1118,6 +1189,10 @@ program(0x4051, 0x40a2, 0x029b)
<p2 x="200" y="-140"/>
</wire>
<wire>
+ <p1 x="-180" y="-460"/>
+ <p2 x="-140" y="-460"/>
+ </wire>
+ <wire>
<p1 x="900" y="140"/>
<p2 x="920" y="140"/>
</wire>
@@ -1226,6 +1301,10 @@ program(0x4051, 0x40a2, 0x029b)
<p2 x="20" y="-280"/>
</wire>
<wire>
+ <p1 x="120" y="-280"/>
+ <p2 x="160" y="-280"/>
+ </wire>
+ <wire>
<p1 x="40" y="280"/>
<p2 x="60" y="280"/>
</wire>
@@ -1266,6 +1345,14 @@ program(0x4051, 0x40a2, 0x029b)
<p2 x="920" y="220"/>
</wire>
<wire>
+ <p1 x="-160" y="-480"/>
+ <p2 x="-140" y="-480"/>
+ </wire>
+ <wire>
+ <p1 x="-120" y="-480"/>
+ <p2 x="120" y="-480"/>
+ </wire>
+ <wire>
<p1 x="900" y="160"/>
<p2 x="920" y="160"/>
</wire>
@@ -1294,6 +1381,10 @@ program(0x4051, 0x40a2, 0x029b)
<p2 x="540" y="-100"/>
</wire>
<wire>
+ <p1 x="-180" y="-420"/>
+ <p2 x="-140" y="-420"/>
+ </wire>
+ <wire>
<p1 x="900" y="100"/>
<p2 x="920" y="100"/>
</wire>
@@ -1358,23 +1449,19 @@ program(0x4051, 0x40a2, 0x029b)
<p2 x="780" y="300"/>
</wire>
<wire>
- <p1 x="100" y="-240"/>
- <p2 x="120" y="-240"/>
- </wire>
- <wire>
<p1 x="-40" y="-240"/>
<p2 x="20" y="-240"/>
</wire>
<wire>
- <p1 x="160" y="-240"/>
- <p2 x="200" y="-240"/>
- </wire>
- <wire>
<p1 x="-280" y="-240"/>
<p2 x="-220" y="-240"/>
</wire>
<wire>
- <p1 x="200" y="-240"/>
+ <p1 x="260" y="-240"/>
+ <p2 x="300" y="-240"/>
+ </wire>
+ <wire>
+ <p1 x="300" y="-240"/>
<p2 x="400" y="-240"/>
</wire>
<wire>
@@ -1410,6 +1497,10 @@ program(0x4051, 0x40a2, 0x029b)
<p2 x="920" y="-120"/>
</wire>
<wire>
+ <p1 x="-180" y="-440"/>
+ <p2 x="-140" y="-440"/>
+ </wire>
+ <wire>
<p1 x="900" y="120"/>
<p2 x="920" y="120"/>
</wire>
@@ -1446,18 +1537,14 @@ program(0x4051, 0x40a2, 0x029b)
<p2 x="440" y="60"/>
</wire>
<wire>
- <p1 x="200" y="-280"/>
- <p2 x="200" y="-240"/>
+ <p1 x="300" y="-320"/>
+ <p2 x="320" y="-320"/>
</wire>
<wire>
<p1 x="200" y="-40"/>
<p2 x="200" y="80"/>
</wire>
<wire>
- <p1 x="200" y="-240"/>
- <p2 x="200" y="-140"/>
- </wire>
- <wire>
<p1 x="200" y="-140"/>
<p2 x="200" y="-80"/>
</wire>
@@ -1543,7 +1630,7 @@ program(0x4051, 0x40a2, 0x029b)
</wire>
<wire>
<p1 x="100" y="-280"/>
- <p2 x="100" y="-240"/>
+ <p2 x="100" y="-260"/>
</wire>
<wire>
<p1 x="40" y="280"/>
@@ -1558,6 +1645,14 @@ program(0x4051, 0x40a2, 0x029b)
<p2 x="620" y="-100"/>
</wire>
<wire>
+ <p1 x="300" y="-320"/>
+ <p2 x="300" y="-240"/>
+ </wire>
+ <wire>
+ <p1 x="300" y="-240"/>
+ <p2 x="300" y="-140"/>
+ </wire>
+ <wire>
<p1 x="-240" y="-340"/>
<p2 x="-240" y="-220"/>
</wire>
@@ -1582,6 +1677,10 @@ program(0x4051, 0x40a2, 0x029b)
<p2 x="440" y="60"/>
</wire>
<wire>
+ <p1 x="120" y="-480"/>
+ <p2 x="120" y="-280"/>
+ </wire>
+ <wire>
<p1 x="-60" y="-140"/>
<p2 x="-60" y="-80"/>
</wire>
diff --git a/digital/atk16_irc.dig b/digital/atk16_irc.dig
new file mode 100644
index 0000000..0037fa0
--- /dev/null
+++ b/digital/atk16_irc.dig
@@ -0,0 +1,341 @@
+<?xml version="1.0" encoding="utf-8"?>
+<circuit>
+ <version>2</version>
+ <attributes>
+ <entry>
+ <string>romContent</string>
+ <romList>
+ <roms/>
+ </romList>
+ </entry>
+ <entry>
+ <string>Width</string>
+ <int>5</int>
+ </entry>
+ </attributes>
+ <visualElements>
+ <visualElement>
+ <elementName>In</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Description</string>
+ <string>IRQ lines</string>
+ </entry>
+ <entry>
+ <string>Label</string>
+ <string>IRQ</string>
+ </entry>
+ <entry>
+ <string>Bits</string>
+ <int>4</int>
+ </entry>
+ </elementAttributes>
+ <pos x="140" y="480"/>
+ </visualElement>
+ <visualElement>
+ <elementName>In</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Description</string>
+ <string>PC value</string>
+ </entry>
+ <entry>
+ <string>Label</string>
+ <string>PC</string>
+ </entry>
+ <entry>
+ <string>Bits</string>
+ <int>16</int>
+ </entry>
+ </elementAttributes>
+ <pos x="140" y="400"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Splitter</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Input Splitting</string>
+ <string>4</string>
+ </entry>
+ <entry>
+ <string>Output Splitting</string>
+ <string>1*4</string>
+ </entry>
+ </elementAttributes>
+ <pos x="160" y="480"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Text</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Description</string>
+ <string>Some IRQ active?</string>
+ </entry>
+ </elementAttributes>
+ <pos x="140" y="440"/>
+ </visualElement>
+ <visualElement>
+ <elementName>In</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Label</string>
+ <string>MAR_IE</string>
+ </entry>
+ </elementAttributes>
+ <pos x="280" y="620"/>
+ </visualElement>
+ <visualElement>
+ <elementName>And</elementName>
+ <elementAttributes/>
+ <pos x="360" y="580"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Multiplexer</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Bits</string>
+ <int>16</int>
+ </entry>
+ </elementAttributes>
+ <pos x="460" y="400"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Out</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Label</string>
+ <string>DBUS</string>
+ </entry>
+ <entry>
+ <string>Bits</string>
+ <int>16</int>
+ </entry>
+ </elementAttributes>
+ <pos x="680" y="420"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Driver</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Bits</string>
+ <int>16</int>
+ </entry>
+ <entry>
+ <string>flipSelPos</string>
+ <boolean>true</boolean>
+ </entry>
+ </elementAttributes>
+ <pos x="600" y="420"/>
+ </visualElement>
+ <visualElement>
+ <elementName>In</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Label</string>
+ <string>PC_OE</string>
+ </entry>
+ </elementAttributes>
+ <pos x="580" y="540"/>
+ </visualElement>
+ <visualElement>
+ <elementName>PriorityEncoder</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Selector Bits</string>
+ <int>2</int>
+ </entry>
+ </elementAttributes>
+ <pos x="240" y="480"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Const</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Value</string>
+ <long>17</long>
+ </entry>
+ <entry>
+ <string>Bits</string>
+ <int>16</int>
+ </entry>
+ </elementAttributes>
+ <pos x="340" y="280"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Multiplexer</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Selector Bits</string>
+ <int>2</int>
+ </entry>
+ <entry>
+ <string>Bits</string>
+ <int>16</int>
+ </entry>
+ </elementAttributes>
+ <pos x="360" y="260"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Const</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Value</string>
+ <long>16</long>
+ </entry>
+ <entry>
+ <string>Bits</string>
+ <int>16</int>
+ </entry>
+ </elementAttributes>
+ <pos x="340" y="260"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Const</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Value</string>
+ <long>18</long>
+ </entry>
+ <entry>
+ <string>Bits</string>
+ <int>16</int>
+ </entry>
+ </elementAttributes>
+ <pos x="340" y="300"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Const</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Value</string>
+ <long>19</long>
+ </entry>
+ <entry>
+ <string>Bits</string>
+ <int>16</int>
+ </entry>
+ </elementAttributes>
+ <pos x="340" y="320"/>
+ </visualElement>
+ <visualElement>
+ <elementName>Testcase</elementName>
+ <elementAttributes>
+ <entry>
+ <string>Testdata</string>
+ <testData>
+ <dataString>IRQ PC MAR_IE PC_OE DBUS
+0b0000 0x5 0 0 Z
+0b0000 0x5 0 1 0x5
+0b0001 0x5 0 1 0x5
+0b0001 0x5 1 1 0x10
+0b0101 0x5 1 1 0x12</dataString>
+ </testData>
+ </entry>
+ </elementAttributes>
+ <pos x="640" y="240"/>
+ </visualElement>
+ </visualElements>
+ <wires>
+ <wire>
+ <p1 x="140" y="480"/>
+ <p2 x="160" y="480"/>
+ </wire>
+ <wire>
+ <p1 x="180" y="480"/>
+ <p2 x="240" y="480"/>
+ </wire>
+ <wire>
+ <p1 x="320" y="480"/>
+ <p2 x="380" y="480"/>
+ </wire>
+ <wire>
+ <p1 x="340" y="320"/>
+ <p2 x="360" y="320"/>
+ </wire>
+ <wire>
+ <p1 x="620" y="420"/>
+ <p2 x="680" y="420"/>
+ </wire>
+ <wire>
+ <p1 x="500" y="420"/>
+ <p2 x="580" y="420"/>
+ </wire>
+ <wire>
+ <p1 x="340" y="580"/>
+ <p2 x="360" y="580"/>
+ </wire>
+ <wire>
+ <p1 x="340" y="260"/>
+ <p2 x="360" y="260"/>
+ </wire>
+ <wire>
+ <p1 x="180" y="520"/>
+ <p2 x="240" y="520"/>
+ </wire>
+ <wire>
+ <p1 x="280" y="620"/>
+ <p2 x="360" y="620"/>
+ </wire>
+ <wire>
+ <p1 x="340" y="300"/>
+ <p2 x="360" y="300"/>
+ </wire>
+ <wire>
+ <p1 x="400" y="300"/>
+ <p2 x="440" y="300"/>
+ </wire>
+ <wire>
+ <p1 x="140" y="400"/>
+ <p2 x="460" y="400"/>
+ </wire>
+ <wire>
+ <p1 x="180" y="500"/>
+ <p2 x="240" y="500"/>
+ </wire>
+ <wire>
+ <p1 x="320" y="500"/>
+ <p2 x="340" y="500"/>
+ </wire>
+ <wire>
+ <p1 x="420" y="600"/>
+ <p2 x="480" y="600"/>
+ </wire>
+ <wire>
+ <p1 x="340" y="280"/>
+ <p2 x="360" y="280"/>
+ </wire>
+ <wire>
+ <p1 x="440" y="440"/>
+ <p2 x="460" y="440"/>
+ </wire>
+ <wire>
+ <p1 x="180" y="540"/>
+ <p2 x="240" y="540"/>
+ </wire>
+ <wire>
+ <p1 x="580" y="540"/>
+ <p2 x="600" y="540"/>
+ </wire>
+ <wire>
+ <p1 x="480" y="440"/>
+ <p2 x="480" y="600"/>
+ </wire>
+ <wire>
+ <p1 x="340" y="500"/>
+ <p2 x="340" y="580"/>
+ </wire>
+ <wire>
+ <p1 x="600" y="440"/>
+ <p2 x="600" y="540"/>
+ </wire>
+ <wire>
+ <p1 x="440" y="300"/>
+ <p2 x="440" y="440"/>
+ </wire>
+ <wire>
+ <p1 x="380" y="340"/>
+ <p2 x="380" y="480"/>
+ </wire>
+ </wires>
+ <measurementOrdering/>
+</circuit> \ No newline at end of file
diff --git a/digital/atk16_mem.dig b/digital/atk16_mem.dig
index 15f080d..5c56552 100644
--- a/digital/atk16_mem.dig
+++ b/digital/atk16_mem.dig
@@ -67,10 +67,10 @@
</entry>
<entry>
<string>Data</string>
- <data>6001,8000,4001,2a00,400a,9e00,1fe0,3178,1b48,6001,f000,3148,1b48
-,3150,1b48,1011,860a,3158,1b48,4200,4401,650,1280,14c0,1009,8408
-,61fa,1b49,2540,1b49,2340,1b49,2f40,51c0,10c0,1b49,2740,1b49,2540
-,1b49,2340,1b49,2f40,51c0</data>
+ <data>4014,2a00,6014,13*8000,4*15,8000,4055,f000,400a,9e00,1fe0,3178
+,1b48,6001,f000,3148,1b48,3150,1b48,1011,860a,3158,1b48,4200,4401
+,650,1280,14c0,1009,8408,61fa,1b49,2540,1b49,2340,1b49,2f40,51c0
+,10c0,1b49,2740,1b49,2540,1b49,2340,1b49,2f40,51c0</data>
</entry>
</elementAttributes>
<pos x="740" y="100"/>
diff --git a/src/asm_eval.py b/src/asm_eval.py
index 691e4eb..c05fc03 100644
--- a/src/asm_eval.py
+++ b/src/asm_eval.py
@@ -24,24 +24,24 @@ constants: dict[str, str] = {
"sign": "3",
}
-Labels = dict[str, int]
+Symbols = dict[str, int]
def check_size(bits: int, val: int) -> None:
if val >= 2 ** bits:
- raise Exception(f"Value does not fit in {bits} bits: {val}")
+ raise Exception(f"Value does not fit in {bits} bits: 0x{val:>04x}")
-def eval_symbol(labels: Labels, c: str) -> str:
- if c in labels:
- return str(labels[c])
+def eval_symbol(symbols: Symbols, c: str) -> str:
+ if c in symbols:
+ return str(symbols[c])
if c in constants:
return constants[c]
return c
-def eval_expr(labels: Labels, expr: str, bits: int = 16) -> int:
+def eval_expr(symbols: Symbols, expr: str, bits: int = 16) -> int:
expr = expr.lower()
- expr = eval_symbol(labels, expr)
- ret = eval(expr, labels.copy()) # eval as Python expr
+ expr = eval_symbol(symbols, expr)
+ ret = eval(expr, symbols.copy()) # eval as Python expr
check_size(bits, ret)
return ret
diff --git a/src/asm_ops.py b/src/asm_ops.py
index 74e7930..61e2caa 100644
--- a/src/asm_ops.py
+++ b/src/asm_ops.py
@@ -11,12 +11,12 @@ class Options:
class Meta:
address: int
-def make_alr(meta: Meta, labels: Labels, alu_op: str, left: str, right: str, target: str) -> int:
+def make_alr(meta: Meta, symbols: Symbols, alu_op: str, left: str, right: str, target: str) -> int:
"""ALR 0000 TTTL LLRR RSSS"""
- target_e = eval_expr(labels, target, bits=3)
- left_e = eval_expr(labels, left, bits=3)
- right_e = eval_expr(labels, right, bits=3)
- alu_op_e = eval_expr(labels, alu_op, bits=3)
+ target_e = eval_expr(symbols, target, bits=3)
+ left_e = eval_expr(symbols, left, bits=3)
+ right_e = eval_expr(symbols, right, bits=3)
+ alu_op_e = eval_expr(symbols, alu_op, bits=3)
word = (0b0000 << 12) + \
(target_e << 9) + \
(left_e << 6) + \
@@ -24,12 +24,12 @@ def make_alr(meta: Meta, labels: Labels, alu_op: str, left: str, right: str, tar
alu_op_e
return word
-def make_ali(meta: Meta, labels: Labels, alu_op: str, left: str, imm: str, target: str) -> int:
+def make_ali(meta: Meta, symbols: Symbols, alu_op: str, left: str, imm: str, target: str) -> int:
"""ALI 0001 TTTL LLII ISSS"""
- target_e = eval_expr(labels, target, bits=3)
- left_e = eval_expr(labels, left, bits=3)
- imm_e = eval_expr(labels, imm, bits=3)
- alu_op_e = eval_expr(labels, alu_op, bits=3)
+ target_e = eval_expr(symbols, target, bits=3)
+ left_e = eval_expr(symbols, left, bits=3)
+ imm_e = eval_expr(symbols, imm, bits=3)
+ alu_op_e = eval_expr(symbols, alu_op, bits=3)
word = (0b0001 << 12) + \
(target_e << 9) + \
(left_e << 6) + \
@@ -37,62 +37,64 @@ 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, addr_reg: str, to_reg: str) -> int:
+def make_ldr(meta: Meta, symbols: Symbols, 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)
+ to_reg_e = eval_expr(symbols, to_reg, bits=3)
+ addr_reg_e = eval_expr(symbols, addr_reg, bits=3)
word = (0b0010 << 12) + \
(to_reg_e << 9) + \
(addr_reg_e << 6)
return word
-def make_str(meta: Meta, labels: Labels, from_reg: str, addr_reg: str) -> int:
+def make_str(meta: Meta, symbols: Symbols, from_reg: str, addr_reg: str) -> int:
"""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)
+ from_reg_e = eval_expr(symbols, from_reg, bits=3)
+ addr_reg_e = eval_expr(symbols, addr_reg, bits=3)
word = (0b0011 << 12) + \
(addr_reg_e << 6) + \
(from_reg_e << 3)
return word
-def make_ldi(meta: Meta, labels: Labels, imm: str, to_reg: str) -> int:
+def make_ldi(meta: Meta, symbols: Symbols, 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)
+ to_reg_e = eval_expr(symbols, to_reg, bits=3)
+ imm_e = eval_expr(symbols, imm, bits=9)
word = (0b0100 << 12) + \
(to_reg_e << 9) + \
imm_e
return word
-def make_jpr(meta: Meta, labels: Labels, addr_reg: str) -> int:
+def make_jpr(meta: Meta, symbols: Symbols, addr_reg: str) -> int:
"""JPR 0101 XXXR RRXX XXXX"""
- addr_reg_e = eval_expr(labels, addr_reg, bits=3)
+ addr_reg_e = eval_expr(symbols, addr_reg, bits=3)
word = (0b0101 << 12) + \
(addr_reg_e << 6)
return word
-def make_jpi(meta: Meta, labels: Labels, imm: str) -> int:
+def make_jpi(meta: Meta, symbols: Symbols, imm: str) -> int:
"""JPI 0110 XXXI IIII IIII"""
- imm_e = eval_expr(labels, imm, bits=9)
+ imm_e = eval_expr(symbols, imm, bits=9)
imm_e = imm_e - meta.address - 1
imm_e = imm_e & (0b111111111)
+ print("symbols:", symbols)
+ print(meta, imm, f"0x{imm_e:>0x}")
word = (0b0110 << 12) + \
imm_e
return word
-def make_brr(meta: Meta, labels: Labels, flag_s: str, addr_reg: str) -> int:
+def make_brr(meta: Meta, symbols: Symbols, flag_s: str, addr_reg: str) -> int:
"""brr 0111 XFFR RRXX XXXX"""
- flag_s_e = eval_expr(labels, flag_s, bits=2)
- addr_reg_e = eval_expr(labels, addr_reg, bits=3)
+ flag_s_e = eval_expr(symbols, flag_s, bits=2)
+ addr_reg_e = eval_expr(symbols, addr_reg, bits=3)
word = (0b0111 << 12) + \
(flag_s_e << 9) + \
(addr_reg_e << 6)
return word
-def make_bri(meta: Meta, labels: Labels, flag_s: str, imm: str) -> int:
+def make_bri(meta: Meta, symbols: Symbols, flag_s: str, imm: str) -> int:
"""BRI 1000 XFFI IIII IIII"""
- flag_s_e = eval_expr(labels, flag_s, bits=2)
- imm_e = eval_expr(labels, imm, bits=9)
+ flag_s_e = eval_expr(symbols, flag_s, bits=2)
+ imm_e = eval_expr(symbols, imm, bits=9)
imm_e = imm_e - meta.address - 1
imm_e = imm_e & (0b111111111)
word = (0b1000 << 12) + \
@@ -100,14 +102,14 @@ def make_bri(meta: Meta, labels: Labels, flag_s: str, imm: str) -> int:
imm_e
return word
-def make_lpc(meta: Meta, labels: Labels, target: str) -> int:
+def make_lpc(meta: Meta, symbols: Symbols, target: str) -> int:
"""LPC 1001 TTTX XXXX XXXX"""
- target_e = eval_expr(labels, target, bits=3)
+ target_e = eval_expr(symbols, target, bits=3)
word = (0b1001 << 12) + \
(target_e << 9)
return word
-def make_hlt(meta: Meta, labels: Labels) -> int:
+def make_hlt(meta: Meta, symbols: Symbols) -> int:
"""HLT 1111 XXXX XXXX XXXX"""
word = (0b1111 << 12)
return word
diff --git a/src/asm_pass0.py b/src/asm_pass0.py
index a0ae56d..4913e4b 100644
--- a/src/asm_pass0.py
+++ b/src/asm_pass0.py
@@ -12,13 +12,9 @@ class Result0Line:
@dataclass
class Result0:
lines: list[Result0Line]
- options: Options
- operations: OpExpansionDict
def pass_0(lines: list[str], file_name: str) -> Result0:
- options = Options()
result_lines: list[Result0Line] = []
- operations: OpExpansionDict = default_expansions.copy()
for (line_num, line) in enumerate(lines):
line = line.split(";")[0].strip()
@@ -29,12 +25,15 @@ def pass_0(lines: list[str], file_name: str) -> Result0:
asm_file_name = args[0]
path = os.path.join(os.path.dirname(file_name), asm_file_name + ".atk16")
with open(path, "r") as f:
- for incl_line in f.readlines():
- result_lines.append(Result0Line(
- src_file=asm_file_name,
- line_num=line_num,
- line=incl_line
- ))
+ incl_lines = f.readlines()
+
+ incl_result0 = pass_0(incl_lines, asm_file_name)
+ for incl_line in incl_result0.lines:
+ result_lines.append(Result0Line(
+ src_file=incl_line.src_file,
+ line_num=incl_line.line_num,
+ line=incl_line.line
+ ))
case _:
result_lines.append(Result0Line(
@@ -44,7 +43,5 @@ def pass_0(lines: list[str], file_name: str) -> Result0:
))
return Result0(
- operations=operations,
- options=options,
lines=result_lines
)
diff --git a/src/asm_pass3.py b/src/asm_pass3.py
index 76e7b84..5221f6d 100644
--- a/src/asm_pass3.py
+++ b/src/asm_pass3.py
@@ -16,21 +16,24 @@ class Result3:
lines: list[Result3Line]
options: Options
operations: OpExpansionDict
- labels: dict[str, int]
+ symbols: dict[str, int]
def pass_3(result2: Result2) -> Result3:
result_lines: list[Result3Line] = []
- labels: dict[str, int] = {}
+ symbols: dict[str, int] = {}
address = 0
for line in result2.lines:
keyword, *args = line.parts
match keyword:
case "@address":
- address = eval(args[0])
+ address = eval_expr(symbols, args[0])
continue
case "@label":
- labels[args[0]] = address
+ symbols[args[0]] = address
+ continue
+ case "@let":
+ symbols[args[0]] = eval_expr(symbols, args[1])
continue
case _:
result_lines.append(Result3Line(
@@ -42,9 +45,16 @@ def pass_3(result2: Result2) -> Result3:
))
address += 1
+ result_lines.sort(key=lambda l: l.address)
+ for result_line in result_lines:
+ rows_with_same_addr = list(filter(lambda l: l.address == result_line.address, result_lines))
+ n = len(rows_with_same_addr)
+ if n > 1:
+ formatted = "\n".join(map(lambda l: " ".join(l.parts), rows_with_same_addr))
+ raise Exception(f"Overlapping segments: address 0x{result_line.address:>04x} has conflicting definitions:\n{formatted}")
return Result3(
operations=result2.operations,
options=result2.options,
lines=result_lines,
- labels=labels,
+ symbols=symbols,
)
diff --git a/src/asm_pass4.py b/src/asm_pass4.py
index dc65b65..462707a 100644
--- a/src/asm_pass4.py
+++ b/src/asm_pass4.py
@@ -17,7 +17,7 @@ class Result4:
lines: list[Result4Line]
options: Options
operations: OpExpansionDict
- labels: dict[str, int]
+ symbols: dict[str, int]
def translate_opt(arg: str, options: Options) -> str:
match arg:
@@ -27,12 +27,11 @@ def translate_opt(arg: str, options: Options) -> str:
def pass_4(result3: Result3) -> Result4:
result_lines: list[Result4Line] = []
- address = 0
for line in result3.lines:
keyword, *args = line.parts
meta = Meta(
- address=address,
+ address=line.address,
)
args = list(map(lambda a: translate_opt(a, result3.options), args))
@@ -41,7 +40,7 @@ def pass_4(result3: Result3) -> Result4:
if keyword in operations:
fn = operations[keyword]
- word = fn(meta, result3.labels, *args)
+ word = fn(meta, result3.symbols, *args)
result_lines.append(Result4Line(
line_num=line.line_num,
src_file=line.src_file,
@@ -56,18 +55,16 @@ def pass_4(result3: Result3) -> Result4:
line_num=line.line_num,
src_file=line.src_file,
address=line.address,
- word=eval_expr(result3.labels, keyword),
+ word=eval_expr(result3.symbols, keyword),
text=text,
original_text=original_text,
))
except:
raise Exception(f"Invalid assembly at {line.src_file}:{line.line_num + 1}\n\n{line}")
- address += 1
-
return Result4(
operations=result3.operations,
- labels=result3.labels,
+ symbols=result3.symbols,
options=result3.options,
lines=result_lines,
)
diff --git a/src/assembler.py b/src/assembler.py
index 8f84288..c678ba0 100755
--- a/src/assembler.py
+++ b/src/assembler.py
@@ -62,9 +62,9 @@ result = bytearray()
result.extend(nop)
for line in result4.lines:
- for (label, label_addr) in result4.labels.items():
- if line.address == label_addr:
- print(f"{label}:")
+ for (symbol, symbol_value) in result4.symbols.items():
+ if line.address == symbol_value:
+ print(f"{symbol}:")
if len(result) < 2 * line.address + 1:
result.extend((2 * line.address + 1 - len(result)) * nop)