Larswad / sd2iec_mega2560

SD2IEC adapted to work with Arduino mega 2560, with some other nice additions.
GNU General Public License v2.0
35 stars 14 forks source link

sd2iec - a controller/interface adapting storage devices to the CBM serial bus Copyright (C) 2007-2014 Ingo Korb ingo@akana.de Parts based on code from others, see comments in main.c for details. JiffyDos send based on code by M.Kiesel Fat LFN support and lots of other ideas+code by Jim Brain Final Cartridge III fastloader support by Thomas Giesel IEEE488 support by Nils Eilers

Free software under GPL version 2 ONLY, see comments in main.c and COPYING for details.

FIXME:This file still needs to be expanded. A lot. FIXME: sprinkle mentions of IEEE488 where appropiate

Deprecation notices

The following feature(s) will be removed in the next release:

Introduction:

sd2iec is firmware, used in hardware designs like MMC2IEC, SD2IEC, or uIEC, that allows the Commodore serial bus to access removable storage devices (MMC, SD, CF) - think of it as a 1541 with a modern storage medium instead of disks. The project was inspired by (and uses a few bits of code from) MMC2IEC[1] by Lars Pontoppidan and once ran on the same hardware before it grew too big for the ATmega32 used there.

Currently, the firmware provide good DOS and file-level compatibility with CBM drives, but much work remains. Unless specifically noted, anything that tries to execute code on the 1541 will not work, this includes every software fastloader.

[1] Homepage: http://pontoppidan.info/lars/index.php?proj=mmc2iec

Please note: Whenever this file talks about "D64 images" the text applies to all Dxx image types, i.e. D64/D71/D81/DNP unless specifically noted.

If you are the author of a program that needs to detect sd2iec for some reason, DO NOT use M-R for this purpose. Use the UI command instead and check the message you get for "sd2iec" and "uiec" instead.

Supported commands:

Large buffers:

