/* -*-C-*-
********************************************************************************
*
* File:         frmtdsk.c
* RCS:          $Header: frmtdsk.c,v 1.1 93/03/19 14:24:40 mjp Exp $
* Description:  Format an Emax disc
* Author:       Mike Prudence, (mjp@hplb.hpl.hp.com)
* Created:      Wed Mar 17 14:39:47 1993
* Modified:     Sat Mar 20 13:47:22 1993 (Mike Prudence) mjp@prudence
* Language:     C
*
* (c) Copyright 1993, Mike Prudence.
*
********************************************************************************
*/

#include <dos.h>
#include "emaxio.h"
#include "rwdisk.h"
#include "frmtdsk.h"

DriveParamTable dpt;

void SetFormatTable (FormatTable ft, int head, int track)
{
  int i, s;
  char used[SCTR_TRK];

  for (i=0; i<SCTR_TRK; i++)
  {
    used[i] = 0;
    ft[i].track = track;
    ft[i].head = head;
    ft[i].sizecode = SIZE_CODE;
  }

  s = 0;
  for (i=0; i<SCTR_TRK; i++)
  {
    while (used[s]) s = (++s) % SCTR_TRK;
    ft[s].sector = i+START_SCTR;
    used[s] = 1;
    s = (s + INTERLEAVE) % SCTR_TRK;
  }
}

void far *GetVector(int num)
{
  FAR_PTR fptr;
  unsigned int far *p;

  p=(unsigned int far *)(4*num);

  fptr.word[0] = *p;
  fptr.word[1] = *(p+1);
  return(fptr.fp);
}

void SetVector(int num, void far *v)
{
  FAR_PTR fptr;
  unsigned int far *p;

  fptr.fp = v;
  p=(unsigned int far *)(4*num);

  *p = fptr.word[0];
  *(p+1) = fptr.word[1];
}

int FormatTrack (int drive, int head, int track)
{
  FormatTable ft;
  int result;
  DriveParamTable far *old_dpt;
  struct diskinfo_t disk_info;

  /* Set up disk info table */

  disk_info.drive=drive;
  disk_info.head=head;
  disk_info.track=track;
  disk_info.sector=START_SCTR;
  disk_info.nsectors=SCTR_TRK;
  disk_info.buffer=ft;

  /* Copy DPT and set sectors per track to 10 */

  old_dpt = GetVector(0x1E);
  dpt = *old_dpt;

  dpt.sectors_track = SCTR_TRK;
  dpt.gap_length = GAP_LENGTH;
  SetVector(0x1E,(void far*) &dpt);

  /* Set format table for track */

  SetFormatTable(ft,head,track);

  /* Format that disc */

  result = 0;

  result = (_bios_disk(_DISK_FORMAT, &disk_info))>>8;

  /* Restore old DPT */

  SetVector(0x1E,old_dpt);

  return(result);
}

int FormatDisk (int drive)
{
  int hd, trk, count, result;
  char s[80];

  cursor_off();

  sprintf(s, "Formatting Emax disk in drive %c",drive+'A');
  write_text (26, 15, 6, s);

  SetupDrive (drive);

  for (trk=0; trk<TRK_CYL; trk++)
  {
    if (kbhit()) break;

    for (hd=0; hd<HEADS; hd++)
    {
      if (kbhit()) break;

#ifdef DEBUG
      sprintf (s,  "Formatting Track %2d Head %2d        ",trk,hd);
#else
      sprintf (s, "%02d%% Complete                           ", 
           ((unsigned long)((trk*2+hd)*100)/((unsigned long)(HEADS*TRK_CYL))));
#endif
      write_text(26, 15, 6, s);

      if (result = FormatTrack(drive,hd,trk))
      {
        write_error(emax_io_error(result));
        cursor_on();
        return(result);
      }
    }
  }

  if (!kbhit())
    {
      write_text (26,13,6,"Writing Operating System EMAXOS.EMX");

      WriteOS (DEFAULT_OS_FILE, drive);
    }

  if (kbhit())
  {
    write_text(26, 15, 6, "        Aborted by keypress!                ");
    getch();
  } else {
    printf(26, 15, 6, "                 Done!                         ");
  }

  cursor_on();
  return 0;
}
