https://github.com/programandala-net/solo-forth
Standard Forth system for ZX Spectrum 128 and compatible computers, with disk drives.
https://github.com/programandala-net/solo-forth
forth zx-spectrum
Last synced: 5 months ago
JSON representation
Standard Forth system for ZX Spectrum 128 and compatible computers, with disk drives.
- Host: GitHub
- URL: https://github.com/programandala-net/solo-forth
- Owner: programandala-net
- License: other
- Created: 2016-10-23T15:05:46.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2025-02-24T14:53:24.000Z (9 months ago)
- Last Synced: 2025-02-24T15:43:46.827Z (9 months ago)
- Topics: forth, zx-spectrum
- Language: Forth
- Homepage: http://programandala.net/en.program.solo_forth.html
- Size: 14.6 MB
- Stars: 23
- Watchers: 8
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.adoc
- License: LICENSE.txt
Awesome Lists containing this project
README
= Solo Forth
:author: Marcos Cruz (programandala.net)
:revdate: 2025-02-24
:toc:
:linkattrs:
// This file is part of Solo Forth
// http://programandala.net/en.program.solo_forth.html
// Last modified: 20250224T1550+0100.
// Description {{{1
== Description
// tag::description[]
Solo Forth is a Forth system for the ZX Spectrum 128 and
compatible computers, with disk drives and +3DOS, G+DOS, or TR-DOS.
Solo Forth cannot run on the original ZX Spectrum 48, but could be
used to develop programs for it.
Solo Forth can be used as a stand-alone Forth system (either in an
emulator or on the real computer), or as part of a cross-development
environment in a GNU/Linux operating system (in theory, other type of
operating systems could be used as well).
// end::description[]
=== Main features
// tag::mainfeatures[]
- Fast DTC (Direct Threaded Code) implementation.
- A kernel as small as possible.
- Name space in banked memory, separated from code and data space.
- Easy access to banked memory.
- Big <<_library,library>> of useful source code.
- Modular <<_platforms,DOS support>>.
- Fully documented source code.
- Detailed documentation.
- Conform to the http://forth-standard.org[Forth
standard,role="external"] (not fully tested yet).
// end::mainfeatures[]
=== Minimum requirements
// XXX REMARK -- These are generic requirements. The manual contains
// more details, depending on the DOS.
- 128 KiB RAM.
- One double-sided 80-track disk drive (two or three recommended,
depending on the DOS).
// tag::name[]
// == Name
// XXX TODO --
// end::name[]
// Motivation, history and current status {{{1
== Motivation, history and current status
// tag::history[]
The motivation behind Solo Forth is double:
1. *I wanted to program the ZX Spectrum with a modern Forth system*:
In 2015, my
http://programandala.net/en.program.abersoft_forth.html[detailed
disassembly of ZX Spectrum's Abersoft Forth], a popular tape-based
implementation of fig-Forth ported to several 8-bit home computers
in the 1980's (and the Forth system I started learning Forth with
in 1984), helped me understand the inner working of the fig-Forth
model, including its by-design limitations, compared to modern
Forths, and discover some bugs of the ZX Spectrum port. At the same time I
wrote the http://programandala.net/en.program.afera.html[Afera
library] in order to make Abersoft Forth more stable, powerful and
comfortable for cross development.
The objective was reached but, after a
certain point, further improvements weren't feasible without making
radical changes in the system. The need for a new Forth system
arised: a Forth designed from the start to use disk drives and
banked memory, and useful for cross-development.
2. *Nobody had written such a Forth system before:* In 2015 there was
no disk-based Forth for the ZX Spectrum platform, and the only
Forth written for ZX Spectrum 128 (the first model with banked
memory) was Lennart Benschop's Forth-83
(1988). But despite being more powerful than fig-Forth, it is still
tape-based and keeps the block sources in a RAM disk. Besides, the
system is built by metacompilation, what makes it difficult to
adapt to disk drives.
The development of Solo Forth started on 2015-05-30, from the
disassembled code of Abersoft Forth. Some ideas and code were reused
also from the Afera library and from a previous abandoned project
called http://programandala.net/en.program.dzx-forth.html[DZX-Forth]
(a port of CP/M DX-Forth to ZX Spectrum +3e).
On 2016-03-13 a Git repository was created from the development
backups, in order to preserve the evolution of the code from the
start, and uploaded to GitHub. On 2020-12-05 the Git repository was
converted to https://fossil-scm.org[Fossil,role="external"], keeping
http://github.com/programandala-net/solo-forth[GitHub as a
mirror,role="external"]. On 2023-04-06 the repository was converted to
https://mercurial-scm.org[Mercurial,role="external"], enabling a
better interaction with GitHub. On 2023-09-12 the Mercurial repository
was https://hg.sr.ht/~programandala_net/solo_forth[published on
Sourcehut], keeping GitHub as a mirror.
Solo Forth is very stable, and it's being used to develop two projects
in Forth:
http://programandala.net/en.program.nuclear_waste_invaders.html[Nuclear
Waste Invaders] and
http://programandala.net/en.program.black_flag.html[Black Flag].
// end::history[]
// Platforms {{{1
[#_platforms]
== Platforms
// tag::platforms[]
[%autowidth]
.Supported platforms
|===
| Computer | Disk interface | DOS
| Pentagon 128 | | TR-DOS
| Pentagon 512 | | TR-DOS
| Pentagon 1024 | | TR-DOS
| Scorpion ZS 256 | | TR-DOS
| ZX Spectrum 128 | Beta 128 | TR-DOS
| ZX Spectrum 128 | Plus D | G+DOS
| ZX Spectrum +2 | Beta 128 | TR-DOS
| ZX Spectrum +2 | Plus D | G+DOS
| ZX Spectrum +2A | (External disk drive) | +3DOS
| ZX Spectrum +2B | (External disk drive) | +3DOS
| ZX Spectrum +3 | | +3DOS
| ZX Spectrum +3e | | +3DOS
|===
// end::platforms[]
// Project directories {{{1
[#_tree]
== Project directories
// tag::tree[]
// XXX OLD -- This tree was created by ``tree``. The UTF-8 graphic
// characters are ruined by `htmldoc` in the PDF. `asciidoctor-pdf`
// renders it fine, except some descriptions are not aligned.
// ....
// .
// ├── backgrounds Version background images
// ├── bin ZX Spectrum binary files for disk 0
// │ ├── fonts Fonts for the supported screen modes
// │ ├── addons Code that is loaded from disk
// │ │ because it's not assembled in the library yet
// │ └── dos DOS files
// ├── disks Disk images
// │ ├── gplusdos G+DOS disk images
// │ ├── plus3dos +3DOS disk images
// │ └── trdos TR-DOS disk images
// ├── doc Documentation
// ├── make Files used by ``make`` to build the system
// ├── screenshots Version screenshots
// ├── src Sources
// │ ├── inc Z80 symbols files
// │ ├── lib Library
// │ ├── loader BASIC loader for disk 0
// │ ├── addons Code that is loaded from disk
// │ └── doc Files used to build the documentation
// ├── tmp Temporary files created by `make`
// ├── tools Development and user tools
// └── vim Vim files
// ├── ftplugin Filetype plugin
// └── syntax Syntax highlighting
// ....
// XXX OLD -- A table version is not legible enough.
// [%autowidth]
// |===
// | Directory | Description
// | backgrounds | Version background images
// | bin | ZX Spectrum binary files for disk 0
// | bin/addons | Code loaded from disk, not assembled in the library yet
// | bin/dos | DOS files
// | bin/fonts | Fonts for the supported screen modes
// | disks | Disk images
// | disks/gplusdos | G+DOS disk images
// | disks/plus3dos | +3DOS disk images
// | disks/trdos | TR-DOS disk images
// | doc | Documentation
// | make | Files used by ``make`` to build the system
// | screenshots | Version screenshots
// | src | Sources
// | src/addons | Code that is loaded from disk
// | src/doc | Files used to build the documentation
// | src/inc | Z80 symbols
// | src/lib | Library
// | src/loader | BASIC loader for disk 0
// | tmp | Temporary files created by ``make``
// | tools | Development and user tools
// | vim | Vim files
// | vim/ftplugin | Filetype plugin
// | vim/syntax | Syntax highlighting
// |===
// XXX OLD -- A list version.
// * *backgrounds* : Version background images
// * *bin* : ZX Spectrum binary files for disk 0
// - *addons* : Code loaded from disk, not assembled in the library yet
// - *dos* : DOS files
// - *fonts* : Fonts for the supported screen modes
// * *disks* : Disk images
// - *gplusdos* : G+DOS disk images
// - *plus3dos* : +3DOS disk images
// - *trdos* : TR-DOS disk images
// * *doc* : Documentation
// * *make* : Files used by ``make`` to build the system
// * *screenshots* : Version screenshots
// * *src* : Sources
// - *addons* : Code that is loaded from disk
// - *doc* : Files used to build the documentation
// - *inc* : Z80 symbols
// - *lib* : Library
// - *loader* : BASIC loader for disk 0
// * *tmp* : Temporary files created by ``make``
// * *tools* : Development and user tools
// * *vim* : Vim files
// - *ftplugin* : Filetype plugin
// - *syntax* : Syntax highlighting
// XXX OLD -- A description list version.
// [horizontal]
// backgrounds :: Version background images
// bin :: ZX Spectrum binary files for disk 0
// bin/addons :: Code loaded from disk, not assembled in the library yet
// bin/dos :: DOS files
// bin/fonts :: Fonts for the supported screen modes
// disks :: Disk images
// disks/gplusdos :: G+DOS disk images
// disks/plus3dos :: +3DOS disk images
// disks/trdos :: TR-DOS disk images
// doc :: Documentation
// make :: Files used by ``make`` to build the system
// screenshots :: Version screenshots
// src :: Sources
// src/addons :: Code that is loaded from disk
// src/doc :: Files used to build the documentation
// src/inc :: Z80 symbols
// src/lib :: Library
// src/loader :: BASIC loader for disk 0
// tmp :: Temporary files created by ``make``
// tools :: Development and user tools
// vim :: Vim files
// vim/ftplugin :: Filetype plugin
// vim/syntax :: Syntax highlighting
[cols="12,14,54"]
|===
| Directory | Subdirectory | Description
| backgrounds | | Version background images
| bin | | ZX Spectrum binary files for disk 0
| bin | addons | Code loaded from disk, not assembled in the library yet
| bin | dos | DOS files
| bin | fonts | Fonts for the supported screen modes
| disks | | Disk images
| disks | gplusdos | G+DOS disk images
| disks | plus3dos | +3DOS disk images
| disks | trdos | TR-DOS disk images
| doc | | Manuals in DocBook, EPUB, HTML and PDF
| make | | Files used by ``make`` to build the system
| screenshots | | Version screenshots
| src | | Sources
| src | addons | Code to be loaded from disk. Not used yet.
| src | doc | Files used to build the documentation
| src | inc | Z80 symbols
| src | lib | Library
| src | loader | BASIC loader for disk 0
| tmp | | Temporary files created by ``make``
| tools | | Development and user tools
| vim | | Vim files
| vim | ftplugin | Filetype plugin
| vim | syntax | Syntax highlighting
|===
// end::tree[]
// Disks {{{1
== Disks
The directory of the <<_tree,directory tree>> contains the
disk images:
....
disks/*/disk_0_boot.*
disks/*/disk_1*_library.*
disks/*/disk_2_programs.*
disks/*/disk_3_workbench.*
....
The subdirectory and the filename extension of every DOS are the
following:
[cols="6,11,18"]
.DOS subdirectories and disk image filename extensions
|===
| DOS | Subdirectory | Filename extension
| +3DOS | plus3dos | dsk
| G+DOS | gplusdos | mgt
| TR-DOS | trdos | trd
|===
// How to run {{{1
[#_run]
== How to run
// tag::attributes[]
:diskdriveformat: Make sure its disk drives are \
configured as double-sided and 80-track in the emulator.
// end::attributes[]
// In +3DOS {{{2
[#_run_plus3dos]
=== In +3DOS
// On ZX Spectrum +3/+3e {{{3
==== On ZX Spectrum +3/+3e
// tag::run_plus3[]
// XXX REMARK -- A problem with Asciidoctor makes the rendering of the
// ZX Spectrum +3e link text fail. It seems the error condition has to
// do with a combination of "+" be at start of a new line, and the
// presence of the link attribute. The result is the "+3e" part is
// omited. Using ``{sp}`` to prevent the text from being splitted
// fixes the problem.
// XXX REMARK -- This tag does not include the title, because this is
// the only entry for +3DOS, and the computers are mentioned in item
// 1:
1. Run a ZX Spectrum emulator and select a ZX Spectrum +3 (or
http://www.worldofspectrum.org/zxplus3e/[ZX
Spectrum{sp}+3e,role="external"]). {diskdriveformat}
2. “Insert” the disk image file as
disk 'A'.
3. Choose “Loader” from the computer start menu. Solo Forth will be
loaded from disk.
// end::run_plus3[]
// In G+DOS {{{2
[#_run_gplusdos]
=== In G+DOS
// On ZX Spectrum 128/+2 with the Plus D interface {{{3
==== On ZX Spectrum 128/+2 with the Plus D interface
// tag::run_128_with_plusd[]
// XXX REMARK -- This tag does not include the title, because this is
// the only entry for +3DOS, and the computers are mentioned in item
// 1:
1. Run a ZX Spectrum emulator and select a ZX Spectrum 128 (or ZX
Spectrum +2) with the Plus D disk interface. {diskdriveformat}
2. “Insert” the disk image file as
disk 1 of the Plus D disk interface.
3. Choose "128 BASIC" from the computer start menu.
4. Type ``run`` in BASIC. G+DOS will be loaded from disk, and Solo
Forth as well.
// end::run_128_with_plusd[]
// In TR-DOS {{{2
[#_run_trdos]
=== In TR-DOS
// tag::trdos_disk_drives[]
[IMPORTANT]
--
[#trdosdiskdrives]
The TR-DOS version of Solo Forth uses numbers as disk drive
identifiers (the same numbers TR-DOS uses internally) instead of the
letters used by the TR-DOS BASIC interface:
.TR-DOS disk drive identifiers
|===
| Drive | In TR-DOS | In Solo Forth
| 1st | A | 0
| 2nd | B | 1
| 3rd | C | 2
| 4th | D | 3
|===
--
// end::trdos_disk_drives[]
// tag::run_pentagon[]
// On Pentagon 128 {{{3
==== On Pentagon 128
1. Run a ZX Spectrum emulator and select a Pentagon 128.
{diskdriveformat}
2. “Insert” the disk image file as
disk 'A'.
3. Choose “TR-DOS” from the computer start menu. This will enter the
TR-DOS command line{blank}footnote:trdoscli[The TR-DOS command line
uses keyboard tokens, like the ZX Spectrum 48, but commands typed
in 'L' cursor mode will be recognized as well, as on the ZX
Spectrum 128 editor. In order to get the 'L' cursor mode you can
type a quote (Symbol Shift + 'P') or press 'E' to get keyword
``REM``. When the DOS command is typed in full, the quote or the
``REM`` must be removed from the start of the line before pressing
'Enter'.].
4. Press the 'R' key to get the ``RUN`` command and press the Enter
key. Solo Forth will be loaded from disk.
// On Pentagon 512 {{{3
==== On Pentagon 512
1. Run a ZX Spectrum emulator and select a Pentagon 512.
{diskdriveformat}
2. “Insert” the disk image file
as disk 'A'.
3. Choose "128k menu"footnote:pentagonboot[In theory, choosing option
“TR-DOS” from the system service menu should work. But it seems it
depends on a specific version of TR-DOS. This alternative method
is longer, but it works with the TR-DOS 5.03 ROM.] from the
computer start menu (the reset service menu). This will enter a ZX
Spectrum 128 style menu. Choose “TR-DOS”. This will enter the
TR-DOS command line{blank}footnote:trdoscli[].
4. Press the 'R' key to get the ``RUN`` command and press the Enter
key. Solo Forth will be loaded from disk.
// On Pentagon 1024 {{{3
==== On Pentagon 1024
1. Run a ZX Spectrum emulator and select a Pentagon 1024.
{diskdriveformat}
2. “Insert” the disk image file
as disk 'A'.
3. Choose "128k menu"footnote:pentagonboot[] from the computer start
menu (the reset service menu). This will enter a ZX Spectrum 128
style menu. Choose “TR-DOS”. This will enter the TR-DOS command
line{blank}footnote:trdoscli[].
4. Press the 'R' key to get the ``RUN`` command and press the Enter
key. Solo Forth will be loaded from disk.
// end::run_pentagon[]
// tag::run_scorpion[]
// On Scorpion ZS 256 {{{3
==== On Scorpion ZS 256
1. Run a ZX Spectrum emulator and select a Scorpion ZS 256.
{diskdriveformat}
2. “Insert” the disk image file
as disk 'A'.
3. Choose "128 TR-DOS" from the computer start menu. Solo Forth will
be loaded from disk.
// end::run_scorpion[]
// tag::run_128_with_betadisk[]
// On ZX Spectrum 128/+2 with the Beta 128 interface {{{3
==== On ZX Spectrum 128/+2 with the Beta 128 interface
1. Run a ZX Spectrum emulator and select a ZX Spectrum 128 (or ZX
Spectrum +2) with the Beta 128 interface. {diskdriveformat}
2. “Insert” the disk image file as disk
A of the Beta 128 interface.
3. Choose "128 BASIC" from the computer start menu.
4. Type `randomize usr 15616` in BASIC (or just `run usr15616` to save
seven keystrokes). This will enter the TR-DOS command
line{blank}footnote:trdoscli[].
5. Press the 'R' key to get the ``RUN`` command and press the Enter
key. Solo Forth will be loaded from disk.
// end::run_128_with_betadisk[]
// How to use the library {{{1
[#_library]
== How to use the library
// In +3DOS {{{2
=== In +3DOS
// tag::library_on_plus3dos[]
// XXX TODO -- is `set-drive` needed?
1. <<_run_plus3dos,Run Solo Forth>>.
2. “Insert” the file as disk B.
`'b' set-drive throw` to make drive 'B' the current one.
3. Type `1 load` to load block 1 from the library disk. By convention,
block 0 cannot be loaded (it is used for comments), and block 1 is
used as a loader. In Solo Forth, block 1 contains `2 load`, in
order to load the `need` tool from block 2.
4. Type `need name`, were “name” is the name of the word or tool you
want to load from the library.
// end::library_on_plus3dos[]
// In G+DOS {{{2
=== In G+DOS
// tag::library_on_gplusdos[]
1. <<_run_gplusdos,Run Solo Forth>>.
2. “Insert” the file as
disk 2 of the Plus D disk interface. Type `2 set-drive throw` to
make drive 2 the current one.
3. Type `1 load` to load block 1 from the library disk. By convention,
block 0 cannot be loaded (it is used for comments), and block 1 is
used as a loader. In Solo Forth, block 1 contains `2 load`, in
order to load the `need` tool from block 2.
4. Type `need name`, were “name” is the name of the word or tool you
want to load from the library.
// end::library_on_gplusdos[]
// In TR-DOS {{{2
=== In TR-DOS
// tag::library_on_trdos[]
1. <<_run_trdos,Run Solo Forth>>.
2. “Insert” the file into the first
disk drive (called A in TR-DOS and 0 in Solo Forth), and the file
into the second disk drive (called
B in TR-DOS and 1 in Solo Forth).
+
--
Notice that the library is split into two disks because the maximun
capacity of a TR-DOS disk is only 640 KiB.
Also remember in Solo Forth the <> are numbers 0..3 instead of letters A..D.
--
3. Type `1 load` to load block 1 from the first library disk. By
convention, block 0 cannot be loaded (it is used for comments), and
block 1 is used as a loader. In Solo Forth, block 1 contains `2
load`, in order to load the `need` tool from block 2.
4. Type `need 2-block-drives` to load and execute the word
`2-block-drives` from the library, setting the first two drives as
block drives in their normal order.
5. Type `need name`, were “name” is the name of the word or tool you
want to load from the library.
// end::library_on_trdos[]
// Documentation {{{1
== Documentation
The directory contains one version of the manual for every
supported DOS, in EPUB, HTML and PDF formats. The manuals
are built automatically from the sources and other files. At the
moment they contain a description of the Forth system, the basic
information required to use it and a complete glossary with cross
references.