USB-64 by Luigi Di Fraia USB-64 - Turning Commodore 64 into a USB host for Mass Storage Drives


Foreword

Over time USB-64 has been criticised in favour of IP network-based solutions. I honestly don't think these two belong to the same subject. I mean, USB-64 is a hack put together in 2 weeks and during my free time (that means evenings and mainly nights) in August 2010. I learned a big deal of things while working at this project, including the CBM BASIC interpreter and Kernel code style, which was great.
For me, USB-64 is more of a proof that with some motivation, enthusiasm and the right information one can achieve things that were not thought of up to that point.

From an idea to a prototype

Back in April I was attending Breakpoint 2010 in Bingen Am Rhein, Germany. There, among several modern PCs one could easily spot a few Commodore computers with people actually developing some code, pixellating some picture, and the Metalvotze guys watching a pron movie on a Commodore 64.

Long story short: there are people who keep using their Commodore 64 for all sorts of creative work. Nice, isn't it?

Over time several guys have designed and made all sorts of add-ons for the Commodore 64 to make using it a more enjoyable experience nowadays. That's 25+ years after it first came out.

I've probably been a voice out of the chorus with my DC2N project: something that can play back tape ROMs at the same painfully low speed as the original ones did. That's great nostalgic stuff for those who enjoy sitting back and watching a game load, listening to its load music, and so on.
Not much of interest for people in the development area though. Well, DC2N made the task of creating tape ROMs a very straightforward one; that was the original purpose anyway.
I personally also used my DC2N to transfer files from PC, where my cross-development toolchain runs, to the Commodore 64. That occurred quite a few times during the devolopment I did for this project, of course.

So that, after Breakpoint I felt I had been lingering for too long and had to move on, explore the available options in order to add some new "nice-to-have" feature to my Commodore 64: I personally always felt the need to have file transfer using simple, fast, and cheap means.

It was a rainy day in August when I had the idea: turn the C64 into a USB host and load/save files directly from/to a USB drive: the idea of USB-64 was born.
It took a few days to arrange the hardware and write a driver in assembly. The first properly assembled prototype was going to appear on the 24th of August. Nobody had been informed about the progress, but a few close friends.

This is what it looked like:

USB-64 prototype by Luigi Di Fraia

USB-64 prototype (serial transfer version)

User interface

One of the first things I realized was: I need this to be hassle free. It also needs to look and feel like a genuine device from the 80's for what concerns the user experience. With a few "must have" enchancements, of course.

So what does that mean? Well, to me it meant writing a superset of the CBM BASIC interpreter with new commands: USB-BASIC. Examples of new commands would include:

    USAVE
    ULOAD
    UVERIFY
    etc.

The error messages had to look and feel like the original ones too. E.g.:

    ?DISK NOT PRESENT  ERROR
    ?DISK FULL  ERROR

Of course, the superset would need to be available in a simple way, possibly having it on a cartridge so that it's ready to use at startup, as enthusi suggested.

It was at that time that I started the BASIC-Plus project: a complete framework to extend the Commodore BASIC V2 with new commands and, why not, functions.

It took a while to check around what was already available. Thanks to Fungus I came across the Transactor magazines which indeed presented an interesting framework for doing exactly what I needed. However, it showed a few features that I thought I could not live with: non BASIC-style tokens, and redefinition of IF (with the added bonus of ELSE, though).

So that, I started working my way through the BASIC and Kernel ROMs and looking for other software here and there. I eventually came to the solution I knew I would have liked. On the 28th of August I did my biggest CVS commit of the whole framework, which included by default two new BASIC commands: COMMANDS and QUIT.

Everything else is up to the programmer who wants to extend the CBM BASIC, including myself when working at USB-BASIC.

BASIC-Plus Commodore BASIC extension framework by Luigi Di Fraia

BASIC-Plus: my framework to extend CBM BASIC

The USB Kernel written in assembly

At the same time I worked at BASIC-Plus, I wrote most of the USB Kernel sitting on the device driver and on which the new BASIC commands were going to sit themselves. A first proof of concept for USAVE was already available on the 20th of August (USB-64 was still almost entirely on an evaluation kit at that time), therefore not yet integrated in USB-BASIC:
    SYS 49501"BASICRAM.PRG",2049,40960
It took 33 seconds to complete without disabling interrupts or blanking the screen. Well, not too bad for a serial transfer. With interrupts disabled and the screen blanked, I later tried the same benchmark test and ended up with roughly 31 seconds. That's 1.2 kB/s transfer rate. Not too bad, but not too good either if you want to handle big files or stream from/to the USB drive.

I went back one step and designed a parallel interface. Unfortunately, this meant more I/O lines required on the Commodore 64 side; so that I had to borrow three from its Serial Port.

Parallel transfer

