First steps into Collapse OS

literally the first time I've tried using it

So I guess people actually read my zany hot takes on Hacker News, because on a whim I visited the Collapse OS website and noticed right there on the homepage that apparently I’m so good at answering questions about things I learned about 5 minutes prior that Collapse OS’ creator namedropped me for, well, doing a “good job” answering questions about a thing I learned about 5 minutes prior.

*record scratch* Yep, that's me.  You might be wondering how I got myself into this situation.

Those comments were more than a year ago, and I only noticed this a few months ago. Naturally, I felt kinda obligated to join the mailing list. And naturally, after reading the various interesting things on the mailing list, I felt obligated to, you know, actually try out Collapse OS.

This post will probably be all over the place, because I’m literally writing it as I go through the process of obtaining, firing up, and exploring Collapse OS.

What the heck is Collapse OS?

So for those who are looking at this word “Collapse OS” and wondering what in tarnation I’m talking about, the basic elevator pitch is that it’s a minimal operating system designed for a specific kind of global supply chain catastrophe - one in a sort of “goldilocks zone” where the world has gone just sour enough that nobody’s making computer chips anymore, but not quite so south that everyone’s ignoring computers entirely and just hunting each other for sport. It’s written in Forth, and targets a handful of 8-bit chips that are both widespread and easy to scavenge off other things - the main one being the good ol’ Zilog Z80.

But we have so many smartphones and laptops and desktops already; surely we’d be able to get by on those, right?

Sure, but those will all start to break down eventually. Smartphones are hardly built for longevity, and the thermal paste in your average laptop or desktop eventually degrades (and unless you stocked up on a whole bunch of the stuff or maybe some mineral oil for immersion cooling, you’re gonna have a bad time there). Your average Z80 or 8080 or other piddly 8-bit CPU doesn’t really have that problem.

Plus, if things get really bad and we run out of 8-bit CPUs to scavenge… well I tell ya hwat I’d sure rather be handwiring something like a Z80 than anything 16-bit, let alone 32 or 64.

Let’s build it

There’s apparently a JS version of Collapse OS, but I want some semblance of the real deal. Unfortunately, I don’t happen to have any Z80 hardware nearby to scavenge, and I’m too lazy right now to get up and hunt something down, but there’s apparently a virtual machine written in C (creatively named “cvm”) that ships with the Collapse OS download, so I guess I’ll start there, right?

I’m typing this post on a Linux machine, so the process should be pretty straightforward: download the tarball, extract it, and make it, right?

