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 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. # PS/2 keyboard on the SMS
  2. Using the shell with a D-pad on the SMS is doable, but not fun at all! We're
  3. going to build an adapter for a PS/2 keyboard to plug as a SMS controller.
  4. The PS/2 logic will be the same as the [RC2014's PS/2 adapter][rc2014-ps2] but
  5. instead of interfacing directly with the bus, we interface with the SMS'
  6. controller subsystem (that is, what we poke on ports `0x3f` and `0xdc`).
  7. How will we achieve that? A naive approach would be "let's limit ourselves to
  8. 7bit ASCII and put `TH`, `TR` and `TL` as inputs". That could work, except that
  9. the SMS will have no way reliable way (except timers) of knowing whether polling
  10. two identical values is the result of a repeat character or because there is no
  11. new value yet.
  12. On the AVR side, there's not way to know whether the value has been read, so we
  13. can't to like on the RC2014 and reset the value to zero when a `RO` request is
  14. made.
  15. We need communication between the SMS and the PS/2 adapter to be bi-directional.
  16. That bring the number of usable pins down to 6, a bit low for a proper character
  17. range. So we'll fetch each character in two 4bit nibbles. `TH` is used to select
  18. which nibble we want.
  19. `TH` going up also tells the AVR MCU that we're done reading the character and
  20. that the next one can come up.
  21. As always, the main problem is that the AVR MCU is too slow to keep up with the
  22. rapid z80 polling pace. In the RC2014 adapter, I hooked `CE` directly on the
  23. AVR, but that was a bit tight because the MCU is barely fast enough to handle
  24. this signal properly. I did that because I had no proper IC on hand to build a
  25. SR latch.
  26. In this recipe, I do have a SR latch on hand, so I'll use it. `TH` triggering
  27. will also trigger that latch, indicating to the MCU that it can load the next
  28. character in the '164. When it's done, we signal the SMS that the next char is
  29. ready by resetting the latch. That means that we have to hook the latch's output
  30. to `TR`.
  31. Nibble selection on `TH` doesn't involve the AVR at all. All 8 bits are
  32. pre-loaded on the '164. We use a 4-channel multiplexer to make `TH` select
  33. either the low or high bits.
  34. ## Gathering parts
  35. * A SMS that can run Collapse OS
  36. * A PS/2 keyboard. A USB keyboard + PS/2 adapter should work, but I haven't
  37. tried it yet.
  38. * A PS/2 female connector. Not so readily available, at least not on digikey. I
  39. de-soldered mine from an old motherboard I had laying around.
  40. * A SMS controller you can cannibalize for the DB-9 connection. A stock DB-9
  41. connector isn't deep enough.
  42. * ATtiny85/45/25 (main MCU for the device)
  43. * 74xx164 (shift register)
  44. * 74xx157 (multiplexer)
  45. * A NOR SR-latch. I used a 4043.
  46. * Proto board, wires, IC sockets, etc.
  47. ## Historical note
  48. As I was building this prototype, I was wondering how I would debug it. I could
  49. obviously not hope for it to work as a keyboard adapter on the first time, right
  50. on port A, driving the shell. I braced myself mentally for a logic analyzer
  51. session and some kind of arduino-based probe to test bit banging results.
  52. And then I thought "why not use the genesis?". Sure, driving the shell with the
  53. D-pad isn't fun at all, but it's possible. So I hacked myself a temporary debug
  54. kernel with a "a" command doing a probe on port B. It worked really well!
  55. It was a bit less precise than logic analyzers and a bit of poking-around and
  56. crossing-fingers was involved, but overall, I think it was much less effort
  57. than creating a full test setup.
  58. There's a certain satisfaction to debug a device entirely on your target
  59. machine...
  60. ## Building the PS/2 interface
  61. ![Schematic](ps2-to-sms.png)
  62. The PS/2-to-AVR part is identical to the rc2014/ps2 recipe. Refer to this
  63. recipe.
  64. We control the '164 from the AVR in a similar way to what we did in rc2014/ps2,
  65. that is, sharing the DATA line with PS/2 (PB1). We clock the '164 with PB3.
  66. Because the '164, unlike the '595, is unbuffered, no need for special RCLK
  67. provisions.
  68. Most of the wiring is between the '164 and the '157. Place them close. The 4
  69. outputs on the '157 are hooked to the first 4 lines on the DB-9 (Up, Down, Left,
  70. Right).
  71. In my prototype, I placed a 1uf decoupling cap next to the AVR. I used a 10K
  72. resistor as a pull-down for the TH line (it's not always driven).
  73. If you use a 4043, don't forget to wire EN. On the '157, don't forget to wire
  74. ~G.
  75. The code expects a SR-latch that works like a 4043, that is, S and R are
  76. triggered high, S makes Q high, R makes Q low. R is hooked to PB4. S is hooked
  77. to TH (and also the A/B on the '157). Q is hooked to PB0 and TL.
  78. ## Building the binary
  79. We start with the base recipe and add a few things:
  80. 1. at the top: `SYSVARS 0x72 + CONSTANT PS2_MEM`
  81. 2. After VDP load: `641 LOAD : (ps2kc) (ps2kcB) ;` (that binds us to port B)
  82. 3. Right after: `411 414 LOADR` (that gives us `(key)`)
  83. 4. After `VDP$`: `PS2$`.
  84. Rebuild, send to SMS, then run with your keyboard interface plugged to PortB.
  85. It should mostly work. There are still a few glitches to iron out...
  86. [rc2014-ps2]: ../../rc2014/ps2