Friday, 21 March 2014

Project Update

Full Single/Double Density Support

I am now able to read double-density and mixed density disks including copy-protected disks. The DMA rate has been bumped to 10.417 MHZ. Due to quirks with the Raspberry Pi SPI interface I have to read tracks in three passes. Each pass grabs approximately 50% of the track and each pass is offset by 1/3 of the disk rotation. Each pass is decoded and then the three passes are stitched together to form a final track. It makes reading disks a little bit slower but still acceptable.

The increased DMA speed gives me a resolution of approximately 100 nanoseconds which makes decoding double density possible as well as supporting a newer TEAC drive that outputs very short disk data pulses - 0.25 microseconds versus 1 microsecond for an original TRS-80 drive.

Attack Force and Defense Command from Big Five software are two mixed format disks I have successfully converted to DMK format. They are good examples of unusual formatting as several of the tracks have a mixture of single and double density sectors and some of the sectors are unusual sizes. I was also able to read a Model III Scripsit disk and run it from an emulator.

Write Support

I am also able to write DMK files to a floppy disk from the device itself. Each track is written in a single pass from index pulse to index pulse. The resulting disks can be used to boot my Model I. I do not yet have double-density or mixed density support since my Model I lacks a double-density adapter so I would only be able to verify a double density disk by reading it back from the Raspberry Pi. I intend to build a double density board for my Model I using existing schematics I have found on the web.

Sunday, 16 March 2014

DMK File Viewer/Editor

My Raspberry Pi system converts TRS-80 floppy disks to DMK files. One of the challenges of working with DMK files is ensuring that they are workable and comparing them to existing samples from other systems. In order to help with this work I wrote a small DMK file editor/viewer which is also able to compare two different DMK files.

This viewer works on tracks and sectors only and does not deal with file name or directories. It has several unique features that I have not found on existing software.

It handles mixed density disks and displays both single-density and double-density sectors, even if they have the same sector numbers.

It displays the CRC for each sector and indicates whether the CRC is bad or not. If you edit a sector the CRC is automatically updated (and corrected). Of course you have to know what you are doing when modifying disk sectors, especially when they contain program files.

You can compare DMK files sector by sector and the software steps through the differences between each sector. Sector data is displayed as both hexadecimal and ASCII format. You can edit using either hexadecimal or ASCII input, though hexadecimal is recommended for non-ASCII files.

DMK Viewer/Editor
The screenshot above shows two DMK files being compared. One from http://trs-80.com/ and one that I created myself using my Raspberry Pi interface board. In this sector the difference is in the serial number which was written to each disk.

The installer can be downloaded here from my Dropbox public folder. Or, if you don't want to install, download this zipfile containing the program and a support dll.

Update: version 1.01 now includes clipboard support for binary copy and paste (sector editor only) and F7 and F8 to move through all sector differences. Note that if there is a sector or track in the right hand view (the file being compared) that isn't in the left hand view (the main view) it won't be displayed.

defensePiFixed.dmk  is a DMK file created using a Raspberry Pi. The original DMK file had two data CRC errors but I was able to fix them using the editor and copying from single-density sectors to the corresponding double-density sectors. The disk is Defense Command which is available on the www.trs-80.com software archive.

Please note that the editor is written in C# and requires the .NET framework 3.5.

Tuesday, 11 March 2014

Board Giveaway

I have built another PCB with improved layout and a debug pin for the logic analyzer so I am giving away my first working prototype PCB to the person who makes the best submissions. I'm looking for someone who has both a Raspberry Pi and a TRS-80 and is capable and interested in moving the project forward. Note: this is the board to read  and convert TRS-80 floppy disks to DMK format, not the floppy drive emulator.

With this board, a Raspberry Pi and a TRS-80 floppy disk drive you can rip TRS-80 floppy disks to .dmk files. Works very well with single density disks including many copy-protected disks. Double-density is a work in progress. Works fairly well for non copy-protected disks with verify enabled.

