- What the heck is Collapse OS?
- Let’s build it
- Baby steps
- Where to begin?
- Arithmetic / Bits
- Uhhh apparently I can’t scroll?
- But can I at least clear the screen?
- Aight now where was I…?
- So what have we learned?
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.
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.
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!