Compare commits

...

2 Commits

Author SHA1 Message Date
Virgil Dupras
d777a74be3 Forth takeover! 2020-05-21 22:16:01 -04:00
Virgil Dupras
0939241db1 Add bootstrap guide 2020-05-21 15:25:12 -04:00
18 changed files with 139 additions and 1930 deletions

View File

@ -2,16 +2,18 @@
*Bootstrap post-collapse technology*
Collapse OS is a z80 kernel and a collection of programs, tools and
documentation that allows you to assemble an OS that, when completed, will be
able to:
Collapse OS is a Forth operating system and a collection of tools and
documentation with a single purpose: preserve the ability to program micro-
controllers through civilizational collapse.
It it designed to:
1. Run on minimal and improvised machines.
2. Interface through improvised means (serial, keyboard, display).
3. Edit text files.
4. Compile assembler source files for a wide range of MCUs and CPUs.
5. Read and write from a wide range of storage devices.
6. Replicate itself.
6. Assemble itself and deploy to another machine.
Additionally, the goal of this project is to be as self-contained as possible.
With a copy of this project, a capable and creative person should be able to
@ -19,14 +21,6 @@ manage to build and install Collapse OS without external resources (i.e.
internet) on a machine of her design, built from scavenged parts with low-tech
tools.
## Forth reboot in process
You are currently looking at the `forth` branch of the project, which is a
Forth reboot of Collapse OS. You can see why I'm doing this in the [related
github issue][forth-issue].
Documentation is lacking, it's not ready yet, this is a WIP branch.
## Getting started
Usage documentation is in-system, so access to documentation requires you to
@ -53,6 +47,12 @@ Then, run `0 LIST` for an introduction, follow instructions from there.
The project unfinished but is progressing well! See [Collapse OS' website][web]
for more information.
## Looking for the assembler version?
The Forth-based Collapse OS is the second incarnation of the concept. The first
one was entirely written in z80 assembly. If you're interested in that
incarnation, checkout the `z80asm` branch.
## Discussion
For a general discussion of Collapse OS and the ecosystem of technologies and
@ -64,4 +64,3 @@ channels are also maintained.
[web]: https://collapseos.org
[discussion]: https://www.reddit.com/r/collapseos
[listserv]: http://lists.sonic.net/mailman/listinfo/collapseos
[forth-issue]: https://github.com/hsoft/collapseos/issues/4

View File

@ -6,7 +6,7 @@ MASTER INDEX
150 Extra words
200 Z80 assembler 260 Cross compilation
280 Z80 boot code 350 Core words
410 PS/2 keyboard subsystem
410 PS/2 keyboard subsystem 420 Bootstrap guide
490 TRS-80 Recipe 520 Fonts
550 TI-84+ Recipe 580 RC2014 Recipe
620 Sega Master System Recipe

View File

@ -13,4 +13,4 @@ Contents
4 Number literals 6 Compilation vs meta-comp.
8 Interpreter I/O 11 Signed-ness
14 Addressed devices 17 DOES>
18 Disk blocks
18 Disk blocks 21 How blocks are organized

13
blk/021 Normal file
View File

@ -0,0 +1,13 @@
How blocks are organized
Organization of contiguous blocks is an ongoing challenge and
Collapse OS' blocks are never as tidy as they should, but we
try to strive towards a few goals:
1. Block 0 contains documentation discovery core keys to the
uninitiated.
2. First section (up to B100) is usage documentation.
3. B100-B200 are for runtime usage utilities
4. B200-B500 are for bootstrapping
5. The rest is for recipes.
6. I'm not sure yet how I'll organize multiple arches.

16
blk/420 Normal file
View File

@ -0,0 +1,16 @@
Bootstrap guide
You want to deploy Collapse OS on a new system? Start here.
What is Collapse OS? It is a binary placed either in ROM on
in RAM by a bootloader. That binary, when executed, initializes
itself to a Forth interpreter. In most cases, that Forth
interpreter will have some access to a mass storage device,
which allows it to access Collapse OS' disk blocks and come
to this block to bootstrap itself some more.
This binary can be separated in 5 distinct layers:
1. Boot code (B280)
2. Boot words (B305)
3. Core words (low) (B350)
4. Drivers (cont.)

16
blk/421 Normal file
View File

@ -0,0 +1,16 @@
5. Core words (high)
Boot code (B280)
This part contains core routines that underpins Forth fundamen-
tal structures: dict navigation and search, PSP/RSP bounds
checks, word types (atom, native, literals, "does type"), etc.
It also of course does core initialization: set RSP/PSP, HERE
CURRENT, then find BOOT and call it (see B89).
It also contains what we call the "stable ABI" in its first
0x100 bytes. The beginning og the dict is intertwined in this
layer because EXIT, (br), (?br) and (loop) are part of the
stable ABI.
(cont.)

16
blk/422 Normal file
View File

@ -0,0 +1,16 @@
Boot words (B305)
Then come the implementation of core Forth words in native
assembly. Performance is not Collapse OS' primary design goal,
so we try to keep this section to a minimum: we much prefer
to implement our words in Forth.
However, some words are in this section for performance
reasons. Sometimes, the gain is too great to pass up.
Core words (low) (B350)
Then comes the part where we begin defining words in Forth.
Core words are designed to be cross-compiled (B260), from a
full Forth interpreter. This means that it has access to more
than boot words. This somes with tricky limitations. (cont.)

16
blk/423 Normal file
View File

@ -0,0 +1,16 @@
See B260 for details.
Drivers
Up until now, we haven't implemented EMIT or KEY yet: those
words are defined in the "high" part of core words because we
generally need machine-specific drivers to implement (emit) and
(key).
Well, now is their time to shine. We split core in two
precisely to fit drivers in there. This way. they have access
to a pretty good vocabulary and they're also give the oppor-
tunity to provide (emit) and (key).
(cont.)

16
blk/424 Normal file
View File

@ -0,0 +1,16 @@
Core words (high) (B350)
Then come EMIT, KEY and everything that depend on it, until
we have a full Forth interpreter. At the very end, we define
tricky IMMEDIATEs that, if defined earlier, would break cross
compilation.
We end that with a hook words which is also where CURRENT will
be on boot.
So that's the anatomy of a Collapse OS binary. How do you build
one? If your machine is already covered by a recipe, you're in
luck: follow instructions.
If you're deploying to a new machine, you'll have to write a
new xcomp (cross compilation) unit. Let's look at its (cont.)

16
blk/425 Normal file
View File

@ -0,0 +1,16 @@
anatomy. First, we have constants. Some of them are device-
specific, but some of them are always there. RAMSTART is the
address at which the RAM starts on the system. System variables
will go there and HERE will go after it.
RS_ADDR is where RSP starts and PS_ADDR is where PSP starts.
RSP and PSP are designed to be contiguous. RSP goes up and PSP
goes down. If they meet, we know we have a stack overflow.
Then, we load the assembler and cross compilation unit, which
will be needed for the task ahead.
Then, it's a matter of adding layer after layer. For most
system, all those layers except the drivers will be added the
same way. Drivers are a bit tricker and machine specific. I
can't help you there, you'll have to use your wits. (cont.)

15
blk/426 Normal file
View File

@ -0,0 +1,15 @@
After we've loaded the high part of the core words, we're at
the "wrapping up" part. We add what we call a "hook word" (an
empty word with a single letter name) which doesn't cost us
much and can be very useful if we need to augment the binary
with more words, and at that point we have our future boot
CURRENT, which PC yields. That is why we write it to the
LATEST field of the stable ABI: This value will be used at
boot.
After the last word of the dictionary comes the "source init"
part. The boot sequence is designed to interpret whatever comes
after LATEST as Forth source, and this, until it reads ASCII
EOT character (4). This is generally used for driver init.
Good luck!

View File

@ -1,470 +0,0 @@
.
.
.
.
. .
. .
. .
...
...
. .
..
..
..
..
.
.
.
.
.
.
.
. .
.
. .
..
.
.
.
.
.
.
.
.
.
.
.
.
.
...
.
. .
.
...
.
.
.
...
.
.
.
.
.
.
.
. .
. .
. .
.
.
..
.
.
...
..
.
.
.
...
..
.
..
.
..
. .
. .
...
.
.
...
.
..
.
..
..
.
...
. .
...
...
.
.
.
.
...
. .
...
. .
...
...
. .
...
.
..
.
.
.
.
.
.
.
.
.
.
...
...
.
.
.
.
.
..
.
.
.
.
...
...
.
..
.
. .
...
. .
. .
..
. .
..
. .
..
..
.
.
.
..
..
. .
. .
. .
..
...
.
..
.
...
...
.
..
.
.
..
.
. .
. .
..
. .
. .
...
. .
. .
...
.
.
.
...
...
.
.
.
..
. .
..
.
..
. .
.
.
.
.
...
. .
...
...
. .
. .
..
. .
. .
. .
. .
...
. .
. .
. .
...
..
. .
..
.
.
...
. .
. .
...
..
..
. .
..
. .
. .
..
.
.
.
..
...
.
.
.
.
. .
. .
. .
. .
...
. .
. .
. .
. .
.
. .
. .
...
...
. .
. .
. .
.
. .
. .
. .
. .
.
.
.
...
.
.
.
...
...
.
.
.
...
.
.
.
.
.
...
.
.
.
...
.
. .
...
.
.
..
.
...
...
.
.
..
. .
..
..
.
.
..
.
.
..
. .
..
.
. .
..
..
..
.
..
.
.
.
. .
..
..
.
.
..
. .
. .
.
.
.
.
.
.
.
..
.
. .
..
. .
. .
..
.
.
.
..
. .
...
. .
. .
..
. .
. .
. .
.
. .
. .
.
..
. .
..
.
..
. .
..
.
..
.
.
.
..
..
.
..
.
...
.
.
..
. .
. .
. .
...
. .
. .
. .
.
. .
. .
...
. .
. .
.
.
. .
. .
.
.
.
...
..
..
...
..
.
.
.
..
.
.
.
.
.
..
.
.
.
..
..
..

View File

@ -1,658 +0,0 @@
.
.
.
.
.
.
. .
. .
. .
.....
. .
.....
. .
.
....
.
...
.
....
.
. .
.
.
.
. .
..
. .
..
.. .
. .
... .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
...
.....
...
. . .
.
.
.....
.
.
.
.
.....
..
..
.
.
.
.
...
. .
. ..
. . .
.. .
. .
...
..
. .
.
.
.
.
....
...
. .
.
.
.
.
.....
...
. .
.
..
.
. .
...
..
. .
. .
.....
.
.
.
.....
.
....
.
.
. .
...
...
.
.
....
. .
. .
...
.....
.
.
.
.
.
.
...
. .
. .
...
. .
. .
...
...
. .
. .
...
.
.
...
.
.
.
.
.
.
.
.
.
..
..
.
..
..
.
.....
.....
.
..
..
.
..
..
.
...
. .
.
.
.
.
...
. .
. ..
. ..
.
. .
...
...
. .
. .
.....
. .
. .
. .
....
. .
. .
....
. .
. .
....
...
. .
.
.
.
. .
...
....
. .
. .
. .
. .
. .
....
.....
.
.
....
.
.
.....
.....
.
.
....
.
.
.
...
. .
.
. ..
. .
. .
...
. .
. .
. .
.....
. .
. .
. .
...
.
.
.
.
.
...
..
.
.
.
.
. .
...
. .
. .
..
.
..
. .
. .
.
.
.
.
.
.
.....
. .
.. ..
. . .
. .
. .
. .
. .
. .
.. .
.. .
. . .
. ..
. ..
. .
...
. .
. .
. .
. .
. .
...
....
. .
. .
....
.
.
.
...
. .
. .
. .
. . .
. ..
....
....
. .
. .
....
. .
. .
. .
...
. .
.
...
.
. .
...
.....
.
.
.
.
.
.
. .
. .
. .
. .
. .
. .
...
. .
. .
. .
. .
. .
. .
.
. .
. .
. .
. .
. . .
. . .
. .
. .
. .
. .
.
. .
. .
. .
. .
. .
. .
.
.
.
.
.....
. .
.
.
.
. .
.....
...
.
.
.
.
.
...
.
.
.
.
.
...
.
.
.
.
.
...
.
. .
. .
.....
.
.
...
.
....
. .
....
.
.
...
. .
...
...
. .
.
. .
...
.
.
...
. .
...
...
. .
.....
.
....
..
. .
.
...
.
...
. .
...
. .
..
.
.
...
. .
. .
.
.
.
.
.
.
. .
..
. .
. .
..
. .
. .
..
.
.
.
..
. .
. . .
. .
. .
. .
...
. .
. .
. .
. .
...
. .
. .
. .
...
...
. .
...
.
.
...
. .
...
.
.
. ..
..
.
.
.
...
.
...
.
...
.
...
.
.
..
. .
. .
. .
. .
...
. .
. .
. .
. .
.
. .
. .
. .
. . .
. .
. .
. .
.
. .
. .
. .
. .
.
.
.
.....
.
.
.
.....
..
.
.
.
.
.
..
.
.
.
.
.
.
.
..
.
.
.
.
.
..
. .
. .

View File

@ -1,658 +0,0 @@
..
..
..
..
..
..
.. ..
.. ..
.. ..
.. ..
.. ..
.......
.. ..
.......
.. ..
.. ..
..
......
.. .
.....
. ..
......
..
..
.. ..
..
..
..
.. ..
..
...
.. ..
.. ..
...
.. .. .
.. ..
... ..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
......
....
......
..
..
..
......
..
..
..
..
......
..
..
..
..
..
..
..
....
.. ..
.. ...
......
... ..
.. ..
....
..
...
..
..
..
..
......
....
.. ..
..
..
..
..
......
....
.. ..
..
...
..
.. ..
....
..
...
....
.. ..
......
..
..
......
..
.....
..
..
.. ..
....
...
..
..
.....
.. ..
.. ..
....
......
..
..
..
..
..
..
....
.. ..
.. ..
....
.. ..
.. ..
....
....
.. ..
.. ..
.....
..
..
...
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
......
......
..
..
..
..
..
..
..
....
.. ..
..
..
..
..
....
.. ..
.. ...
.. . .
.. ...
..
....
....
.. ..
.. ..
......
.. ..
.. ..
.. ..
.....
.. ..
.. ..
.....
.. ..
.. ..
.....
....
.. ..
..
..
..
.. ..
....
....
.. ..
.. ..
.. ..
.. ..
.. ..
....
......
..
..
.....
..
..
......
......
..
..
.....
..
..
..
....
.. ..
..
.. ...
.. ..
.. ..
....
.. ..
.. ..
.. ..
......
.. ..
.. ..
.. ..
......
..
..
..
..
..
......
.....
..
..
..
..
.. ..
...
.. ..
.. ..
....
...
....
.. ..
.. ..
..
..
..
..
..
..
......
.. ..
... ...
.......
.. . ..
.. . ..
.. ..
.. ..
.. ..
.. ..
... ..
......
.. ...
.. ..
.. ..
....
.. ..
.. ..
.. ..
.. ..
.. ..
....
.....
.. ..
.. ..
.....
..
..
..
....
.. ..
.. ..
.. ..
.. . .
.. ..
.. ..
.....
.. ..
.. ..
.....
.. ..
.. ..
.. ..
....
.. ..
..
....
..
.. ..
....
......
..
..
..
..
..
..
.. ..
.. ..
.. ..
.. ..
.. ..
.. ..
....
.. ..
.. ..
.. ..
.. ..
.. ..
....
..
.. ..
.. ..
.. . ..
.. . ..
.......
... ...
.. ..
.. ..
.. ..
....
..
....
.. ..
.. ..
.. ..
.. ..
.. ..
....
..
..
..
......
..
..
..
..
..
......
.....
..
..
..
..
..
.....
..
..
..
..
..
.....
..
..
..
..
..
.....
..
....
.. ..
. .
...
.. ..
..
.....
..
..
......
....
..
.....
.. ..
.....
..
..
.....
.. ..
.. ..
.. ..
.....
....
.. ..
..
.. ..
....
..
..
.....
.. ..
.. ..
.. ..
.....
....
.. ..
......
..
....
...
..
..
.....
..
..
..
.....
.. ..
.. ..
.....
..
..
..
.....
.. ..
.. ..
.. ..
.. ..
..
...
..
..
..
....
..
...
..
..
..
..
..
..
.. ..
.. ..
....
.. ..
.. ..
...
..
..
..
..
..
....
.. ..
.......
.. . ..
.. . ..
.. ..
.....
.. ..
.. ..
.. ..
.. ..
....
.. ..
.. ..
.. ..
....
.....
.. ..
.. ..
.....
..
.....
.. ..
.. ..
.....
..
.. ..
... ..
..
..
..
.....
..
....
..
.....
..
..
.....
..
..
..
...
.. ..
.. ..
.. ..
.. ..
.....
.. ..
.. ..
.. ..
....
..
.. ..
.. . ..
.. . ..
.......
.. ..
.. ..
....
..
....
.. ..
.. ..
.. ..
.. ..
.....
..
......
..
..
..
......
..
..
..
...
..
..
..
..
..
..
..
..
..
..
..
..
...
..
..
..
.. .
.. . ..
. ..

View File

@ -1,15 +0,0 @@
# fonts
This folder contains bitmap fonts that are then converted to ASM data tables.
The format for them is straightforward: dots and spaces. Each line is a line in
the letter (for example, in a 6x8 font, each character is 8 lines of 6
characters each, excluding newline).
They cover the 0x21 to 0x7e range and are placed sequentially in the file.
Dots and spaces allow easy visualisation of the result and is thus rather handy.
Padding is excluded from fonts. For example, 5x7.txt is actually a 6x8 font, but
because characters are always padded, it's useless to keep systematic blank
lines or rows around.

View File

@ -1,7 +1,5 @@
MEMDUMP_TGT = memdump
BLKDUMP_TGT = blkdump
UPLOAD_TGT = upload
FONTCOMPILE_TGT = fontcompile
TTYSAFE_TGT = ttysafe
PINGPONG_TGT = pingpong
BIN2C_TGT = bin2c
@ -9,7 +7,7 @@ EXEC_TGT = exec
BLKPACK_TGT = blkpack
BLKUNPACK_TGT = blkunpack
BLKUP_TGT = blkup
TARGETS = $(MEMDUMP_TGT) $(BLKDUMP_TGT) $(UPLOAD_TGT) $(FONTCOMPILE_TGT) \
TARGETS = $(MEMDUMP_TGT) $(UPLOAD_TGT) \
$(TTYSAFE_TGT) $(PINGPONG_TGT) $(BIN2C_TGT) $(EXEC_TGT) $(BLKPACK_TGT) \
$(BLKUNPACK_TGT) $(BLKUP_TGT)
OBJS = common.o
@ -21,9 +19,7 @@ all: $(TARGETS)
$(CC) $(CFLAGS) -c $< -o $@
$(MEMDUMP_TGT): $(MEMDUMP_TGT).c
$(BLKDUMP_TGT): $(BLKDUMP_TGT).c
$(UPLOAD_TGT): $(UPLOAD_TGT).c
$(FONTCOMPILE_TGT): $(FONTCOMPILE_TGT).c
$(TTYSAFE_TGT): $(TTYSAFE_TGT).c
$(PINGPONG_TGT): $(PINGPONG_TGT).c
$(BIN2C_TGT): $(BIN2C_TGT).c

View File

@ -1,38 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include "common.h"
/* Read specified number of bytes in active blkdev at active offset.
*/
int main(int argc, char **argv)
{
if (argc != 3) {
fprintf(stderr, "Usage: ./memdump device bytecount\n");
return 1;
}
unsigned int bytecount = strtol(argv[2], NULL, 16);
if (!bytecount) {
// nothing to spit
return 0;
}
int fd = open(argv[1], O_RDWR|O_NOCTTY);
char s[0x30];
sendcmdp(fd, "i=0");
sprintf(s, "while i<0x%04x getb:puth a:i=i+1", bytecount);
sendcmd(fd, s);
for (int i=0; i<bytecount; i++) {
read(fd, s, 2); // read hex pair
s[2] = 0; // null terminate
unsigned char c = strtol(s, NULL, 16);
putchar(c);
}
read(fd, s, 2); // read prompt
return 0;
}

View File

@ -1,71 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libgen.h>
/* This script converts "space-dot" fonts to binary "glyph rows". One byte for
* each row. In a 5x7 font, each glyph thus use 7 bytes.
* Resulting bytes are aligned to the **left** of the byte. Therefore, for
* a 5-bit wide char, ". . ." translates to 0b10101000
* Left-aligned bytes are easier to work with when compositing glyphs.
*/
int main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: ./fontcompile fpath\n");
return 1;
}
char *fn = basename(argv[1]);
if (!fn) {
return 1;
}
int w = 0;
if ((fn[0] >= '3') && (fn[0] <= '8')) {
w = fn[0] - '0';
}
int h = 0;
if ((fn[2] >= '3') && (fn[2] <= '8')) {
h = fn[2] - '0';
}
if (!w || !h || fn[1] != 'x') {
fprintf(stderr, "Not a font filename: (3-8)x(3-8).txt.\n");
return 1;
}
fprintf(stderr, "Reading a %d x %d font\n", w, h);
FILE *fp = fopen(argv[1], "r");
if (!fp) {
fprintf(stderr, "Can't open %s.\n", argv[1]);
return 1;
}
// We start the binary data with our first char, space, which is not in our
// input but needs to be in our output.
for (int i=0; i<h; i++) {
putchar(0);
}
int lineno = 1;
char buf[0x10];
while (fgets(buf, 0x10, fp)) {
size_t l = strlen(buf);
if (l > w+1) { // +1 because of the newline char.
fprintf(stderr, "Line %d too long.\n", lineno);
fclose(fp);
return 1;
}
// line can be narrower than width. It's padded with spaces.
while (l < w+1) {
buf[l] = ' ';
l++;
}
unsigned char c = 0;
for (int i=0; i<w; i++) {
if (buf[i] == '.') {
c |= (1 << (7-i));
}
}
putchar(c);
lineno++;
}
fclose(fp);
return 0;
}