Sectorforth is a 16-bit x86 Forth that fits in a 512-byte boot sector

sigalor2 pts0 comments

GitHub - cesarblum/sectorforth: sectorforth is a 16-bit x86 Forth that fits in a 512-byte boot sector. · GitHub

/" data-turbo-transient="true" />

Skip to content

Search/

Sign in<br>Sign upAppearance settings

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

cesarblum

sectorforth

Public

Notifications<br>You must be signed in to change notification settings

Fork<br>34

Star<br>488

master

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>8 Commits<br>8 Commits

examples

examples

LICENSE

LICENSE

Makefile

Makefile

README.md

README.md

sectorforth.asm

sectorforth.asm

View all files

Repository files navigation

sectorforth

sectorforth is a 16-bit x86 Forth that fits in a 512-byte boot sector.

Inspiration to write sectorforth came from a 1996<br>Usenet thread<br>(in particular, Bernd Paysan's first post on the thread).

Batteries not included

sectorforth contains only the eight primitives outlined in the Usenet<br>post above, five variables for manipulating internal state, and two I/O<br>primitives.

With that minimal set of building blocks, words for branching, compiling,<br>manipulating the return stack, etc. can all be written in Forth itself<br>(check out the examples!).

The colon compiler (:) is available, so new words can be defined easily<br>(that means ; is also there, of course).

Contrary to many Forth implementations, sectorforth does not attempt to<br>convert unknown words to numbers, since numbers can be produced using the<br>available primitives. The two included I/O primitives are sufficient to<br>write a more powerful interpreter that can parse numbers.

Primitives

Primitive<br>Stack effects<br>Description

( addr -- x )<br>Fetch memory contents at addr

( x addr -- )<br>Store x at addr

sp@<br>( -- sp )<br>Get pointer to top of data stack

rp@<br>( -- rp )<br>Get pointer to top of return stack

0=<br>( x -- flag )<br>-1 if top of stack is 0, 0 otherwise

( x y -- z )<br>Sum the two numbers at the top of the stack

nand<br>( x y -- z )<br>NAND the two numbers at the top of the stack

exit<br>( r:addr -- )<br>Pop return stack and resume execution at addr

key<br>( -- x )<br>Read key stroke as ASCII character

emit<br>( x -- )<br>Print low byte of x as an ASCII character

Variables

Variable<br>Description

state<br>0: execute words; 1: compile word addresses to the dictionary

tib<br>Terminal input buffer, where input is parsed from

>in<br>Current parsing offset into terminal input buffer

here<br>Pointer to next free position in the dictionary

latest<br>Pointer to most recent dictionary entry

Compiling

sectorforth was developed using NASM 2.15.01. Earlier versions of NASM<br>are probably capable of compiling it, but that hasn't been tested.

To compile sectorforth, just run make:

$ make

That will produce a compiled binary (sectorforth.bin) and a floppy disk<br>image (sectorforth.img) containing the binary in its boot sector.

Running

The makefile contains two targets for running sectorforth in QEMU:

debug starts QEMU in debug mode, with execution paused. That allows<br>you to set up a remote target in GDB (target remote localhost:1234) and<br>set any breakpoints you want before sectorforth starts running.

run simply runs sectorforth in QEMU.

Usage

Up to 4KB of input can be entered per line. After pressing return, the<br>interpreter parses one word at a time an interprets it (i.e. executes it<br>or compiles it, according to the current value of the state variable).

sectorforth does not print the ok prompt familiar to Forth users.<br>However, if a word is not found in the dictionary, the error message !!<br>is printed in red, letting you know an error happened.

When a word is not found in the dictionary, the interpreter's state is<br>reset: the data and return stacks, as well as the terminal input buffer<br>are cleared, and the interpreter is placed in interpretation mode. Other<br>errors (e.g. compiling an invalid address in a word definition and<br>attempting to execute it) are not handled gracefully, and will crash the<br>interpreter.

Code structure

Comments throughout the code assume familiarity with Forth and how it is<br>commonly implemented.

If you're not familiar with Forth, read Leo Brodie's<br>Starting Forth.

If you're not familiar with how Forth is implemented on x86, read the<br>assembly code for Richard W.M. Jones'<br>jonesforth.

sectorforth draws a lot of inspiration from jonesforth, but the latter<br>does a much better job at explaining the basics in its comments.

For an excellent introduction to threaded code techniques, and to how to<br>implement Forth in different architectures, read Brad Rodriguez's<br>Moving Forth.

About<br>sectorforth is a 16-bit x86 Forth that fits in a 512-byte boot sector.<br>Resources<br>Readme<br>MIT license<br>Activity<br>Stars<br>488 stars<br>Watchers<br>14 watching<br>Forks<br>34 forks<br>Report...

sectorforth forth stack addr byte boot

Related Articles