!pr0
!lm12
!rm75
Catalog Arranger ...................................Bill Morgan

We all have the problem:  a disk starts getting full, we delete some files to make space, and our new files (from our latest project) end up scattered all through the catalog.  A disk that has been used for a few months ends up with a thoroughly shuffled catalog.

There are programs available to alphabetize a catalog, but that's not always what I want to do.  I want HELLO at the beginning, utilities next (assembler, text editor, ES-CAPE, disk zap, etc.), then various projects.  The files for each project should all be grouped together, with the current job at the end of the catalog.

I decided that what I want to be able to do is to "pick up" one entry in the catalog, move it to exactly where I want it, put it down, then go get another one and put that one in its place, and so on.  Here's my program to do just that.


Using Catalog Arranger

First BLOAD CATALOG ARRANGER, then insert the disk you want to modify.  When you type CALL 2051 (or 803G from the monitor) the disk will spin for a little while as the catalog is read into a sort of string array.  The first 22 entries in the catalog will then be displayed, with the first entry shown in inverse.  You may notice that deleted files are also displayed, with a minus sign before the file type and a stray inverse character out at the end of the file name.  Control characters are also displayed in inverse.

The inverted entry is a cursor showing the "active entry".  If you press the arrow keys, this cursor will move up and down the display.  When the cursor reaches the center of the screen, it will stop moving and the display will scroll up and down around it.

When you have the cursor on an item you wish to move, press RETURN.  The word "MOVING" will appear in inverse in the lower left corner of the screen.  When this "moving flag" is on, the entry in the cursor will be carried wherever the cursor goes.  When it reaches the place where you want to put it, press RETURN again.  The moving flag will disappear and that entry will stay where you just put it.

There are a couple of other commands as well.  Pressing the "B" key moves the cursor to the beginning of the catalog, and the "E" key moves it to the end.  If the moving flag is on, the item in the cursor will be carried right along.  There is also an "R" command, to read in a new catalog.  This is useful if you want to reread the current catalog and start all over again, or to move on to another disk.

When you have the catalog arranged just the way you want it, press the "W" key to write the revised catalog onto the disk.  Press ESC when you want to exit the program.
Catalog Organization

If you are familiar with the internal structure of an Apple DOS catalog, you can skip ahead to the section labelled "How Catalog Arranger Works".

The first step in reading a disk catalog is to read the VTOC (Volume Table of Contents), which is always located at track $11, sector 0.  The second and third bytes in the VTOC (offsets 1 and 2) contain the track and sector of the start of the catalog.  On a standard DOS 3.3 disk these always point to track $11, sector $0F, and the rest of the catalog is always on track $11.  These locations can be changed, however.  For example, some programs to convert DOS 3.2 disks to DOS 3.3 leave the first catalog sector at track $11, sector $0C.  Therefore, it is safest to follow the pointers rather than assuming that the catalog will always be in its usual place.

In a catalog sector, the first byte is not used.  The second and third bytes point to the next track and sector of the catalog.  If the track byte is zero, it means that there is no next sector, this is the end of the catalog.  The fourth through the eleventh bytes are not used.  The actual catalog information starts at the twelfth byte of the sector (offset $B) and fills the rest of the sector.  Each catalog entry takes 35 bytes, so there are 7 entries in each sector.

The first two bytes of an entry contain the track and sector of the file's track/sector list.  If the first byte is $FF, the file has been deleted.  In that case, the track number has been moved to the end of the file name.  If the first byte is zero, this entry has never been used, and we are past the end of the catalog.

The third byte tells the file type and whether the file is locked.  Here are the type codes:

!lm+5
00 -- TEXT file
01 -- INTEGER BASIC program
02 -- APPLESOFT BASIC program
04 -- BINARY file
08 -- S file -- not used
10 -- R file -- DOS Toolkit relocatable object file
20 -- A file -- Lazer Pascal source file
40 -- B file -- Lisa assembler source file
!lm-5

If the file is locked, $80 is added to the type code.

The next 30 bytes are the file name.  If the name is less than 30 characters long, it is filled out with spaces (ASCII $A0).

The last two bytes are the length of the file, in sectors.  This is expressed as first low byte, then high byte.
!np
Here's a diagram:

    0       1       2     3 . . . . 32      33         34
 --------------------------------- --------------------------
| Track | Sector | Type | Name . . . . | Len - Lo | Len - Hi |
 --------------------------------- --------------------------

You can find more information on the structure of the catalog in the DOS Manual on pages 129-134 or in the book Beneath Apple DOS on pages 4-4 through 4-7.  It is impossible to recommend Beneath Apple DOS too highly; if you have any interest in the internals of DOS, get that book.


How Catalog Arranger Works

After initialization, the program builds a table of pointers into the storage area.  We can build this table in advance because we know that all entries will be the same length.  The catalog is then read into the array, each entry being placed according to the next pointer in the table.  The end of the table is then marked with two zero bytes after the last element used.

The next step is to display the entries in the array.  The display routine starts by checking ACTIVE.ELEMENT to see whether to start the display with the first element, or somewhere in the middle.  It then scans up the table, displaying each catalog entry and inverting the one corresponding to ACTIVE.ELEMENT.  The routine that actually displays each line borrows a couple of subroutines in DOS to decode the file type and display the file size.

When MOVING.FLAG is off, the arrow, B, and E commands simply change the value of ACTIVE.ELEMENT.  When MOVING.FLAG is on, the arrows swap entries in the table up or down, and B and E repeatedly swap entries to move ACTIVE.ELEMENT to the beginning or end.

When writing the catalog back onto the disk we have to be careful to put the catalog sectors back in the same place they came from, since we can't assume that the catalog came from track $11.  We do this by reading the first catalog sector into the buffer, scanning up the pointer table and moving the indicated entries into the catalog buffer, and then writing the buffer to the same disk sector it came from.  We then get the track and sector pointers (which haven't been changed) from the buffer and use them to read the next sector.  This whole process ends when we run out of entries in the pointer table.
!np
Limitations and Additional Features

There are a few points that need more work:

!lm+5
Disk error handling.  The program just prints "I/O ERROR" and stops.  It needs a real error handler.

This program will handle catalogs with up to 127 entries.  A standard disk has no more than 105, but some catalogs are modified to have more.
!lm-5

I plan to add several more commands to Catalog Arranger:

!lm+5
Alphabetic sort.  This would be useful too, maybe just from the cursor to the end of the catalog.  That would keep the utilities in place at the beginning.

Sort by file type.

Delete and undelete files.

Move deleted files to the end.

Rename files by editing the file name in the cursor.  That would be a lot easier than typing entire file names twice, as RENAME requires.

Display and allow changing the values of SLOT and DRIVE.

Display the value of ACTIVE.ELEMENT and NUMBER.OF.ENTRIES, and maybe free sectors on the bottom line.

Write the catalog out to the disk as a text file.
!lm-5

Adding many of these features would also require reworking the command structure (which wouldn't hurt anyway!)



Here is a summary of the commands:

!lm+10
!pp-10
     B -- Move the cursor to the beginning of the catalog.
     E -- Move the cursor to the end of the catalog.
     R -- Read the catalog from the disk.
     W -- Write the catalog to the disk.
   --> -- Move the cursor down one item.
   <-- -- Move the cursor up one item.
RETURN -- Toggle the moving flag on or off.
   ESC -- Exit the program.
!lm-10
!pp0
