|
- # TRS-80 Model 4p
-
- The TRS-80 (models 1, 3 and 4) are among the most popular z80
- machines. They're very nicely designed and I got my hands on a
- 4p with two floppy disk drives and a RS-232 port. In this
- recipe, we're going to get Collapse OS running on it.
-
- # Not entirely standalone
-
- Collapse OS uses the TRS-80 drivers rather than its own. On most
- TRS-80 models, those drivers are on ROM, but in the case of the
- 4P model, those drivers are on the TRSDOS disk (well, from what
- I understand, not all of it, but still, a big part of it).
-
- It would be preferable to develop drivers from scratch, but it
- represents a significant effort for a modest payout (because
- it's only actually useful when you want to use a 4P model that
- has no TRSDOS disk).
-
- Maybe those drivers will be developed later, but it's not a
- priority for now.
-
- # Floppy or RS-232?
-
- There are many ways to get Collapse OS to run on it. One would
- involve writing it to a floppy. I bought myself old floppy
- drives for that purpose, but I happen to not have any functional
- computer with a floppy port on it. I still have the motherboard
- of my old pentium, but I don't seem to have a video card for it
- any more.
-
- Because my 4p has a RS-232 port and because I have equipment to
- do serial communication from modern machines (I didn't have a
- DB-9 to DB-25 adapter though, I had to buy one), I chose that
- route.
-
- # Gathering parts
-
- * A TRS-80 model 4p with a RS-232 port
- * A TRSDOS 6.x disk
- * A means to do serial communication. In my case, that meant:
- * A USB-to-serial device
- * A null modem cable
- * A DB-9 gender changer
- * A DB-9 to DB-25 adapter
-
- # Overview
-
- We need to send sizeable binary programs through the RS-232 port
- and then run it. The big challenge here is ensuring data
- integrity. Sure, serial communication has parity check, but it
- has no helpful way of dealing with parity errors. When parity
- check is enabled and that a parity error occurs, the byte is
- simply dropped on the receiving side. Also, a double bit error
- could be missed by those checks.
-
- What we'll do here is to ping back every received byte back and
- have the sender do the comparison and report mismatched data.
-
- Another problem is ASCII control characters. When those are sent
- across serial communication channels, all hell breaks lose. When
- sending binary data, those characters have to be avoided. We use
- tools/ttysafe for that.
-
- Does TRSDOS have a way to receive this binary inside these
- constraints? Not to my knowledge. As far as I know, the COMM
- program doesn't allow this.
-
- What are we going to do? We're going to punch in a binary
- program to handle that kind of reception! You're gonna feel real
- badass about it too...
-
- # Keyboard cheatcheet
-
- The TRS-80 4P keyboard doesn't show all available characters.
- When you hold CLEAR, you can do:
-
- _ --> ENTER
- [] --> <>
- ^ --> ;
- \ --> /
-
- # Building the binary
-
- You can build the binary to send to the TRS-80 with "make" in
- /arch/z80/trs80, which will yield
- "os.bin". You'll need it later.
-
- # Testing serial communication
-
- The first step here is ensuring that you have bi-directional
- serial communication. To do this, first prepare your TRS-80:
-
- set *cl to com
- setcomm (word=8,parity=no)
-
- The first line loads the communication driver from the COM/DRV
- file on the TRSDOS disk and binds it to *cl, the name generally
- used for serial communication devices. The second line sets
- communication parameters in line with what is generally the
- default on modern machine. Note that I left the default of 300
- bauds as-is.
-
- Then, you can run "COMM *cl" to start a serial communication
- console.
-
- Then, on the modern side, use your favorite serial communication
- program and set the tty to 300 baud with option "raw". Make sure
- you have -parenb.
-
- If your line is good, then what you type on either side should
- echo on the other side. If it does not, something's wrong.
- Debug.
-
- # Punching in the goodie
-
- As stated in the overview, we need a program on the TRS-80 that:
-
- 1. Listens to *cl
- 2. Echoes each character back to *cl
- 3. Adjusts ttysafe escapes
- 4. Stores received bytes in memory
-
- You're in luck: that program has already been written. It's in
- B612 and B613 in /arch/z80/trs80/blk. By running "make" earlier,
- you have, in your current folder, a blkfs that contains those
- blocks. To have a forth running on it, you could overwrite
- /cvm/blkfs and run /cvm/forth. You can then compile it with:
-
- 5 LOAD ( z80 assembler )
- 0x0238 CONSTANT COM_DRV_ADDR
- 0x3000 CONSTANT DEST_ADDR
- 612 LOAD
- 613 LOAD
-
- Then, you can use "DUMP" to visualize the data you'll need to
- punch in:
-
- H@ ORG @ - ORG @ DUMP
-
- It can run from any offset (all jumps in it are relative), but
- writes to DEST_ADDR. Make sure you don't place it in a way to be
- overwritten by its received data.
-
- Wondering what is that COM_DRV_ADDR constant? That's the DCB
- handle of your *cl device. You will need to get that address
- before you continue. Go read the following section and come back
- here.
-
- How will you punch that in? The "debug" program! This very
- useful piece of software is supplied in TRSDOS. To invoke it,
- first run "debug (on)" and then press the BREAK key. You'll get
- the debug interface which allows you to punch in any data in any
- memory address. Let's use 0x5000 which is the offset it's
- designed for.
-
- For reference: to go back to the TRSDOS prompt, it's
- "o<return>".
-
- First, display the 0x5000-0x503f range with the d5000<space>
- command (I always press Enter by mistake, but it's space you
- need to press). Then, you can begin punching in with
- h5000<space>. This will bring up a visual indicator of the
- address being edited. Punch in the stuff with a space in between
- each byte and end the edit session with "x".
-
- # Getting your DCB address
-
- In the previous step, you need to set COM_DRV_ADDR to your "DCB"
- address for *cl. That address is your driver "handle". To get
- it, first get the address where the driver is loaded in memory.
- You can get this by running "device (b=y)". That address you see
- next to *cl? that's it. But that's not our DCB.
-
- To get your DBC, go explore that memory area. Right after the
- part where there's the *cl string, there's the DCB address
- (little endian). On my setup, the driver was loaded in 0x0ff4
- and the DCB address was 8 bytes after that, with a value of
- 0x0238. Don't forget that z80 is little endian. 38 will come
- before 02.
-
- # Saving that program for later
-
- If you want to save yourself typing for later sessions, why not
- save the program you've painfully typed to disk? TRSDOS enables
- that easily. Let's say that you typed your program at 0x5000 and
- that you want to save it to RECV/CMD on your second floppy
- drive, you'd do:
-
- dump recv/cmd:1 (start=x'5000',end=x'5030',tra='5000')
-
- A memory range dumped this way will be re-loaded at the same
- offset through "load recv/cmd:1". Even better, TRA indicates
- when to jump after load when using the RUN command. Therefore,
- you can avoid all this work above in later sessions by simply
- typing "recv" in the DOS prompt.
-
- Note that you might want to turn "debug" off for these commands
- to run. I'm not sure why, but when the debugger is on, launching
- the command triggers the debugger.
-
- # Sending binary through the RS-232 port
-
- Once you're finished punching your program in memory, you can
- run it with g5000<enter> (not space). If you've saved it to
- disk, run "recv" instead. Because it's an infinite loop, your
- screen will freeze. You can start sending your data.
-
- To that end, there's the tools/pingpong program. It takes a
- device and a filename to send. Before you send the binary, make
- it go through tools/ttysafe first (which just takes input from
- stdin and spits tty-safe content to stdout):
-
- ./ttysafe < stage1.bin > stage1.ttysafe
-
- On OpenBSD, the invocation can look like:
-
- doas ./pingpong /dev/ttyU0 os.ttysafe
-
- You will be prompted for a key before the contents is sent. This
- is because on OpenBSD, TTY configuration is lost as soon as the
- TTY is closed, which means that you can't just run stty before
- running pingpong. So, what you'll do is, before you press your
- key, run "doas stty -f /dev/ttyU0 300 raw" and then press any
- key on the pingpong invocation.
-
- If everything goes well, the program will send your contents,
- verifying every byte echoed back, and then send a null char to
- indicate to the receiving end that it's finished sending. This
- will end the infinite loop on the TRS-80 side and return. That
- should bring you back to a refreshed debug display and you
- should see your sent content in memory, at the specified address
- (0x3000 if you didn't change it).
-
- If there was no error during pingpong, the content should be
- exact. Nevertheless, I recommend that you manually validate a
- few bytes using TRSDOS debugger before carrying on.
-
- *debugging tip*: Sometimes, the communication channel can be a
- bit stubborn and always fail, as if some leftover data was
- consistently blocking the channel. It would cause a data
- mismatch at the very beginning of the process, all the time.
- What I do in these cases is start a "COMM *cl" session on one
- side and a screen session on the other, type a few characters,
- and try pingpong again.
-
- # Saving to disk
-
- If everything went well, you could run Collapse OS with
- g3000<return>. But instead of doing that, why not save it to
- disk?
-
- dump cos/cmd:1 (start=x'5000',end=x'7000',tra='5000')
-
- And there we go! A Collapse OS launchable from floppy!
-
- # Sending blkfs to floppy
-
- As it is, your system fully supports reading and writing to
- floppy drive 1. It also had CL< to read a char from its RS-232
- port and CL> to emit to it.
-
- That's all you need to have a full Collapse OS with access to
- disk blocks.
-
- First, make sure your floppies are formatted. Collapse OS is
- currently hardcoded to single side and single density, which
- means there's a limit of 100 blocks per disk.
-
- You'll need to send those blocks through RS-232. First, let's
- initialize the driver with CL$. This driver does not require
- the TRS-DOS driver to be loaded. Also, it is hardcoded to
- "no parity, 8 bit words". And takes a "baud code" as an argu-
- ment. It's a 0-15 value with these meanings:
-
- 00 50 01 75 02 110 03 134.5
- 04 150 05 300 06 600 07 1200
- 08 1800 09 2000 0a 2400 0b 3800
- 0c 4800 0d 7200 0e 9600 0f 19200
-
- After CL$ is called, let's have the CL take over the prompt:
-
- ' CL> ' EMIT **!
- ' CL< ' KEY **!
-
- See "Aliases" in usage.txt for details. Your serial link now has
- the prompt. You will also have to make your newlines CRLF. The
- TRS-80 wants CR only, but serial communications (and blkup)
- expect CRLF:
-
- ' CRLF ' NL **!
-
- Now, you can use /tools/blkup to send a disk's contents. First,
- extract the first 100 blocks from blkfs:
-
- dd if=emul/blkfs bs=1024 count=100 > d1
-
- Now, insert your formatted disk in drive 1 and push your blocks:
-
- tools/blkup /dev/ttyUSB0 0 d1
-
- It takes a while, but you will end up having your first 100
- blocks on floppy! Go ahead, LIST around. Then, repeat for other
- disks.
-
- # Floppy organisation
-
- Making blkfs span multiple disk is a bit problematic with
- regards to absolute block references in the code. You'll need to
- work a bit to design your very own Collapse OS floppy set. See
- /doc/usage.txt for details.
-
- # Coming back to keyboard
-
- Once you're done, you will want to go back to local control:
-
- ' CR ' NL **!
- ' (emit) ' EMIT **!
- ' (key) ' KEY **!
-
- # Self-hosting
-
- As it is, your installment of Collapse OS is self-hosting using
- instructions from /doc/selfhost.txt. The difference is that
- instead of writing the binary you have in memory to EEPROM,
- you'll quit to TRSDOS with BYE and use TRSDOS' DUMP utility to
- save to disk like you already did before.
|