Quote HereEpson PF-10 disk drive (borrowed from fjkraan's PX-8 site
A problem and fix was given to me by another builder. Before building, please see here.
In November of 1984 the Epson PX-8 had just come out. I was about to leave for Germany for my first assignment in the army. I wanted a good computer to take with me, and the PX-8 seemed perfect. It was $995! That was two months pay. But my sister loaned me the money and I bought it. I wanted the PF-10 floppy disk drive, but it was another $595, or month and a half pay. I decided to wait and buy it later. Later never came.
I really like the PX-8 and did a lot with it. I managed (barely) without the disk. The ramdisk and tape drive made it workable. But when I had the money to buy the disk drive, I decided that instead I would buy an Ampro little board plus and a floppy disk for it, and use the PX-8 as a terminal. But that's another story. So I never got the floppy.
I've kept the PX-8 all these years and still like it. I've always wanted to build a drive emulator that plugged in like the real thing and was smaller, lighter, easier to carry, and cheaper. Until recently I couldn't find enough documentation on the serial protocol. Now I have it, so...
There are at least a couple different programs out there that let you connect your PX-8 to a PC and use the PC as virtual floppy drives. But that kind of defeats the purpose of having a portable computer. Your laptop just became chained to your desk. I want a solution that is at least as portable as the original, preferably more so.
The Epson PX-8 was one of the very first laptops. It runs CP/M, which was the main 8 bit "business oriented" operating system. The computer has a Z-80 compatible processor (NSC-800 from National Semiconductor,) 64K of RAM, an 8 line by 80 column LCD display, a full-travel keyboard, the serial (peripheral) interface as well as an additional RS-232 interface, a microcassette recorder, and a few other niceties. It has CP/M in ROM which allows more RAM for applications. Between 9K and 24K of the RAM can be used for a RAM disk. The RAM is backed up even when power is off so you don't lose your data. It can hold two ROM chips that are used as read-only disk drives holding applications. One ROM was provided with Microsoft BASIC and one with a version of Wordstar. Others have a spreadsheet and scheduling program and CP/M utilities.
The system is a decent CP/M machine. The biggest complaints are the slow and small display (which was actually pretty advanced at the time) and the lack of actual disk drives built in. The keyboard is very nice. It actually has two other processors that handle much of the housekeeping. It has an expansion connector where various things, including larger RAM disks could be attached. The display is dot addressable as 480 x 64 pixels.
There is a lot more information on the web:
Fred Jan Kraan's site
And lots more. Google is your friend.
Here is a review from Byte Magazine's Feb 84 issue.
The PX-8 (and PX-4 and HX-20) use a serial interface that is essentially RS-232 to talk to peripherals, including disks. It is a three wire interface using no hardware handshaking. It runs at 38,400 bps. All communication follows the Epson Serial Protocol (EPSP.) In the PX-8 (and PX-4) communication with the floppy drive is low-level, basically reading and writing raw sectors. A single floppy disk can store a total of 320K bytes (somewhat less usable.) The computer can handle up to four drives. Since the CP/M is stored in and runs from ROM in the PX-8 it requires changing the ROM to increase drive size or number of drives. We won't bother.
The above defines what we need. We need RS-232 communication at 38,400 bps, we need a processor to control the protocol and the reading and writing of data, and we need some place to store that data -- from 320K for a single drive, to 1280K for four drives, or more if we want to be able to "change disks." We would prefer the storage is non-volatile so it stays put when we turn off the power. Of course, we need power for the whole thing.
This is preliminary. I haven't finished the hardware or software, so things are subject to change. But they shouldn't change much.
The hardware consists of an Arduino Nano, an SD card and adapter, a MAX232 type interface, and a battery and 8 pin mini din connector. I want this to be a quick and easy project so that it actually gets done. By using the Arduino and a pre-made SD card interface, hardware development is much simplified. I only need one, after all. The Arduino also makes software development easier, especially by using the SD card library which can read and write FAT format SD card files. I'm using an Arduino Mega for development because it has more than one hardware serial port. That way I can use one to communicate with the PX-8 and one to communicate to the PC to display debugging info.
For now, the SD card will hold four files containing four disk images for each of the four possible disk drives. These files will be readable and writable on a PC so that you can copy the disk images onto them directly. PX-8 requests will read and write directly into the appropriate file as commands come in. Eventually I plan to add a "disk change" capability so that you can store numerous disk images on the SD card and select them as needed. That will probably require a custom command not defined in the EPSP protocol as well as a custom program running on the PX-8.
I plan to put everything on one small board and put it in a small case with a battery pack. A connector will plug in to the serial connection to make a small addition to the PX-8. It should be quite portable. A custom solution using a bare ATMega instead of an Arduino would be pretty simple, but I probably won't bother.
The firmware in the Arduino will run a state machine to execute the protocol. As commands are identified they will be carried out. I only intend to support the disk commands used by the PX-8 (and PX-4 by default) and not any of the command used in the HX-20, which operates quite differently. Source will be posted, so if you want to extend it, go ahead.
Let's get to work...
After wading through a lot of documents getting bits and pieces of how the protocol is supposed to work, and finding disagreement and downright errors, I finally had some success!
Can't write to disk yet, but soon...
More progress! Later the same night as I last posted I succesfully got the beast to write! I haven't had a chance to do much more or to update this until today. The code is rather fragile and I have run into a couple problems, but it certainly seems to be working at this point.
The next steps are to clean up the code and make it more robust. Then, port it back to the Arduino Nano as intended. Considerable testing will be done during and after those tasks. I also need to update the documentation. The state diagram has changed somewhat I hope to post the code and docs soon. Perhaps in the next two weeks, depending on free time. Oh, yeah. And build a proper board!
One issue I found today that I still don't understand relates to the SD card library. During my initial experimenting I put a call early on to read a sector from one of the virtual disk files and display it in the Arduino terminal. When starting to clean up the code today I took that out. And it crashed. It turns out that as long as I read a sector from any virtual drive before entering the state machine it works fine. If I don't the PX8 will get a BDOS error. I thought at first that the first file read by the SD lib was doing some initialization that took a while, but that appears to not be the problem. hmmm
For now I am just going to leave it. I do intend to find the issue. Even if it continues to work perfectly I just can't let it go. It could be a sign of a bug somewhere that I haven't found yet, too. But for now that initial read doesn't hurt anything and maybe I will find the problem while poking around in other stuff.
Since I need to bang on this thing a bunch I'm creating disk images of CP/M software. After the first release the next feature I intend to add is a way to change "disks." I want to issue a command from the PX8 to tell the PFBDK to replace one disk file with another. I haven't decided for sure how I want to go about that. I have a couple ideas but I have some time to think about it first.
Lots to do. Back to work...
After a few false starts, including building a complete board that I could never get to work, I finally got the blasted thing soldered up and working. For now I am using 4 AA NiMh batteries in a 4 cell holder with a switch to power it. At some point in the future I may add a charger, but at least for now I will just take them out and charge them separately.
Here is a picture of the setup as it is right now. I need to add some sort of case that mounts to the PX8 somehow. But it's usable as-is.
I want to make a couple of changes still. The first is a simple software change. Currently it loads the files "PX8DSK.000" to "PX8DSK.003" as drives "D:" through "G:". I'm going to change that to "D:img" through "G.img". I also want to add battery monitoring. That will require a little hardware and a bit of software. If the battery voltage drops too low (4 volts?) it will shutdown and not allow operation. Perhaps a warning when the voltage is getting close to the limit. Not sure how I want to do that, exactly. But 2200 mAh batteries should give me some time to think about it.
The biggest thing left to do is to allow changing "disks." That will take some software on PFBDK as well as some software running on the PX8 itself. Shouldn't be too hard. I think I know how I'm going to do it. Probably by using BIOS calls to read and write certain "unused" sectors on the last disk to get and change the file used for each disk. Not in too big of a rush, yet.
Within the next couple of days I will get the schematic and source code posted. I will add descriptions and comments for both. Tonight, I will go to bed happy!
As promised, here is the schematic...
|Arduino Nano clone (ebay)||approx $2.00|
|SD card module (ebay)||approx $3.00|
|Max232A or Max232 RS232 driver/receiver||approx $1.00|
|1uF (Max232) or 0.1uF (Max232a) ceramic caps x 5||approx $1.00|
|22uF, 10V electrolytic||approx $0.50|
|8 pin mini DIN plug||approx $1.00|
|4 x AA battery holder with switch||approx $2.00|
|Superbright Green LED||approx $0.50|
|4700 ohm, 1/4 watt resistor||approx $0.05|
|Prototyping strip board||approx $2.00|
|2 pin jumper||approx $0.05|
The schematic and parts list are shown above. Solder it up from the schematic. The mini din connector only needs three connections. The serial interface doesn't use any hardware handshaking, so it only needs signal ground, transmit, and receive. The AA batteries used should be rechargeable NiCd or NiMH, but not fresh off the charger. When just off the charger they may have a voltage that is a little high (around 6V total) so let them sit a while and they should drop to around 4.8 to 5V.
The jumper shown on the schematic between the Arduino Rx pin and the MAX232 pin 12 needs to be removed to program the Arduino. It must be in place to use the pfbdk. Here is the Arduino source file. It is intended for use with an Arduino Nano, but can also be used with an Arduino Mega as I did for development. In that case connection should be made to the correct pins, which you can find by looking at the source. The source will probably also work as-is with an Arduino Uno, but I haven't tried it. The pin connections should be the same as the Nano. The code was written with Arduino 1.8.5. It uses the SD card library, which also uses the SPI library. Those should be installed with the IDE by default. Flash the ARduino.
The Arduino firmware looks for four files named "D.pfd", "E.pfd", "F.pfd", and "G.pfd" on the SD card. Those will be, respectively, drives 1, 2, 3, and 4 which default on the PX8 to D, E, F, and G. Here are some disk images you can use. Those images mostly came from FJ Kraan's site or Udo Monk's Z80Pack site. I converted them with my tools and cpmtools. Name the desired images with the "D.pfd" etc names and copy them to the SD card. The SD card should be formatted with the standard FAT16 or FAT32 (they come that way.)
I have created a couple of tools for handling disk images. In that zip file is source code for "px8_mkdisk.c" which is a program that creates an empty disk image suitable for pfbdk. There is also "px8_d88.c" which takes a .d88 image file as used by vfloppy and converts it to a suitable raw image file. The Makefile used to build both of those programs is also included. They are simple and crude, but usable. Also included is a diskdefs file for cpmtools to work with that raw image format. These were all built and used on Linux. I've no idea if they will work on any other platform.
Once you have it built and programmed, with the image files on the SD card, plug it in to the PX8 and turn it on. Then turn on the PX8 and you *should* be able to access all four floppy drives.
If you build this I would love to get feedback. If you have trouble getting it going, please let me know and we'll try to get it fixed. If you find bugs let me know and I will try to resolve them. I've only done minimal testing so far, so bugs are rather likely. If you think it's the greatest thing since sliced bread, I'd love to know that too.
Thanks to all the people who have made this possible by putting documents, programs, disk images, and lots of other stuff on the web. Special thanks for this particular project to FJ Kraan and Udo Monk. I hope they don't mind that I "borrowed" disk images and photos!
In the year and a half since I built this, several people have contacted me about it. I've asked people to send me pictures and links if they build it so that I can post them here.
Georg Schäfer contacted me a couple months ago to let me know he had built a PFBDK and was finishing it up. He ran into a couple problems caused by changes in the Arduino software from the version I had used. I will let him tell the story in his original email, posted below.
But first, here is his work. This is the first picture he sent with his
As I mentioned, he also let me know about some problems he ran into. He asked
me to reword it in my own words, but I don't think I could make it any clearer.
So here is his explanation:
"In your Arduino version 1.8.5 the SD library has a different definition of FILE_WRITE than the following versions. I use 1.8.9 and didn't manage to get something written until I found the difference:
1.8.5: #define FILE_WRITE (O_READ | O_WRITE | O_CREAT)
1.8.9: #define FILE_WRITE (O_READ | O_WRITE | O_CREAT | O_APPEND)
So the current version always wants to append to a file - even though we first do a seek.
Although i think it is a bug in the SD library I changed your code to be independent from any future variations:
File dsk = SD.open(diskNames[unit * 2 + disk], FILE_WRITE);
File dsk = SD.open(diskNames[unit * 2 + disk], (O_READ | O_WRITE | O_CREAT));
I guess it should be sufficient to use only "O_WRITE", because you open the file for every single read or write. "
Contact me at: