How is this even magic?

So obviously I said that this blog is about magic, but ultimately it’s about magic with computers, and there’s an equivalence between arcane magic and arcane computing: oldnessness.

Around this time you should be realizing that you only have yourself to blame for reading material that’s this contrived.

But in all seriousness, I don’t actually think that computers work by magic, there’s always a deeper understanding to be had of the “sufficiently advanced technology” to make it distinguishable from magic, and there’s more “coagula” to be had the more you “solve”. Or something. So before embarking on Fuzix, I decided to play around a little with CP/M and utilizing the filesystem junk that’s provided for free as part of RomWBW.

Files

By default, an unpartitioned SD card (I assume that’s what it is, I took it straight from the packaging and dumped it into the SPI adapter) is broken up into “slices” of 8MB because CP/M is adorable and that’s all it can handle. On booting into CP/M with a ludicrously overprovisioned 16GB card installed:

    Boot Selection? C

    Loading CP/M 80 v2.2...



    CBIOS v3.0 [WBW]

    Formatting RAMDISK...

    Configuring Drives...

       A:=MD1:0
       B:=MD0:0
       C:=SD0:0
       D:=SD0:1
       E:=SD0:2
       F:=SD0:3
       G:=SD0:4
       H:=SD0:5
       I:=SD0:6
       J:=SD0:7

       1932 Disk Buffer Bytes Free

    CP/M-80 v2.2, 54.0K TPA

    B>

Here A: is (I assume) an as-yet uninserted (by virtue of being nonexistant) floppy drive, B: is the flash ROM with RomWBW et al on (and our current drive as indicated by the prompt) and C: onwards are the drive labels for the slices.

I can list C: thusly:


    B>dir
    B: ASM      COM : CLRDIR   COM : COMPARE  COM : COPY     CFG
    B: COPY     COM : DDT      COM : DDTZ     COM : DUMP     COM
    B: ED       COM : FA16     CFG : FDISK80  COM : FILEATTR COM
    B: FILEDATE CFG : FILEDATE COM : FLASH    COM : INITDIR  CFG
    B: INITDIR  COM : LDDS     COM : LDP2D    COM : LINK     COM
    B: LOAD     COM : MBASIC   COM : NULU     COM : PIP      COM
    B: PUTDS    COM : RELOG    COM : RMAC     COM : STAT     COM
    B: SUBMIT   COM : SUPERSUB COM : TD       CFG : TD       COM
    B: UNARC    COM : XSUB     COM : ZAP      COM : ZCAL     COM
    B: ZCNFG    COM : ZCNFG24  CFG : ZDE      COM : ZPATH    COM
    B: ZSCONFIG COM : ZXD      CFG : ZXD      COM : ASSIGN   COM
    B: FDU      COM : FORMAT   COM : MODE     COM : RTC      COM
    B: SURVEY   COM : SYSCOPY  COM : SYSGEN   COM : TALK     COM
    B: TIMER    COM : XM       COM : INTTEST  COM : CPM      SYS
    B: ZSYS     SYS
    B>

yeet

So I mentioned in one of my previous posts that I like the idea of being able to self-host on this thing, so for starters I’d love to have some docs available seeing as old tools are so user hostile. To do this, I’ll need to be able to copy files across.

XM is an implementation of XModem which is a protocol for transferring files over serial.

A quick google tells us that it’s possible to set up the XM receive with:

XM R C:SOMEFILE.TXT

and to send over the screen session by typing the leader and then:

: !! exec sx somefile.txt

And you’ll end up with SOMEFILE.TXT in your C: drive. all on one line because CP/M uses DOS-style line endings.

Obviously this is a bit of a 3-point turn, and I don’t want to store my copies of these files on Linux with dos line endings, so I wrote yeet:

#!/usr/bin/env bash
set -xe

FILE=$(readlink -f $1)
DEST="C:$(basename $FILE)"

if ! [[ -f $FILE ]]; then
        echo "$FILE is not a file" >&2
        exit 1
fi

screen -p 0 -X stuff "XM R $DEST\n"
sleep 1
screen -p 0 -X exec '!!' bash -c "unix2dos < $FILE | sx -"

This is a pretty rudamentary version with lots of things hardcoded, but essentially it uses the fact that you can send commands to screen from outside of the session.

What yeet does is grab the full path to the file, then extract the file’s basename and tell screen to type XM R C:SOMEFILE.TXT\n into the session (so you need to be at a CP/M prompt)

It then waits a second just in case (it’s not like this sleep command is even the longest delay anyway) and then runs the command exec !! bash -c "unix2dos < /path/to/somefile.txt | sx -" which will send the XModem formatted file as piped to stdin from the output of unix2dos so that not only do we get the file sent, but it’s also got the correct line terminators.

This all works surprisingly well

What next?

Well for starters, the contents of ZDE.TXT which is the full manual for the ZDE visual text editor is too large to open in the ZDE visual text editor - it runs out of memory - and the TYPE command dumps the whole thing without paging, so writing a pager in Z80 ASM seems like a good next project to learn about the platform.

Also, there’s the clear case of the reciprocal command for yeet to fetch a file. This will be trivial, and I also have a name for it.

Because “yeet” is like, Gen-Z slang or something, and it was best explained to me as the reciprocal of the word “yoink” in the phrase:

The Lord yeeteth, and The Lord yoinketh away.