The MMC2IEC device
The following is the original MMC2IEC project documentation as it appeared on the first Lars' Electric Endeavors website. I am not involved in the developments of MMC2IEC and haven't been since I created the device back in 2007. Both the firmware and hardware have forked no doubt multiple times into newer and better variants, so the following material is mainly to preserve history. For up-to-date information check out the MMC2IEC page on c64-wiki.com.
Lars, January 2018
It has always been tricky to transfer data between a PC and a Commodore 64. As the old machine lacks any even remotely modern interfaces, tricks of some sort are always required to do the transfer. The MMC2IEC device can be seen as yet another one of these tricks, but it does so much more.
The MMC2IEC device tries to simulate a 1541 disk drive connected to the C64 using the IEC bus and accessing data from a SD/MMC flash memory card. The MMC2IEC is both greatly limited and greatly extended in features when comparing to the original 1541:
Features: (as of v0.7)
- Supports C64 kernel LOAD and SAVE functions.
- Supports wildcards.
- Supports all? SD and MMC cards.
- Thorough FAT16 and FAT32 support.
- Directory listing and changing supported through LOAD commands.
- PRG file load and save.
- D64 image readonly support. LOAD"$" produces a realistic listing when a D64 image is active.
- T64 image readonly support. LOAD"$" produces a tape contents listing.
- Live configurable to be device 8 or 9, and works with other devices on the bus.
- SD card write protect switch works.
- No fast loader support.
- None of the Commodore DOS functions beside LOAD and SAVE works.
- Few, if any, D64 games with loaders work.
- No long filenames.
Background and credits
The idea of transfering data to the C64 from a flash media was conceived long ago as I did an university project. In cooperation with other students we created a data logger interfacing a SD-card using an AVR. The SD-card data access and FAT driver modules were created back then and they were thoroughly tested. The FAT driver is not completely my own invention, it is a partial rewrite of work done by Angelo Bannack and Giordano Bruno Wolaniuk who used work done by Pascal Stang. See fat.c for details.
At some point I discovered Jan Derogee's 1541-III device which was a major inspiration. Before that I considered creating a C64 datasette simulator, but the 1541-III made me realise that it was possible to simulate a 1541.
The MMC2IEC project thus started as an attempt to port Derogee's 1541-III from PIC to the Atmel AVR architecture such that I could combine it with my FAT and SD-card modules. Soon enough I gave up the porting and implemented the IEC and 1541 simulation from scratch, but it would have been impossible without referring to Derogee's project all the time.
At a later point I realised that the MMC2IEC was perfectly suited for embedding in a C64-DTV mod. And so far I have only tested the MMC2IEC on a DTV in conjunction with my Wooden DTV mod.
This project is open source under the GPL license.
This is a quick overview of the software structure and some parts are superficially described. See detail documentation in the source code comments.
The software compiles with AVR-GCC. Download the source at the downloads page.
The following diagram shows how the modules calls each other. Note that not all modules and not all connections are shown in the diagram.
This file contains the main function, which calls various initialize functions and repeatedly calls the interface handler.
In this file the parsing and responding to IEC commands is implemented. This includes interpreting user commands, composing the C64 BASIC listings and transferring native, D64 or T64 files.
The low level I/O to the IEC bus with its quirky handshaking and some of the IEC protocol is implemented in this module. As of v0.7 this module has been tested successfully against a DTV as well as a C64, and with another 1541 device on the bus.
Read only implementation of listing and accessing files in a D64 image.
Read only implementation of listing and accessing files in a T64 image.
This module implements FAT16 and FAT32 with read and write access, as well as directory manipulation. It requires a hefty amount of resources from the AVR. See source for details.
This module implements communication with SD cards using hardware SPI. The driver has shown its value over time, in that it has worked with every SD and MMC card I have thrown at it.
Implementing the IEC protocol was a nightmare. The different states of LISTEN/UNLISTEN, TALK/UNTALK and the way commands were transferred was backwards to say the least. I'm not sure if I have the implementation correct yet. But it to works for SAVE and LOAD at least.
You can enable debug printing of IEC commands to the UART by setting the UART_DEBUG define in config.h.
It was tempting to make the ATN signal of the IEC bus interrupt handled, as the ATN signal is supposed to have a "stop everything and listen" meaning. But after further analysis I concluded that it would only complicate things. After all, the protocol allows for a significant delay from ATN to the device says "I'm listening".
In fact the implementation does not use interrupts at all, it is completely sequential. Whenever needed, execution is blocked until a given operation is complete. This fact is critical in the IEC_driver, because the communication might have come out of sync, and there you are, waiting for a handshake that never comes. To solve this, all loops in IEC_driver have timeouts. This is also true for loops in the SD-Card driver.
The device uses an Atmel AVR Atmega32 running internal 8 MHz oscillator, which is approximately 7.6 MHz on a 3.3 V supply.
The IEC signalling is implemented by changing the port status between high impedance and active low. The internal pullup is not utilized, and there are no pullups on the DTV version schematic. The pullups on the DTV mainboard are sufficient.
The hardware SPI is utilized for communication with the SD-card and the UART can be used for debug printing.
As of firmware v0.7 the SDCARD_DETECT mechanical switch is utilized. The result is a tremendous improvement in usability. Now SD cards insertion and ejection just works, and it is not required to do LOAD"<<",8 any more. The write protect mechanical switch now also has the desired effect.
The following I/O connections are expected by the software according to the setup in config.h. It is possible to reconfigure almost all I/O lines except SPI. Features such as DEVICE9 jumper, SDCARD_DETECT and SDCARD_WP can also be removed by changing config.h.
Hardware SPI is used for MMC/SD card access: PB7 SCK, output PB6 MISO, input PB5 MOSI, output PB4 SS, output The IEC bus: PC0 ATN, input PC1 DATA, open collector emulation PC2 CLOCK, open collector emulation LEDS: PA0 (active low) IEC communication going on PA1 (active low) Fat dirty indicator (don't remove flash media) DEVICE9 jumper PA2 If jumped to GND, MMC2IEC acts as device 9, otherwise 8 SDCARD_DETECT PD2 Must connect to GND when SD CARD is present in socket SDCARD_WP PD6 Must connect to GND when SD CARD is not write protected
Hardware-wise there are two versions of the MMC2IEC device: A DTV version and a C64 version.
This version is the simplest with no level conversion at all. The AVR runs at 3.3 V from the DTV and interfaces the SD-Card and the DTV directly. Strictly speaking you have to use an Atmega32L low voltage version, but I have not had any problems running non low voltage AVR's at 3.3 V at 8 MHz.
The schematic is quite simple:
I made the board layout as compact as possible and with no components on the bottom side, allowing for fitting into my Wooden DTV:
Finally I got the PCB ordered and I was quite pleased with the result. After soldering the device looked like this:
See how I embedded it into my Wooden DTV here
When MMC2IEC has to interface a real C64, level conversion has to be done somewhere, since the IEC bus operates at 5V and the SD-Card can maximally handle 3.3 V. As the SD-Card interface is the must demanding speed-wise, I chose to do the level conversion at the IEC bus signals.
Mosfets were used for level conversion of the open-collector bus signalling, see schematic. The interfacing is a clever little circuit that allows both sides to pull low using the mosfet, while high impedance state is achieved when neither side pulls low. The pull up resistor on the AVR side is to ensure that the rise time in high impedance state is fast enough.
For powersupply, a 3.3 V regulator from Texas Instruments was intended, but I got a 3.0 V version instead. It works just fine.
My current effectuation of the C64 MMC2IEC, with the v0.7 firmware, works very well. It loads and saves PRG files flawlessly, just as the DTV version. But I'm not happy with the hardware yet. For one thing, it uses batteries, and I have not found a suitable casing yet. I'll post pictures when I'm done with it.
This is a quick guide to the command interface understood by MMC2IEC: (from mmc2iec.c)
USAGE GUIDE: ------------ The MMC2IEC device implements accessing FAT16/32 filesystems on MMC or SD flash media. The CBM IEC protocol is implemented and the kernel load and save routines on the C64 works, loading from either PRG, D64 or T64 files, and saving only to PRG type files in FAT. Selecting directories and images is possible through LOAD"xxx" commands issued on the CBM. This is a quick overview of the commands, say MMC2IEC is IEC device 8: LOAD"<<",8 Reset SD card state. Do this if the SD card is exchanged. Read < as the petscii back-arrow. If SDCARD_DETECT signals is available, this operation is rarely needed. In FAT mode: (the default mode) LOAD"$",8 Gets directory listing, equivalent to LOAD".",8 LOAD"gamesdir",8 Enter the "gamesdir" directory, and get listing. LOAD"..",8 Up one directory and get directory listing. LOAD"tetris.prg",8 Loads the "tetris.prg" program file. SAVE"example.prg",8 Save into "example.prg" which is a FAT file. LOAD"disk.d64",8 Loads the disk.d64 image and enters D64 mode. LOAD"tape.t64",8 Loads the tape.t64 image and enters T64 mode. In D64 mode: Load "$", "*", wildcards, filenames works (almost) as espected on a 1541. LOAD"<",8 (back-arrow). Escape D64 mode, and back to FAT mode. SAVE"abc",8 Fools the CBM, but has no effect. Saves in D64 are not implemented In T64 mode: Load "$", "*", wildcards, filenames works as if it was a D64. LOAD"<",8 (back-arrow). Escape T64 mode, and back to FAT mode. SAVE"abc",8 Fools the CBM, but has no effect.
Enhanced interface demonstration
As of firmware v0.8, MMC2IEC supports more CBM DOS features. Messages through the error channel has been implemented, such as file not found, drive not ready and others. This is the welcome message:
Now Save-With-Replace works with SAVE"@:FILE", which will erase FILE first if it did exist. I have not implemented the Save-With-Replace bug, though ;)
But that's not the most interesting:
The "N:" operation initializes a new special disk "image", which is not readonly! I came up a with new file format for this read/write disk simulation, the .M2I file. The file is just an index with 16 char petscii filenames, the FAT filesystem is still utilized for file management:
When the M2I file is open, scratch and rename works, even with wildcards:
M2I files can also be entered with LOAD"FILE.M2I" and exited with LOAD"←", just like D64 and T64. It should be noted that scratch and rename also works in FAT mode, but not with wildcards.
The M2I disks has no limit on size and can be utilized for emulating multidisk games, such as:
This is the contents of the Last Ninja 2 M2I file:
LAST NINJA 2 D: :---------------- P:last.prg :LAST N.2++/IKARI D: :---------------- P:1a.prg :1A.````````````` P:1b.prg :1B.CENTRAL PARK P:2a.prg :2A.````````````` P:2b.prg :2B.THE STREET P:3a.prg :3A.````````````` P:3b.prg :3B.THE SEWERS P:4a.prg :4A.````````````` P:4b.prg :4B.THE BASEMENT P:5a.prg :5A.````````````` P:5b.prg :5B.THE OFFICE P:6a.prg :6A.````````````` P:6b.prg :6B.THE MANSION P:7a.prg :7A.````````````` P:7b.prg :7B.FINAL BATTLE D: :---------------- P:challeng.prg:CHALLENGE /UNIC D: :----------------
One day I will provide command line tools to make M2I systems from D64 or directories.
Finally, a little tip I discovered. If you want to change directory or mode with MMC2IEC, without loading and messing up what's in memory, use an OPEN operation instead of LOAD. For instance, to go to parent directory:
OPEN 15,8,0,"..":CLOSE 15
MMC2IEC source and schematic version 0.8
By Lars Ole Pontoppidan
Last update May 2007
MMC2IEC devices (that used to be) for sale
Lars from 2018 writing: In order not to mislead I've removed the original paragraph about devices being for sale. For the record - I did sell a small batch back in 2007 of devices of my design. NKC Electronics also made a batch back then of their design that was supposed to be compatible, but there was "a little change in the pin assignment on the Atmel" as I wrote back then. The details of this escape my records.
The following is the original description of the batch I sold:
What do you get
You will get a MMC2IEC rev. 2 printed circuit board (PCB) with all components mounted and soldered, and with the microcontroller programmed with the latest firmware. All you need to do is supply power and connect it to either DTV or C64.
Features of the MMC2IEC rev. 2 PCB:
- The device can be powered either directly or through a 3.3 V low-dropout regulator on the board. The regulator can handle at maximum 6 V. So, either power it directly from the DTV power supply, or from some voltage between 3.5 and 6 V.
- Level interfacing of the IEC signals is included in the design allowing connection with DTV as well as C64. Other IEC devices can also be connected the IEC bus, such as a real 1541 floppy.
- Two device selection jumpers allows hot-switching the IEC device number between 8, 9, 10 and 11.
- The SD-card socket features push/push action to insert and eject. Card detect and write protect is implemented and utilized by the software.
- The firmware can be upgraded with Atmel ISP programming tools.
- Also read about the general features of MMC2IEC on the intro page.
Comments powered by Talkyard