# 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+(Cgt;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

## A nasty "virus" for the 1541

This information was originally posted in the newsgroup comp.sys.cbm by Andreas Boose (boose@linux.rz.fh-hannover.de):

`OPEN1,8,15,"M-W"+CHR$(12)+CHR$(28)+CHR$(1)+CHR$(206)` will do the trick.

The r/w head is now in write mode until reset. Trying to read/write something via LOAD/SAVE (directory, other files) makes things even worse: The drives starts spinning (= present track deleted), tries to read the dir track (= track 18 deleted) and finally bumps the r/w head to position 0 (= tracks 1-17 corrupted). If the clueless user inserts another disk without resetting the drive, it will get the same "treatment"...

To get rid of those surprises and for debugging proposes I installed a "write LED" on my 1541:

## Write LED for the 1541

by Andreas Boose

Connect a (red) LED parallel to R51 (91 ohm). You also need a 50..100 ohm resistor in serial to the LED to reduce the current. The LED will light a bit brighter than the active LED, but that's necessary to see even the shortest write access.

With a bit of experience you can identify whether the drive writes via its own routines, via a fast-save (you can even figure out the interleave) and whether it is formatting (looks impressive).

            A|\ |K    +--------+        Note the orientation of the
         +---| >|-----+50..100 +---+    LED's cathode!
         |   |/ |     +--------+   |
         |                         |
         |                         |
         |        +--------+       |     +-----...
     ----+--------+  R51   +-------+-----+  R52...
                  +--------+             +-----...