northrup@DESKTOP-H5JOODG:~/opt/collapseos-20210802> ls
arch     blk.fs   CONTRIBUTING  cvm  emul    Makefile  sloc.sh  tools
AUTHORS  CHANGES  COPYING       doc  extras  README    TODO
northrup@DESKTOP-H5JOODG:~/opt/collapseos-20210802> make
find arch cvm emul tools -name Makefile -execdir make clean \;
make[1]: Entering directory '/home/northrup/opt/collapseos-20210802/arch/8086/pcat'
rm -f *.bin
make[1]: Leaving directory '/home/northrup/opt/collapseos-20210802/arch/8086/pcat'
make[1]: Entering directory '/home/northrup/opt/collapseos-20210802/arch/z80/ti84'
rm -f *.bin *.rom *.8xu
make[1]: Leaving directory '/home/northrup/opt/collapseos-20210802/arch/z80/ti84'
make[1]: Entering directory '/home/northrup/opt/collapseos-20210802/arch/z80/trs80-4p'
rm -f *.bin
make[1]: Leaving directory '/home/northrup/opt/collapseos-20210802/arch/z80/trs80-4p'
make[1]: Entering directory '/home/northrup/opt/collapseos-20210802/arch/z80/sms'
rm -f os.sms
make[1]: Leaving directory '/home/northrup/opt/collapseos-20210802/arch/z80/sms'
make[1]: Entering directory '/home/northrup/opt/collapseos-20210802/arch/z80/rc2014'
rm -f os.bin
make[1]: Leaving directory '/home/northrup/opt/collapseos-20210802/arch/z80/rc2014'
make[1]: Entering directory '/home/northrup/opt/collapseos-20210802/arch/z80/z80mbc2'
rm -f os.bin
make[1]: Leaving directory '/home/northrup/opt/collapseos-20210802/arch/z80/z80mbc2'
make[1]: Entering directory '/home/northrup/opt/collapseos-20210802/arch/6809/coco2'
rm -f os.bin
make[1]: Leaving directory '/home/northrup/opt/collapseos-20210802/arch/6809/coco2'
make[1]: Entering directory '/home/northrup/opt/collapseos-20210802/cvm'
rm -f stage cos-serial cos-grid *.o grid.bin blkfs
make[1]: Leaving directory '/home/northrup/opt/collapseos-20210802/cvm'
make[1]: Entering directory '/home/northrup/opt/collapseos-20210802/emul/8086'
rm -f forth pcat cpu.o forth.bin
make[1]: Leaving directory '/home/northrup/opt/collapseos-20210802/emul/8086'
make[1]: Entering directory '/home/northrup/opt/collapseos-20210802/emul/z80'
rm -f forth rc2014 sms ti84 *.o *.bin
make[1]: Leaving directory '/home/northrup/opt/collapseos-20210802/emul/z80'
make[1]: Entering directory '/home/northrup/opt/collapseos-20210802/tools'
rm -f memdump upload ttysafe pingpong exec blkpack blkunpack blkup blkdown common.o
make[1]: Leaving directory '/home/northrup/opt/collapseos-20210802/tools'
find . -name memdump -or -name "*.core" -delete

Well that didn’t do much. Maybe I need to just make cvm directly?

northrup@DESKTOP-H5JOODG:~/opt/collapseos-20210802> cd cvm
northrup@DESKTOP-H5JOODG:~/opt/collapseos-20210802/cvm> make
cc -c -std=c89  vm.c -o vm.o
make -C ../tools blkpack
make[1]: Entering directory '/home/northrup/opt/collapseos-20210802/tools'
cc  -c common.c -o common.o
cc  blkpack.c common.o -o blkpack
make[1]: Leaving directory '/home/northrup/opt/collapseos-20210802/tools'
cat ../blk.fs ../extras/emul6809.fs ../extras/tests.fs | ../tools/blkpack > blkfs
Block 0 encountered. Bumping current blkid to 530.
Block 0 encountered. Bumping current blkid to 550.
cc -std=c89  -DFBIN_PATH=\"`pwd`/serial.bin\" -DBLKFS_PATH=\"`pwd`/blkfs\" stage.c vm.o -o stage
cc -std=c89  -I. -DFBIN_PATH=\"`pwd`/serial.bin\" -DBLKFS_PATH=\"`pwd`/blkfs\" cos-serial.c vm.o -o cos-serial
cat common.fs grid.fs | ./stage > grid.bin
Using blkfs /home/northrup/opt/collapseos-20210802/cvm/blkfs
Collapse OS ok
\ This is xcomp code that is common to both serial and grid
 ok
\ binaries.
 ok
3 VALUES PS_ADDR $fffa RS_ADDR $ff00 HERESTART 0
 ok
RS_ADDR $90 - VALUE SYSVARS
 ok
SYSVARS $80 + VALUE GRID_MEM
 ok
ASM
 ok
CREATE nativeidx 0 ,
 ok
: NATIVE nativeidx @ DUP C, 1+ nativeidx ! ;
 ok
XCOMPL XCOMPH
201 202 203 204 205  ok

 ok
HERE TO ORG
 ok
$15 ALLOT0
 ok
( END OF STABLE ABI )
 ok
CODE EXIT NATIVE
 ok
CODE (br) NATIVE
 ok
CODE (?br) NATIVE
 ok
CODE (loop) NATIVE
 ok
