Ruud's Commodore Site: Findings Home Email

Findings 90x0


My findings about the disassembly of the Commodore 9060/9090 ROMs.


The story of this document

I disassembled the ROMs of the Commodore 9060/9090 hard disk drives (9060) and ran into some problems. This document is meant to express these problems and to ask questions about them.


Some preinformation

The disassembly is based on revision C for the Bus Controller (BC) and revision B for the Disk Controller (DC).


Bus Controller

Some small items:
- A lot of the source code is exactly the same as the one of the CBM 8250 floppy drive. I can't give you a percentage.
- The 8250 ROM contains the Reset an Format routine for the DC at the beginning. The 9060 ROM doesn't contain any code for the DC at all.
- The 9060 contains all the code for a second drive with the exception of the Backup/Duplicate command.
- The low level formatting of the hard disk (HD) is not done by the DC. It is initiated by the BC by sending the value $C4 as job code to the DC. The DC on its turn sends the command code $04 to the SASI board, which handles the complete low level formatting of the HD. The DC just checks if everything went well.
- From E_0C0B9 on something is calculated and stored in $10C9 but I haven't figured out what.

Some puzzling items:
- At E_CB08 a subroutine is executed that fills buffer 1 with a pattern. The content of buffer 1 is written to the disk. The pattern depends on the number of the head. Why ???
- At E_D90B the sector number is compared with the number of sectors/track. This number = $20. But the sector number is always smaller then $20 due to the AND action just before. Error, dumb programming?
-

A really confusing item:
After successfully having "formatted" the sector (read: written the contents of Buffer 1 to the sector), the BC branches to A_CB29. First the head is checked, which is zero at start, and we branch to A_CB43. There the track is increased and after checking if the last track has been formatted, sector zero of the new track is formatted.
After having reached the maximum number of tracks, the number is decreased (E_CB4F), the head is increased to one and sector zero is formatted. After branching to A_CB29 the head is checked again. Being one the track is decreased, checked and sector zero is formatted again. Once the track is zero again, the head is increased to two and we start formatting sector zero again. Now the track number is increased again like when the head was zero.
This process goes on for all heads and the routine jumps to J_CC15. My first confusion: "What about the other sectors ???".

At J_CB16 you will find the routine that covers the other sectors. The confusing thing here is that it is only called from the routine at A_CB5C. The BC branches to this routine at E_CB12 after having found an error when formatting a sector.
What the routine now does is formatting this sector 30 times. When finished, it jumps to J_CB16. There the sector number is increased and deducted from NumSecXhead, which represents the number of sectors/track times the number of heads.
If this is supposed to happen with all sectors, my question is: how is the error generated to make the BC branch to A_CB5C ???

If the above indeed happens as described above, here is the next weird thing: counting down from NumSecXhead to zero means that all sectors for a given track are formatted. Thus for all heads, independent of the variable FormatHead. Which means that all sectors are formatted 120 or 180 times!

More confusing things: if things go wrong at A_CB5C, the subroutine at P_CBA4 is called. And to be honest, I haven't any idea what this routine does. It juggles with pointers and numbers and I cannot see any relation with the original task: formatting a sector.

The routine starting at J_CC15 is confusing as well. The routine is entered with Sector = 0, set at E_CAFD. At E_CC32 Buffer 0 is written to the HD. If errorless, the routine branches to A_CC4D. There Sector is checked for the value zero. As it is zero indeed, the routine continues. At E_CC61 it branches to A_CC88. From there on the routine ends in a RTS which, IMHO, ends the formatting process.
Either the above assumption is right and then one can question what the meaning of the whole action is or I'm wrong and then I hope you can point me to my error(s).


Disk Controller

Some small items:
- The DC has 4 KB of RAM mapped from $0400 till $1400 but only 3 KB of it are tested. At E_F838 the pointer is loaded with the value 8 instead of the expected value 4. AFAIK the range $0400/$07FF is only tested by the BC.
- The memory address A_0499 is used but, except during the RAM test, isn't filled by the BC or DC. AFAIK the RAM test fills it with the value $A9.
- The memory address A_04A3 is used but, except during the RAM test, isn't filled by the BC or DC. AFAIK the RAM test fills it with the value $B3.
- The DC supports 11 job codes but AFAIK only three, Read, Write and Format, are used by the BC and two by the DC; Verify and $BC.
- The job code $BC is used by the DC when, according the jumper, a disk with six heads has been installed. The job sends the code $C0 to the SASI board plus some data, including the number of heads. The only thing I can imagine is that the board checks in one or another way (by seeking a sector ???) if the 6th head indeed exists.


Error handling

IMHO there is a mismatch with the error code produced by the DC and the one generated by the BC. The DC reads two status bytes. If the first byte isn't zero, the second one contains an error code. It is loaded at A_FC06 and processed. The result is one of the error codes found from $FE12 on. This code is written over the original job code. It is always smaller than $11 which means bit 7 is 0 which on its turn means that the job has ended.
From E_EFE5 on the given code is processed. At A_EFEC this given code can be: 2,3, 4, 5, 6, 7, 9 and 11. $20 is added and the result is decreased with 2. This ends up in the possible error codes $20..$25, $27 and $29. And there is no message for error code $29. OTOH the above range also means that the error message for code $28 never will be used.


Older revisions

There is also a revision A for the DC available. The differences with revision B are minor. For more details please see this document. On Bo's Commodore site you will also find a revision A for the $C000/$DFFF part of the BC ROM (if it hasn't been removed already) but this seems to be a broken ROM: it seems to be the same as revision B but bit 3 of every byte is set.

There is also a revision B available for the BC.





Having questions or comment? You want more information?
You can email me here.