/* -*-C-*-
********************************************************************************
*
* File:         emaxio.c
* RCS:          $Header: emaxio.c,v 1.1 93/03/19 14:24:08 mjp Exp $
* Description:  E-mu Emax Sampler - raw disk IO routines
* Author:       Mike Prudence. (mjp@hplb.hpl.hp.com)
* Created:      Wed Mar 17 14:29:00 1993
* Modified:     Sat Mar 20 13:51:02 1993 (Mike Prudence) mjp@prudence
* Language:     C
*
* (c) Copyright 1993, Mike Prudence.
*
********************************************************************************
*/

#include "emaxio.h"

#define __EMAXIO_VERSION	"1.1"
#define __EMAXIO_DATE		"Fri Mar 19 13:33:16 1993"

int DriveReset (int drive)
{
  struct diskinfo_t disk_info;

  disk_info.drive=drive;

  return (_bios_disk(_DISK_RESET,&disk_info)) >> 8;
}

int DriveCheck (int drive)
{
   struct diskinfo_t disk_info;
   byte b[SCTR_SIZE];
   int result;

   disk_info.drive=drive;
   disk_info.sector=START_SCTR;
   disk_info.track=0;
   disk_info.head=0;
   disk_info.nsectors=1;
   disk_info.buffer=b;

   result = (_bios_disk(_DISK_READ, &disk_info))>>8;

   /* Let a 'disk has been changed' error through, here, as it is really
      what we would expect 99.9% of the time. */

   if ((result == 0) || (result == 6))
      return 0;
   else
      return result;
}

int ReadAbsSectors 
   (int drive, int head, int track, int sector, int nsects, void* buffer)
{
  struct diskinfo_t disk_info;

  disk_info.drive=drive;
  disk_info.head=head;
  disk_info.track=track;
  disk_info.sector=sector;
  disk_info.nsectors=nsects;
  disk_info.buffer=buffer;

  return (_bios_disk(_DISK_READ, &disk_info))>>8;
}

int WriteAbsSectors
    (int drive, int head, int track, int sector, int nsects, void* buffer)
{
  struct diskinfo_t disk_info;

  disk_info.drive=drive;
  disk_info.head=head;
  disk_info.track=track;
  disk_info.sector=sector;
  disk_info.nsectors=nsects;
  disk_info.buffer=buffer;

  return (_bios_disk(_DISK_WRITE, &disk_info))>>8;
}

int VerifyAbsSectors
    (int drive, int head, int track, int sector, int nsects, void* buffer)
{
  struct diskinfo_t disk_info;

  disk_info.drive=drive;
  disk_info.head=head;
  disk_info.track=track;
  disk_info.sector=sector;
  disk_info.nsectors=nsects;
  disk_info.buffer=buffer;

  return (_bios_disk(_DISK_VERIFY, &disk_info))>>8;
}

char* emax_io_error (int result)
{
  char unk_err[80];

  switch (result)
  {
    case 1:     return("Bad BIOS command!");
    case 2:     return("Address mark not found!");
    case 3:     return("Disk write-protected!");
    case 4:     return("Sector not found!");
    case 5:     return("Reset failed!");
    case 6:     return("Disk has been changed!");
    case 8:     return("DMA overrun!");
    case 9:     return("Attempted DMA across 64K boundary");
    case 12:    return("Unsupported track or invalid media!");
    case 16:    return("Read CRC/ECC error!");
    case 17:    return("Corrected CRC/ECC error (beware!)");
    case 32:    return("Controller failed!");
    case 64:    return("Seek failed!");
    case 128:   return("No response from drive!");
    case 0xCC:  return("Write fault!");
    default:    sprintf(unk_err,"Unknown error code %d!",result);
                return unk_err;
  }
}


int SetupDrive
    (int drive)
{
  int err, count;
  byte buf[SCTR_SIZE];

  count = 3;
  do
  {
    err = VerifyAbsSectors(drive,0,0,1,1,buf);
    if (err)
    {
      DriveReset(drive);
      count--;
    }
  }
  while ((err) && (count > 0));
  return(err);
}

