[Coco] Re: Disk Basic and 512 byte block floppies.

John E. Malmberg wb8tyw at qsl.net
Wed Jan 21 23:34:23 EST 2004


Amardeep S Chana wrote:
> "John E. Malmberg" <wb8tyw at qsl.net> wrote in message
> news:bukito$m4b$1 at sea.gmane.org...
> 
>>There is a MS-DOS API for doing setting disk parameters including the
>>sector size, and it has been documented to work for all versions of
>>MS-DOS since 2.x.

>>Much of the documentation for that API has been removed from the MSDN
>>documentation that I have for my old copy of Visual Studio.  But it is
>>still in my even older Symantec C++ kit.
> 
> 
>>So yes there is a documented PC BIOS and MS-DOS API to set the sector
>>size of floppy disks.
> 
> 
> It would be great if you could look in the Symantec docs and post some
> details about the call.  If there is such a function I'll gladly eat my
> words!  But I'll remain skeptical until I can identify an int/fcn around
> which code can be written to validate the capability.

_bios_disk(_DISK_READ, &diskinfo), as used below.

There is a variant of this that takes the parameters a little bit 
differently.

These honor the setting of the disk parameter block that you referenced 
in a later post.  It is not just used for hints to the file system, it 
actually controls how the bios calls work, or at least it use to.

I first found this documented in the Tandy 2000 programming manual, and 
the Microsoft Quick-C product documented how to access these functions 
with out assembly.

These APIs can not be accessed from DOSX or a WINDOWS program.

>>The API has been tested to work in the DOS Emulators in Windows 95,98,
>>and Windows NT 4.0.

I am in the process of modifying this code to make it have better 
diagnostics.

For MS-DOS, 3 retries were the most that were ever needed.  But with my 
Windows 98 system, it sometimes take 15 to 20 retries.

And sometimes I have to remove and reinsert the disk.



#include <stdio.h>
#include <bios.h>

#define G_SECTORS 9

#pragma pack(1)
typedef struct {
     unsigned char fdc1;         /* 4bit step rate, 4bit head unload time */
     unsigned char fdc2;         /* 7bit head load time, 1 bit DMA flag */
     unsigned char motor_off;    /* motor off delay */
     unsigned char sector_size;  /* 0 = 128, 1 = 256, 2 = 512, 3 = 1024 */
     unsigned char num_sectors;
     unsigned char gap_length;   /* Read/write sector gap */
     unsigned char dtl_length;   /* Data transfer length */
     unsigned char fgap_length;  /* Format gap length */
     unsigned char fill_byte;    /* Format fill byte */
     unsigned char settling_time; /* head settle time */
     unsigned char motor_time;   /* Motor start time */
     } disk_param_blk;
#pragma pack()

typedef disk_param_blk __far *int_vec;

unsigned rdwrtfloppy_bios
   (unsigned short drive,
    unsigned short head,
    unsigned short track,
    unsigned short strtsec,
    unsigned short nsecs,
    unsigned short action,
    void __far *trackbuf)
{
int_vec bios_dpb;
int_vec saved_dpb;
int_vec __far * vec_loc;

disk_param_blk new_blk;

struct diskinfo_t diskinfo;
unsigned disk_stat;

unsigned reset_stat;
int retry;
     disk_stat = 255;

      /* change the disk param block to use coco parameters */
     /*----------------------------------------------------*/

      /* Find the original disk parameter table */
     /*----------------------------------------*/
     vec_loc = (int_vec __far *)(0x1E * 4);
     bios_dpb = *vec_loc;


      /* Copy the old block into the new block */
     /*---------------------------------------*/
     saved_dpb = &new_blk;

      /* Adjust the sector size and count for a TRS-80 color computer */
     /*--------------------------------------------------------------*/

     saved_dpb->gap_length = bios_dpb->gap_length;
     saved_dpb->sector_size = bios_dpb->sector_size;
     saved_dpb->num_sectors = bios_dpb->num_sectors;
     bios_dpb->num_sectors = T_SECTORS;
     bios_dpb->gap_length = 0x2a;
     bios_dpb->sector_size = S_SECTORS / 256;

     diskinfo.drive = drive;

      /* set up the disk request */
     /*-------------------------*/
     diskinfo.drive = drive;
     diskinfo.head = 0;
     diskinfo.track = track;
     diskinfo.sector = strtsec;
     diskinfo.nsectors = nsecs;
     diskinfo.buffer = trackbuf;
     retry = 0;

     do
     {
           /* Process the data from the disk */
          /*--------------------------------*/
          if (action == READ)
             disk_stat = _bios_disk(_DISK_READ, &diskinfo);
          else if (action == WRITE)
              disk_stat = _bios_disk(_DISK_WRITE, &diskinfo);

          if (disk_stat > nsecs)
          {
               /* Retry the read a few times before giving up */
              /*---------------------------------------------*/
              retry++;
          }
      } while (disk_stat > nsecs && retry <= 30);

       /* Restore the old disk parameter pointer */
      /*----------------------------------------*/
     bios_dpb->num_sectors = saved_dpb->num_sectors;
     bios_dpb->sector_size = saved_dpb->sector_size;
     bios_dpb->gap_length = saved_dpb->gap_length;

       /* return the data and the status */
      /*--------------------------------*/
      return disk_stat;
}

-John
wb8tyw at qsl.net
Personal Opinion Only





More information about the Coco mailing list