diff --git a/.gitignore b/.gitignore index 7585238..02bb41e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ book +target \ No newline at end of file diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 6aa4e34..7651b7a 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -2,5 +2,28 @@ [Introduction](README.md) -- [DSA](dsa/overview.md) - - [Syntax](dsa/syntax.md) +- [DSA - Damn Simple Assembly](dsa.md) + - [Instructions](dsa/instructions.md) + - [Hardware Instructions](dsa/instructions/hardware.md) + - [Pseudo Instructions](dsa/instructions/pseudo.md) + - [Data Directives](dsa/instructions/directives.md) + - [Usable Registers](dsa/registers.md) + - [Imports](dsa/imports.md) + - [Calling Convention](dsa/cconv.md) + - [Examples](dsa/examples.md) + - [Tooling](dsa/tooling.md) + - [Assembler](dsa/tooling/assembler.md) + - [Syntax](dsa/tooling/syntax_tooling.md) +- [DSA Emulator](emulator.md) + - [Building the Emulator](emulator/building.md) + - [Features](emulator/features.md) + - [Control Panel](emulator/features/control_panel.md) + - [Memory Inspector](emulator/features/memory_inspector.md) + - [Stack Inspector](emulator/features/stack_inspector.md) + - [Editor](emulator/features/editor.md) + - [Loader](emulator/features/loader.md) + - [Display](emulator/features/display.md) + - [Instruction History](emulator/features/instruction_history.md) +- [DSC - Damn Simple Code](dsc.md) +- [Other Language Support](misc_languages.md) + - [Brainf*](misc_languages/brainf.md) \ No newline at end of file diff --git a/src/dsa.md b/src/dsa.md new file mode 100644 index 0000000..1beedbf --- /dev/null +++ b/src/dsa.md @@ -0,0 +1,12 @@ +# DSA Assembly Language Instruction Reference + +## Overview + +This document provides a comprehensive reference for the DSA (Damn Simple Architecture) assembly language, including all hardware instructions and pseudo-instructions with their syntax variations and usage examples. + +## Table of Contents +- [Instructions](instructions.md) +- [Tooling](tooling.md) +- [Imports](imports.md) +- [Calling Convention](cconv.md) +- [Examples](examples.md) diff --git a/src/dsa/cconv.md b/src/dsa/cconv.md new file mode 100644 index 0000000..ea35369 --- /dev/null +++ b/src/dsa/cconv.md @@ -0,0 +1,90 @@ +# Calling Convention +## Calling Convention + +| Step | Responsibility | Action | Description | +|------|----------------|--------|-------------| +| 0 | **Caller** | Save Current State | Ensure that any registers with important data in are pushed to the stack so that they can be restored later. +| 1 | **Caller** | Push arguments | Push exactly n arguments to the stack
(in order, last argument pushed first) | +| 2 | **Caller** | Call function | Execute `call namespace::function`
this automatically pushes the return address (pcx) and jumps to the function | +| 3 | **Function** | Set up stack frame | Execute `push bpr; mov spr, bpr` to establish new stack frame | +| 4 | **Function** | Access arguments | Read arguments starting at `spr+8`
(first 3 args at offsets 8, 12, 16) | +| 5 | **Function** | Execute function | Perform the function's operations using the arguments | +| 6 | **Function** | Store return value | Write return value (if any) to `spr+8` | +| 7 | **Function** | Restore stack frame | Execute `mov bpr, spr; pop bpr` to restore previous stack frame | +| 8 | **Function** | Return | Execute `return` pseudo-instruction to return to caller | +| 9 | **Caller** | Clean up stack | Pop exactly n arguments from the stack to clean up | +| 10 | **Caller** | Handle unused values | Use `pop zero` to discard any unused stack values if needed | +| 11 | **Caller** | Restore State | Pop any registers that were pushed in step 0
(or `pop zero` if no longer needed) | + +**Notes:** + +- The namespace in step 2 is the name assigned in the `include` statement +- The `call` pseudo-instruction automatically handles return address management so long as the callee does not mess with the stack +- Arguments are accessed by the callee using offsets from the base pointer (bpr) + + + +### Function Control + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **CALL** | `namespace::function` | Call a function with automatic return address management | +| **RETURN** | - | Return from a function to the caller | + +**Examples:** + +`call-local.dsa` +```dsa +// ensure the stack is set up first! + +caller: + push rg0 + push rg1 + + call callee // make call to a local function + pop rg0 // put result in rg0 + pop zero // void second return val + +callee: + // setup new stack frame + push bpr + mov spr, bpr + + // function body + + // restore the stack frame + mov bpr, spr + pop bpr + return ; Return from the current function +``` +`call-external.dsa` +```dsa +include external "./external.dsa" + +// ensure the stack is set up first! +db string: "Hello, world!" +caller: + // push args + lwi string, rg0 + push rg0 + call external::callee // do something with the string + pop zero +``` + + +`external.dsa` +```dsa +callee: + // set up the stack + push bpr + mov spr, bpr + + // function body + + // restore the stack frame + mov bpr, spr + pop bpr + return ; Return from the current function +``` + + diff --git a/src/dsa/examples.md b/src/dsa/examples.md new file mode 100644 index 0000000..6c57995 --- /dev/null +++ b/src/dsa/examples.md @@ -0,0 +1,125 @@ +# Examples + + +## Library Examples + +### Multiplication Library (multiply.dsa) + +```dsa +// multiply.dsa +// usage: +// +// include multiply "" +// +// usage for multiply: +// push (arg1) +// push (arg0) +// call multiply::multiply +// pop (arg0) +// pop (arg1) + +multiply: + push bpr + mov spr, bpr + + ldw bpr, rg0, 8 // load op 1 + ldw bpr, rg1, 12 // load op 2 + + lli 0, acc // initialize accumulator + +start: + add acc, rg0, acc + dec rg1 + + cmp rg1, zero + jgt start + +end: + stw acc, bpr, 8 // store result for caller + mov bpr, spr + pop bpr + return +``` + +### Print Library (print.dsa) + +```dsa +// print.dsa +// usage: +// +// include print "" +// +// usage for print: +// push (register containing address of string) +// call print::print +// pop zero +// +// usage for reset: +// call print::reset + +dw display: 0x20000 +dw current: 0x20000 + +// prints the given text to the screen. +print: + push bpr + mov spr, bpr + + ldw bpr, rg0, 8 // get string address argument + ldw current, rg1 // get current display position + +print_loop: + ldb rg0, acc + stb acc, rg1 + + iadd rg0, 1 + iadd rg1, 1 + + cmp acc, zero + jne print_loop + jmp end + +// return +end: + stw rg1, current + + mov bpr, spr + pop bpr + return + +// resets the cursor position on the screen +reset: + push bpr + mov spr, bpr + ldw display, rg1 + stw rg1, current + mov bpr, spr + pop bpr + return +``` + +### Example Program (main.dsa) + +```dsa +include print "./print.dsa" + +dw stack: 0x10000 +db string: "'To confuse your enemy, you must first confuse yourself' - Probably Sun Tzu." + +init: + // set up a stack. + ldw stack, bpr + mov bpr, spr + +start: + lwi string, rg1 + + // push string address argument + push rg1 + // call print function + call print::print + // clean up stack + pop rg1 + + hlt +``` \ No newline at end of file diff --git a/src/dsa/imports.md b/src/dsa/imports.md new file mode 100644 index 0000000..0908a24 --- /dev/null +++ b/src/dsa/imports.md @@ -0,0 +1,46 @@ +# Imports + +## Module System + +| Mnemonic | Syntax | Description | +|----------|--------|-------------| +| **INCLUDE** | `alias[:] "path"` | Include module symbols | + +## Import Precedence + +**Notes:** +- The order of imports may affect the order in which dependencies are placed into the output binary. +- Circular dependencies are allowed and fully supported. +- The module name is caller-defined and can be used to create aliases for libraries within the scope of the calling file. This makes namespacing easy. + +**Examples:** +```dsa +include print "./lib/print.dsa" +include maths "./lib/maths.dsa" +``` + +## External Symbol Access Convention + +External symbols are accessed using the `::` operator. + +**Examples:** + +```dsa +include print "./lib/print.dsa" + +init: + // ensure we have a stack setup so we can call functions properly + +db string: "Hello world!" + +start: + // load the address of the string into rg1. + lwi string, rg1 + // push the string address argument + push rg1 + // call the print function + call print::print + // clean up the stack + pop zero + hlt +``` \ No newline at end of file diff --git a/src/dsa/instructions.md b/src/dsa/instructions.md new file mode 100644 index 0000000..c8a626b --- /dev/null +++ b/src/dsa/instructions.md @@ -0,0 +1,8 @@ +# Instructions + +This section is a complete overview of the assembly language and instructions. It includes both the hardware instructions that translate directly to machine code as well as pseudo instructions and directives that are translated to hardware instructions or directives by the assembler. + +### Instruction Types +- [Hardware Instructions](hardware.md) +- [Pseudo Instructions](pseudo.md) +- [Directives](directives.md) \ No newline at end of file diff --git a/src/dsa/instructions/directives.md b/src/dsa/instructions/directives.md new file mode 100644 index 0000000..ccdc38b --- /dev/null +++ b/src/dsa/instructions/directives.md @@ -0,0 +1,41 @@ +# Data Directives + +### Data Definition + +| Mnemonic | Syntax | Description | +|----------|--------|-------------| +| **DB** | `name: value1 [, value2, ...]` | Define bytes
*(byte aligned)*| +| **DH** | `name: value1 [, value2, ...]` | Define half-words
*(2 byte aligned)*| +| **DW** | `name: value1 [, value2, ...]` | Define words
*(4 byte aligned)*| + +**Examples:** +```dsa +db message: "Hello World", 0, 0x20, 231 +dh numbers: 1000, 2000, 3000 +dw stack: 0x10000 +``` + +**Notes:** +- All string literals are automatically *null-terminated* +- + +### Memory Reservation + +| Mnemonic | Syntax | Description | +|----------|--------|-------------| +| **RESB** | `name: size` | Reserve bytes | +| **RESH** | `name: size` | Reserve half-words | +| **RESW** | `name: size` | Reserve words | + +**Examples:** +```dsa +resb buffer: 256 ; Reserve 256 bytes +resh array: 100 ; Reserve space for 100 half-words +resw heap: 1024 ; Reserve space for 1024 words +``` + +### Imports +| Mnemonic | Syntax | Description | +|----------|--------|-------------| +| **INCLUDE** | `module_name "path"` | Include module symbols | +[More details on the module System](../imports.md) diff --git a/src/dsa/instructions/hardware.md b/src/dsa/instructions/hardware.md new file mode 100644 index 0000000..71e6f46 --- /dev/null +++ b/src/dsa/instructions/hardware.md @@ -0,0 +1,190 @@ +# Hardware Instructions + +### Data Movement Instructions + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **MOV** | `src_reg, dest_reg` | Copy value from source to destination register | +| **MOVS** | `src_reg, dest_reg` | Copy with sign extension | + +**Examples:** + +```dsa +mov rg0, rg1 ; Copy rg0 to rg1 +movs rg0, rg1 ; Copy rg0 to rg1 with sign extension +``` + +### Memory Access Instructions + +#### Load Instructions + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **LDB** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load byte from memory | +| **LDBS** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load byte with sign extension | +| **LDH** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load half-word (16-bit) | +| **LDHS** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load half-word with sign extension | +| **LDW** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load word (32-bit) | + +**Examples:** + +```dsa +; Direct register addressing +ldb rg0, rg1 ; Load byte from address in rg0 +ldw rg0, rg1, 8 ; Load word from (rg0 + 8) + +; Label addressing +ldb buffer, rg2 ; Load byte from label 'buffer' +ldw stack, bpr ; Load stack address into base pointer +``` +**Label Expansions:** +```dsa +; ldb buffer, rg2 expands to: +lli buffer, rg2 ; Load lower 16 bits of buffer address +lui buffer, rg2 ; Load upper 16 bits of buffer address +ldb rg2, rg2 ; Load byte from address in rg2 + +; ldw stack, bpr expands to: +lli stack, bpr ; Load lower 16 bits of stack address +lui stack, bpr ; Load upper 16 bits of stack address +ldw bpr, bpr ; Load word from address in bpr +``` +#### Store Instructions + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **STB** | `src_reg, base_reg [, offset]`
`src_reg, label [, offset]` | Store byte to memory | +| **STH** | `src_reg, base_reg [, offset]`
`src_reg, label [, offset]` | Store half-word to memory | +| **STW** | `src_reg, base_reg [, offset]`
`src_reg, label [, offset]` | Store word to memory | + +**Examples:** +```dsa +; Direct register addressing +stb rg0, rg1 ; Store byte from rg0 to address in rg1 +stw rg0, rg1, 12 ; Store word to (rg1 + 12) + +; Label addressing +stb acc, buffer ; Store byte from accumulator to 'buffer' +stw rg1, current ; Store word to 'current' variable +``` +**Label Expansions:** +```dsa +; stb acc, buffer expands to: +lli buffer, rgf ; Load lower 16 bits of buffer address +lui buffer, rgf ; Load upper 16 bits of buffer address +stb acc, rgf ; Store byte from acc to address in rgf + +; stw rg1, current expands to: +lli current, rgf ; Load lower 16 bits of current address +lui current, rgf ; Load upper 16 bits of current address +stw rg1, rgf ; Store word from rg1 to address in rgf +``` +### Immediate Load Instructions + +| Mnemonic | Operands | Description | +|----------|----------|------------------------------------------------------------------------| +| **LLI** | `imm, dest_reg` | Load 16-bit immediate into lower 16 bits
**Clears upper 16 bits!** | +| **LUI** | `imm, dest_reg` | Load 16-bit immediate into upper 16 bits | + +**Usage** + +ensure that you always run **Lli** before **Lui** as **Lli** clears the upper 16 bits. + +**Examples:** +```dsa +lli 0x1234, rg0 ; Load 0x1234 into lower 16 bits of rg0 +lui 0xABCD, rg0 ; Load 0xABCD into upper 16 bits of rg0 +``` +### Jump Instructions + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **JMP** | `addr [, offset_reg]`
`imm, offset_reg` | Unconditional jump | +| **JEQ** | `addr [, offset_reg]` | Jump if equal flag set | +| **JNE** | `addr [, offset_reg]` | Jump if not equal flag set | +| **JGT** | `addr [, offset_reg]` | Jump if greater than flag set | +| **JGE** | `addr [, offset_reg]` | Jump if greater or equal flags set | +| **JLT** | `addr [, offset_reg]` | Jump if less than flag set | +| **JLE** | `addr [, offset_reg]` | Jump if less or equal flags set | + +**Examples:** +```dsa +jmp start ; Jump to label 'start' +jmp 4, ret ; Jump to address (4 + ret register) +jeq end ; Jump to 'end' if equal flag set +jgt loop ; Jump to 'loop' if greater than flag set +``` +### Arithmetic Instructions + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **ADD** | `src1_reg, src2_reg, dest_reg` | Addition | +| **SUB** | `src1_reg, src2_reg, dest_reg` | Subtraction | +| **IADD** | `src_reg, imm [, dest_reg]` | Immediate addition | +| **ISUB** | `src_reg, imm [, dest_reg]` | Immediate subtraction | +| **INC** | `reg` | Increment register by 1 | +| **DEC** | `reg` | Decrement register by 1 | + +**Examples:** +```dsa +add rg0, rg1, rg2 ; rg2 = rg0 + rg1 +sub rg0, rg1, rg2 ; rg2 = rg0 - rg1 +iadd rg0, 10 ; rg0 = rg0 + 10 +// or using alternate syntax +addi rg0, 1 ; rg0 = rg0 + 1 +inc rg0 ; rg0 = rg0 + 1 +``` +### Bitwise Operations + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **AND** | `src1_reg, src2_reg, dest_reg` | Bitwise AND | +| **OR** | `src1_reg, src2_reg, dest_reg` | Bitwise OR | +| **XOR** | `src1_reg, src2_reg, dest_reg` | Bitwise XOR | +| **NOT** | `src_reg, dest_reg` | Bitwise NOT | +| **NAND** | `src1_reg, src2_reg, dest_reg` | Bitwise NAND | +| **NOR** | `src1_reg, src2_reg, dest_reg` | Bitwise NOR | +| **XNOR** | `src1_reg, src2_reg, dest_reg` | Bitwise XNOR | + +**Examples:** +```dsa +and rg0, rg1, rg2 ; rg2 = rg0 & rg1 +not rg0, rg1 ; rg1 = ~rg0 +``` +### Shift Operations + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **SHL** | `reg, shift_amount` | Shift left | +| **SHR** | `reg, shift_amount` | Shift right | + +**Examples:** +```dsa +shl rg0, 2 ; Shift rg0 left by 2 bits +shr rg0, 3 ; Shift rg0 right by 3 bits +``` +### Comparison and Control + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **CMP** | `reg1, reg2` | Compare registers and set flags | + +**Examples:** +```dsa +cmp rg0, zero ; Compare rg0 with zero register +cmp rg1, rg2 ; Compare rg1 with rg2 +``` +### System Instructions + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **HLT** | - | Halt processor execution | +| **NOP** | - | No operation | +| **INT** | `interrupt_code` | Trigger interrupt | +| **IRT** | - | Return from interrupt | + +**Examples:** +```dsa +hlt ; Stop processor execution +int 0x21 ; Trigger interrupt 0x21 +``` diff --git a/src/dsa/instructions/pseudo.md b/src/dsa/instructions/pseudo.md new file mode 100644 index 0000000..3418984 --- /dev/null +++ b/src/dsa/instructions/pseudo.md @@ -0,0 +1,24 @@ +# Pseudo Instructions + +### Stack Operations + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **PUSH** | `reg` | Push register value onto stack | +| **POP** | `reg` | Pop stack value into register | + +**Examples:** +```dsa +push rg0 ; Push rg0 value onto stack +pop ret ; Pop return address +``` +### Memory Access Shortcuts + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **LWI** | `name, reg` | Load address into register | + +**Examples:** +```dsa +lwi string, rg1 ; Load address of 'string' into rg1 +``` diff --git a/src/dsa/overview.md b/src/dsa/overview.md deleted file mode 100644 index 9bfa999..0000000 --- a/src/dsa/overview.md +++ /dev/null @@ -1 +0,0 @@ -# DSA diff --git a/src/dsa/registers.md b/src/dsa/registers.md new file mode 100644 index 0000000..ef1cd04 --- /dev/null +++ b/src/dsa/registers.md @@ -0,0 +1,15 @@ +# Usable Registers + +| Register | Type | Description | +|----------|------|---------------------------------------------------------------------------------------------------| +| `rg0-rgf` | General Purpose | General-purpose registers. | +| `acc` | Special | Accumulator for calculations and temporary storage - don't use this for variables as pseudo instructions may overwrite this implicitly! | +| `spr` | Special | Stack pointer | +| `bpr` | Special | Base pointer for stack frames | +| `ret` | Special | Return address register | +| `idr` | Privileged | Interrupt descriptor table address
**on-read/write: protection fault (unless in kernel mode)** | +| `mmr` | Privileged | Hardware memory map table address
**on-read/write: protection fault (unless in kernel mode)** | +| `zero` | Read-only | Always contains zero
**on-read: always returns zero**
**on-write: value is voided** | +| `pcx` | Read-only | Program counter
**on-write: protection fault** | +| `noreg` | Placeholder | Indicates absence of register argument
**on-read/write: illegal instruction fault** | + diff --git a/src/dsa/syntax.md b/src/dsa/syntax.md deleted file mode 100644 index 84c4b67..0000000 --- a/src/dsa/syntax.md +++ /dev/null @@ -1,431 +0,0 @@ -# DSA Assembly Language Instruction Reference - -## Overview - -This document provides a comprehensive reference for the DSA (Damn Simple Architecture) assembly language, including all hardware instructions and pseudo-instructions with their syntax variations and usage examples. - -## Calling Convention - -| Step | Responsibility | Action | Description | -|------|----------------|--------|-------------| -| 1 | **Caller** | Push arguments | Push exactly n arguments to the stack (in order, last argument pushed first) | -| 2 | **Caller** | Call function | Execute `call namespace::function` - this automatically pushes the return address (pcx) and jumps to the function | -| 3 | **Function** | Set up stack frame | Execute `push bpr; mov spr, bpr` to establish new stack frame | -| 4 | **Function** | Access arguments | Read arguments starting at `spr+8` (first 3 args at offsets 8, 12, 16) | -| 5 | **Function** | Execute function | Perform the function's operations using the arguments | -| 6 | **Function** | Store return value | Write return value (if any) to `spr+8` | -| 7 | **Function** | Restore stack frame | Execute `mov bpr, spr; pop bpr` to restore previous stack frame | -| 8 | **Function** | Return | Execute `return` pseudo-instruction to return to caller | -| 9 | **Caller** | Clean up stack | Pop exactly n arguments from the stack to clean up | -| 10 | **Caller** | Handle unused values | Use `pop zero` to discard any unused stack values if needed | - -**Notes:** - -- The namespace in step 2 is the name assigned in the `include` statement -- The `call` pseudo-instruction automatically handles return address management so long as the callee does not mess with the stack -- Arguments are accessed by the callee using offsets from the base pointer (bpr) - -## Registers - -| Register | Type | Description | -|----------|------|---------------------------------------------------------------------------------------------------| -| `rg0-rgf` | General Purpose | General-purpose registers. | -| `acc` | Special | Accumulator for calculations and temporary storage - don't use this for variables as pseudo instructions may overwrite this implicitly! | -| `spr` | Special | Stack pointer | -| `bpr` | Special | Base pointer for stack frames | -| `ret` | Special | Return address register | -| `idr` | Privileged | Interrupt descriptor table address
**on-read/write: protection fault (unless in kernel mode)** | -| `mmr` | Privileged | Hardware memory map table address
**on-read/write: protection fault (unless in kernel mode)** | -| `zero` | Read-only | Always contains zero
**on-read: always returns zero**
**on-write: value is voided** | -| `pcx` | Read-only | Program counter
**on-write: protection fault** | -| `noreg` | Placeholder | Indicates absence of register argument
**on-read/write: illegal instruction fault** | - -## Hardware Instructions - -### Data Movement Instructions - -| Mnemonic | Operands | Description | -|----------|----------|-------------| -| **MOV** | `src_reg, dest_reg` | Copy value from source to destination register | -| **MOVS** | `src_reg, dest_reg` | Copy with sign extension | - -**Examples:** - -```dsa -mov rg0, rg1 ; Copy rg0 to rg1 -movs rg0, rg1 ; Copy rg0 to rg1 with sign extension -``` - -### Memory Access Instructions - -#### Load Instructions - -| Mnemonic | Operands | Description | -|----------|----------|-------------| -| **LDB** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load byte from memory | -| **LDBS** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load byte with sign extension | -| **LDH** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load half-word (16-bit) | -| **LDHS** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load half-word with sign extension | -| **LDW** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load word (32-bit) | - -**Examples:** - -```dsa -; Direct register addressing -ldb rg0, rg1 ; Load byte from address in rg0 -ldw rg0, rg1, 8 ; Load word from (rg0 + 8) - -; Label addressing -ldb buffer, rg2 ; Load byte from label 'buffer' -ldw stack, bpr ; Load stack address into base pointer -``` -**Label Expansions:** -```dsa -; ldb buffer, rg2 expands to: -lli buffer, rg2 ; Load lower 16 bits of buffer address -lui buffer, rg2 ; Load upper 16 bits of buffer address -ldb rg2, rg2 ; Load byte from address in rg2 - -; ldw stack, bpr expands to: -lli stack, bpr ; Load lower 16 bits of stack address -lui stack, bpr ; Load upper 16 bits of stack address -ldw bpr, bpr ; Load word from address in bpr -``` -#### Store Instructions - -| Mnemonic | Operands | Description | -|----------|----------|-------------| -| **STB** | `src_reg, base_reg [, offset]`
`src_reg, label [, offset]` | Store byte to memory | -| **STH** | `src_reg, base_reg [, offset]`
`src_reg, label [, offset]` | Store half-word to memory | -| **STW** | `src_reg, base_reg [, offset]`
`src_reg, label [, offset]` | Store word to memory | - -**Examples:** -```dsa -; Direct register addressing -stb rg0, rg1 ; Store byte from rg0 to address in rg1 -stw rg0, rg1, 12 ; Store word to (rg1 + 12) - -; Label addressing -stb acc, buffer ; Store byte from accumulator to 'buffer' -stw rg1, current ; Store word to 'current' variable -``` -**Label Expansions:** -```dsa -; stb acc, buffer expands to: -lli buffer, rgf ; Load lower 16 bits of buffer address -lui buffer, rgf ; Load upper 16 bits of buffer address -stb acc, rgf ; Store byte from acc to address in rgf - -; stw rg1, current expands to: -lli current, rgf ; Load lower 16 bits of current address -lui current, rgf ; Load upper 16 bits of current address -stw rg1, rgf ; Store word from rg1 to address in rgf -``` -### Immediate Load Instructions - -| Mnemonic | Operands | Description | -|----------|----------|------------------------------------------------------------------------| -| **LLI** | `imm, dest_reg` | Load 16-bit immediate into lower 16 bits
**Clears upper 16 bits!** | -| **LUI** | `imm, dest_reg` | Load 16-bit immediate into upper 16 bits | - -**Usage** - -ensure that you always run **Lli** before **Lui** as **Lli** clears the upper 16 bits. - -**Examples:** -```dsa -lli 0x1234, rg0 ; Load 0x1234 into lower 16 bits of rg0 -lui 0xABCD, rg0 ; Load 0xABCD into upper 16 bits of rg0 -``` -### Jump Instructions - -| Mnemonic | Operands | Description | -|----------|----------|-------------| -| **JMP** | `addr [, offset_reg]`
`imm, offset_reg` | Unconditional jump | -| **JEQ** | `addr [, offset_reg]` | Jump if equal flag set | -| **JNE** | `addr [, offset_reg]` | Jump if not equal flag set | -| **JGT** | `addr [, offset_reg]` | Jump if greater than flag set | -| **JGE** | `addr [, offset_reg]` | Jump if greater or equal flags set | -| **JLT** | `addr [, offset_reg]` | Jump if less than flag set | -| **JLE** | `addr [, offset_reg]` | Jump if less or equal flags set | - -**Examples:** -```dsa -jmp start ; Jump to label 'start' -jmp 4, ret ; Jump to address (4 + ret register) -jeq end ; Jump to 'end' if equal flag set -jgt loop ; Jump to 'loop' if greater than flag set -``` -### Arithmetic Instructions - -| Mnemonic | Operands | Description | -|----------|----------|-------------| -| **ADD** | `src1_reg, src2_reg, dest_reg` | Addition | -| **SUB** | `src1_reg, src2_reg, dest_reg` | Subtraction | -| **IADD** | `src_reg, imm [, dest_reg]` | Immediate addition | -| **ISUB** | `src_reg, imm [, dest_reg]` | Immediate subtraction | -| **INC** | `reg` | Increment register by 1 | -| **DEC** | `reg` | Decrement register by 1 | - -**Examples:** -```dsa -add rg0, rg1, rg2 ; rg2 = rg0 + rg1 -sub rg0, rg1, rg2 ; rg2 = rg0 - rg1 -iadd rg0, 10 ; rg0 = rg0 + 10 -// or using alternate syntax -addi rg0, 1 ; rg0 = rg0 + 1 -inc rg0 ; rg0 = rg0 + 1 -``` -### Bitwise Operations - -| Mnemonic | Operands | Description | -|----------|----------|-------------| -| **AND** | `src1_reg, src2_reg, dest_reg` | Bitwise AND | -| **OR** | `src1_reg, src2_reg, dest_reg` | Bitwise OR | -| **XOR** | `src1_reg, src2_reg, dest_reg` | Bitwise XOR | -| **NOT** | `src_reg, dest_reg` | Bitwise NOT | -| **NAND** | `src1_reg, src2_reg, dest_reg` | Bitwise NAND | -| **NOR** | `src1_reg, src2_reg, dest_reg` | Bitwise NOR | -| **XNOR** | `src1_reg, src2_reg, dest_reg` | Bitwise XNOR | - -**Examples:** -```dsa -and rg0, rg1, rg2 ; rg2 = rg0 & rg1 -not rg0, rg1 ; rg1 = ~rg0 -``` -### Shift Operations - -| Mnemonic | Operands | Description | -|----------|----------|-------------| -| **SHL** | `reg, shift_amount` | Shift left | -| **SHR** | `reg, shift_amount` | Shift right | - -**Examples:** -```dsa -shl rg0, 2 ; Shift rg0 left by 2 bits -shr rg0, 3 ; Shift rg0 right by 3 bits -``` -### Comparison and Control - -| Mnemonic | Operands | Description | -|----------|----------|-------------| -| **CMP** | `reg1, reg2` | Compare registers and set flags | - -**Examples:** -```dsa -cmp rg0, zero ; Compare rg0 with zero register -cmp rg1, rg2 ; Compare rg1 with rg2 -``` -### System Instructions - -| Mnemonic | Operands | Description | -|----------|----------|-------------| -| **HLT** | - | Halt processor execution | -| **NOP** | - | No operation | -| **INT** | `interrupt_code` | Trigger interrupt | -| **IRT** | - | Return from interrupt | - -**Examples:** -```dsa -hlt ; Stop processor execution -int 0x21 ; Trigger interrupt 0x21 -``` -## Pseudo-Instructions - -### Data Definition - -| Mnemonic | Syntax | Description | -|----------|--------|-------------| -| **DB** | `name: value1 [, value2, ...]` | Define bytes | -| **DH** | `name: value1 [, value2, ...]` | Define half-words | -| **DW** | `name: value1 [, value2, ...]` | Define words | - -**Examples:** -```dsa -db message: "Hello World", 0 -dh numbers: 1000, 2000, 3000 -dw stack: 0x10000 -``` -### Memory Reservation - -| Mnemonic | Syntax | Description | -|----------|--------|-------------| -| **RESB** | `name: size` | Reserve bytes | -| **RESH** | `name: size` | Reserve half-words | -| **RESW** | `name: size` | Reserve words | - -**Examples:** -```dsa -resb buffer: 256 ; Reserve 256 bytes -resh array: 100 ; Reserve space for 100 half-words -resw heap: 1024 ; Reserve space for 1024 words -``` -### Stack Operations - -| Mnemonic | Operands | Description | -|----------|----------|-------------| -| **PUSH** | `reg` | Push register value onto stack | -| **POP** | `reg` | Pop stack value into register | - -**Examples:** -```dsa -push rg0 ; Push rg0 value onto stack -pop ret ; Pop return address -``` -### Memory Access Shortcuts - -| Mnemonic | Operands | Description | -|----------|----------|-------------| -| **LWI** | `name, reg` | Load address into register | - -**Examples:** -```dsa -lwi string, rg1 ; Load address of 'string' into rg1 -``` - -### Function Control - -| Mnemonic | Operands | Description | -|----------|----------|-------------| -| **CALL** | `namespace::function` | Call a function with automatic return address management | -| **RETURN** | - | Return from a function to the caller | - -**Examples:** -```dsa -call print::print ; Call the print function from the print namespace -return ; Return from the current function -``` - -### Module System - -| Mnemonic | Syntax | Description | -|----------|--------|-------------| -| **INCLUDE** | `module_name "path"` | Include module | - -**Examples:** -```dsa -include print "print.dsa" -include fib "fib.dsa" -``` -## Library Examples - -### Multiplication Library (multiply.dsa) - -```dsa -// multiply.dsa -// usage: -// -// include multiply "" -// -// usage for multiply: -// push (arg1) -// push (arg0) -// call multiply::multiply -// pop (arg0) -// pop (arg1) - -multiply: - push bpr - mov spr, bpr - - ldw bpr, rg0, 8 // load op 1 - ldw bpr, rg1, 12 // load op 2 - - lli 0, acc // initialize accumulator - -start: - add acc, rg0, acc - dec rg1 - - cmp rg1, zero - jgt start - -end: - stw acc, bpr, 8 // store result for caller - mov bpr, spr - pop bpr - return -``` - -### Print Library (print.dsa) - -```dsa -// print.dsa -// usage: -// -// include print "" -// -// usage for print: -// push (register containing address of string) -// call print::print -// pop zero -// -// usage for reset: -// call print::reset - -dw display: 0x20000 -dw current: 0x20000 - -// prints the given text to the screen. -print: - push bpr - mov spr, bpr - - ldw bpr, rg0, 8 // get string address argument - ldw current, rg1 // get current display position - -print_loop: - ldb rg0, acc - stb acc, rg1 - - iadd rg0, 1 - iadd rg1, 1 - - cmp acc, zero - jne print_loop - jmp end - -// return -end: - stw rg1, current - - mov bpr, spr - pop bpr - return - -// resets the cursor position on the screen -reset: - push bpr - mov spr, bpr - ldw display, rg1 - stw rg1, current - mov bpr, spr - pop bpr - return -``` - -### Example Program (main.dsa) - -```dsa -include print "./print.dsa" - -dw stack: 0x10000 -db string: "'To confuse your enemy, you must first confuse yourself' - Probably Sun Tzu." - -init: - // set up a stack. - ldw stack, bpr - mov bpr, spr - -start: - lwi string, rg1 - - // push string address argument - push rg1 - // call print function - call print::print - // clean up stack - pop rg1 - - hlt -``` \ No newline at end of file diff --git a/src/dsa/tooling.md b/src/dsa/tooling.md new file mode 100644 index 0000000..6719810 --- /dev/null +++ b/src/dsa/tooling.md @@ -0,0 +1,12 @@ +# Tooling + +## Tooling Options + +### Assembler +- The assembler is the program that translates assembly code into machine code. +- It is the only tool required to build DSA assembly language programs. +- The assembler also works as a library that can be called from applications such as the emulator + +### Our Tooling: +- [Assembler](assembler.md) +- [Syntax Tooling](syntax_tooling.md) \ No newline at end of file diff --git a/src/dsa/tooling/assembler.md b/src/dsa/tooling/assembler.md new file mode 100644 index 0000000..24bb3bd --- /dev/null +++ b/src/dsa/tooling/assembler.md @@ -0,0 +1,23 @@ +# Assembler + +## Building the Assembler +### Clone the repository + +```bash +git clone https://git.zxq5.dev/LowLevelDevs/damn_simple_architecture.git +cd damn_simple_architecture +``` + +### Build the assembler + +```bash +cd assembler +cargo build --release +``` + +## Usage + +```bash + -i -o +``` + diff --git a/src/dsa/tooling/syntax_tooling.md b/src/dsa/tooling/syntax_tooling.md new file mode 100644 index 0000000..5d9a40c --- /dev/null +++ b/src/dsa/tooling/syntax_tooling.md @@ -0,0 +1,10 @@ +# Syntax tooling + +## Syntax Highlighting + +### Emulator +- our custom Emulator has built-in syntax highlighting for the DSA assembly language. all files with the .dsa extension have the syntax applies + +### VSCode +- install our custom VSCode extension from the marketplace +[dsa-tooling.dsa-language-support](https://marketplace.visualstudio.com/items?itemName=dsa-tooling.dsa-language-support) \ No newline at end of file diff --git a/src/dsc.md b/src/dsc.md new file mode 100644 index 0000000..66ab689 --- /dev/null +++ b/src/dsc.md @@ -0,0 +1 @@ +# DSC - Damn Simple Code diff --git a/src/emulator.md b/src/emulator.md new file mode 100644 index 0000000..fd8b03d --- /dev/null +++ b/src/emulator.md @@ -0,0 +1,12 @@ +# DSA Emulator +# DSA Emulator + +The DSA Emulator is a visual emulator that allows you to debug and test your programs in a controlled environment. It is composed of a control panel, memory inspector, and a built in editor. + +The control panel lets you view all of the registers, step through the instructions, and view the current instruction counter. + +The memory inspector lets you view any region of memory in the emulator. + +The editor contains a built in assembler instance, so you can edit and assemble your code from the comfort of the emulator. + +The loader is responsible for loading your code into memory so that the emulator can run it. diff --git a/src/emulator/building.md b/src/emulator/building.md new file mode 100644 index 0000000..971a0af --- /dev/null +++ b/src/emulator/building.md @@ -0,0 +1 @@ +# Building the Emulator diff --git a/src/emulator/features.md b/src/emulator/features.md new file mode 100644 index 0000000..ead0223 --- /dev/null +++ b/src/emulator/features.md @@ -0,0 +1 @@ +# Features diff --git a/src/emulator/features/control_panel.md b/src/emulator/features/control_panel.md new file mode 100644 index 0000000..8483318 --- /dev/null +++ b/src/emulator/features/control_panel.md @@ -0,0 +1 @@ +# Control Panel diff --git a/src/emulator/features/display.md b/src/emulator/features/display.md new file mode 100644 index 0000000..57f7784 --- /dev/null +++ b/src/emulator/features/display.md @@ -0,0 +1 @@ +# Display diff --git a/src/emulator/features/editor.md b/src/emulator/features/editor.md new file mode 100644 index 0000000..068f68b --- /dev/null +++ b/src/emulator/features/editor.md @@ -0,0 +1 @@ +# Editor diff --git a/src/emulator/features/instruction_history.md b/src/emulator/features/instruction_history.md new file mode 100644 index 0000000..9a7b0b1 --- /dev/null +++ b/src/emulator/features/instruction_history.md @@ -0,0 +1 @@ +# Instruction History diff --git a/src/emulator/features/loader.md b/src/emulator/features/loader.md new file mode 100644 index 0000000..86160c1 --- /dev/null +++ b/src/emulator/features/loader.md @@ -0,0 +1 @@ +# Loader diff --git a/src/emulator/features/memory_inspector.md b/src/emulator/features/memory_inspector.md new file mode 100644 index 0000000..734101e --- /dev/null +++ b/src/emulator/features/memory_inspector.md @@ -0,0 +1 @@ +# Memory Inspector diff --git a/src/emulator/features/stack_inspector.md b/src/emulator/features/stack_inspector.md new file mode 100644 index 0000000..934f8a0 --- /dev/null +++ b/src/emulator/features/stack_inspector.md @@ -0,0 +1 @@ +# Stack Inspector diff --git a/src/misc_languages.md b/src/misc_languages.md new file mode 100644 index 0000000..31f9779 --- /dev/null +++ b/src/misc_languages.md @@ -0,0 +1 @@ +# Other Language Support diff --git a/src/misc_languages/brainf.md b/src/misc_languages/brainf.md new file mode 100644 index 0000000..d81bb0c --- /dev/null +++ b/src/misc_languages/brainf.md @@ -0,0 +1 @@ +# Brainf*