Mirror of CollapseOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 10.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. # TRS-80 Model 4p
  2. The TRS-80 (models 1, 3 and 4) are among the most popular z80 machines. They're
  3. very nicely designed and I got my hands on a 4p with two floppy disk drives and
  4. a RS-232 port. In this recipe, we're going to get Collapse OS running on it.
  5. ![Collapse OS on a TRS-80 Model 4P](collapseos-on-trs80.jpg)
  6. ## Not entirely standalone
  7. Collapse OS uses the TRS-80 drivers rather than its own. On most TRS-80 models,
  8. those drivers are on ROM, but in the case of the 4P model, those drivers are on
  9. the TRSDOS disk (well, from what I understand, not all of it, but still, a big
  10. part of it).
  11. It would be preferable to develop drivers from scratch, but it represents a
  12. significant effort for a modest payout (because it's only actually useful when
  13. you want to use a 4P model that has no TRSDOS disk).
  14. Maybe those drivers will be developed later, but it's not a priority for now.
  15. ## Floppy or RS-232?
  16. There are many ways to get Collapse OS to run on it. One would involve writing
  17. it to a floppy. I bought myself old floppy drives for that purpose, but I happen
  18. to not have any functional computer with a floppy port on it. I still have the
  19. motherboard of my old pentium, but I don't seem to have a video card for it any
  20. more.
  21. Because my 4p has a RS-232 port and because I have equipment to do serial
  22. communication from modern machines (I didn't have a DB-9 to DB-25 adapter
  23. though, I had to buy one), I chose that route.
  24. ## Gathering parts
  25. * A TRS-80 model 4p with a RS-232 port
  26. * A TRSDOS 6.x disk
  27. * A means to do serial communication. In my case, that meant:
  28. * A USB-to-serial device
  29. * A null modem cable
  30. * A DB-9 gender changer
  31. * A DB-9 to DB-25 adapter
  32. ## Overview
  33. We need to send sizeable binary programs through the RS-232 port and then run
  34. it. The big challenge here is ensuring data integrity. Sure, serial
  35. communication has parity check, but it has no helpful way of dealing with
  36. parity errors. When parity check is enabled and that a parity error occurs, the
  37. byte is simply dropped on the receiving side. Also, a double bit error could be
  38. missed by those checks.
  39. What we'll do here is to ping back every received byte back and have the sender
  40. do the comparison and report mismatched data.
  41. Another problem is ASCII control characters. When those are sent across serial
  42. communication channels, all hell breaks lose. When sending binary data, those
  43. characters have to be avoided. We use `tools/ttysafe` for that.
  44. Does TRSDOS have a way to receive this binary inside these constraints? Not to
  45. my knowledge. As far as I know, the COMM program doesn't allow this.
  46. What are we going to do? We're going to punch in a binary program to handle that
  47. kind of reception! You're gonna feel real badass about it too...
  48. ## Building the binary
  49. You can start the process by building the binary. Running `make` in this folder
  50. will yield a `os.bin` file. You'll need it later.
  51. ## Testing serial communication
  52. The first step here is ensuring that you have bi-directional serial
  53. communication. To do this, first prepare your TRS-80:
  54. set *cl to com
  55. setcomm (word=8,parity=no)
  56. The first line loads the communication driver from the `COM/DRV` file on the
  57. TRSDOS disk and binds it to `*cl`, the name generally used for serial
  58. communication devices. The second line sets communication parameters in line
  59. with what is generally the default on modern machine. Note that I left the
  60. default of 300 bauds as-is.
  61. Then, you can run `COMM *cl` to start a serial communication console.
  62. Then, on the modern side, use your favorite serial communication program and set
  63. the tty to 300 baud with option "raw". Make sure you have `-parenb`.
  64. If your line is good, then what you type on either side should echo on the
  65. other side. If it does not, something's wrong. Debug.
  66. ## Punching in the goodie
  67. As stated in the overview, we need a program on the TRS-80 that:
  68. 1. Listens to `*cl`
  69. 2. Echoes each character back to `*cl`
  70. 3. Adjusts `ttysafe` escapes
  71. 4. Stores received bytes in memory
  72. That program has already been written, it's in `recv.asm` in this folder. You
  73. can get the binary with `zasm < recv.asm | xxd`.
  74. It's designed to run from offset `0x5000` and write received data in `0x3000`
  75. and onwards.
  76. How will you punch that in? The `debug` program! This very useful piece of
  77. software is supplied in TRSDOS. To invoke it, first run `debug (on)` and then
  78. press the `BREAK` key. You'll get the debug interface which allows you to punch
  79. in any data in any memory address. Let's use `0x5000` which is the offset it's
  80. designed for.
  81. For reference: to go back to the TRSDOS prompt, it's `o<return>`.
  82. First, display the `0x5000-0x503f` range with the `d5000<space>` command (I
  83. always press Enter by mistake, but it's space you need to press). Then, you can
  84. begin punching in with `h5000<space>`. This will bring up a visual indicator of
  85. the address being edited. Punch in the stuff with a space in between each byte
  86. and end the edit session with `x`.
  87. But wait, it's not that easy! You see those `0xffff` addresses? They're
  88. placeholders. You need to replace those values with your DCB handle for `*cl`.
  89. See below.
  90. ## Getting your DCB address
  91. In the previous step, you need to replace the `0xffff` placeholders in
  92. `recv.asm` with your "DCB" address for `*cl`. That address is your driver
  93. "handle". To get it, first get the address where the driver is loaded in
  94. memory. You can get this by running `device (b=y)`. That address you see next
  95. to `*cl`? that's it. But that's not our DCB.
  96. To get your DBC, go explore that memory area. Right after the part where there's
  97. the `*cl` string, there's the DCB address (little endian). On my setup, the
  98. driver was loaded in `0x0ff4` and the DCB address was 8 bytes after that, with
  99. a value of `0x0238`. Don't forget that z80 is little endian. `38` will come
  100. before `02`.
  101. ## Saving that program for later
  102. If you want to save yourself typing for later sessions, why not save the
  103. program you've painfully typed to disk? TRSDOS enables that easily. Let's say
  104. that you typed your program at `0x5000` and that you want to save it to
  105. `RECV/CMD` on your second floppy drive, you'd do:
  106. dump recv/cmd:1 (start=x'5000',end=x'5030',tra='5000')
  107. A memory range dumped this way will be re-loaded at the same offset through
  108. `load recv/cmd:1`. Even better, `TRA` indicates when to jump after load when
  109. using the `RUN` command. Therefore, you can avoid all this work above in later
  110. sessions by simply typing `recv` in the DOS prompt.
  111. Note that you might want to turn `debug` off for these commands to run. I'm not
  112. sure why, but when the debugger is on, launching the command triggers the
  113. debugger.
  114. ## Sending binary through the RS-232 port
  115. Once you're finished punching your program in memory, you can run it with
  116. `g5000<enter>` (not space). If you've saved it to disk, run `recv` instead.
  117. Because it's an infinite loop, your screen will freeze. You can start sending
  118. your data.
  119. To that end, there's the `tools/pingpong` program. It takes a device and a
  120. filename to send. Before you send the binary, make it go through
  121. `tools/ttysafe` first (which just takes input from stdin and spits tty-safe
  122. content to stdout):
  123. ./ttysafe < os.bin > os.ttysafe
  124. On OpenBSD, the invocation can look like:
  125. doas ./pingpong /dev/ttyU0 os.ttysafe
  126. You will be prompted for a key before the contents is sent. This is because on
  127. OpenBSD, TTY configuration is lost as soon as the TTY is closed, which means
  128. that you can't just run `stty` before running `pingpong`. So, what you'll do is,
  129. before you press your key, run `doas stty -f /dev/ttyU0 300 raw` and then press
  130. any key on the `pingpong` invocation.
  131. If everything goes well, the program will send your contents, verifying every
  132. byte echoed back, and then send a null char to indicate to the receiving end
  133. that it's finished sending. This will end the infinite loop on the TRS-80 side
  134. and return. That should bring you back to a refreshed debug display and you
  135. should see your sent content in memory, at the specified address (`0x3000` if
  136. you didn't change it).
  137. If there was no error during `pingpong`, the content should be exact.
  138. Nevertheless, I recommend that you manually validate a few bytes using TRSDOS
  139. debugger before carrying on.
  140. *debugging tip*: Sometimes, the communication channel can be a bit stubborn and
  141. always fail, as if some leftover data was consistently blocking the channel. It
  142. would cause a data mismatch at the very beginning of the process, all the time.
  143. What I do in these cases is start a `COMM *cl` session on one side and a screen
  144. session on the other, type a few characters, and try `pingpong` again.
  145. ## Running Collapse OS
  146. If everything went well, you can run Collapse OS with `g3000<space>`. You'll
  147. get a usable Collapse OS prompt!
  148. Like with the `recv` program, nothing stops you from dumping that binary to a
  149. floppy.
  150. ## Configuration
  151. In addition to the generic basic shell, this build of Collapse OS has support
  152. for floppy drive `:1` as a block device (mapped to device `0`). Block device
  153. commands work as expected.
  154. In addition to this, there is a `flush` command to ensure that dirty buffers are
  155. synced to disk. Make sure you run this after a write operation or before
  156. swapping disks.
  157. On top of that, there's CFS support builtin. To enable a FS, type `fson` while
  158. the active block device is properly placed (you can initialize a new FS by
  159. writing `CFS\0\0\0\0` to the disk). If it doesn't error out, commands like
  160. `fls` and `fnew` will work. Don't forget to flush when you're finished :)
  161. There is also a custom `recv` command that does the same "ping pong" as in
  162. `recv.asm`, but once. It puts the result in `A`. This can be useful to send down
  163. a raw CFS: you just need a while loop that repeatedly call `recv:putb a`.
  164. ## Assembling programs
  165. Running `make` will yield a `floppy.cfs` file that you can dump on a disk. This
  166. CFS contains a properly configured `zasm` as well as a test `hello.asm` file.
  167. By mounting this CFS (running `fson` with the active device properly placed),
  168. you can assemble and run a binary from `hello.asm` in the same way that you
  169. would in any CFS-enabled shell. You'll then see those sweet "Assembled from a
  170. TRS-80" words!