Please email submissions to me at alan.page.ca (@) gmail.com. Photos of your Pi and/or TRS-80 are encouraged. Submissions may be published on this blog, but with email addresses removed. Please indicate if there is any part of your submission you don't want published.
Prototype PCB Board
The successful applicant will receive the prototype board shown here and I will pay shipping (cheapest ground rate).

If there is sufficient interest I am willing to build a few more boards and sell them at the cost of materials plus shipping.

Current Status

DMA is working well at 5 MHZ. It is very reliable with FM decoding, marginal for MFM decoding. This appears to be the limit for getting a full track in a continuous chain of DMA blocks. For some unknown reason the DMA chain stalls out at around 128K. I can extend it by clearing the output FIFO but then there is a one microsecond gap which could cause data loss. Faster DMA speeds could be achieved by using multiple overlapping operations. For example, two 8 MHZ request chains covering 2/3 of a revolution each. I would then need to splice the two blocks together on a suitable boundary.

ZIP file of current PCB schematic/layout for KiCad
ZIP file of current source code.

Sunday, 12 January 2014

DMA Support (at last)

The initial implementation of DMA for SPI is based on recent examples of using the Pi DMA hardware from user mode rather than from a kernel driver. This is an approach for the impatient and the foolhardy as it bypasses the kernel to access the DMA hardware registers directly but has the advantage of quick prototyping and overhead.

The Raspberry Pi has 16 DMA channels. Channels 1,3,6 and 7 are reserved for the GPU. Various sources indicate that channels 0 and 2 are also used by the system. SPI requires two channels, one for sending and one for receiving. I am using channels 13 and 14 for SPI DMA and so far have not encountered problems. These channels are "Lite" channels which have less capabilities than channels 0-7 but seem to be sufficient for SPI transfers


SPI DMA runs at at approximately 4 MHZ. Much to my surprise the input signal is continuous unlike the non-DMA signal which has a one clock cycle gap between bytes. A sample from my logic analyzer is shown below and comparing this signal with the raw data confirms that there are no gaps. This results in a substantial improvement in the data quality and I hope to implement MFM decoding support in the future.

SPI DMA - Data on top, SPI clock on bottom. (Data signal inverted as I was recording from a different pin)

SPI without DMA. Note the gaps in the SPI clock signal where no data is recorded.

In binary notation the SPI DMA signal from the disk drive looks like this:
0001111000000000000111100000000000011110000000000001111100000000
This is a sequence of four FM data/clock pulses. The raw pulses are about 4-5 'bits' wide which corresponds to about 1 microsecond. The gaps between the raw pulses are about 12 bits wide which corresponds to about 3 microseconds. This closely matches the specifications of the original floppy disk controller on the TRS-80. The task of the software is to measure the spacing of the pulses and turn them into FM disk encoding. I am able to record copy-protected disks and run them on various emulators successfully.

PCB

I have also built the first PCB. I have designed other PCBs but this is the first one I have etched and drilled myself. A picture of the PCB is below. It is single sided to make it easier to build. The large areas of bare copper were left to make the etching compound last longer. The cable from the floppy disk drive plugs into the connector to the right. The connector that plugs into the Raspberry Pi is mounted below the board on the left side. The corner cut out on the top left is to clear the RCA video connector. I have a few improvements in mind for the layout to make soldering easier and to provide some pins to connect the logic analyzer. In theory it would support writing to the floppy drive but there is no software support for that at present.


Wednesday, 6 November 2013

Pull-up and Pull-down Resistors

Pull-up and Pull-down

It's a boring subject to some, but resistors are important for the correct operation of electronic circuits. According to Wikipedia pull-up (and pull-down) resistors are used to ensure that inputs are at expected levels when external devices are disconnected. Pull-up resistors are connected to +ve voltage to drive the line high and pull-down resistors are connected to ground to drive it low. Without a pull-up or pull down resistor the output could be set to an undesired state or jump between 0 and 1. When the input is connected to another component it can still be driven to the desired state, overriding the default pull-up or pull-down state.