To support commands which directly access the storage devices support for larger buffers was added. A large buffer can be allocated by opening a file named "##" (exactly three characters" with replaced by a single digit specifying the number of 256-byte buffers to be chained into one large buffer - e.g. "##2" for a 512 byte buffer, "##4" for 1024 bytes etc. Unlike a standard buffer where the read/write pointer is set to byte 1, a large buffer will start with the r/w pointer pointing to byte 0 because that seems to be more sensible to the author.

If there aren't enough free buffers to support the size you requested a 70,NO CHANNEL message is set in the error channel and no file is opened. If the file name isn't exactly three bytes long a standard buffer ("#") will be allocated instead for compatibility.

The B-P command supports a third parameter that holds the high byte of the buffer position, For example, "B-P 9 4 1" positions to byte 260 (1*256+4) of the buffer on secondary address 9.

Long File Names:

Long file names (i.e names not within the 8.3 limits) are supported on FAT, but for compatibility reasons the 8.3 name is used if the long name exceeds 16 characters. If you use anything but ASCII characters on the PC or their PETSCII equivalents on the Commodore you may get strange characters on the other system because the LFN use unicode characters on disk, but sd2iec parses only the low byte of each character in the name.

EEPROM file system

WARNING: The EEPROM file system is a newly-implemented file system that may still contain bugs. Do not store data on it that you cannot affort to lose. Always make sure that you have a backup. Also, the format may change in later releases, so please expect that the partition may need to be erased in the future.

Devices running sd2iec always have an EEPROM to store the system configuration, but on some devices this EEPROM is much larger than required. To utilize the empty space on these devices (currently any microcontroller with at least 128K of flash), a special EEPROM file system has been implemented. This can for example be used to store a small file browser or fast loader so it can be used independent of the storage medium that is currently inserted.

The EEPROM file system will always register itself on the last partition number (see "Partitions" below). You can check the list of partitions ("$=P") to find the current partition number of the EEPROM file system or use the alias function (see below) to access it.

To simplify calculations, block numbers on the EEPROMFS are calculated using 256 bytes per block instead of the usual 254 bytes as used by Commodore drives. Internally, the allocation is even more fine-grained (using 64 byte sectors), which means that the number of free blocks shown on an empty file system may be less than the sum of the number of blocks of all files on a full file system.

The EEPROM file system does not support subdirectories. It can be formatted using the N: command as usual, but the disk name and ID are ignored. The capacity of the EEPROM file system varies between devices: On AVR devices it is 3.25 KBytes and at most 8 files can be stored on it. On a2iec, the file system can hold 7 KBytes and at most 16 files can be stored on it. The actual number of files that can be stored depends on the length of the files, longer files need more than one directory entry.

Partitions:

sd2iec features a multi-partition support similiar to that of the CMD drives. The partitions (which may be on separate drives for some hardware configurations) are accessed using the drive number of the commands sent from the computer and are numbered starting with 1. Partition 0 is a special case: Because most software doesn't support drive numbers or always sends drive number 0, this partition points to the currently selected partition. By default, accesses to partition 0 will access partition 1, this can be changed by sending "CP" over the command channel with being an ASCII number from 1 to 255. "C<Shift-P" (0x42 0xd0) works the same, but expects a binary partition number as the third character of the command.

To allow a "stable" access to the EEPROM file system no matter how many partitions are currently available, a special character has been introduced that will always access the EEPROM file system (if available). When sd2iec sees a "!" character where it expects a partition number and the "!" character is directly followed by a colon (i.e. "!:"), it will access the EEPROMFS if available. Direct access using the assigned partition number is of course still available. Additionally "$!" will always load the directory of the EEPROM file system partition (if available), similar to "$1" to "$9" for partitions 1 to 9.

Software fastloaders:

Note: Using sd2iec without an external crystal or similiar precise clock source is not a supported configuration. If you try that anyway, be prepared to suffer from random data corruption. You have been warned. Some fastloader implementations will actively refuse to work if you use an unsuitable clock source.

Turbodisk
---------
Turbodisk is detected by the CRC of its 493 byte long floppy code and
the M-E address 0x0303. The same code seems to be used under various names,
among them "Turbodisk" (both 2.1 and 2.2) and "Fast-Load".
It is not known if there is an NTSC-compatible version of this fastloader.

Final Cartridge III
-------------------
Both the fast loader and the fast saver of Final Cartridge III are supported.
The FC3 is both PAL and NTSC compatible.

The slightly different fastloader used for files freezed with the FC3
is also supported.

EXOS V3 and The Beast System
----------------------------
Both supported, the loader used by these kernals is very similiar to
the FC3 fast loader.

Action Replay 6
---------------
The AR6 reads a byte from the drive rom to check which fastloader it should
use. When file-based M-R emulation is disabled sd2iec returns a value that
should force the cartridge to use the standard kernal loader instead of its
many fastloaders/-savers. This means that accessind sd2iec with
file-based rom emulation enabled will fail because the cartridge
will enable fastloader that will probably not be recognized.

Currently the only recognized AR6 fastloader and fastsaver are the
ones for the 1581.

Dreamload
---------
Dreamload uses direct track/sector access, so it is only supported
on D64 or similiar disk image formats. As sd2iec has to wait for commands
from the C64 constantly the disk change buttons may become unresponsive,
try multiple times if you need to. Dreamload is a "captive" fastloader,
sd2iec stay in Dreamload mode until it receives a "quit loader" command
from the C64. To force sd2iec to resume normal operation, hold the disk
change button until the red LED turns on (just like sleep mode).

Please note that Dreamload does not work with more than one device on the
serial bus due to the way it uses the ATN line.

ULoad Model 3
-------------
ULoad Model 3 uses direct track/sector access, so it is only supported
on D64 or similiar disk image formats. Currently there is exactly one
supported variant of ULoad Model 3, which is the one used by
Ultima 3 Gold. There are no other known variants at this time, but
this may change.

If you are a coder and want to use ULoad Model 3 in your own program,
either configure it to produce the same drive code as U3Gold or
contact me so we can work out a way to trigger ULoad M3 support
without uploading any drive code at all.

G.I. Joe Loader
---------------
Said to be the most-ripped IRQ loader. Unfortunately this is a
"captive" fastloader similiar to dreamload (but not restricted
to disk images because it is file name-based) and there is no
reliable way to detect if the computer has been reset to switch
back to the standard protocol. To exit this loader, hold down
the disk change button until the red LED turns on, just like
sleep mode.

Epyx FastLoad Cartridge
-----------------------
ONLY the fast loader from this cartridge is supported, no
disk editor/copier/whatever functions.

GEOS
----
GEOS 2.0 can be booted from D64 images made from original disks
as well as D41/71/81 images created using geoMakeBoot (make sure to
Configure the system for a 1541/1571/1581 before using geoMakeBoot).
When file-based M-R emulation is disabled, GEOS may detect sd2iec as
a 1541 or 1581, depending on the version of Configure used. This may
cause the system to fail to boot, e.g. if sd2iec is detected as a 1581
while booting from a D64 disk image. It is recommended to set up file-
based M-R emulation when using GEOS to avoid these problems.

GEOS 1.3 may or may not work - it boots, but wasn't tested in-depth.
Gateway seems to work but was not tested beyond booting it from a D64
image.

Using the buttons for changing the current disk image is supported,
but do make sure that you only access disk images that the drive
type that is selected in GEOS would support (i.e. D64 for a 1541,
D64/D71 for a 1571 and D81 for a 1581).

Wheels
------
Wheels can be booted from any disk image type it supports. The correct
rom emulation file (XR) MUST be set, especially for CMD HD emulation.

Do not use the disk change feature to change disk images when HD emulation
is in use - Wheels does not check for disk changes on that drive!
For other drive types the restrictions on disk image type of GEOS also
apply to Wheels.

ELoad Version 1
---------------
This loader was made for EasyProg but may also be used in other programs.
It detects and supports the sd2iec natively.

Maniac Mansion
--------------
Original versions of Maniac Mansion have an additional copy protection
check that is not supported by sd2iec. Please use a cracked version
instead - the ones from Gamebase 64 seem to work. Please remember to
add an empty D64 for the save/load disk to your swaplist if you want
to save your game.

The game uses a captive loader that unfortunately cannot detect if it
should exit automatically - to resume normal operation, you need to
hold down the NEXT button until the red LED turns on.

Zak McKracken
-------------
Same as Maniac Mansion, but this game only has a code list protection,
so images of original disks should work fine.

JiffyDOS:

The JiffyDOS protocol has very relaxed timing constraints compared to Turbodisk, but still not as relaxed as the standard Commodore IEC protocol.

x00 files:

P00/S00/U00/R00 files are transparently supported, that means they show up in the directory listing with their internal file name instead of the FAT file name. Renaming them only changes the internal name. The XE command defines if x00 extensions are used when writing files, by default sd2iec uses them for SEQ/USR/REL files but not for PRG. Parsing of x00 files is always enabled even when writing them is not.

x00 files are recognized by checking both the extension of the file (P/S/U/R with a two-digit suffix) and the header signature.

Disk Images:

Disk images are recognized by their file extension (.D64, .D41, .D71, .D81, .DNP) and their file size (must be one of 174848, 175531, 349696, 351062, 819200 or a multiple of 65536 for DNP). If the image has an error info block appended it will be used to simulate read errors. Writing to a sector with an error will always work, but it will not clear the indicated error. D81 images with error info blocks are not supported.

Warning: There is at least one program out there (DirMaster v2.1/Style by THE WIZ) which generates broken DNP files. The usual symptom is that moving from a subdirectory that was created with this program back to its parent directory using CD:_ (left arrow) sets the current directory not to the parent directory, but to an incorrect sector instead. A workaround for this problem in sd2iec would require an unreasonable amount of system resources, so it is recommended to avoid creating subdirectories with this version of DirMaster. It is possible to fix this problem using a hex editor, but the exact process is beyond the scope of this document.

M2I files:

NOTICE: Support for M2I files will be removed in the next release, see the deprecation notices at the top of this file for advice.

M2I files are fully supported. sd2iec supports SEQ and USR files in this format in addition to PRG and DEL which were already implemented in MMC2IEC. For compatibility reasons the file type is not checked when opening files. Inside an M2I file the files are always shown as 0 (DEL) or 1 blocks because calling stat for every file was slowing down the directory listing too much. For compatibility with existing M2I files the data files do not use P00 headers even when the file type is SEQ or USR.

REL files:

Partial REL file support is implemented. It should work fine for existing files, but creating new files and/or adding records to existing files may fail. REL files in disk images are not supported yet, only as files on a FAT medium. When x00 support is disabled the first byte of a REL file is assumed to be the record length.

Changing Disk Images

Because some programs require more than one disk side there is support for changing the currently mounted disk image with two buttons called NEXT and PREV connected to the AVR.

If your circuit doesn't have disk change pins/buttons you might be able to add it yourself. In all cases the buttons need to connect the given pins of the chip to ground.

To use this functionality, you can either create a swap list file yourself or let sd2iec create one for you.

Creating a swap list

A swap list is a text file with one line per disk image or directory you want to be able to change into. You are not limited to using disk images, a swap list file may also refer to standard directories on the SD card or anything else the CD command of sd2iec will accept.

The swap list file is relatively tolerant against multiple styles of line-endings, sd2iec should be able to parse the file no matter if you create it on a Windows system, Unix or even the C64 itself - as a side effect, empty lines are also ignored. By default sd2iec assumes that the file is encoded in ASCII (for files created on a PC or similar), but if the first line of the file exactly reads "#PETSCII" (in hex: 23 50 45 54 53 43 49 49), file names are assumed to be encoded in PETSCII instead and this marker line is skipped.

An example swap list file could look like this: === example 1 === FOO.D64 BAR.D64 BAZ.D64 === end of example 1 ===

=== example 2 === //NEATGAME/:DISK1A.D64 //NEATGAME/:DISK1B.D64 //NEATGAME/:DISK2A.D64 //NEATGAME/:DISK2B.D64 === end of example 2 ===

The swap list is enabled by sending "XS:filename" over the command channel with filename being the name of the swap list. A list activated in this way stays active until you explicitly disable it again by sending "XS" on the command channel or you manually activate another swap list with "XS:otherfilename".

Since the manual activation of swap lists is still a bit of a hassle, sd2iec will automatically try to activate a swap list named "AUTOSWAP.LST" in the current directory if you use the disk change buttons while no swap list is active. A swap list enabled in this way behaves almost exactly as a swap list enabled with XS, but it auto-deactivates when a CD (change directory) command is received by sd2iec. This way a different AUTOSWAP.LST file is always correctly recognized after you have changed into a different directory.

sd2iec can even auto-generate a swap list for you that contains all disk images (e.g. D64/D71/D81/DNP) in the current directory if no AUTOSWAP.LST is present in this directory. To do so, change into the directory that you want scanned and use the HOME function (see below). sd2iec will then create a file called AUTOSWAP.GEN and activate it as if it was the standard AUTOSWAP.LST, including its auto-deactivation features. The AUTOSWAP.GEN file will never be recognized the same way as AUTOSWAP.LST, so you will need to either rename the file (R:AUTOSWAP.LST=AUTOSWAP.GEN) or ask sd2iec to generate it again by using the HOME function in the same directory if you want to use it again. This mode of operation was chosen to avoid the accidental destruction of pre-existing AUTOSWAP.LST files and to allow sd2iec to recognize newly-added disk images in the directory without manually removing the generated swap list.

Please note that using the swap-list auto generation feature will currently leave an empty AUTOSWAP.GEN file on the card if no disk images were found. This may be fixed in the future.

Using a swap list

Navigation in a swap list is really simple: Press the NEXT button to activate the next line of the file or the PREV button to activate the previous line of the file. Both of these buttons wrap to the other end of the file if they hit the beginning/end of the list. You can also hit both buttons together to trigger the HOME function which jumps to the first entry of the swap list.

sd2iec will confirm each of these three actions with a specific flashing pattern on the device's LEDs. The pattern first flashed both the red and green LEDs on for a short moment, then it flashes either one or both of them. For the NEXT function, the green LED flashes; for the PREV function the red LED flashes and for HOME both LEDs flash.

If any of these three functions is activated without an active swap list and sd2iec finds an AUTOSWAP.LST file, they will all be treated as the HOME function: The first line of the file is active and the red and green LEDs both flash twice. The same happens when an AUTOSWAP.GEN file is created, although the flashing pattern may not be very discernible because of the preceding card activity.

Sleep Mode:

If you hold the disk change button down for two seconds, sd2iec will enter "sleep mode". In this mode it doesn't listen to the bus at all until you hold down the disk change button for two seconds again which resumes normal operation. Sleep mode allows you to keep sd2iec connected to the serial bus even when you load something from a different drive that uses a fast loader that doesn't work with more than one device on the bus.

While sleep mode is active, the red LED will be on and the green LED will be off.

Card detection test:

Because some SD slots seem to suffer from bad/unreliable card detect switches a test mode for this has been implemented on the units that have SD card support. If you hold down the PREV button during powerup, the red (dirty) LED will reflect the card detect status - if the LED is on the card detect switch is closed. Please note that this does not indicate successful communication with the card but merely that the mechanical switch in the SD card slot is closed.

On units with two sd2iec-controlled LEDs, the green (busy) LED will indicate the state of the write protect switch - if the LED is lit, the write protection is on. Due to the way the write protect notch works on SD cards, the indication is only valid when the card is fully inserted into the slot.

To exit from the diagnostic mode, power-cycle the device or push the NEXT button once.

Other important notes:

Compilation notes:

sd2iec requires avr-libc version 1.6.x.

sd2iec is set up to be compiled in multiple configurations, controlled by configuration files. By default the Makefile looks for a file named 'config', but you can override it by providing the name on the make command line with "make CONFIG=filename[,filename...]".

An example configuration file named "config-example" is provided with the source code, as well as abridged files corresponding to the release binaries. If you want to compile sd2iec for a custom hardware you may have to edit config.h too to change the port definitions.

MEGA2560 / Arduino considerations

A separate configuration has been added for the mega2560, this enables the Arduino community to easily use sd2iec with a regular Arduino or clone together with an sd-card shield. To avoid flashing the arduino bootloader (which is not really needed or recommended since the stock one works just fine) and make things a little easier a separate flash_arduino.sh script has been added in the scripts folder. This script assumes by default to use the avrdude tool in the avr toolchain, but the path's can be easily changed to point out the toolchain root in the Arduino SDK. The script expects the board to show up on /dev/ttyACM0. It is possible that root access is required.

The default assumption of the MEGA2560 is that no LEDs or extra push-buttons has been added to the board. This however can be easily added by simply changing the commented-out suggested GPIO's in the archconfig.h for this purpose. That way, drive activity and error LED's can be functional, same goes for a floppy switching button for M2I or D64 disks.

For the SD-card shield it should be connected to the Arduino ICSP header (located at the middle of the board). The shield also expects GND, probably 3V and also 5V to be connected.

Some boards also expects the chip select pin (SS) to be connected. There is one special case added for that in the config2560 already, but there are probably other shield out there that expects a different pin for that.