Coder Social home page Coder Social logo

derzforth's People

Contributors

aw avatar theandrew168 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

derzforth's Issues

Split out docs by board

Group the necessary setup, build, program, and interact steps out by board. Some sections will be duped but that's fine. Still cleaner than the weird flow currently in the README.

Consider shrinking the word size for dict entries

Currently, dictionary entries have their entire name spelled out and aligned to a 4-byte boundary. While this is no big deal for words with small names, it starts to really consume Flash / RAM as words get larger. For example, the word name alone for GPIO_CTL_OUT_ALT_OPEN_DRAIN occupies 28 bytes!

There are already strategies in the Forth world to mitigate this issue. Some use a standard 4-byte header to detail the word's length (1 byte) and then the first 3 characters of the name (3 bytes). This method is detailed in the book Threaded Interpretive Languages. This would lead to a high number of collisions for similarly-prefixed words, however.

I wonder if a simple 32-bit string hash would be better fit here? Maybe something like the basic hash function described in TPOP? It'd be fairly easy to implement in assembly, too. I'll do some basic testing to see what sort of collision issues I'd have for the words I currently define to utilize the RCU and GPIO.

Ideas for fixing variables

As discussed previously, variables STATE, HERE, LATEST, TIB should be stored at memory addresses, not in registers.

Below are a few ideas which could help you:

  1. Store each variable at a memory location right below TIB_BASE_ADDR = 0x3000:
TIB = TIB_BASE_ADDR - 4
LATEST = TIB - 4
HERE = LATEST - 4
STATE = HERE - 4
  1. Since the values are in memory instead of registers, the body_fun needs a small change, example:
body_latest:
    li t0, LATEST # load memory address into temporary
    lw t0, 0(t0) # load address stored at LATEST into temporary
    sw t0, 0(DSP) # store address to top of data stack
    addi DSP, DSP, 4 # increment data stack by 32-bits
    j next
  1. Repeat for body_state, body_tib, etc... Well you know, there's quite a few other places this is needed, but if you had macros you could write one which performs those first two instructions (li and lw), so anywhere derzforth.asm makes use of LATEST, STATE, HERE, TIB could be replaced with t0 or something like that.. just a thought (I realize it's not going to be that simple).

I don't know if the above code is correct since I haven't tested it, but I think that's the idea.

General refactor

Once Bronzebeard supports compressed instruction optimizations, make a pass through the DerzForth assembly code to better prepare it for compression. Optimize the register selection as well based on the C extension's "popular" registers. Consider flipping the stack direction but only slightly. Also simplify how procedures are handled: no need to hardcode each arg / ret register if they never nest (or only nest a couple times).

Verify that the existing examples still work.

How to effectively test the project

I've been thinking about how I could verify that DerzForth "works" and that new changes didn't break anything. I think there are a couple of routes:

  1. Find a simulator that works and abstract out the IO-specific portions
  2. Test on a real Longan Nano / Wio Lite and use something like pexpect to test commands / responses

Either way, having something in place to verify behavior will definitely pay itself off as new features / optimizations are introduced.

Forgot a _BIT ?

Hi,

Thanks for that Forth, is a reference for riscv boards.

There is no file file GD32VF103.asm in sources, then I get one from github, but usart control bits have a sufix _BIT, as

USART_STAT_RBNE_BIT = 5
USART_STAT_TBE_BIT = 7

in file https://github.com/theandrew168/derzforth/blob/main/boards/gd32_dev_board/board.asm, there is no suffix, then maybe could changed for

line 98, andi t1, t1, USART_STAT_RBNE # isolate read buffer not empty (RBNE) bit
to
line 98, andi t1, t1, USART_STAT_RBNE_BIT # isolate read buffer not empty (RBNE) bit

line 112, andi t1, t1, USART_STAT_TBE # isolate transmit buffer empty (TBE) bit
to
line 112, andi t1, t1, USART_STAT_TBE_BIT # isolate transmit buffer empty (TBE) bit

Thanks.

Alvaro

Please explain dictionary entry header

I'm trying to understand derzforth's word header but I can't seem to grok how you're defining it.

The sectorforth's diagram of a word's dictionary entry looks like this:

; Each dictionary entry is laid out in memory as such:
;
; *--------------*--------------*--------------*--------------*
; | Link pointer | Flags+Length |    Name...   |    Code...   |
; *--------------*--------------*--------------*--------------*
;     2 bytes         1 byte      Length bytes     Variable
;

I made a diagram for derzforth:

+--------------+-------+-----------+------------+
| Link pointer | Flags | Word Name | Code Field |
---------------+-------+-----------+------------+
  32-bits        2 bits  30 bits     32-bits

My questions to better understand derzforth:

  • Can you confirm if this is accurate?
  • Why is the length not saved in the header as in other Forths?
  • Why are the flags part of the Name instead of a separate byte/word?
  • Why is the Code field always enter?

I think with this knowledge I'll be better positioned to contribute here.

Thanks!

Can beqz simply jump to 0(ra) ?

Hi,

In looking at the functions such as memclr and memcpy, I noticed there's a line like this:

memclr:
    beqz a1, memclr_done  # loop til size == 0
    ...
memclr_done:
    ret

I wonder if it's necessary to jump to a label which only performs a ret .. jalr zero, 0(ra).

Could that label simply be omitted and the code changed to this?:

memclr:
    beqz a1, 0(ra)  # loop til size == 0 then return

I haven't made a PR because I thought maybe there was a reason you did it that way.

Single-line comment support

Currently, the Forth interpreter doesn't properly ignore comments (both backslash line comments and paren-range comments). Ignoring them shouldn't be too hard to do directly in assembly. In the future, comments could possibly be implemented in Forth itself (if that'd even be necessary).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.