Tuesday, 24 September 2013

Introduction to the project

Last winter I started a project to create a Virtual Floppy disk emulator for the TRS-80 Model I using a Raspberry Pi. The original project description is here.

My TRS-80 Model 1

The project was inspired by several similar projects based on Arduino and other micro-controllers and because my ancient TRS-80 Model I was having problems reading and writing floppy disks as the electronics and hardware aged. It's also rather difficult to transfer software to and from the TRS-80 without such a system.

The advantage of the Raspberry Pi is that it is a complete system with video, USB, keyboard, mouse and storage support. The disadvantage is that the current available operating systems are not ideal for real-time. But the hardware features of the processor help overcome that limitation as will be seen later.

TRS-80 Floppy Disk Interface (Model I)

The TRS-80 Model I expansion interface (which supported the first floppy drives for the TRS-80) was created around 1978. It was designed to use existing floppy disk drives (with perhaps some minor customizations) connected by ribbon cable to the expansion interface. It used a Western Digital 1771 floppy disk controller IC which supported single density only, running at a clock speed of 1 MHz. (The timing diagrams on the 1771 data sheet are for 2 MHz so you have to adjust them for the slower speed of the Model I.)

Interface Signals

For this discussion I will refer to output signals as signals output from the Raspberry Pi emulator that input to the TRS-80 expansion interface and input signals as signals coming into the Raspberry Pi emulator from the expansion interface. Because several floppy drives could be connected to the same line the TRS-80 used open collector TTL interfacing with 150 ohm pull-up resistors to 5 volts. This meant that 'active' signals pulled the voltage down to zero.

Note: The connectors on the TRS-80 Expansion Interface are flat two-sided card-edge connectors but the schematic in the technical reference manual refers to "Pin numbers" so "Cable pin" refers to the pin numbers from the schematic.

The output signals are:
  1. Index Pulse. Cable Pin 8. This short (4 millisecond) pulse is sent at the beginning of every track. On a real floppy drive this is generated by a photocell pointed at a LED shining through the index hole on the floppy disk.
  2. Track Zero. Cable pin 26. Active when the R/W/ head is at track zero (the home position). This is used by the floppy disk controller when seeking.
  3. Write Protect. Cable pin 28. Also generated by a photocell/LED combination when the write protect notch on the disk is covered.
  4. Read Data. Cable pin 30. This is the data from the disk R/W head that has been transformed from the raw analog signal to digital pulses by circuitry in the floppy disk drive. Because drives may vary slightly in speed from the ideal 300 rpm the floppy disk controller is somewhat tolerant of variations from the ideal signal. My system has an add-on data separator board from Percom that improves the performance in this area.
Because more than one floppy drive can be connected to the cable, a drive should only pull an output signal low when it has been made active (selected) by the drive select signal. The TRS-80 supported up to four drives, numbers from 0 to 3.

The input signals are:
  1. Drive Select 0. Cable pin 10. Selects drive 0 when active. In an actual drive this would cause the R/W head to press against the disk surface. DS0 on the schematic.
  2. Drive Select 1. Cable pin 12. Selects drive 1 when active. DS1 on the schematic.
  3. Drive Select 2. Cable pin 14. Selects drive 2 when active. DS2 on the schematic.
  4. Drive Select 3. Cable pin 32. Selects drive 3 when active. DS3 on the schematic.
  5. Motor On. Cable pin 16. Turns all drive motors on. The emulator should only be transmitting track data on the Read Data pin and accepting data on the Write Data pin when both Motor On and the appropriate Drive Select signals are active.The expansion interface contained a timer circuit that would automatically shut off this signal after a few seconds if the operating system was not using the drive interface.
  6. Direction Select. Cable pin 18. Selects the direction of movement of the R/W head when the step signal is pulsed.
  7. Step. Cable pin 20. This short (about 8 microseconds) pulse indicated that the R/W head should be moved one step in the direction indicated by the Direction Select pin. Fortunately the Raspberry Pi has programmable edge detect triggers that will watch for this and set a bit when the line is pulsed. Since an actual floppy disk takes a couple of milliseconds (or more) to move the physical head from one track to the next but the emulator can move the virtual R/W head almost instantly, the timing is not critical. I have been able to poll the edge detect signal rather than trying to use interrupts (which are not well documented).
  8. Write Data. Cable pin 22. Not yet implemented. This would contain the data to be written to the disk surface.
  9. Write Gate. Cable pin 24. Not yet implemented. Signals that the write data is valid and should be written to the disk. Stays low for the duration of the write operation.

