An AVR (atmega328p) based floppy drive emulator for PC
fddEMU is a DIY floppy drive emulator. You can immediately begin testing fddEMU on serial terminal with an arduino nano, an SD adapter that converts 5 volts arduino power supply and signals to 3.3 volts suitable for SD card, an SD card, and some jumper cables.
Standalone (using without usb serial connection) require SSD1306 i2c screen, buttons and a 5 volts power supply.
Requirements
- Arduino nano (UNO will do but button inputs require ADC7, use serial commands instead)
- Micro SD card adapter (converts 5 volts arduino power supply and signals to 3.3 volts)
- A micro SD card (formatted FAT16/32, floppy images in root directory)
- Two 1kOhm resistors (for step and readdata pins - atmega's internal pullups are not sufficicient for parasitic capacitance of long floppy drive cable)
- Male to female jumper wires (for connecting arduino nano pins to FDC ribbon cable)
- Male to male jumper wires (for pullup on step and readdata pins)
Optional
- 0.96" i2c OLED (SSD1306) screen (for output)
- 4 or 5 1kOhm resistors (for making ADC buttons)
- 1 100kOhm resistor (ADC7 has no pullup, so an external pullup required)
- 4 or 5 push buttons (required for ADC input obviously)
- 5 volts power supply (Computer PSU 5v pins or an external PSU can be used)
- Female to female jumper wires (for connecting SD adapter to arduino nano)
- Breadboard or perfboard (for placing pullups and ADC buttons)
Programming
Arduino bootloader could be used for uploading (see command below), simply replace /dev/ttyUSB0 with your usb port
avrdude -B 10 -p m328p -c arduino -P /dev/ttyUSB0 -U flash:w:fddEMU.hex
Pin mapping (single drive)
Pin | Arduino Nano | FDD Ribbon Cable |
---|---|---|
GND | GND | 1 (GND) |
STEP | D2 | 20 (Step pulse) |
STEP_DIR | D3 | 18 (Direction) |
MOTOR_A | D4 | 16 (Motor on B) |
SELECT_A | D5 | 12 (Drive Select B) |
SIDE | D6 | 32 (Select head) |
INDEX | D7 | 8 (Index pulse) |
READDATA | D8 | 22 (Write data) |
WRITEDATA | D9 | 30 (Read data) |
WRITE_GATE | A0 | 24 (Write enable) |
TRACK_0 | A1 | 26 (Track zero) |
WRITE_PROTECT | A2 | 28 (Write protect) |
DISK_CHANGE | A3 | 34 (Disk changed) |
Pin mapping (dual drive)
Pin | Arduino Nano | FDD Ribbon Cable |
---|---|---|
GND | GND | 1 (GND) |
STEP | D2 | 20 (Step pulse) |
STEP_DIR | D3 | 18 (Direction) |
SELECT_B | D4 | 14 (Drive Select A) |
SELECT_A | D5 | 12 (Drive Select B) |
SIDE | D6 | 32 (Select head) |
INDEX | D7 | 8 (Index pulse) |
READDATA | D8 | 22 (Write data) |
WRITEDATA | D9 | 30 (Read data) |
WRITE_GATE | A0 | 24 (Write enable) |
TRACK_0 | A1 | 26 (Track zero) |
WRITE_PROTECT | A2 | 28 (Write protect) |
DISK_CHANGE | A3 | 34 (Disk changed) |
Pin | Arduino Nano | Micro SD adapter |
---|---|---|
Slave Select | D10 | CS |
MOSI | D11 | MOSI |
MISO | D12 | MISO |
SCK | D13 | SCK |
VCC | 5V | VCC |
GND | GND | GND |
Pin | Arduino Nano | 0.96" OLED SSD1306 |
---|---|---|
GND | GND | GND |
VCC | 5V | VCC |
SDA | A4 | SDA |
SCL | A5 | SCL |
Resistor ladder for ADC buttons
Limitations
- fddEMU is not an cycle exact floppy emulator , it is more of a hack (it's a bit slower than actual fdd) but it works because floppy controllers have sensible timeouts and we take advantage of that.
- fddEMU uses MFM encoding (used by HD and DD disks) so there is no FM encoding (used by SD disks) support as of now. But it is possible to implement FM encoding.
- fddEMU uses raw floppy images (images prepared with dd or rawread) does not require or use a MFM file. Converts raw image sectors to MFM on the fly using ArduinoFDC library.
- fddEMU supports fixed sector size of 512 bytes, other sector sizes are not supported.
- Requires a Floppy Drive Controller (FDC) on the PC side to communicate so it probably wont work with an Amiga.
- If read data pin (D8) is disconnected or does not have sufficient external pullup fddEMU might hang up while reading data from host, which might cause a static image on screen. To protect the screen currently a watchdog timer of 8 seconds is set (which is the longest duration for watchdog timer). If mcu (arduino) can't access SD card after reset remove the sd card, wait a few seconds, reinsert the SD card then reset the arduino.
Acknowledgements
- ArduinoFDC by David Hansel. fddEMU uses a modified ArduinoFDC library renamed to avrFlux for communicating with FDC.
- Petit FAT FS by Chan adapted for hardware SPI by Bill Greiman. fddEMU uses a modified Petit FAT FS.
- rjhcoding.com/avrc-sd-interface Great tutorial for using SD card with AVR.
- u8glib Very useful for incorporating SSD1306 and can easily be used with various displays.
Releases
How to use
- fddEMU looks for a boot record on "sector 0" of the image. If the boot record reports that the image is formatted as "FAT1?", sector size is 512, number of heads is 2 and number of tracks and number of sectors are less than 255 the image file is loaded with the settings provided by the boot record. To be able to read these custom FAT12 images host system should support provided number of tracks and sectors. If there is no boot record file size is compared to the standart floppy sizes (1.44M, 1.2M, 720K and 360K), if file size matches one of these sizes it is loaded as raw image.
- Image file must be contiguous for fddEMU to be able to load, if the file is not contiguous an error message will be shown and loading will fail.
- Contiguity check would take long for large files (> 2MB) during this check fddEMU can not be used.
- For booting a host system, on startup fddEmu looks for "BOOT.IMG" on SD card. If there is a "BOOT.IMG" on the SD card fddEMU tries to load this file to drive A.
- if image file has "read only" attribute set, fddEMU will report "Write Protected" to host system.
- To protect OLED screen fddEMU will put screen to sleep after some idle time, press "S1" (SELECT) button or "S" key inside serial terminal to wake screen up.
- When host is reading/writing one of the emulated drives, BUSY message will be shown on screen and serial, during this time fddEMU will not respond to input. Warning: fddEMU will not put the screen to sleep while drive is active. If there is a hardware or software problem causing an emulated drive to go continuously active, OLED screen might be damaged.
fddEMU button interface:
- S1: Load Virtual Disk
- S2: Next
- S3: Previous
- S4: Open file selection Menu / Load selected file
- S5: Eject selected disk / Cancel loading file
On the main screen, drive 0 "A" and -if enabled- drive 1 "B" are displayed. To use any of the functions a drive must first be selected through "S2" or "S3" buttons.
After a drive is selected:
"S1" button: in main status screen, if virtual disk is enabled, loads the virtual disk to selected drive.
"S2" button: in main status screen selects drive down, in file selection menu selects file down.
"S3" button: in main status screen selects drive up, in file selection menu selects file up.
"S4" button: in main status screen opens file selection menu, in file selection menu loads the selected image file to the selected drive.
"S5" button: in main status screen ejects image file loaded to the selected drive, in file section menu cancels file selection and returns to main status screen.
How to use (Serial)
fddEMU serial interface is used through keys
- S: Select
- N: Next file
- P: Previous file
- L: Load selected file
- E: Eject selected disk / Cancel loading file
To use any of the functions a drive must first be selected through "S" key then serial terminal will report "Sel drive: A" or if drive B is selected "Sel drive: B".
After a drive is selected:
"S" key: shows serial status information and selects next drive.
"N" key: selects next image file. If virtul disk is enabled and if the last file in the directory is reached selects virtual disk .
"P" key: selects the previous image file. If the first file is selected, this file is reselected.
"L" key: loads selected image file to the selected drive.
"E" key: ejects image file loaded to selected drive. If pressed during file selection, cancels file selection.
How to use through host system (Virtual Disk)
-if virtual disk is enabled and loaded- Virtual disk root directory contains a "DISKS" directory, a "DRVA.TXT" file and if DUAL drives enabled a "DRVB.TXT" file. If an SD card is inserted "DISKS" directory contains the file listing of inserted SD card's root directory otherwise it will be empty. "DRVA.TXT" would contain name of the image file loaded the "drive 0" and "DRVB.TXT" would contain name of the image file loaded to "drive 1". Writing the name of an image file to either "DRVA.TXT" or "DRVB.TXT" would result loading requested image file to respective emulated drive upon host releasing the drive. However disk write cache might interfere writing into these files and a cache flush might be required.
How to build (Makefile)
Current Makefile assumes avr-gcc and avr-binutils are installed and are in the path,
avr specific includes are in "/usr/avr/include" and u8glib library is installed in
"libs/u8glib" (either install through git or extract downloaded "u8glib.zip" to "libs/"
directory).
make: builds binary with default options.
build options:
- GUI: enables graphical user interface on OLED screen and ADC buttons (enabled default by Makefile).
- SERIAL: enables serial user interface and serial commands.
- VFFS: enables virtual disk.
- DEBUG: enables debug output on serial.
- FLIP: flips the image on OLED screen 180 degrees (enabled default by Makefile).
- WDT: enables watchdog timer (enabled default by Makefile).
These build options could either be switched on and off from Makefile or commandline (eg.: 'make DUAL=1 GUI=1 VFFS=1 SERIAL=0 DEBUG=0').
Flashing the mcu could also be done by Makefile. "make flash" programs "fddEMU.hex" to default serial port "/dev/ttyUSB0". If you want to use another serial port assign it to PORT variable (eg.: "make flash PORT=/dev/ttyUSB2").
Note: Please report any errors on github issues for fddEMU. Suggestions for improvements and feedback could be posted on fddEMU blog page Although the blog page is in turkish, feel free to write comments either in turkish or english.