commit 7b779979dd38e376675dd3971271f6c93e539c44
parent d10cfddad74e227b7d797baf69e236ba52ed988c
Author: Christian Ermann <christianermann@gmail.com>
Date: Thu, 24 Oct 2024 18:13:00 -0700
Add 'type'
Diffstat:
3 files changed, 136 insertions(+), 30 deletions(-)
diff --git a/forth.s b/forth.s
@@ -1,35 +1,117 @@
.extern uart_put_char
.extern uart_get_char
+.extern uart_put_string
+.extern __stack_top
-.section ".text"
+#define w a0
+#define x t0
+#define ip s1
+#define psp sp
+#define rsp s2
+#define cell 4
+
+#define load_cell lw
+#define store_cell sw
+
+.macro next
+ load_cell w, 0(ip)
+ load_cell x, 0(w)
+ addi ip, ip, cell
+ jr x
+.endm
+
+.macro push_addr addr
+ la w, version_string
+ push w
+.endm
+
+.macro push_imm imm
+ li w, \imm
+ push w
+.endm
+
+.macro push reg
+ store_cell \reg, -cell(psp)
+ addi psp, psp, -cell
+.endm
+
+.macro pop reg
+ load_cell \reg, 0(psp)
+ addi psp, psp, cell
+.endm
+
+.macro push_ret reg
+ store_cell \reg -cell(rsp)
+ addi rsp, rsp, -cell
+.endm
+
+.macro pop_ret reg
+ load_cell \reg, 0(rsp)
+ addi rsp, rsp, cell
+.endm
+
+.macro defcode name, name_length, flags, label, last
+ .section .data
+ .balign cell
+ .globl name_\label
+name_\label:
+ .int name_\last # 1. Link to the previously defined word.
+ .byte \flags # 3. Set the flags.
+ .byte \name_length # 4. Set the name length.
+ .ascii "\name" # 5. Set the name.
+ .balign cell # 6. Add any padding we may need.
+ .globl \label
+\label:
+ .int code_\label # 7. Set the codeword.
+ .section ".text"
+ .globl code_\label
+code_\label: # 8. This is where our assembly code will go.
+.endm
+
+.macro defword name, name_length, flags, label
+ .section ".rodata"
+ .balign cell
+ .globl name_\label
+name_\label:
+ .int link
+ .equ link, name_\label
+ .byte \flags
+ .byte \name_length
+ .ascii "\name"
+ .balign cell
+ .globl \label
+\label:
+ .int docol
+.endm
+
+.equ name_null, 0
+
+defcode "exit", 4, 0, exit, null
+ pop_ret ip
+ next
+
+defcode "type", 4, 0, type, exit
+ pop a1 # length
+ pop a0 # address
+ jal uart_put_string
+ next
+
+.section ".rodata"
+program:
+ .int type
+
+version_string:
+ .ascii "soup forth rv32\n"
+ version_string_len = (. - version_string)
+
+.section ".text.boot"
start:
- li a0, 'H
- jal uart_put_char
- li a0, 'e
- jal uart_put_char
- li a0, 'l
- jal uart_put_char
- li a0, 'l
- jal uart_put_char
- li a0, 'o
- jal uart_put_char
- li a0, ',
- jal uart_put_char
- li a0, '
- jal uart_put_char
- li a0, 'W
- jal uart_put_char
- li a0, 'o
- jal uart_put_char
- li a0, 'r
- jal uart_put_char
- li a0, 'l
- jal uart_put_char
- li a0, 'd
- jal uart_put_char
- li a0, '!
- jal uart_put_char
- li a0, '\n
- jal uart_put_char
+ la psp, __stacktop
+ la ip, program
+
+ push_addr version_string
+ push_imm version_string_len
+
+ next
diff --git a/ns16550a.s b/ns16550a.s
@@ -1,6 +1,7 @@
.global uart_init
.global uart_put_char
.global uart_get_char
+.global uart_put_string
.equ UART_ADDR, 0x10000000
@@ -47,3 +48,18 @@ _put_char:
sb a0, (t0)
ret
+uart_put_string:
+ addi s2, a0, 0
+ addi s3, a1, 0
+ addi s4, ra, 0
+ blez s3, _out_of_chars
+_next_char:
+ lb a0, 0(s2)
+ addi s2, s2, 1
+ addi s3, s3, -1
+ jal uart_put_char
+ bgtz s3, _next_char
+_out_of_chars:
+ addi ra, s4, 0
+ ret
+
diff --git a/riscv32-virt.ld b/riscv32-virt.ld
@@ -3,7 +3,15 @@ OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(start)
+MEMORY {
+ RAM (rwx) : ORIGIN = 0x80000000, LENGTH = 0x8000000
+}
+
SECTIONS {
- .text 0x80000000 : { *(.text); *(.text.*) }
+ __stacktop = ORIGIN(RAM) + LENGTH(RAM);
+
+ . = ORIGIN(RAM);
+ .text : { *(.text.boot); *(.text); *(.text.*) } >RAM
+ .rodata : { *(.rodata); } >RAM
}