Commodore Disk Drives

Introduction

Over the years Commodore released many disk drives for their various computers, some of which will be covered on this page.

Commodore 1541

Overview

The Commodore 1541, branded as VIC 1541 on early models, sometimes called CBM 1541, is a 5.25" ‘mini’ floppy disk drive that was released in 1982, featuring an integrated power supply (voltage dependent on the region), and connects to a C64 via the serial port but is also compatible with the VIC-20 since the 1541 supports 1540 mode. The drive was a worthwhile investment as the alternative at the time was using cassettes with the datasette, which were a lot slower, less reliable, and less versatile. As well as slight variations on the original model (the first lot had a handle mechanism and the later used a lever), there were also two main revisions of the 1541, starting with the more reliable and quieter 1541C in 1986 (along with the C64C) and the even more dependable 1541-II in 1988, which used an external power supply, allowing it to run cooler and take up less space. The 1541 was discontinued in 1993.

Disks in the 1541 run at 300 rpm, and the 'brains' of the drive is a 6502 CPU running at 1MHz (very similar to the C64), and the drive also contains 2KB of work RAM, and 16KB ROM which holds the firmware (CBM DOS), and as it handles I/O via two 6522 ICs, the 1541 can be thought of as containing an embedded computer. This gives the disk drive a big benefit over disk drives for other microcomputers in that it can work independently of the C64, for e.g., if you format a disk you can still use the C64 while the disk drive continues to do its job. Another advantage of the 1541's design is the simplicity of being able to connect the drive (and other peripherals daisy chained) to the C64's serial port as opposed to other microcomputers which required a disk drive controller to be added to the computer.

The standard for disks formatted in a 1541 is 35 tracks, 17 to 21 sectors per track, 256 bytes per block, 683 blocks total (644 free blocks due to the directory requiring the rest), 144 entries (programs/data files) in the directory, 174KB total storage, and potential transfer speeds between a 1541 and C64 between 300B/sec to 400B/sec.

As well as being very heavy - the original 1541 model weighs 5KG (part of the weight is the mains transformer), the 1541 is very large, with the first model measuring (HWD) 97 x 200 x 374 mm, similar in size to a C64. The 1541 was originally packaged with the disk drive, power cable, serial bus cable (6-pin DIN), manual, and demonstration disk titled ‘model 1541 test/demo-diskette’. 

At the front of the 1541 is the power LED (green), disk drive LED (red) and disk entry point which features (depending on the model) either a drive latch that is pushed down/up or a lever that is turned down/up to lock or release a disk. The drive light is lit whenever the disk is accessed (read/write) but flashes if an error occurs, and the power LED will flash if there is an electronic error. At the back of the original model is a 3-pin mains IEC power in connector, power switch, fuse holder, and two 6-pin DIN serial ports, one to connect to a C64, the other for another disk drive. On the 1541-II there are additionally two DIP switches for setting the device number (8 to 11), and the power connector is 4-pin for use with the external PSU.

When connecting the drive to a C64/VIC-20, plug one end of the serial cable into the computer’s serial port and the other into either of the two serial ports at the rear of the drive; up to five disk drives and one printer can be daisy chained. If you do not have a suitable serial cable you can find construction details at:

https://sta.c64.org/cbmserc.html

After connecting up, power on all drive(s)/printer first (it’s advised not to have a disk inserted into a drive when powered on) and you should see both the power LED and drive LED come to life, with the drive light going off after a few seconds. Then you can power on the C64, which should cause the disk drive LED to light briefly.

If you aren't familiar with using a 1541 then it's a good idea to read the user guide, linked below, but I will briefly go over using the drive:

http://www.zimmers.net/anonftp/pub/cbm/manuals/drives/1541_Users_Guide.pdf

Note that on page four of the user guide it shows both types of the original model 1541.

To save a program to disk we use a similar format to saving to tape with the addition of specifying the device number:

SAVE "FILE",8

Where 'FILE' is the name of the file (16 characters maximum) and '8' is the disk drive device number.

No surprise then to load a file from disk use:

LOAD "FILE",8

You can check a previously saved file on disk matches what is in the computer's memory using:

VERIFY "FILE",8

SCRATCH is used to delete a file using this format:

OPEN 1,8,15,"S:FILE"

CLOSE 1

Where 'FILE' is the name of the file to be deleted.

When we get on to formatting a disk I will go into more detail about the use of the OPEN command.

