!pr1
Making Dos-less Disks......................Bob Sander-Cederlof

Last night I re-invented the wheel, and I think I made a pretty good one.  I learned a little at the same time.

When you use the DOS "INIT" command, a copy of DOS is written on tracks 0 through 2.  If the disk is meant to be a data disk, that wastes three perfectly good tracks.  Because of the way DOS checks for the end of track-sector lists and various other things, a standard DOS cannot allow files to be written into track 0.  But it is perfectly all right to leave the DOS image off of tracks 1 and 2 and use them for files.  Of course it is a good idea to change the image on track 0 so that it will not begin to boot DOS and get lost (when you forget it is DOS-less and try to boot it anyway).

There are some more wasted sectors in track 17, the catalog track.  INIT sets up 15 sectors for the catalog, which is enough for 105 files.  I have never needed that many, but some of you might have even needed more.  Last night I needed only about 30 files, and I needed every sector I could get to store them all.  My "wheel" sets up only seven catalog sectors, enough for only 49 files.  This frees up eight more sectors for data.

With the help of "Beneath Apple DOS" I examined the code in the DOS File Manager which handles the INIT command ($AE8E-AF07).  This routine calls RWTS to initialize 35 empty tracks on a diskette, writes a VTOC in track 17 sector 0 and writes 15 empty catalog sectors on the rest of track 17.  Then it scoots back to track 0 and writes the DOS image on the first three tracks.

I used Rak-Ware's DISASM to make a source file out of the INIT code, and then loaded it into the S-C Macro Assembler.  Then step-by-step I proceeded to add meaningful labels and comments, and modify the code to do what I wanted.

The File Manager INIT code expects various parameters to have been set up by the DOS command parser, and those will not be set up when my program runs.  I decided I would let my program assume that the last disk drive you accessed is the one where you have placed the blank disk you want to initialize.

I also decided to make the volume number always 001.  I always do this anyway, and generally consider the volume number to be a nuisance (since I don't have a Corvus which uses the volume numbers for something useful).  If you want to be able to choose the volume number, you could add the code for that purpose.  Lines 1240-1270 set the volume number into the VTOC image and into the RWTS parameter block (IOB).

Lines 1290-1300 call RWTS to format the blank diskette.  Beware!  It is entirely too easy to forget to remove your heavily loaded program diskette before running this program!  Be absolutely SURE you have the diskette in the drive which you WANT to initialize.  After this program runs, the disk will have no remnant of any data which may have been on it before.

Lines 1310-1570 set up a VTOC image.  The program assumes that part of the VTOC image at $B3BB is already set up, because you could not run this program without having read at least one VTOC somewhere along the way.  The VTOC bitmap is set up first to $FFFF0000 at each sector position, and then the entry for track 0 is cleared.  Finally the bits for sector 0 and sectors 9 through 15 of track 17 are cleared.  Then lines 1580-1640 call on RWTS to write out the VTOC on track 17, sector 0.

The catalog sectors are chained together with a series of pointers.  A pointer in the VTOC points to the first catalog sector, which is almost always track 17 sector 15.  A pointer in the first catalog sector points to the second one, and so on.  The last catalog sector points at track 0, which is a flag indicating the end of the catalog.  (Too bad, because if DOS tested for a final pointer to 0,0 instead of just 0,x we could put the catalog for this data disk all in track 0 and free up even more sectors.)

Lines 1650-1700 clear the catalog buffer, and then lines 1710-1900 insert the forward pointers and call on RWTS to write each sector on the disk.

Finally, lines 1910-2000 write out a bootup program on track 0 sector 0.  BOOTER is the code that will be executed if you accidentally try to boot our DOS-less disk.

Lines 2010-2090 finish setting up a call to RWTS, and check for an I/O error.  I didn't bother to write any error handler into this program, as you can see by the BRK in line 2090.  If you want you can printout the DOS error code at this point, or at least get it in the A-register before the BRK.

The BOOTER program is tricker than it looks.  Anyway it tricked me a lot.  First notice the .PH and .EP directives in lines 2120 and 2280.  These tell the assembler to continue assembling bytes following the preceding code, but to assemble it with the assumption that at execution time it will be origined at $0800.  The boot ROM on the disk controller reads track 0 sector 0 into $800-$8FF, so BOOTER has to be set up to run there.

Notice line 2140, which is ".HS 01"  The boot ROM reads the first sector into $800-8FF, then checks location $800 to see how many sectors you want the boot ROM to read.  About the only disk I have heard of which has anything other than 01 in this byte is the BASICS disk.  If you put, for example, 03 in that byte sectors 1 and 2 would be read into $900 and $A00.  You can read up to 16 sectors this way, but remember that the sector numbers will not be the same as the ones you use when you write them with RWTS.  (RWTS uses a table to convert logical sector numbers into physical sector numbers.)

Line 2150 turns off the disk motor.  I forgot the first time, and of course the drive just kept spinning.

Lines 2160-2210 print out the message from lines 2240-2270.  My first attempt I called the standard COUT subroutine at $FDED to print each character, and I lost an hour finding out why I never saw my message.  Instead, the drive just kept grinding the head to track 0, over and over and over....  But it worked if I first copied the boot ROM code from $C600 down to $8600, and typed 8600G to boot.  I finally figured out that PR#6 sets the output hook to slot 6 and leaves it there.  Then the next character that is printed (usually the prompt character for whatever language you are in) through COUT goes to the disk interface and proceeds to boot.  My message sent another character to COUT and restarted the boot, ad infinitum.  Changing line 2190 to "JSR $FDF0" fixed it all.

After printing the message line 2220 jumps to the initial entry point of the monitor, so you get a "*" prompt.  If you previously had DOS in memory, you will probably be able to use 3D0G to get back to BASIC or the assembler or whatever.  Otherwise, stick in a disk that DOES have DOS and try booting again.

Line 2300 is just window dressing.  It assures that the rest of track 0 sector 0 will have nothing but zeroes in it.  No particular value, but I like it that way.