CODE (b) NATIVE
 ok
CODE (n) NATIVE
 ok
CODE (s) NATIVE
 ok
CODE >R NATIVE
 ok
CODE R> NATIVE
 ok
CODE 2>R NATIVE
 ok
CODE 2R> NATIVE
 ok
CODE EXECUTE NATIVE
 ok
CODE ROT NATIVE
 ok
CODE DUP NATIVE
 ok
CODE ?DUP NATIVE
 ok
CODE DROP NATIVE
 ok
CODE SWAP NATIVE
 ok
CODE OVER NATIVE
 ok
CODE AND NATIVE
 ok
CODE OR NATIVE
 ok
CODE XOR NATIVE
 ok
CODE NOT NATIVE
 ok
CODE + NATIVE
 ok
CODE - NATIVE
 ok
CODE * NATIVE
 ok
CODE /MOD NATIVE
 ok
CODE ! NATIVE
 ok
CODE @ NATIVE
 ok
CODE C! NATIVE
 ok
CODE C@ NATIVE
 ok
CODE PC! NATIVE
 ok
CODE PC@ NATIVE
 ok
CODE I NATIVE
 ok
CODE I' NATIVE
 ok
CODE J NATIVE
 ok
CODE BYE NATIVE
 ok
CODE ABORT NATIVE
 ok
CODE QUIT NATIVE
 ok
CODE []= NATIVE
 ok
CODE = NATIVE
 ok
CODE < NATIVE
 ok
CODE FIND NATIVE
 ok
CODE 1+ NATIVE
 ok
CODE 1- NATIVE
 ok
CODE TICKS NATIVE
 ok
CODE ROT> NATIVE
 ok
CODE CRC16 NATIVE
 ok
CODE CARRY? NATIVE
 ok
CODE >> NATIVE
 ok
CODE << NATIVE
 ok
CODE >>8 NATIVE
 ok
CODE <<8 NATIVE
 ok
CODE 'S NATIVE
 ok
CODE 'R NATIVE
 ok
CODE FILL NATIVE
 ok
CODE MOVE NATIVE
 ok
CODE MOVE- NATIVE
 ok
COREL
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224  ok
: (key?) 0 PC@ 1 ;
 ok