Floating Inputs

The Raspberry Pi GPIO pins are all initialized as inputs when power is applied even though later on the boot code and drivers will change the pin functions and whether they are inputs or outputs. One of the issues with my first prototype board was that the floppy drive motor would spin up when power was turned on to the system. After some investigation I realized that this resulted from a floating input because the boot state connected the GPIO input to the 74LS06 input with no other source to set the inputs low or high. The solution is to add pull-up or pull-down resistors to set the desired power-on state.

I'd like to thank my brother, Noel, for this diagram showing suggested values for pull-up and pull-down resistors based on the data sheet for the 76LS06 IC, I could not have designed the interface electronics without his advice. Based on his suggestions I will be using 2.2k resistors for pull-down and 10k resistors for pull-up (to 3.3v).

The motor, drive select and step signals must be pulled to ground to prevent them becoming active on power up. Other signals such as step direction and side select can be pulled in either direction, but pulling them high with 10k resistors consumes less power and is the preferred solution. The write gate signal is connected to GPIO 2 (SDA) which already has a 1.8K pull-up resistor on the Pi circuit board so it can be left as-is.

Open Collector Pull-Up

Pull up resistors are also used for connecting the GPIO inputs to the output of open collector devices such as the 74LS06 device I am using. In this case the pull up resistors are connected to 3.3v, not 5v to ensure that the Raspberry Pi GPIO pins are not driven higher than 3.3v, which could damage them. In this configuration a lower value resistor improves the switching speed of the signal. This is important when reading floppy disk data at high clock rates (4-8 MHz) but less important for long duration signals such as the index pulse. Again, based on advice from my brother I have chosen 330 ohm for the floppy disk data and 10k for other signals. The track zero signal is connected to GPIO pin 3 (SCL) which already has a 1.8K pull up resistor on the Pi circuit board. I could also have used the internal GPIO pull-up resistors but they are not connected at power on.




Tuesday, 29 October 2013

Schematic and Layout (updated)

Schematic V2
I've updated the original post with a better schematic that supports (in theory) write operation and side select for Model III computers. The improved layout is suitable for building by hobbyists as it is single-sided and the traces have been widened and corners smoothed for improved etching according to advice I received. The large open area in the bottom right is designed to be cut out to clear the audio and video connectors. I hope to build a few of these using single-sided PCB prototype boards. The program that I am using is KiCad EDA Software Suite and project files for the design are available on request or I can export Gerber files.While I believe the schematic above is correct I offer no warranty for anyone who chooses to use this design. Though if you have the tools and experience to build your own board you probably are capable of checking and even improving on my layout.


Wider traces and smooth corners for better etching. Large pads for easier drilling.

CONN_2 is a jumper wire to avoid needing a double-sided board as I could not route that line directly. P1 is a right-angle female 34-pin cable connector. The outline in the picture is misleading as the ribbon cable plugs into the left side with the cable exiting up and to the left. P2 is a 26 pin female pin header which is fitted underneath the board and plugs into the male header on the Raspberry Pi. The finished board is approximately 2-1/2 x 2-12 inches square.

I have successfully read some copy-protected game disks using the software and I believe that with further tweaking I should be able to read most copy-protected disks.



Monday, 21 October 2013

Using the Raspberry Pi to Read Floppy Disks

Reversing the Process to Read TRS-80 Floppy Disks

The Catweasel is an add-on card for the PC which allows reading TRS-80 floppy disks. It works by emulating a floppy disk controller using a combination of hardware and software. At the very start of the current project I believed that similar functionality would be possible by reversing the input and output signals and connecting a TRS-80 floppy drive to the interface board. Just recently I have succeeded in doing this

Interface Card
This picture of the device shows the interface board on the left and the floppy drive connector on the right. The interface board plugs into the top of the Raspberry Pi and the floppy card edge connector plugs into the TRS-80 floppy disk drive. The logic analyzer plug is for testing and development only and is not required for operation.