When I finally got the missing components I built the test device for parallel transfer. It looks like it is fast enough now:
    SYS 49501"BASICRAM.PRG",2049,40960
This time it took less than 4 seconds to complete: 9.5 kB/s about. That's less than half the time it takes for the Action Replay VI fastload to save the same amount of data to disk.

Is there room for improvement? Yes, there is. The driver and the software that sits on top of it are far from being heavily optimized. This could be pushed a little bit more, if wanted.

USB-64 prototype by Luigi Di Fraia

USB-64 prototype (parallel transfer version)

USB-64 prototype by Luigi Di Fraia

USB-64 connected to a Commodore 64



USB-64 demo program loading from a USB drive

Cartridge DIY

I flashed the cartridge version of the handling software on my blank EEPROM, thanks to Dirk, a colleague from which I borrowed an UV eraser and an EPROM programmer. Other users will be able to flash the new ROM into their preferred cart, e.g. EasyFlash.

USB-64 cartridge for Commodore 64 by Luigi Di Fraia

USB-64 software on a cartridge

USB-64 cartridge menu for Commodore 64 by Luigi Di Fraia

USB-64 selection menu


USB-64 oldskool cartridge (EPROM based!)

USB-BASIC for Commodore 64 by Luigi Di Fraia

USB-BASIC with a few new USB-related commands




USB-BASIC in action

Software

The USB-64 software consists of ALL of the following components:
  • low level drivers
  • USB Kernel
  • BASIC extension (available in direct mode and program mode)
Programmers wanting to support the USB-64 hardware in their software have two options:
  • BASIC programmers should use the BASIC extension: UINIT, USAVE, etc
  • assembly programmers should use the USB Kernel: jsr UINIT, jsr USAVE, etc
Programmers might benefit of the USB-64 capabilities for different reasons. Examples include:
  • save animations to a USB drive from a painting program
  • stream an ASCII movie from a USB drive
  • save huge amounts of samples to a USB drive, coming from a custom data acquisition device
  • store DB data on a USB drive
No device number is assigned to USB-64. My USB Kernel is alone responsible for all access to a single USB-64 device. CBM Kernel routines are simply not used for USB access and therefore do not need to see a new device number to pass control to my USB Kernel.
In this way, I can keep the two Kernels distinct and I don't have to give custom ROMs to users in order to change their CBM Kernel ($E000-$FFFF) into something that understands new device numbers; nor I need to change system vectors to point to code that wraps CBM Kernel routines.

Supported USB Mass Storage Devices

Theoretically USB-64 supports all those devices that implement the standard USB mass-storage device class:
  • external magnetic hard drives
  • external optical drives, including CD and DVD reader and writer drives
  • portable flash memory devices
  • adapters bridging between standard flash memory cards and a USB connection
  • digital cameras
  • various digital audio players & portable media players
  • Card readers
  • PDAs
  • mobile phones
The above list is given for reference purposes only, as found on Wikipedia here.

I personally tried USB-64 with a card reader and with 2 external hard drives without issues.

What next

  • I plan to make a third version that fits into the serial port of the Commodore 64 and draws power from an external PSU rather than from the C64 itself. The reason is that the user port connectors are becoming very rare and expensive. (Update: I was told that these connectors are not so rare; in fact, they are still manufactured, e.g. in Germany, and sold at a reasonable price - 2 euros about)
    Of course, it will only allow serial transfer at 1.2 kB/s.

  • Because of the transfer rate achievable with the parallel version and because of the amount of RAM available for buffering, I wrote the proof of concept for a tape dumping software (in assembly) for the Commodore 64, a la DC2N.
    DC2N Commodore 64 version by Luigi Di Fraia

    Update: my tests suggest that the C64 is not fast enough to store 16-bit values in RAM and move the content around (to USB or to other RAM locations, i.e. to anywhere else) as soon as enough data has been received.
    I might explore the feasibility of making 8-bit dumps, but that's not something that excites me too much.
    The good aspect of this development is that I wrote a few rusable assembly modules that I might leverage for future projects.

  • I am also writing a tool (mixed BASIC and Assembly) that uses the serial version of the device to make D64 images (free time allowing).

    D64 Creator by Luigi Di Fraia


  • The API will be documented in order to let developers take advantage of USB-64 in their own software.


Contact

Comments? Feedback? If you are interested in a USB-64 device, let me know: if enough people are interested I might consider producing a batch. The total cost could be around 25 GBP - 30 euros, for an average batch of the parallel version (that does NOT include the cartridge: you would only get the .CRT file to use with your existing cartridge).

Just e-mail me.

Back to my C64 Section.


Comers since area creation: Since April 2002 - Best viewed at 1024x768



All images, files, and text on this page are Copyright ©2010 Luigi Di Fraia. All Rights Reserved.
Use of the material provided by means of this page is prohibited without the explicit permission of the owner.