forth-riscv

My forth
git clone git://git.electrosoup.com/forth-riscv
Log | Files | Refs

commit 7b779979dd38e376675dd3971271f6c93e539c44
parent d10cfddad74e227b7d797baf69e236ba52ed988c
Author: Christian Ermann <christianermann@gmail.com>
Date:   Thu, 24 Oct 2024 18:13:00 -0700

Add 'type'

Diffstat:
Mforth.s | 140++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Mns16550a.s | 16++++++++++++++++
Mriscv32-virt.ld | 10+++++++++-
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 }