: _ ( n blk( -- ) SWAP ( blk( n )
 ok
  ( n ) L|M 3 PC! 3 PC! ( blkid )
 ok
  ( blk( ) L|M 3 PC! 3 PC! ( dest ) ;
 ok
: (blk@) 1 3 PC! ( read ) _ ;
 ok
: (blk!) 2 3 PC! ( write ) _ ;
 ok
BLKSUB
230 231 232 233 234  ok
: INIT BLK$ ;
 ok
( fork between grid and serial begins here )
 ok
: COLS $03 PC@ ; : LINES $04 PC@ ;
 ok
: CURSOR! ( new old -- )
 ok
    DROP COLS /MOD 6 PC! ( y ) 5 PC! ( x ) ;
 ok
: CELL! ( c pos -- ) 0 CURSOR! 0 PC! ;
 ok
: NEWLN ( ln -- ln ) 1+ DUP LINES = IF 1- 0 7 PC! THEN ;
 ok
GRIDSUB
240 241  ok
: INITG INIT GRID$ ;
 ok
XWRAP INITG
226 227 228 229  ok
ORG HERE BYE
SP fff6 (ffdc) RS ff04 (ff2c)
cc -std=c89  -DFBIN_PATH=\"`pwd`/grid.bin\" -DBLKFS_PATH=\"`pwd`/blkfs\" cos-grid.c vm.o -lcurses -o cos-grid
/usr/lib64/gcc/x86_64-suse-linux/11/../../../../x86_64-suse-linux/bin/ld: cannot find -lcurses
collect2: error: ld returned 1 exit status
make: *** [Makefile:33: cos-grid] Error 1

Well shit. I have openSUSE’s ncurses-devel package installed; maybe it wants ncurses5-devel?

northrup@DESKTOP-H5JOODG:~/opt/collapseos-20210802/cvm> sudo zypper in ncurses5-devel
[sudo] password for root:
Loading repository data...
Reading installed packages...
Resolving package dependencies...

The following 2 NEW packages are going to be installed:
  libncurses5 ncurses5-devel

2 new packages to install.
Overall download size: 955.0 KiB. Already cached: 0 B. After the operation, additional
1.8 MiB will be used.
Continue? [y/n/v/...? shows all options] (y):
Retrieving package libncurses5-6.2.20210724-24.1.x86_64
                                                  (1/2), 608.3 KiB (  1.2 MiB unpacked)
Retrieving: libncurses5-6.2.20210724-24.1.x86_64.rpm ...............[done (11.8 KiB/s)]
Retrieving package ncurses5-devel-6.2.20210724-24.1.x86_64
                                                  (2/2), 346.7 KiB (693.5 KiB unpacked)
Retrieving: ncurses5-devel-6.2.20210724-24.1.x86_64.rpm .........................[done]

Checking for file conflicts: ....................................................[done]
(1/2) Installing: libncurses5-6.2.20210724-24.1.x86_64 ..........................[done]
(2/2) Installing: ncurses5-devel-6.2.20210724-24.1.x86_64 .......................[done]
northrup@DESKTOP-H5JOODG:~/opt/collapseos-20210802/cvm> make
cc -std=c89  -DFBIN_PATH=\"`pwd`/grid.bin\" -DBLKFS_PATH=\"`pwd`/blkfs\" cos-grid.c vm.o -lcurses -o cos-grid
/usr/lib64/gcc/x86_64-suse-linux/11/../../../../x86_64-suse-linux/bin/ld: cannot find -lcurses
collect2: error: ld returned 1 exit status
make: *** [Makefile:33: cos-grid] Error 1

Dang nabbit. Maybe I just need to force it to use ncurses?

northrup@DESKTOP-H5JOODG:~/opt/collapseos-20210802/cvm> cp Makefile Makefile.old
northrup@DESKTOP-H5JOODG:~/opt/collapseos-20210802/cvm> sed 's/lcurses/lncurses/g' Makefile.old > Makefile
northrup@DESKTOP-H5JOODG:~/opt/collapseos-20210802/cvm> make
cc -std=c89  -DFBIN_PATH=\"`pwd`/grid.bin\" -DBLKFS_PATH=\"`pwd`/blkfs\" cos-grid.c vm.o -lncurses -o cos-grid
northrup@DESKTOP-H5JOODG:~/opt/collapseos-20210802/cvm> ls
blkfs      cos-grid.c    grid.bin  Makefile.old  serial.fs  vm.c
common.fs  cos-serial    grid.fs   README        stage      vm.h
cos-grid   cos-serial.c  Makefile  serial.bin    stage.c    vm.o

Ayyy that seemed to do it! …but now what? README says:

Build

Running make will yield 3 executables:

cos-serial: a Collapse OS prompt running in serial mode. It’s the simplest way to run Collapse OS, but it can’t run Grid applications such as the Visual Editor. However, it can be used non-interactively, that is, you can pipe commands to interpret to it.

cos-grid: Emulates a 80x32 grid using the “curses” library and runs Collapse OS within it. It can run Grid applications such as the Visual Editor.

stage: special binary used to compile and spit. Instead of spitting contents to stdout, it does so on stderr, and at the end of its run, pops the 2 last elements of the PSP, considers it a spitting range, and dumps the contents of its memory within that range.

To play around, you’ll almost always want to run “make && ./cos-grid”.

Oh, okay, maybe I should’ve read that first…

northrup@DESKTOP-H5JOODG:~/opt/collapseos-20210802/cvm> make && ./cos-grid
┌────────────────────────────────────────────────────────────────────────────────┐
│Collapse OS ok                                                                  │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                                                │
│                                                        SP fff8 (fff0) RS ff10 (ff1a)

Well hot diggity damn, it’s runnin’!

Baby steps

So it’s Forth, right? Might as well make sure.

1 1 +
 ok
.
2 ok

Yep, sure is Forth. What else can I do in here? Quick glance at doc/intro.txt

Where to begin?

If you’re reading this and don’t know where to begin, you’re likely to have access to a modern computer. The best place to begin is to build the C VM of Collapse OS in /cvm. You can then begin playing with it with the help of usage.txt and impl.txt.

Aight, let’s check out doc/usage.txt.

If you already know Forth, start here. Otherwise, read primer.txt first.

"That sign can't stop me because I can't read!"

But this and doc/impl.txt seem to be mostly implementation details and other specifics around Collapse OS’ Forth dialect, so fine, I guess I’ll go peruse doc/primer.txt.

42 $8000 C! $8000 C@ .

This writes the byte “42” at address $8000, and then reads back that byte from the same address and print it.

Well that’s neat.

The cell size in Collapse OS is 16 bit, that is, each item in stacks is 16 bit, @ and ! read and write 16 bit numbers. Whenever we refer to a number, a pointer, we speak of 16 bit.

To read and write bytes, use C@ and C!.

Nice. So if I do…

: read8000 $8000 C@ ;
 ok
: write8000 $8000 C! ;
 ok
123 write8000
 ok
read8000 .
 123 ok
read8000 .
 123 ok

Cool, so I can store stuff outside the stack. That’ll surely come in handy.

Starting Forth by Leo Brodie explains all of this in detail. Read this if you can. If you can’t, well, let this sink in for a while, browse the dictionary (dict.txt) and try to understand why this or that word is immediate. Good luck!

Aight, let’s look for some cool stuff in doc/dict.txt, then!

Arithmetic / Bits

Oh cool, I can do math.

1 3 mod
mod word not found ok

Oh. I guess Collapse OS is case-sensitive. Makes sense.

1 3 MOD .
1 ok

Uhhh apparently I can’t scroll?

Didn’t take long for me to hit the bottom of the “grid”, and it seems there’s no autoscroll. Hmmm… maybe doc/grid.txt has something to say about that?

…nope, but it does say:

AT-XY ( x y – ) moves the cursor to the specified position. It is equivalent to setting XYPOS directly, but uses separate X and y numbers.

And whaddya know, blindly typing in 0 0 AT-XY did indeed move the cursor back up top. Doesn’t clear the line automatically when I’m in it, though.

The clearing of the newly entered line is usually only desirable when in “shell” mode. In “graphical” mode, we usually don’t want this to happen. XYMODE is a flag to indicate whether the grid system is in “graphical” mode. When its value is nonzero, NEWLN is not called when entering a new line.

Okay, and

XYMODE .
XYMODE word not found ok

Huh.

NEWLN
stack underflow ok
0 NEWLN
ok

Well that didn’t do much, either.

But can I at least clear the screen?

Maybe…

CELLS
CELLS word not found ok
: CELLS COLS LINES * ;
 ok
CELLS .
2560 ok

Well that’s promising.

'? CLEAR .
0 ok

Alright, cool, name ain’t taken. So…

: CLEAR CELLS 1 - 0 DO ' ' I CELL! LOOP 0 0 AT-XY ;
 ok
CLEAR
 ok

Well it didn’t hang, but it didn’t clear my dang screen, either.

' ' 1 CELL!
 ok

And that sure did turn the second character on the grid into some character my terminal’s font can’t comprehend. I guess a space ain’t a space? Or maybe I just don’t know the syntax there. Let’s test the other part of the function…

: FOO CELLS 1 - 0 DO I . SPC> LOOP ;
 ok
FOO
( yeah it's just a bunch of numbers, y'all )

Oh wait a second, maybe it is auto-scrolling. Is my terminal just not tall enough?

Aight, still looks ugly, but at least I can see what I’m typing when I hit the bottom. Still wanna clear the screen, though…

: CLEAR 0 0 AT-XY CELLS 1 - 0 DO SPC> LOOP 0 0 AT-XY ;
ok
CLEAR
ok

And the screen’s clear! Well, except for the status line being a bit up in the air at the moment, but still, good enough.

Aight now where was I…?

Right, I was playing around a bit with MOD, right?

3 3 MOD .
0 ok
5 5 MOD .
0 ok
15 3 MOD .
0 ok
15 5 MOD .
0 ok

Hmmm…

: IS-FIZZ 3 MOD 0 = ;
br ovfl ok

What the heck does that mean?

3 IS-FIZZ .
1 ok

Works anyway, I guess. Onward…

: IS-BUZZ 5 MOD 0 = ;
ok
: IS-FIZZBUZZ IS-FIZZ IS-BUZZ AND ;
ok
5 IS-BUZZ .
1 ok
3 IS-BUZZ .
0 ok
3 IS-FIZZBUZZ .
0 ok
5 IS-FIZZBUZZ .
stack underflow ok

Whoops! Got a bit lost with my stack there, I guess. Easy enough to fix.

: IS-FIZZBUZZ DUP IS-FIZZ SWAP IS-BUZZ AND ;
ok
3 IS-FIZZBUZZ .
0 ok
5 IS-FIZZBUZZ .
0 ok
15 IS-FIZZBUZZ .
1 ok

How do strings work, though?

LIT" fizz"
ok
.
stack underflow ok

Uhh…

W" fizz"
ok
.
stack underflow ok
," fizz"
ok
.
stack underflow ok

Oh wait a sec…

." fizz" STYPE
stack underflow ok

Fuck.

LIT" fizz" STYPE
stack underflow ok

Maybe I should just look at some actual code? Hmmm… oooh, the memory editor has this little ditty:

: status 0 COLS nspcs
  0 0 AT-XY ." A: " ADDR .X SPC> ." C: " POS .X SPC> ." S: "
  SCNT ?DUP IF 0 DO 'S I << + @ .X SPC> LOOP THEN POS pos! ;

…wait, have I just been overthinking this the whole time?

: foo ." fizz" ;
ok
foo
fizz ok

You motherf- you know, kinda silly to blame a little 8-bit Forth machine for my own ineptitude, right? Let’s just forget that all happened and put it all together.

: FIZZBUZZ
ok
  100 1 DO
ok
    I IS-FIZZ IF ." fizz"
ok
              ELSE I IS-BUZZ IF ." buzz"
ok
                             ELSE I IS-FIZZBUZZ IF ." fizzbuzz"
ok
                                                ELSE I
ok
                                                THEN
ok
                             THEN
ok
              THEN
ok
  LOOP
ok
;
ok
FIZZBUZZ

And it was at that precise moment that cvm came crashing down, leaving me with a clear-as-mud SP ff8a (ff84) RS ff08 (ff22) and my terminal prompt.

But I just realized that this was no Collapse OS bug, but rather me forgetting a teensy weensy . and (I’m guessing) blowing out the poor little VM’s stack. So let’s fire it back up, and I wanna try the non-grid VM this time.

northrup@DESKTOP-H5JOODG:~/opt/collapseos-20210802/cvm> make && ./cos-serial
make: Nothing to be done for 'all'.
Using blkfs /home/northrup/opt/collapseos-20210802/cvm/blkfs
Collapse OS ok
: IS-FIZZ 3 MOD 0 = ;
 ok
: IS-BUZZ 5 MOD 0 = ;
 ok
: IS-FIZZBUZZ DUP IS-FIZZ SWAP IS-BUZZ AND ;
 ok
: FIZZBUZZ 100 1 DO I IS-FIZZ IF ." fizz" ELSE I IS-BUZZ IF ." b
 ok

Aight that was weird. Let’s clean up and try again…

.
4556 ok
.
4549 ok
.
4531 ok
.
stack underflow ok
.
stack underflow ok
: FIZZBUZZ 100 1 DO
 ok
I IS-FIZZ IF ." fizz"
 ok
ELSE I IS-BUZZ IF ." buzz"
 ok
ELSE I IS-FIZZBUZZ IF ." fizzbuzz"
 ok
ELSE I . THEN THEN THEN LOOP ;
 ok
FIZZBUZZ
12fizz4buzzfizz78fizzbuzz11fizz1314fizz1617fizz19buzzfizz2223fizzbuzz26fizz2829fizz3132fizz34buzzfizz3738fizzbuzz41fizz4344fizz4647fizz49buzzfizz5253fizzbuzz56fizz5859fizz6162fizz64buzzfizz6768fizzbuzz71fizz7374fizz7677fizz79buzzfizz8283fizzbuzz86fizz8889fizz9192fizz94buzzfizz9798fizz ok

Oi, forgot spaces. And I messed up the order of the fizzbuzz checks. And… wait, can I pipe into cos-serial, right? Let’s make a fizzbuzz.forth real quick…

: IS-FIZZ 3 MOD 0 = ;
: IS-BUZZ 5 MOD 0 = ;
: IS-FIZZBUZZ DUP IS-FIZZ SWAP IS-BUZZ AND ;
: FIZZBUZZ
  100 1 DO
    I IS-FIZZBUZZ IF ." fizzbuzz"
                  ELSE I IS-BUZZ IF ." buzz"
                                 ELSE I IS-FIZZ IF ." fizz"
                                                ELSE I .
                                                THEN
                                 THEN
                  THEN
    SPC> LOOP
;
FIZZBUZZ

And the moment of truth…

northrup@DESKTOP-H5JOODG:~/opt/collapseos-20210802/cvm> ./cos-serial <fizzbuzz.forth
Using blkfs /home/northrup/opt/collapseos-20210802/cvm/blkfs
Collapse OS ok
: IS-FIZZ 3 MOD 0 = ;
 ok
: IS-BUZZ 5 MOD 0 = ;
 ok
: IS-FIZZBUZZ DUP IS-FIZZ SWAP IS-BUZZ AND ;
 ok
: FIZZBUZZ
 ok
  100 1 DO
 ok
    I IS-FIZZBUZZ IF ." fizzbuzz"
 ok
                  ELSE I IS-BUZZ IF ." buzz"
 ok
                                 ELSE I IS-FIZZ IF ." fizz"
 ok
                                                ELSE I .
 ok
                                                THEN
 ok
                                 THEN
 ok
                  THEN
 ok
    SPC> LOOP
 ok
;
 ok
FIZZBUZZ
1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 fizz 19 buzz fizz 22 23 fizz buzz 26 fizz 28 29 fizzbuzz 31 32 fizz 34 buzz fizz 37 38 fizz buzz 41 fizz 43 44 fizzbuzz 46 47 fizz 49 buzz fizz 52 53 fizz buzz 56 fizz 58 59 fizzbuzz 61 62 fizz 64 buzz fizz 67 68 fizz buzz 71 fizz 73 74 fizzbuzz 76 77 fizz 79 buzz fizz 82 83 fizz buzz 86 fizz 88 89 fizzbuzz 91 92 fizz 94 buzz fizz 97 98 fizz  ok
BYE
SP fffa (ffe6) RS ff04 (ff16)

Alright, I can officially add Forth and Collapse OS to my résumé now!

So what have we learned?

Collapse OS is pretty cool so far. It’s a fun little system, but just as importantly, it’s definitely gonna be a tool in my post-apocalyptic toolbox. Just as importantly as that, though, is that I can see this having some use before then; why wait for the world to end when folks can start whipping up apocalypse-ready hardware and software?

I haven’t gotten to any of the built-in programs yet; there’s apparently a memory editor and two text editors at the very least. I also haven’t gotten around to doing anything with persistent storage yet. Maybe next time!