Interface Circuitry

There were two main considerations when choosing what ICs to interface between the Rasperry Pi and the TRS-90 expansion interface. The first was the TTL logic (5v) used by the TRS-80 which is not compatible with the lower voltage (3.3v) logic on the Raspberry Pi. The second was the very low resistance (150 ohm) of the pull-up resistors. This results in a fairly high current and I needed to use 74LS06 to drive the output signals. Also, many level translation chips, especially bi-directional ones, would not work with such low resistance pull-up values. Fortunately I found I was able to avoid level translation chips in my design. While I could have used a 74LS05 for the input signals I found it was simpler to use a 74LS06 for both input and output so I could chose the IC that was most convenient.

Originally I put a level translation between the Pi and the 74LS06 for the output signals but it turned out not to be necessary and the Pi seems to be able to drive the 74LS06 directly. The input signals use the open collector of the 74LS06 (could be a 74LS05, but easier to use the same IC for both) and rely on the pull-up resistors on the GPIO pins to perform the level translation to the correct voltage. The Pi has programmable pull-up resistors on the GPIO pins so I just program them in the initialization code. Two GPIO pins also have pull-up resistors on the board itself, so it's convenient to use these two as input pins for the floppy drive interface.

Note: all Raspberry Pi pins refer to the Rev 2 pins as seen here.

Current configuration is shown below.

Read Data must be connected to GPIO pin 10.
Write Data must be connected to GPIO pin 9.
GPIO pin 11 (which is the SPI clock) should be left alone. I connect it to a pin for use with a logic analyzer to help me see what's happening.
I also leave GPIO pins 7 and 8 alone as they are part of the SPI interface and unavailable as I am using that interface for read and write data. GPIO 2 and 3 have pull-up resistors on the board itself so I use them as inputs.

Note: All outputs are pulled up to 5v by 150 ohm resistors on the Expansion Interface.

Write Protect (output) connected to GPIO 18 - Header pin P1-12.
Track 0 (output) connected to GPIO 23 - Header pin P1-16.
Read data (output) connected to GPIO 10 - Header pin P1-19.
Index Pulse (output) connected to GPIO 24 - Header pin P1-18.

Drive Select 0 (input) connected to  GPIO 2 - Header pin P1-03. (has 1K8 pull-up on the board)
Drive Select 1 (input) connected to GPIO 25 - Header pin P1-22.
Motor On (input) connected to GPIO 4 - Header pin P1-07.
Direction Select (input) connected to GPIO 17 - Header pin P1-11.
Direction Step (input) connected to GPIO 27 - Header pin P1-13.
Drive Select 2 (input) connected to GPIO 22 - Header pin P1-15.
Write Gate (input) connected to GPIO 15 - Header pin P1-10.
Write Data (input) connected to GOIP 9 - Header pin P1-21.

Update Sept 30. I found that using GPIO 3 as an input caused Rasbpian to hang while booting so I have changed Drive Select 1 to use GPIO 25, header pin P1-22 instead. This problem doesn't exist under RISC OS so perhaps a driver needed to be disabled.

One of the drives connected to the cable should have 150 ohm pull-up resistors to 5v. Only one drive should have the pull-up resistors and generally it is the last drive on the cable. I put a set of pull-up resistors on my interface board and a jumper between the resistors and 5v from the Pi power supply. The TRS-80 drive cable does not provide +5 volts so it's necessary to use +5 volts from the Pi board.

Not listed here are the ground signals from the cable which should be connected to ground on the Pi.

 This is a picture of the top of the original prototype (plugged into the Raspberry Pi beneath it). The IC on the left is a level translation board which I found was not necessary. The connector to the Pi is at the bottom left. The cable that connects to the Expansion Interface is at the top. The resistors are pull-up resistors and the yellow jumper connects them to +5v. The board itself is just a plain prototype board with a cutout for one of the Pi connectors that is too high for the pin header.

This is a picture of the bottom of the original prototype. The connector that is plugged into the Pi is at the left. The floppy disk connector is at the right.