Raspberry Pi
The Raspberry Pi is pictured to the left. The Pi contains connectors for a keyboard, mouse, monitor and network. The operating system on the SD card is Raspbian which is based on Debian Linux.


The interface board sits on top of the Pi during use. It is about the same size as the Raspberry Pi. No PC or Mac is required as this is a complete standalone computer system.


Complete Device

The complete device is shown to the left plugged into the Raspberry Pi and with the floppy cable plugged into an old TRS-80 floppy disk drive.

Technical Details

I used the same pins as in the original device but rewired so inputs become outputs and vice versa with one exception. The original card connected the Raspberry Pi SPI output pin to the expansion interface floppy data input line. This project needs to connect the Raspberry Pi SPI input pin (GPIO 9 - MISO) to floppy disk cable pin 30 to read floppy disk data into the Pi. To write data to the floppy disk you could connect SPI output pin (GPIO 10 - MOSI) to floppy disk cable 22 (WRITE GATE signal would also have to be connected).

I found during testing that enabling the internal pull-up resistor for GPIO 9 had no effect when SPI mode was enabled. An external 10k pull-up resistor solved the problem. Another minor issue is that, using the current pin connections, the floppy disk drive motor spins and the head is loaded during the Raspberry Pi boot since those pins seem to be output high during the boot process. I suspect that selecting different pins will solve that problem. In the meantime I use the wiringPi gpio utility during boot to set the desired pin configuration and I/O direction. (Note: solved with the use of pull-down resistors.)

Software

The initial version was written under Raspbian for the Pi and used both the WiringPi and the bcm2835 low level library. I had hoped to using WiringPi exclusively but the current state of the driver is insufficient for my needs. Reading from the SPI using WiringPi leaves gaps in the data and the methods to wait for edge detect are very slow and end up returning far too late to be useful. However, a lot of work is being done by various people to implement DMA for SPI in Raspbian and I hope eventually to make use of this work when it shows up in the standard releases.

The software initializes the Pi GPIO pins and SPI interface then sets the correct output values to step the read/write head to the desired track. Once at the desired track it starts a high-priority thread which waits for the index signal and then reads an entire track of data in a single pass. It then processes the data and writes it to the DMK file format before stepping to the next track. A single-density 35 track floppy disk can be read in under 20 seconds using the initial version of the software.

The software itself is essentially the Tim Mann cw2dmk utility rewritten to handle the input data after it has been tweaked to generate clock and data bits. In the absence of DMA support I use a data rate of approximately 3 MHZ which is sufficient for single density but would not handle double density.

Signal Details

This picture shows the raw data coming from the drive at the top and the SPI clock at the bottom. As you can see, the SPI clock is not synchronized with the data coming from the drive. This is to be expected since there is no mechanism to cause synchronization and the SPI clock divider is not granular enough to allow a perfect match. In any case, it doesn't cause a problem. The main concern is to use a SPI clock rate fast enough to avoid missing clock or data pulses that extend into the 'dead zone' between SPI bytes. The SPI interface will not see pulses that fall inside the gap between bytes so I increase the clock rate to a little over 3 MHZ and I find that a single clock or data bit from the disk drive is received as 2-3 bits through the SPI interface. Worst case, if a clock or data bit exactly straddles the gap between bytes I would expect to see a single bit set in the output. The software counts the number of zero bits between the ones and, if the number of zero bits is greater than 16 it counts it as a zero, otherwise it counts it as a one.

Because I am polling for the index signal in software there is a 10 microsecond gap between the start of the index signal and the start of data. This represents less than three clock/data pairs so is unlikely to cause problems.

I have successfully read actual floppy boot disks into the Pi and used them in the TRS-80 emulator from www.trs-80emulators.com. While I was able to read some copy-protected disks into the Pi, not all of them worked correctly in the emulator. I believe this is because the cw2dmk utility was designed to make copies of unprotected disks and, by default, ignores misplaced address marks and other deliberate errors on copy protected disks.

I have not tried to write back to a floppy disk but it should be easy to do so.