

                        Ŀ
                                          
                            CHAPTER  V    
                                          
                        


                 Ŀ
                                                 
                     THE LDC FORMAT OPERATION    
                                                 
                     AND OTHER LDC OPERATIONS    
                                                 
                 



1. THE COMPLETE LDC FORMAT OPERATION

   Although there is no point in performing complete LDC format
operations (because that is just what INT 13h/function 5 does),some
almost trivial modification will allow us to perform what we are
really interested in : ABORTED format operations.

The complete technique involves the following steps :

         (A) Turn the disk drive motor on         (if necessary)
         (B) Recalibrate the read/write head      (if necessary)
         (C) Position the read/write head over the desired track
                                                  (if necessary)
         (D) Initialize the DMA                      (see below)
         (E) Command phase                           (see below)
         (F) Wait for the operation to be complete
             (wait_int procedure; see Chapter IV - section 3)

         (G) Read the result phase bytes             (see below)


The DMA initialization step is quite standard (see Chapter IV -
section 2); the DMA command code is of course  4Ah  (write) and the
number of bytes to transfer is  4 * (number of sectors per track).

The command phase requires a 6-byte sequence as follows :


          Ŀ
                                                           
                 format track command phase sequence       
                                                           
          Ĵ
                                                          
           byte                                           
            no                 description                
                                                          
          Ĵ
                                                          
            01     MUST be  4Dh                           
                                                          
          Ĵ
                                                          
            02     (4 * head) + drive                     
                                                          
          Ĵ
                                                          
            03     data size code                         
                   code n means  128 * 2^n bytes/sector   
                                                          
          Ĵ
                                                          
            04     number of sectors/track                
                                                          
          Ĵ
                                                          
            05     format gap length                      
                    (number of bytes of  4Eh  written     
                    between sectors)                      
                                                          
          Ĵ
                                                          
            06     format fill byte                       
                    (the data value stored in each byte   
                    of the sectors when a track is        
                    formatted)                            
                                                          
          




The result phase provides 7 bytes. Details are given in Hogan's
Sourcebook (8.19). The result bytes MUST be read (unless a disk
controller reset is performed).



2. ABORTED FORMAT OPERATIONS

   A format operation may be aborted any time. All that is needed is
to perform a disk controller reset (see chapter IV - section 5).
The abortion is usually performed in the following circumstances :

   . While the CRC bytes for the last CHRN field are being written.
     This is the only way to 'write' a bad CRC word for a CHRN field.
     Such sectors are called 'hidden sectors' because they are not
     spotted by the standard method described in Chapter III. We shall
     discuss hidden sectors in section 4.

   . Just after the CRC bytes for the last CHRN field are written.
     This is the way to ensure that a sector has no data marks
     (3 bytes of A1h + FBh); see Chapter I - section 7.

   . While the data bytes are being written or while the CRC bytes for
     the data field are being written. These are ways to 'write' a bad
     CRC word for a data field.

   . Just after the last sector is written (see example 1 below).

To play such tricks we need to know when the last CHRN field is about
to be written. That is when the DMA counter (accessible through
port 5) holds a value of  FFFFh .

The following procedure may be used :


; abort       the wait_int procedure may NOT be used when
;             dealing with aborted operations because  it
;             waits for the operation to be complete!


abort         proc      near
              mov       dh,2       ; or any suitable value
              xor       cx,cx
ab1:          in        al,5
              mov       ah,al
              in        al,5
              cmp       ax,0ffffh
              je        ab2
              loop      ab1
              dec       dh
              jnz       ab1
              jmp       ab_error

ab2:

;
;             delay  (depending on one wants to do)
;
;             perform a disk controller reset
;
              ret

ab_error:

;
;             time out error
;
;             tell the calling program
;

abort         endp



WARINING: Issuing an aborted format command may occasionally cause a
          'glitch' on the opposite side of the diskette (same track).
This is probably due to a hardware bug.


   Let us denote

   the number of sectors/track (command phase parameter)  by  EOT
   the sector size code (command phase parameter)         by  NN
   the format gap length (command phase parameter)        by  FGL

We are now ready to give a few examples.


EXAMPLE 1

We want track 21/head 0 to contain 12 sectors as follows:

   CHRN field   CHRN  true data  data 
                CRC     size     CRC            remarks
  
   21 00 01 02   ok      512      ok  
   21 00 02 02   ok      512      ok  
   21 00 03 02   ok      512      ok  
   21 00 04 02   ok      512      ok  
   21 00 05 02   ok      512      ok  
   21 00 06 02   ok      512      ok  
   21 00 07 02   ok      512      ok  
   21 00 08 02   ok      512      ok  
   21 00 09 02   ok      512      ok  
   21 00 10 01   ok      256      ok  
   21 33 12 02   bad     ---      --   no data; just hidden sect

