IDE Driver Software

(part 3 of the Smart IDE)

by Bob Wolley

Start

 


The Last piece of the puzzle - the software. Take a look at the listing. See the title? 1DE38.ASM That is the 38th version of the IDE code that I have done. And, it will not be my last. Let's talk about how an IDE drive is programmed.

IDE Overview
One of the great things about an IDE drive is that it very simple to run. No low-level formatting is required, you tell it how many heads and sectors per track (not the other way around), and you only need two instructions, read and write! You communicate with the drive using two sets of registers - in our case at $Dl5x and $D166. You load the sector number(s) into the proper registers and just ask the drive to read or write. If you are using a late-model, buffered drive, data is read or written as fast as you like from the data register until the transfer is complete. From an 8-bit standpoint, the real deal here is that all sectors are 256 bytes. No double read buffer gyrations needed. Of course, there is a loss of half of your drive's capacity since the interface is 16 bits wide and we're only using 8 Yep, you only get to use 40 megs from an 80 MB drive. Or, 600 megs on a 1.2 GIG unit. SO? That's the price you pay for such a clean, fast, and simple design. At today's prices, who can complain? (don't even ask me about using the whole drive - I am not going to do a 16 bit interface. It would be slow, expensive and messy.)

Reset
OK, on to the registers. First is $D166. This is the reset register. The interface has hardware reset from the 1200XL connected to pin 1 of the drive. Every time you push RESET on your 1200XL, the drive gets reset (you may even notice the drive start to spin down). When you are doing IDE development, you may want to disconnect the hardware reset and just use the soft reset at $D166. This will allow you to reset only your 1200XL if the system is hung, preserving the IDE register status for examination. Either way, you must assert reset for at least 5 microseconds to clear the drive. It will then take a little while for the drive to get itself back together and go not busy (all regs will read $DO during reset). Currently, I am not using $D166 reset, so don't look for it in the 1DE38 code.

Registers

Next are the $Dl5x regs. I'll list them in order:

ADDR READ WRITE
50 data reg data reg
51 error reg write comp
52 sector count sector count
53 sector number sector num
54 cylinder low cylinder low
55 cylinder high cylinder hi
56 SDH SDH
57 status command

Most of those may be self-explanatory. Data is the read or write data. The error reg has error codes if $57 has bit 0 set (xxxxxxx 1). Sector count allows you to read multiple sectors with one command - set it to 1. Sector number is the number of the sector you wish to read or write ($01 - $10). Cylinder low and high are the cylinder number you are accessing ($0000 - $FFFF). SDH contains three parameters: the sector size in bits 5 and 6 (01), the head number in bits 0 - 3 ($0 - $F), and the drive (master or slave) in bit 4. For example $A7 selects the master drive and head 07. $B9 selects the slave drive on head 09. (I have been able to run two drives at once with some success.... but it needs some s/w yet).

Code Overview
The driver code and the configuration table sit in the space newly acquired at $D600 thru $D7FF. This may allow some software that poaches in the OS space for its own routines to run with an IDE drive, since $D6xx and $D7xx are never usable from a software routine. The IDE drivers will run with a DOS that is not HD intelligent. Many of my partitions boot good old DOS 2.0, both single and double density. Just the ticket for AtariWriter on cartridge. In fact, the IDE drive runs without any DOS at all, as in SCOPY and other M/L utilities. It just looks like any other disk drive to the SIO code. There is currently space for 16 partitions in HDTABL, but 63 would be supported in the current code. And, the HDTABL could be loaded from disk as many times as necessary, giving you unlimited partitions - 16 at a time. No or little error checking is done in IDE38 code. This is NOT a great idea. While I am using new, modern drives, I don't seem to have a problem. Some of my old, high-mileage clunkers do not fare so well. The older drives do not seem to like having 16 heads and 16 SPT, either. So, beware. This IDE stuff is not all perfect in the software department. Of course, the value of the SmartIDE modification is to develop OS routines steadly - in particular, the IDE code. So folks, get on the ball and do some of this stuff. Write some good hacks to the code and send it to AC for future articles! Once we have some really effective code you can add an IDE with just the HC138 and a new ROM. The hardware seems to be pretty solid. That is not to say that it does not have any problems - the Sweet 16 will not work with it, I'm afraid. But, on a standard machine, it is at least consistent and reliable.

OK, on to the code itself.

IDE vs. SIO
The IDE drive has a hook into the normal SIO code at $C95B. We JSR into the new routine to see if the I/O is pointed to an IDE partition. The first check is the SELECT key (line 360-380). I have allowed the SELECT key to override the IDE code. If you want to bypass all of the active IDE partitions, just hold SELECT down and your system will use only SIO devices. This makes it quick to peek at a directory or copy a single file to or from a floppy. For example, you have a floppy set as D2: and an IDE partition set as D2:. The IDE drive at D2: will always answer for D2: since the IDE code has priority. But, if you want to read from the floppy D2:, you can simply hold SELECT down and all D2: access will be on the SIO. To copy a file from the floppy D2: to the IDE D2: you can hold SELECT when DOS asks for the source and release SELECT when DOS asks for the destination drive. Works just fine. The next test is for the device in the OS DDEVIC ($0300). If it is not a $31, then we are not talking to a disk drive and we can exit IDE code. The last test is to find the device address, DUNIT ($0301) in the HDTABL at $D7C0.

HDTABL
The HDTABL is a 64 byte data field that contains 16 four byte entries. Each entry represents a partition or range of sectors on the IDE drive. The first byte is the high order byte of the first sector in the partition and the second byte is the low order byte of the first sector in the is to develop OS routines easily - in partition. The third byte is the number of particular, the IDE code. So, you folks 256 sector clusters in the partition (max sectors is still 65K or 16mb). The fourth byte is a composite - bits 5-7 are density tags that are returned on a STATUS command. $8x is a 1050 in dual density (1024 sectors). $6x is a double density disk. And $Ox is a single density disk. Bit 4 is the IDE drive bit (which I do not use in the current code). Setting bit 4 will select the slave drive on the IDE buss instead of the master drive. This will be great help when you want to back up your I-ID data on one of those SyQuest 135mb removable drives. Just add it as a slave drive and copy from one IDE drive to another! Finally, bits 0-3 are the drive address itself. As an example, a $64 in byte 4 would indicate a DD partition on the master drive that will respond to D4: on the SIO. A $92 would be a 1050 density partition on the slave drive that would answer as $D2:. Any drive that has bits 0-3 set off is not active or disabled. Examine the data loaded in the HDTABL in 1DE38.ASM. The first partition at line 2730 is a DD drive set as Dl: on the master drive. It is 4096 sectors long and starts on sector $0000 of the IDE drive. The entry at line 2760 is a SD drive that is unassigned and is 1536 sectors long starting at IDE sector $001C. And, as I write this I notice that the next partition starts at IDE sector $0020 - which does not allow enough space for the previous partition! You be very careful when you set up HDTABL, OK? That little error in line 2770 would eat my 8 meg partition if I used the previous partition past 1024 sectors, wouldn't it? Note that the HDTABL is not required to be in any specific order except for the first three entries, which we will cover later. This allows you to overlay any of the entries you wish in order to change which partitions are "mounted" on a particular "drive".

Searching HDTABL
Finding the device address in HDTABL is just a matter of checking byte four of each entry for a match to $0301, DUNIT. line 420 loads the an index to the end of the table and the search progresses backwards until a match is found or the index is less than zero. If no match has been found, then that drive is not an active IDE drive. The first drive found starting from the bottom will cause a branch into IDE code at line 580.

R We Busy?
Before we try to access the drive, we check for BUSY at line 590. This code just loops forever if the drive is hung. A better approach would be to branch out into a routine that would determine the reason for the BUSY and take action. Maybe later.... As I said earlier, a new drive never has a problem here. Older drives, not so true. OK?

Command Dcode
Now we are into the real code at line 630. Here we determine the command. No real cute coding; just compare DCOMND at $0302 with all valid IDE commands. If we do not find one, return a command reject at line 790. Notice that the $4E command in line 760 just branches into the STATUS routine. This command and the $4F command are the read and write configuration commands used by the PERCOM standards. If you want to use SpartaDOS or any other DOS that needs this data, you must implement these two commands. And, yes that means that any DOS using these commands will not recognize the IDE drives as anything other than an 810 or 1050. Gives us something to work on, doesn't it? MYDOS works just fine without the $4E and $4F.

SETREGS
So, now we get to the command itself. The only commands that do anything with the IDE drives are the read and write commands. The first step in both commands is to JSR to to SETREGS. This is where we convert the logical sector number from SIO to a physical sector, head and cylinder on the IDE drive. Lines 1540 to 1580 sets the data address for the transfer. Lines 1590 to 1630 loads the IDE sector number ($D153) from the low order SIO sector number ($030A). Notice how simple that is? Later on, we'll discuss the IDE INIT code where we tell the IDE drive that he has 16 sectors per track and 16 heads per cylinder. This makes it simple to convert the SIO sector number to the IDE parameters. Lines 1640 to 1710 loads the IDE physical head ($D156) from the remaining low order SIO sector value. Lines 1720 to 1790 adds the HDTABL partition offset in bytes 1 and 2 to the high order SIO sector ($030B) and stores the result in the IDE cylinder low ($D154) and cylinder high ($D155). It also checks the range of the SIO sectors at line 1730 to insure that we don't overrun the next HDTABL partition. Last, but not least, we tell the IDE drive that we will only read one sector (lines 1800 to 1810) and clear the carry bit to signify no sector error. Back in the read or write command, we check for a sector overrun and start the command.

Read Command
The IDE read command is a $20. Just loading that value into the command register at $D157 will initiate the seek to the data sector and read all the data into the IDE buffer. Once the drive is not BUSY (lines 1190 to 1210), you are ready to read your data. By checking the data ready bit (bit 3) in the STATUS register ($D157), we can determine when the sector may be transferred into our memory (at ($32) ,Y). Once the first data byte is ready, by the way, it is not really necessary to check status to see if any subsequent bytes are available since we are reading a memory buffer, not a mechanical device at this point. There are two sector sizes on the Atari, 128 and 256 bytes, as defined in DBYTLO at $0308. If we are reading a 128 byte sector, the last 128 bytes just get thrown away (lines 1300 to 1340). We do not want to read them into memory. A 256 byte sector will read all 256 bytes into memory (lines 1220 to 1290). At that point, bit 3 of the IDE STATUS register will be reset to 0. That's it. Set a few flags in the SIO and you're done (lines 970 to 990 and 840 to 880). Cut out all the unnecessary code and you can read a 720 sector DD disk in about 4 seconds not too bad!

Write Command
The write command is similar to the read command except the command code is a $30. We do not need to check the sector size here since the last half of the sector is not used for 128 byte sectors anyway. The code simply writes the 256 bytes starting at the SIO data address into the IDE data register. The drive will do the seek and store the data after the transfer. Be aware! As written, this code does not keep you from writing 256 DD sectors to a SD drive as would normally be the case. You can hose yourself all up if you are not careful in the HDTABL configuration. It would be a good idea to check the sector length against the HDTABL size Maybe later.

OK, other stuff....

IDE Initialization
IDE drives must be initialized before you use them. You must tell the drive how many sectors per track and how many heads per cylinder they should configure themselves into or the drive will use it's native values. We want to have a drive that has 16 sectors per track and 16 heads - this makes the code very simple. So, we do this every time we RESET the drive. Line 320 patches the OS to init the IDE drive. INITCODE (at line 1850) first checks for the IDE drive to have completed it's RESET and then stores the number of sector in $D152 and the number of heads in $D156. Storing a $91 in the command reg at $D157 initializes the drive with our values (line 1940 to 1950). Simple.

Dynamic Selection
There are a couple of bells and whistles in this code that I like. The first three HDTABL entries are reserved for Dl:. I have patched the OS to respond to CNTL-F1 in lines 180 to 200 so that this keystroke now selects Dl: from one of four options. SIO Dl:, if it is connected, or any of the first three HDTABL entries. The purpose of this feature is to allow you to change "diskettes" in Dl: on the fly. Or, you can switch from the IDE drive to the SIO drive with just a keystroke. I also use the two L1 and L2 indicators on the 1200XL to indicate just who's on Dl:. 00 is the SIO drive, 01 is HDTABL entry 1 (at $D7C0), 10 is HDTABL entry 2 ($D7C4), and 11 is HDTABL entry 3 ($D7D0). This code is in SELNXTHD at lines 205 thru 2100 and SETL1L2 at lines 2430 thru 2540. I also allow D2: to be toggled between the HDTABL IDE drive and the SIO drive using the CNTL-F2 keystroke (lines 220 thru 260 and 2590 thru 2680). Overall, I can select IDE drives 1-3 or the SIO drive on Dl: and IDE drive or SIO drive on D2: from within any program that has not overlaid the OS too badly. Works really great!

FINIS
Anything else? I guess not in this issue. I will really, really try not to screw up the publication schedule any more. I know a number of you subscribers are wondering about our viability - I would rather print something useful on an irregular basis than just print whatever we have on a fixed schedule. I hope at least some of you agree and continue to support us. For the others, we'll work on it, OK? Don't give up - better yet, volunteer! We could use the help. That way, I may not have to have either a project or a magazine - we can have both.


You can download the disk with all the code here.

about 13k in ZIP format.



Start


E-Mail Me
Comments, questions, email me.


These pages created and maintained by Clarence Dyson

Copyright © 1996,1999 Clarence Dyson. All rights reserved.
Any reproduction, duplication, or distribution in any form
is expressly prohibited, except by consent of credited creators.

Ride Free, Citizen