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.

328 lines
11KB

  1. # TRS-80 Model 4p
  2. The TRS-80 (models 1, 3 and 4) are among the most popular z80
  3. machines. They're very nicely designed and I got my hands on a
  4. 4p with two floppy disk drives and a RS-232 port. In this
  5. recipe, we're going to get Collapse OS running on it.
  6. # Not entirely standalone
  7. Collapse OS uses the TRS-80 drivers rather than its own. On most
  8. TRS-80 models, those drivers are on ROM, but in the case of the
  9. 4P model, those drivers are on the TRSDOS disk (well, from what
  10. I understand, not all of it, but still, a big part of it).
  11. It would be preferable to develop drivers from scratch, but it
  12. represents a significant effort for a modest payout (because
  13. it's only actually useful when you want to use a 4P model that
  14. has no TRSDOS disk).
  15. Maybe those drivers will be developed later, but it's not a
  16. priority for now.
  17. # Floppy or RS-232?
  18. There are many ways to get Collapse OS to run on it. One would
  19. involve writing it to a floppy. I bought myself old floppy
  20. drives for that purpose, but I happen to not have any functional
  21. computer with a floppy port on it. I still have the motherboard
  22. of my old pentium, but I don't seem to have a video card for it
  23. any more.
  24. Because my 4p has a RS-232 port and because I have equipment to
  25. do serial communication from modern machines (I didn't have a
  26. DB-9 to DB-25 adapter though, I had to buy one), I chose that
  27. route.
  28. # Gathering parts
  29. * A TRS-80 model 4p with a RS-232 port
  30. * A TRSDOS 6.x disk
  31. * A means to do serial communication. In my case, that meant:
  32. * A USB-to-serial device
  33. * A null modem cable
  34. * A DB-9 gender changer
  35. * A DB-9 to DB-25 adapter
  36. # Overview
  37. We need to send sizeable binary programs through the RS-232 port
  38. and then run it. The big challenge here is ensuring data
  39. integrity. Sure, serial communication has parity check, but it
  40. has no helpful way of dealing with parity errors. When parity
  41. check is enabled and that a parity error occurs, the byte is
  42. simply dropped on the receiving side. Also, a double bit error
  43. could be missed by those checks.
  44. What we'll do here is to ping back every received byte back and
  45. have the sender do the comparison and report mismatched data.
  46. Another problem is ASCII control characters. When those are sent
  47. across serial communication channels, all hell breaks lose. When
  48. sending binary data, those characters have to be avoided. We use
  49. tools/ttysafe for that.
  50. Does TRSDOS have a way to receive this binary inside these
  51. constraints? Not to my knowledge. As far as I know, the COMM
  52. program doesn't allow this.
  53. What are we going to do? We're going to punch in a binary
  54. program to handle that kind of reception! You're gonna feel real
  55. badass about it too...
  56. # Keyboard cheatcheet
  57. The TRS-80 4P keyboard doesn't show all available characters.
  58. When you hold CLEAR, you can do:
  59. _ --> ENTER
  60. [] --> <>
  61. ^ --> ;
  62. \ --> /
  63. # Building the binary
  64. You can build the binary to send to the TRS-80 with "make" in
  65. /arch/z80/trs80, which will yield
  66. "os.bin". You'll need it later.
  67. # Testing serial communication
  68. The first step here is ensuring that you have bi-directional
  69. serial communication. To do this, first prepare your TRS-80:
  70. set *cl to com
  71. setcomm (word=8,parity=no)
  72. The first line loads the communication driver from the COM/DRV
  73. file on the TRSDOS disk and binds it to *cl, the name generally
  74. used for serial communication devices. The second line sets
  75. communication parameters in line with what is generally the
  76. default on modern machine. Note that I left the default of 300
  77. bauds as-is.
  78. Then, you can run "COMM *cl" to start a serial communication
  79. console.
  80. Then, on the modern side, use your favorite serial communication
  81. program and set the tty to 300 baud with option "raw". Make sure
  82. you have -parenb.
  83. If your line is good, then what you type on either side should
  84. echo on the other side. If it does not, something's wrong.
  85. Debug.
  86. # Punching in the goodie
  87. As stated in the overview, we need a program on the TRS-80 that:
  88. 1. Listens to *cl
  89. 2. Echoes each character back to *cl
  90. 3. Adjusts ttysafe escapes
  91. 4. Stores received bytes in memory
  92. You're in luck: that program has already been written. It's in
  93. B612 and B613 in /arch/z80/trs80/blk. By running "make" earlier,
  94. you have, in your current folder, a blkfs that contains those
  95. blocks. To have a forth running on it, you could overwrite
  96. /cvm/blkfs and run /cvm/forth. You can then compile it with:
  97. 5 LOAD ( z80 assembler )
  98. 0x0238 CONSTANT COM_DRV_ADDR
  99. 0x3000 CONSTANT DEST_ADDR
  100. 612 LOAD
  101. 613 LOAD
  102. Then, you can use "DUMP" to visualize the data you'll need to
  103. punch in:
  104. H@ ORG @ - ORG @ DUMP
  105. It can run from any offset (all jumps in it are relative), but
  106. writes to DEST_ADDR. Make sure you don't place it in a way to be
  107. overwritten by its received data.
  108. Wondering what is that COM_DRV_ADDR constant? That's the DCB
  109. handle of your *cl device. You will need to get that address
  110. before you continue. Go read the following section and come back
  111. here.
  112. How will you punch that in? The "debug" program! This very
  113. useful piece of software is supplied in TRSDOS. To invoke it,
  114. first run "debug (on)" and then press the BREAK key. You'll get
  115. the debug interface which allows you to punch in any data in any
  116. memory address. Let's use 0x5000 which is the offset it's
  117. designed for.
  118. For reference: to go back to the TRSDOS prompt, it's
  119. "o<return>".
  120. First, display the 0x5000-0x503f range with the d5000<space>
  121. command (I always press Enter by mistake, but it's space you
  122. need to press). Then, you can begin punching in with
  123. h5000<space>. This will bring up a visual indicator of the
  124. address being edited. Punch in the stuff with a space in between
  125. each byte and end the edit session with "x".
  126. # Getting your DCB address
  127. In the previous step, you need to set COM_DRV_ADDR to your "DCB"
  128. address for *cl. That address is your driver "handle". To get
  129. it, first get the address where the driver is loaded in memory.
  130. You can get this by running "device (b=y)". That address you see
  131. next to *cl? that's it. But that's not our DCB.
  132. To get your DBC, go explore that memory area. Right after the
  133. part where there's the *cl string, there's the DCB address
  134. (little endian). On my setup, the driver was loaded in 0x0ff4
  135. and the DCB address was 8 bytes after that, with a value of
  136. 0x0238. Don't forget that z80 is little endian. 38 will come
  137. before 02.
  138. # Saving that program for later
  139. If you want to save yourself typing for later sessions, why not
  140. save the program you've painfully typed to disk? TRSDOS enables
  141. that easily. Let's say that you typed your program at 0x5000 and
  142. that you want to save it to RECV/CMD on your second floppy
  143. drive, you'd do:
  144. dump recv/cmd:1 (start=x'5000',end=x'5030',tra='5000')
  145. A memory range dumped this way will be re-loaded at the same
  146. offset through "load recv/cmd:1". Even better, TRA indicates
  147. when to jump after load when using the RUN command. Therefore,
  148. you can avoid all this work above in later sessions by simply
  149. typing "recv" in the DOS prompt.
  150. Note that you might want to turn "debug" off for these commands
  151. to run. I'm not sure why, but when the debugger is on, launching
  152. the command triggers the debugger.
  153. # Sending binary through the RS-232 port
  154. Once you're finished punching your program in memory, you can
  155. run it with g5000<enter> (not space). If you've saved it to
  156. disk, run "recv" instead. Because it's an infinite loop, your
  157. screen will freeze. You can start sending your data.
  158. To that end, there's the tools/pingpong program. It takes a
  159. device and a filename to send. Before you send the binary, make
  160. it go through tools/ttysafe first (which just takes input from
  161. stdin and spits tty-safe content to stdout):
  162. ./ttysafe < stage1.bin > stage1.ttysafe
  163. On OpenBSD, the invocation can look like:
  164. doas ./pingpong /dev/ttyU0 os.ttysafe
  165. You will be prompted for a key before the contents is sent. This
  166. is because on OpenBSD, TTY configuration is lost as soon as the
  167. TTY is closed, which means that you can't just run stty before
  168. running pingpong. So, what you'll do is, before you press your
  169. key, run "doas stty -f /dev/ttyU0 300 raw" and then press any
  170. key on the pingpong invocation.
  171. If everything goes well, the program will send your contents,
  172. verifying every byte echoed back, and then send a null char to
  173. indicate to the receiving end that it's finished sending. This
  174. will end the infinite loop on the TRS-80 side and return. That
  175. should bring you back to a refreshed debug display and you
  176. should see your sent content in memory, at the specified address
  177. (0x3000 if you didn't change it).
  178. If there was no error during pingpong, the content should be
  179. exact. Nevertheless, I recommend that you manually validate a
  180. few bytes using TRSDOS debugger before carrying on.
  181. *debugging tip*: Sometimes, the communication channel can be a
  182. bit stubborn and always fail, as if some leftover data was
  183. consistently blocking the channel. It would cause a data
  184. mismatch at the very beginning of the process, all the time.
  185. What I do in these cases is start a "COMM *cl" session on one
  186. side and a screen session on the other, type a few characters,
  187. and try pingpong again.
  188. # Saving to disk
  189. If everything went well, you could run Collapse OS with
  190. g3000<return>. But instead of doing that, why not save it to
  191. disk?
  192. dump cos/cmd:1 (start=x'5000',end=x'7000',tra='5000')
  193. And there we go! A Collapse OS launchable from floppy!
  194. # Sending blkfs to floppy
  195. As it is, your system fully supports reading and writing to
  196. floppy drive 1. It also had CL< to read a char from its RS-232
  197. port and CL> to emit to it.
  198. That's all you need to have a full Collapse OS with access to
  199. disk blocks.
  200. First, make sure your floppies are formatted. Collapse OS is
  201. currently hardcoded to single side and single density, which
  202. means there's a limit of 100 blocks per disk.
  203. You'll need to send those blocks through RS-232. First, let's
  204. initialize the driver with CL$. This driver does not require
  205. the TRS-DOS driver to be loaded. Also, it is hardcoded to
  206. "no parity, 8 bit words". And takes a "baud code" as an argu-
  207. ment. It's a 0-15 value with these meanings:
  208. 00 50 01 75 02 110 03 134.5
  209. 04 150 05 300 06 600 07 1200
  210. 08 1800 09 2000 0a 2400 0b 3800
  211. 0c 4800 0d 7200 0e 9600 0f 19200
  212. After CL$ is called, let's have the CL take over the prompt:
  213. ' CL> ' EMIT **!
  214. ' CL< ' KEY **!
  215. See "Aliases" in usage.txt for details. Your serial link now has
  216. the prompt. You will also have to make your newlines CRLF. The
  217. TRS-80 wants CR only, but serial communications (and blkup)
  218. expect CRLF:
  219. ' CRLF ' NL **!
  220. Now, you can use /tools/blkup to send a disk's contents. First,
  221. extract the first 100 blocks from blkfs:
  222. dd if=emul/blkfs bs=1024 count=100 > d1
  223. Now, insert your formatted disk in drive 1 and push your blocks:
  224. tools/blkup /dev/ttyUSB0 0 d1
  225. It takes a while, but you will end up having your first 100
  226. blocks on floppy! Go ahead, LIST around. Then, repeat for other
  227. disks.
  228. # Floppy organisation
  229. Making blkfs span multiple disk is a bit problematic with
  230. regards to absolute block references in the code. You'll need to
  231. work a bit to design your very own Collapse OS floppy set. See
  232. /doc/usage.txt for details.
  233. # Coming back to keyboard
  234. Once you're done, you will want to go back to local control:
  235. ' CR ' NL **!
  236. ' (emit) ' EMIT **!
  237. ' (key) ' KEY **!
  238. # Self-hosting
  239. As it is, your installment of Collapse OS is self-hosting using
  240. instructions from /doc/selfhost.txt. The difference is that
  241. instead of writing the binary you have in memory to EEPROM,
  242. you'll quit to TRSDOS with BYE and use TRSDOS' DUMP utility to
  243. save to disk like you already did before.