C= commodore 64


1541 tricks

The Utility Loader '&' command.

This information was originally posted by Peter Weighill (stuce@csv.warwick.ac.uk, address no more valid) to the Usenet newsgroup comp.sys.cbm. It was corrected in a follow-up posted by Nicholas Cull (Nicholas.Cull@comp.vuw.ac.nz). The information was edited together by Marko Mäkelä.

Introduction

A little known and little used command on the 1541 disk drive is the "&" command. This is probably due to the fact that there is no mention of it in the "1541 DISK DRIVE users guide". Many other books about the disk drive also fail to mention it. As to a use for the command, I have not found one yet. Perhaps someone could think of one. [Marko's note: There is a utility that enables the use of subdirectories on 1541 drives.] I would expect that the 1570/1571 and 1581 drive will also contain the "&" command as well, since they are based on the 1541.

Utility loader ("&" command)

The utility loader is the command which will load a USR file from disk into disk drive memory where it will then execute. The format for the command is as follows: OPEN15,8,15:PRINT#15,"&filename":CLOSE15.

USR files

A "&" file has to follow certain guidelines. It is limited to just one sector and this sector is constructed as below:
Byte   Description
----   -----------
0      Next file block's track
1      Next file block's sector
2      Start address low  order
3      Start address high order
4      Number of bytes in this program part (0 means 256)
5..    Program code bytes
..X    last program code byte
X+1    Checksum of the program bytes
X+2    Start address low  order
X+3    Start address high order
...
This means that "&" file may consist of multiple parts, each limited to 256 bytes. A program part's checksum byte is calculated by adding all the values of the bytes, starting at the low order start address (byte 0), while adding you subtract 255 from the total every time it exceeds 255. In machine language, you can do it even easier: ; the accumulator holds the current data byte clc adc checksum adc #0 sta checksum One final constraint is that the filename must begin with an "&". Below is a program which will make it easier for you to create a USR file in the required format, so that it can be executed by the utility loader command. The program automatically calculates the length of the code and also the checksum at the end. All you need to do is add your own code to the data statements between 200 and 350 and specify a filename in line 10.

10 OPEN2,8,2,"0:&filename,U,W" 20 READNB 30 READLO,HI,LN:C=LO+HI:C=C+(C>255)*255 40 C=C+(LNAND255):C=C+(C>255)*255 50 PRINT#2,CHR$(LO);CHR$(HI);CHR$(LNAND255); 60 READD:PRINT#2,CHR$(D); 70 C=C+D:C=C+(C>255)*255 80 LN=LN-1:IFLN>0THEN60 90 PRINT#2,CHR$(C); 100 NB=NB-1:IFNB>0THEN30 110 CLOSE2 120 END 190 : 200 DATA2 :REM number of data blocks 210 DATA128,3 :REM lo/hi start address of first block 220 DATA6 :REM length of first block 230 : REM program code 240 DATA32,71,198,76,0,3 300 DATA0,3 :REM lo/hi start address of second block 310 DATA26 :REM length of second block 320 : REM rest of program code 330 DATA173,0,28,41,16,201,16,208,11 340 DATA169,247,45,0,28,141,0,28,76 350 DATA0,3,32,24,193,76,0,3 The example code in the program is not that useful, it is just there to show how the utility loader works. It just switches the drives light on and off depending on if the write protect sensor is covered or not.

Errors that can occur

39, FILE NOT FOUND
This occurs if the file you specified using the utility loader command does not exist or is not a USR file.
50, RECORD NOT PRESENT
The checksum calculated by the disk drive and the checksum at the end of the file differ.
51, OVERFLOW IN RECORD
The end of the file was encountered unexpectedly. May indicate an incorrect length byte, or additional data written after the end of the last data block.
[Nicholas Cull's note:] One caution should be added at this point. Although data may be transferred to any address in the RAM of the drive, it should be remembered that part of the memory will be allocated to buffering the file as it comes off the disk. Thus it may be possible to overwrite incoming data being buffered in memory before it can be transferred correctly to its new location. Experimentation may be the best way of determining which areas are "safe" and which ones have problems. I found that the file seemed to be buffered in locations $0600 to $0700, but this would depend on how may files you had open, etc.

Checking that a file is on the disk

Introduction

If you wrote a program which needed to check that a particular file existed on a disk then you would probably open the file for a read, then check the error channel for 62, FILE NOT FOUND: 10 OPEN15,8,15 20 OPEN2,8,2,"filename,P,R" 30 INPUT#15,E,E$ 40 IFE>0THENPRINTE$:GOTO60 50 PRINT"FILE EXISTS" 60 CLOSE2:CLOSE15 Another way to check if a file exists is to try to rename it as itself: 10 OPEN15,8,15,"R:filename=filename" 20 INPUT#15,E,E$ 30 CLOSE15 40 PRINTE$ If the file exists then the error created is 63, FILE EXISTS, otherwise it is 62, FILE NOT FOUND. Judge for yourself which works better.

Reverse head knock on the floppy drive

Posted in the newsgroup comp.sys.cbm by Michael Parson (mparson@mercury.utb.edu):

The following was taken from RUN magazine, Sept 1988 Issue, Magic Trick $4CC, page 12.

If your 1541 or 1581 disk drive hasn't been behaving well lately, it may be out of alignment. You could take it to a repair shop, but before you shell out $0 or $50, try "knocking" some sense into it with my Reverse Knocker program.

This 64- and 128-mode program reverse-knocks the drive head 100 times, which may re-align the drive just enough to postpone and expensive realignment. Be forewwarned: have an old work disk in the drive when you run it, and don't worry if running this program makes your disk drive sound like a smoldering Buddy Rich drum solo. It is a noisy program, but if you type it in correctly, it won't hurt the drive or disk at all.

0 REM REVERSE KNOCK YOUR DRIVE - STEPHEN CHEUNG
10 OPEN 15,8,15,"I"
20 SP=1:FORI=1 TO 100:GOSUB40:NEXT
30 FORI=1 TO 20:SP=-1:GOSUB40:NEXT:PRINT"ALL DONE!":PRINT#15,"I":CLOSE15:END
40 PRINT#15,"M-R"CHR$(0)CHR$(28):GET#15,A$:A=ASC(A$+CHR$(0)):BI=A AND 3
50 BI=BI+SP:BI=BI AND 3
60 R=(A AND 252) OR BI: PRINT#15,"M-W"CHR$(0)CHR$(28)CHR$(1)CHR$(R):RETURN

Marko Mäkelä (Marko.Makela@HUT.FI)