Two passes are required to format such a track.

(a) Call format with     EOT =  12        track = 21
                         FGL = 233        head  =  0
                         NN  =   1

                         CHRN fields      21 00 01 02
                                          21 00 02 02
                                          21 00 03 02
                                          21 00 04 02
                                          21 00 05 02
                                          21 00 06 02
                                          21 00 07 02
                                          21 00 08 02
                                          21 00 09 02
                                          21 00 10 01
                                          21 33 12 02

                         ABORT while CRC bytes for last CHRN field.
                               are being written

(b) Call format with     EOT =  9         track = 21
                         FGL = 32         head  =  0
                         NN  =  2

                         CHRN fields      21 00 01 02
                                          21 00 02 02
                                          21 00 03 02
                                          21 00 04 02
                                          21 00 05 02
                                          21 00 06 02
                                          21 00 07 02
                                          21 00 08 02
                                          21 00 09 02

                         ABORT just after the last sector is written.

Some elementary arithmetic is necessary to determine the FGL values.
The table in Appendix B may be helpful.


EXAMPLE 2

We want track 22/head 0 to contain 9 sectors as follows:

   CHRN field   CHRN  true data  data 
                CRC     size     CRC            remarks
  
   22 00 01 02   ok      512      ok   wrong angular position (*)
   22 00 02 02   ok      512      ok  
   22 00 03 02   ok      512      ok  
   22 00 04 02   ok      512      ok  
   22 00 05 02   ok      512      ok  
   22 00 06 02   ok      512      ok  
   22 00 07 02   ok      512      ok  
   22 00 08 02   ok      512      ok  
   22 00 09 02   ok      512      bad 

   (*) we want the angular position of the first CHRN field to be 25


Call format with         EOT = 19         track = 22
                         FGL = 80         head  =  0
                         NN  =  2

                         CHRN fields      22 00 01 02
                                          22 00 02 02
                                          22 00 03 02
                                          22 00 04 02
                                          22 00 05 02
                                          22 00 06 02
                                          22 00 07 02
                                          22 00 08 02
                                          22 00 09 02
                                          22 00 10 02
                                          22 00 01 02
                                          22 00 02 02
                                          22 00 03 02
                                          22 00 04 02
                                          22 00 05 02
                                          22 00 06 02
                                          22 00 07 02
                                          22 00 08 02
                                          22 00 09 02

                         ABORT while the CRC bytes for the last sector
                               data bytes are being written.

This trick is used by some copy protection methods.
Note that some of the data bytes for sector 9 are at the beginning of
the track while the other ones are at the end of the track.
The data CRC error in sector 9 will be corrected if this sector is
rewritten (unless an aborted write operation is performed).


EXAMPLE 3

This example demonstrates an overwriting technique that is often
quite useful.
We want track 23/head 0 to contain 7 sectors as follows:

   CHRN field   CHRN  true data  data 
                CRC     size     CRC            remarks
  
   23 00 01 01   ok      256      ok  
   23 00 02 02   ok      512      ok  
   23 00 03 03   ok     1024      ok  
   23 00 04 03   ok     1024      ok  
   23 00 05 03   ok     1024      ok  
   23 00 06 02   ok      512      ok  
   23 00 07 04   ok      ---      --   no data; CHRN field only


Call format with         EOT = 15         track = 23
                         FGL = 85         head  =  0
                         NN  =  1

                         CHRN fields      23 00 01 01
                                          23 00 02 02
                                          23 00 21 01
                                          23 00 03 03
                                          23 00 31 01
                                          23 00 32 01
                                          23 00 04 03
                                          23 00 41 01
                                          23 00 42 01
                                          23 00 05 03
                                          23 00 51 01
                                          23 00 52 01
                                          23 00 06 02
                                          23 00 61 01
                                          23 00 07 04

                         ABORT just after CRC bytes for the last
                               CHRN field are written.

Writing the appropriate number of bytes to sectors 1..6 will destroy
the unwanted CHRN fields (INT 13h/function 3 may be used).


EXERCISE

Format track track 24/head 0 as follows:

   CHRN field   CHRN  true data  data 
                CRC     size     CRC            remarks
  
   24 00 01 02   ok      512      ok  
   24 00 02 02   ok      512      ok  
   24 00 03 02   ok      512      ok  
   24 00 04 02   ok      512      ok  
   24 00 05 02   ok      512      ok  
   24 00 06 02   ok      512      ok  
   24 00 07 02   ok      512      ok  
   24 00 08 02   ok      512      ok  
   24 00 09 02   ok      ---      --   no data; CHRN field only.
   24 00 10 02   ok      512      ok   CHRN fields for sectors
                                       9 and 10 must be 7 apart



