diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2023-04-13 14:48:34 +0300 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2023-04-13 14:49:59 +0300 |
| commit | 9d4c6fc299294ac36f7082599edce19286fa0f99 (patch) | |
| tree | e7601bb1cd9950482f125377d25b6d5d40b72e62 | |
| parent | afd5f32e56d3d30bfa98fb35deff51febf50e594 (diff) | |
Add @let directive, start pondering interrupt control
| -rw-r--r-- | asm/bootstrap.atk16 | 23 | ||||
| -rw-r--r-- | asm/ext_std.py | 4 | ||||
| -rw-r--r-- | asm/fibo.atk16 | 14 | ||||
| -rw-r--r-- | asm/ram_offset.atk16 | 2 | ||||
| -rw-r--r-- | atk16-syntax/atk16-syntax-0.0.1.vsix | bin | 4383 -> 4351 bytes | |||
| -rw-r--r-- | atk16-syntax/extension.js | 16 | ||||
| -rw-r--r-- | atk16-syntax/package.json | 2 | ||||
| -rw-r--r-- | atk16-syntax/syntaxes/atk16.tmLanguage.json | 20 | ||||
| -rw-r--r-- | digital/atk16.dig | 203 | ||||
| -rw-r--r-- | digital/atk16_irc.dig | 341 | ||||
| -rw-r--r-- | digital/atk16_mem.dig | 8 | ||||
| -rw-r--r-- | src/asm_eval.py | 16 | ||||
| -rw-r--r-- | src/asm_ops.py | 66 | ||||
| -rw-r--r-- | src/asm_pass0.py | 21 | ||||
| -rw-r--r-- | src/asm_pass3.py | 20 | ||||
| -rw-r--r-- | src/asm_pass4.py | 13 | ||||
| -rwxr-xr-x | src/assembler.py | 6 |
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 Binary files differindex 342049e..253d326 100644 --- a/atk16-syntax/atk16-syntax-0.0.1.vsix +++ b/atk16-syntax/atk16-syntax-0.0.1.vsix 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) |