To check what files are on a disk there is no directory command, instead a variation of the LOAD command is used:

LOAD "$",8

Which will overwrite any BASIC program stored in memory with the disk directory, which is viewed using the LIST command. This directory listing consists of the drive number (always 0 on the 1541 since it's a single disk drive), disk name and ID, disk format (2A = formatted in a 1541), and then each file (if any) is listed; file block length, file name, and file type (PRG = BASIC/machine code/SEQ = sequential data/REL = relative data).

Something that can confuse newcomers to the 1541 is that trying to save a file with the same name as one already on the disk doesn't overwrite it as you would expect (on modern computers you would at least get a prompt asking whether you actually wanted to overwrite the existing file). As far as the 1541 is concerned, you are trying to store a second file on the disk with the same name as an existing file, which results in an error (the drive light will constantly flash).

To actually overwrite an existing file either delete and save it again or put '@0' before the file name, such as:

SAVE “@0:FILE”,8

Another disk operation you may want to do is to format a disk, which prepares it for use and wipes out any exisitng data, so make sure you have backups of any data you want to keep. Formatting a disk, however, isn't as simple as loading or saving a file, requiring a string of characters as follows to send the NEW (shorhand 'N' has been used) command to the 1541:

OPEN 1,8,15,"N:NAME,ID"

CLOSE 1

Replace 'NAME' with the required disk name (16 characters maximum) and 'ID' with a 2-digit number, which should be unique to each disk.

The formatting operation takes about 90 seconds but you can still use your C64 while the formatting takes place and then you can save and load files. To go into more detail about the format instruction, the OPEN command is used to open a channel to a disk drive, with the '1' representing the logical file number (handle), '8' is the device number, '15' is the secondary number (command channel), and 'N:NAME,ID' is the command to send to the disk drive. 'CLOSE 1' then closes the channel.

It is sometimes useful to get information about a disk drive error but unfortunately, on the C64 it requires that we run a program:

10 OPEN15,8,15:INPUT#15,E,E$,T,S:PRINT E;E$;T;S:CLOSE15

No disk error will result in: 0 OK 0  0

The format of the message is: error number, error message, track error, sector error. A value of 0 means no error.

If there was a disk error the error status will be cleared when the error is read or when another disk operation successfully finishes.

As a simple test to see an error, try to open a file that doesn't exist like this:

LOAD "NOTHING",8

Make sure you don't actually have a file on disk called NOTHING. You will get a ?FILE NOT FOUND ERROR IN 10. By running line 10 as above you will get basically the same error:

62 FILE NOT FOUND 0   0

While not any more helpful, for other types of errors you will get more information. For example, try to save the BASIC program we already have but use the same name as a file already on disk, which we know from earlier will cause an error. The 1541 will react as if saving the program but the drive LED will flash rapidly as if there was an error but BASIC will not inform you as such. But if you run our program you will get:

63 FILE EXISTS 0  0

Which actually tells us the error. You will also notice that the drive LED will stop flashing.

A sort of Easter egg, we can actually get the 1541 ROM type from the error channel. To do so, turn the 1541 off and make sure the disk drive door is open if there's a disk inside (just to avoid accidental writes), power on the disk drive and after the drive LED goes out, RUN the program. You should get something like this:

73 CBM DOS V2.6 1541 0  0

Note that error 73 is technically the DOS mismatch error.

When using multiple drives daisy chained, each drive needs to be referred to by a different device number, with '8' being the default set at the factory. Unfortunately, on the original model changing the device number involves either cutting traces or bending a pin on one of the 6522 ICs, which is described in the service manual.

There are modern alternatives to the 1541, providing for cheaper and more reliable alternatives:

SD2IEC - see the SD2IEC section further down this page.

Raspberry Pi powered 1541 disk drive emulator:

https://cbm-pi1541.firebaseapp.com/

UNO2IEC Arduino based 1541 emulator providing access to files on a host PC:

https://github.com/Larswad/uno2iec

D64 is a disk image format representing 1541 formatted disks and is used for preservation, floppy drive emulators and C64 emulators. D64, however, doesn't work with copy protected disks, you must use an alternative disk image type, such as G64, which contains raw disk data (including errors, if any), allowing for support of copy protected disks, and recovery of disks with errors to (possibly) be fixed.

Greaseweazle is an open source floppy disk controller that allows the use of 'PC' disk drives for reading and writing of C64 disks using a modern computer, capturing data at low level. Please see my Greaseweazle page for more details.

Resources

Commodore 1541 Disk Drive User's Guide:

https://archive.org/details/Commodore_1541_Disk_Drive_Users_Guide_1982-09_Commodore/mode/2up

Inside Commodore DOS:

https://archive.org/details/Inside_Commodore_Dos

The anatomy of the 1541 disk drive : a complete guide to using the Commodore disk drive:

https://archive.org/details/The_Anatomy_of_the_1541_Disk_Drive

Technical

You can find schematics for the various 1541 versions at:

http://www.zimmers.net/anonftp/pub/cbm/schematics/drives/new/1541/index.html

The service manual for the 1540 and 1541 can be found at:

https://www.classic-computing.org/wp-content/uploads/2016/01/15401541_SERVICE-MANUAL.pdf

The Ultimate Commodore 1541 Drive Talk — Michael Steil (Vintage Computer Federation):

Commodore 1540 & 1541 ROMs:

http://www.zimmers.net/anonftp/pub/cbm/firmware/drives/new/1541/

CBM DOS ROM disassembly and memory variables for Commodore 1541 drive:

https://g3sl.github.io/c1541rom.html

Note: easy to follow format.

Commodore 1541 DOS ROM Disassembly:

http://svn.nomike.com/playground/trunk/emu/C64/doc/1541.html

Commodore 1541 drive memory map:

https://sta.c64.org/cbm1541mem.html

Explanation of why the 1541 is slower than it should have been:

https://www.lemon64.com/forum/viewtopic.php?t=52439

Even though it should be possible to daisy chain five 1541 drives there may be difficulty with an older model C64, for more information see:

https://www.lemon64.com/forum/viewtopic.php?t=65446&sid=8772ea32203a36320225adc91dc11a89

Troubleshooting

If you acquire a 1541 in modern times then, unless otherwise assured, there is the possibility of faults, such as PSU failure (e.g., one or more voltages absent), bad capacitors, defective drive mechanism (e.g. unaligned head). Of course, you should only service the drive yourself if you have experience as, especially with the drives featuring a built-in PSU, there are dangerous voltages involved.

Please see the Technical section on this page for links to schematics and service manual.

Some basic checks you can do on a faulty 1541:

Check for blown fuse - replace if no definite reason found for the fuse breaking.

Check for shorts between 5V and GND, and 12V and GND, and then check further to see what is causing the short(s):

See if either of the bridge rectifiers have failed using diode test on a multimeter, replace if failed.

Check for and replace bad capacitors.

Test and replace the voltage regulators if failed.

If the power supply has failed in the original drive model you can replace it with a modern solution, which is covered in this article:

https://hackaday.io/project/25768-commodore-1541-psu-replacement

Using a modern PSU should ensure the drive runs cooler, gives off less heat, lower the weight of the drive, and (depending on the PSU) accommodate a wide range of mains input voltages. If the internal power supply isn't dead but requires a different mains input voltage (i.e. the drive has been imported) then only the transformer needs changing. A 1541 should never be run on a higher mains voltage (e.g. 230V on a US drive) as it can destroy the drive, at the very minimum the fuse will blow but likely the power supply circuit will be taken out. Other than the difference in mains voltage that the 1541 requires, there is no compatibility issue with (for e.g.) using a US drive on a PAL C64.

The 1541 will do a number of basic checks upon power up and if a problem is detected it will indicate the possible failure by flashing the drive LED a number of times, pausing, and flashing again. The flash codes are:

Flash count Failure

2 Zero Page

3,4 DOS ROMs

5,6,7,8 RAM

This at least gives a rough indication for troubleshooting the 1541 further.

Uploading code

The 1541 was designed to allow custom code to be uploaded to it from a C64 (or any other device compatible with the serial port) or disk, which has an effect for as long as the drive is powered on (if you want to permanently alter the way the 1541 behaves then you need to make a replacement ROM). Uploading custom code to a 1541 opens up many possibilities including faster disk access due to better programming, saving data to disk in different formats (which can  also speed up disk access), adding copy protection, and storing more data on disks. There is a downside to the ability to unload code to a 1541, although it probably wasn't common back in the day, a virus of sorts could be written that take control of the 1541, wiping or corrupting data on a disk, or even instructing the drive to behave in a manner that could damage it.

The aim of this section is to serve as an introduction to using some advanced features of a 1541 including running custom code on the drive, but before we can get into the examples it's important to understand the 1541's direct-access commands, the full list is as follows:

Block-Read (Ul) read a data block into 1541 RAM.

Buffer-Pointer (B-P) set pointer to any byte in a disk buffer.

Block-Write (U2) write a data block from 1541 RAM to diskette.

Memory-Read (M-R) peek bytes out of 1541 RAM or ROM.

Memory-Write (M-W) poke bytes into 1541 RAM.

Block-Allocate (B-A) set bit in BAM to indicate a sector is in use.

Block-Free (B-F) set bit in BAM to indicate a sector is not in use.

Memory-Execute (M-E) execute a 6502 routine stored in 1541 RAM or ROM.

Block-Execute (B-E) load and execute a 6502 routine in 1541 RAM.

Please see Inside Commodore DOS, found in the Resources section, to learn more about the direct-access command, but for now don't worry too much about understanding what these do yet, the following examples make use of a few of them as to illustrate their purpose.

The first example program doesn't run code on the 1541 but does read from its memory by retrieving a number of bytes from the 1541 and displaying them, which utilises the 1541's Memory-Read direct-aceess command. This program was adapted from an example given in the Commodore 1541 Disk Drive User's Guide page 45 (see Resources section).

10 OPEN15,8,15

20 A=58811:C=8

30 A1=INT(A/256):A2=A-A1*256

40 PRINT#15,"M-R"CHR$(A2)CHR$(A1)CHR$(C)

50 INPUT#15,A$:PRINT A$

60 FOR I=1 TO C

70 PRINT ASC(MID$(A$,I,1));

80 NEXT

90 CLOSE 15

Line 10 opens up the disk drive for access.

Line 20 sets A to the start address of the data in the ROM to read from and C to the number of bytes to read (255 maximum).

Line 30 calculates the high byte of A and puts it into A1, and the low byte which is put in A2.

Line 40 executes the Memory-Read command, specifying the address low byte, high byte, and number of bytes to read (optional value, defaults to 1 if not specified).

Line 50 gets the complete string from the error channel and prints it out (although it's called the 'error channel', it can be used for more than just getting error information).

Line 60 to 80 loops through each character of A$ and displays in decimal the character value.

Line 90 closes the disk drive channel.

Running the program on an original 1541 you should get:

DOS V2.6

68 79 83 32 86 50 46 54

Note that this program is particularly designed for displaying strings, if it reads other types of data it may result in an error when the program is run; for handling generic data values you could use GET# instead of INPUT# and read a byte at a time.

Now we are going to upload a simple program to the 1541 which will cause the drive LED to light for a short while, a sort of 'Hello world' example:

10 OPEN 15,8,15

20 A=768:C=34

30 A1=INT(A/256):A2=A-A1*256

35 FOR I=1 TO C:READ D:D$=D$+CHR$(D):NEXT

40 PRINT#15,"M-W"CHR$(A2)CHR$(A1)CHR$(C)D$

50 PRINT#15,"M-E"CHR$(A2)CHR$(A1)

60 CLOSE 15

100 DATA 32,24,193,169,80,141,48,3,169,0,141,11,24,141,8,24,169,255

110 DATA 141,9,24,169,32,44,13,24,240,251,206,48,3,208,231,96

Line 20 sets A to the start address, a RAM location in the 1541 (data buffer #0, which is used during disk operations), and C to the number of bytes to write to memory.

Line 35 sets up a loop to read each value from the DATA statements into D and convert into an ever growing string D$.

Line 40 is where we write to the 1541's RAM using the Memory-Write command, which requires the address low byte, high byte, number of bytes to write, and the bytes to be written (which are stored in D$.

Line 50 makes use of the Memory-Execute command to run the code we uploaded to the 1541. It needs the address low byte and high byte of where we stored our code.

Line 100 and 110 contain the values to write to the 1541's memory, which consists of machine code values.

After running the program you should see the drive's LED light immediately and then go out after about 5 seconds, at which point the C64 will give back control.

Here’s the assembly listing version of the machine code held in the DATA statements, consisting of address/label, opcode/operand(s), instruction, comment:

768 32 24 193 JSR 49432 ;Turn drive LED on

771 169 80 LDA #80

773 141 48 3 STA 816 ;Counter    

776 LOOP1 169 0 LDA #0

778 141 11 24 STA 6155 ;ACR

781 141 8 24 STA 6152 ;T2C-L

784 169 255 LDA #255

786 141 9 24 STA 6153 ;T2C-H

789 169 32 LDA #32

791 LOOP2 44 13 24 BIT 6157 ;Time up?

794 240 251 BEQ LOOP2

796 206 48 3 DEC 816

799 208 231 BNE LOOP1 ;Count complete?

807  96 RTS


On the first line we call a 1541 ROM routine at 49432 to turn the drive LED on; if we were to exit with an RTS after, the drive LED would quickly go out as DOS kicks back in and takes control of the drive light, so we have to set up a delay, which we will now go into detail. After turning on the LED we set our counter start value 80 and store it in the 1541’s RAM at address 816, not far from the end of the program. You can set this variable to any value from 0 (LED stays on the longest time) to 1 (LED goes off quickly).

At the start of LOOP1 we set up timer 2 of one of the 6522 ICs in the 1541, a timer that isn’t normally used by the drive (the base address of the 6522 which are using is at 6144). The code sets the 6522’s ACR and T2C-L registers to 0 and the T2C-H register to value 255, which starts the timer, counting down from 65280. Please read up on the 6522 if you wish to understand better how it works.

We then continually check to see if the timer has reached its minimum value (the wait is up) by bit testing value 32 against the 6522’s IFR register, if the time isn’t up then we go back to LOOP2 and bit test again. When the time is up we decrement the counter at 816 and do a test to see if the decrement resulted in zero, if not then we go to LOOP1 and set up the timer again. Note that we shouldn’t need to set the ACR again but it’s handy to have it set to zero along with T2C-L, saving a few bytes.

When the value at 816 does become zero, meaning the complete delay is up, the program falls through to the RTS and the 1541 carries on running DOS and the drive LED goes out. This is the reason that setting 816 to zero initially creates the longest delay (about 17 seconds) since we do a decrement on 816 before testing for zero, thus it will become 255 before we do the check, creating a delay slightly longer than starting on 255 (about 16 seconds).

The example program is very simple as an introduction to uploading code to a 1541 and running it, but it isn’t ideal since it locks up the drive to prevent DOS from immediately turning the drive LED off but of course there may have been a better approach. The Memory-Write command can only send a maximum of 34 bytes at a time - exactly what we've used - but the program could have been shortened slightly by making use of a free zero page RAM location in the 1541 to store the counter variable.

The BASIC program will get stuck on the CLOSE command until the 1541 becomes responsive again; if CLOSE isn’t included in the program then the program will end immediately while the drive LED continues to light. In this situation you can still issue a disk command in direct mode (such as to get the directory) but the drive won't respond until our uploaded program finishes.

If you are interested in writing your own custom code to run on a 1541, I hope my example program has at least given you an idea of how to go about the task but I would advise that you take advantage of a C64 emulator, such as VICE, which lets you test and examine its virtual 1541 at low level, which helped me greatly in getting the test program working, which I then checked on a real 1541.

Please see the section I did on C64 emulation to get a better understanding of the advantages of emulators.

Commodore 3040

Overview

The Commodore 3040 is a 5.25" dual drive disk system for the European market (model 2040 is the US equivalent so most information on the 3040 will also apply to the 2040) originally designed for use with Commodore PET computers (but can be used with a C64/C128 using an adapter). The drives are single density, single sided (similar to the Commodore 1540 and 1541), utilising the Shugart 390 type drive, and the 3040 connects to the computer via IEEE-488. The 3040 was originally sold with user manual and test/demo disk.

On the front of the disk drive system is a 3040 badge and the two disk drives (which have indicator lights to show disk access) are located toward the bottom, with drive 1 on the left, and drive 0 on the right. Between the two drives is a power/error indicator light. At the rear is the IEEE-488 female edge connector top left, and there is a label bottom middle which indicates the model type (Commodore DUAL FLOPPY), power rating (EU model: 240V .6A 50Hz), serial number and place of manufacturer (USA). The wired-in power cable is to the right of the label, a warning label to the far right, fuse holder to the right of the power lead, and power switch at the far right.

The specification for the disk format is as follows:

Total capacity: 176640

Directory entries: 152 per disk

Sectors per track: 17 to 21

Bytes per sector: 256

Tracks: 35

Blocks: 690

Supports soft sectored format disks.

All content of this and related pages is copyright (c) James S. 2022-2023