3. OTHER LDC OPERATIONS

   The disk controller accepts some other useful operations :

      . Read data
      . Write data
      . Read deleted data
      . Write deleted data

From a programming point of view these operations are quite similar
to the read track operation (Chapter IV). Details may be found in
Hogan's Sourcebook (8.18).
They may be aborted (using the same technique as described for
format).

Just a few words about 'deleted' data. The terminology is misleading.
Deleted data are not physically erased! They are just marked as
deleted (i.e. the normal data mark  3 bytes of A1h + FBh  is changed
into  3 bytes of A1h + FAh . That is the secret!).


EXERCISE

Disassemble the INT 13h ROM routines.
It is not a trivial exercise but it is quite rewarding.




4. HIDDEN SECTORS

   First we want to know how read track deals with hidden sectors.
Let us carry out the following experiment:

(a) We need a brand new diskette (because we do not want leftovers
    from previous format operations).

    Call format with     EOT =  9         track = 21
                         FGL = 80         head  =  0
                         NN  =  2

                         CHRN fields      21 00 01 02
                                          21 00 02 02
                                          21 00 03 02
                                          21 00 04 02
                                          21 00 05 02
                                          21 00 06 02
                                          21 00 07 02
                                          21 00 08 02
                                          21 00 09 02

                         ABORT while the CRC bytes for the last
                               CHRN field are being written


Next call format with    EOT =  1         track = 21
                         FGL = 80         head  =  0
                         NN  =  2

                         CHRN field       27 12 13 14

                         ABORT while the CRC bytes for the
                               CHRN field are being written


Track 21/head 0 now contains two hidden sectors.


(b) Call read track with   NB  = 1200h       track = 21
                           EOT = 9           head  = 0
                           NN  = 2
                           GL  = 2Ah

The result phase bytes show CRC errors and a missing address mark
error. The data buffer contains the data bytes form sectors 1..8.


Next call read track with  NB  = 2400h       track = 21
                           EOT = 9           head  = 0
                           NN  = 3
                           GL  = 2Ah

The result phase bytes show CRC errors and a missing address mark
error. 1000h bytes are transferred to the data buffer.


CONCLUSION : Read track does not mind CHRN fields with bad CRC but it
             aborts when it does not find a data mark.


REMARK : There is a way around the brand new disk requirement
         mentioned above. Reformatting a track with one sector of
size code 6 does not leave any CHRN field or data mark.



We now discuss a difficult problem : finding hidden sectors.
The technique described in Chapter III does not report the CHRN fields
with bad CRC.
Read track may sometimes help to report the existence of a hidden
sector but it does not generally allows to identify such a sector.
The read command is useful to confirm the existence of a hidden sector
(if we know its CHRN field) because the result phase bytes show
a CRC error for the CHRN field.

I confess I do not know of a general method to spot all hidden sectors
on a track.
I shall describe what I know about it. Comments from readers will be
most welcome.

Suppose that  c h r n   ,  c' h' r' n'  are the nth and the (n+1)th
visible CHRN fields. We discuss a method to spot an in between hidden
sector provided :

           . the CHRN fields are not too close to each other
           . the hidden sector CHRN field is not of  c h r n

 (i)  Position the read/write head on the beginning of the track (using
      the technique described in Chapter IV - section 5)

(ii)  Position the read/write head a few bytes further than the  nth
      CHRN field (by reading  n  CHRN fields)

(iii) Issue a read CHRN command. This operation MUST be aborted so
      that the disk controller is not given any chance to read the
      (n+1)th  CHRN field. The timing is of course critical!

(iv)  The previous step being an aborted operation we do not know
      about the result phase bytes. They are kept secret by the disk
      controller. So we want it to confide its secret.
      The trick is to issue a 'wrong' read CHRN command (change the
      first byte in the command phase sequence to  OAh ). The four
      last result phase bytes provide us with a CHRN field. If it is
      not of  c h r n  then we have found a hidden sector (if it is
      of  c' h' r' n'  we could retry with a shorter delay in
      step (iii), just to be sure).




REMARK : Searching for all hidden sectors on a track can take a 'long'
         time. So it is good practice to revitalize the motor shut off
count down byte at memory location  0000:0440h.
This is quite easy :


revital         proc      near
                xor       ax,ax
                mov       es,ax
                cli
                or        es:[0440h],0ffh
                sti
                ret
revital         endp



Turning the motor off when disk accesses are no longer needed can be
done in a similar way : setting the motor shut off count down byte to
a small value (say 25h) is a good way to do it.
