⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diskfile.c

📁 Due to an increase in demand for and questions about direct disk access for Micrososft platforms, a
💻 C
字号:
/* DISKFILE.C - file to disk / disk to file using DISKLIB

   An "industry standard" floppy image writer/reader. Image format
   is track 0, side 0; track 0, side 1; track 1, side 0; etc.

   version 2.0    05-Nov-1998    uses DISKLIB
   version 1.1    27-Feb-1998    better error handling

   BUGS:    In the functions trackread() and trackwrite(), there is
            a bug: if the attempt to read/write an entire track fails,
            and the track is handled by sectors, the program will crash
            with DJGPP, and Watcom and Microsoft if the latter two are
            compiled in the small model. Ideas anyone?

*/

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <io.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>
#include <setjmp.h>

#include <bios.h>                /* _DISK.... */
#include <dos.h>                 /* REGS */
#include <conio.h>               /* getch() */

#include "dosio.h"
#include "disklib.h"

#ifdef __WATCOMC__
#define _open  open
#define _read  read
#define _write write
#define _close close
#endif

int file2disk(int fd, int disk, int tracks, int heads, int sectors,
              size_t bufsz, char *buffer);
int disk2file(int fd, int disk, int tracks, int heads, int sectors,
              size_t bufsz, char *buffer);
int trackread(int disk, int track, int head, int nsectors, char *buffer);
int trackwrite(int disk, int track, int head, int nsectors, char *buffer);
void die(const char *msg, const char *fmt, int arg);
void ctrlc(int sig);
void outchar(int c);  /* INT 10h output with translations/cursor move */
void charout(int c);  /* INT 10h output no traslations/no cursor move */


jmp_buf Jmpbuf;                     /* abort place holder */
int Keep;                           /* keep going on bad sectors */


int main(int argc, char **argv)
{
int fd,i;
int disk,file;
char *buffer;
size_t bufsz;
int tracks,sectors,heads;

   if (argc < 3)
   {
      printf("\nusage: diskfile <file> <drive>\n");
      printf("       diskfile <drive> <file>\n");
      printf("\nwrite file to floppy, or write floppy to file\n");
      return 1;
   }

   if (argv[1][1] == ':' && argv[1][2] == '\0')          /* 1st is drive */
   {
      disk = toupper(argv[1][0]) - 'A';
      file = 2;
   }
   else if (argv[2][1] == ':' && argv[2][2] == '\0')     /* 2nd is drive */
   {
      disk = toupper(argv[2][0]) - 'A';
      file = 1;
   }
   else
   {
      printf("\ndrive specification not found (%s, %s)\n",argv[1],argv[2]);
      return 1;
   }

   if (disk < 0 || disk > 1)    /* floppies only */
   {
      printf("\ndrive specification not valid (%c:)\n",disk+'A');
      return 1;
   }

   if ((i = disk_get_physical(disk,&tracks,&sectors,&heads)) != DISK_OK)
      die("BIOS error: ",disk_error(i),0);

   if ((buffer = malloc(bufsz = sectors * 512)) == NULL)
      die("not enough memory found!"," (%u)",bufsz);

   printf("\nreseting controller... ");
   disk_reset(disk);

   printf("homing disk...");
   if ((i = disk_read_p(disk,0,1,0,buffer,1)) != DISK_OK)
      die("BIOS error: ",disk_error(i),0);

   if (file == 1) {
      printf("\rwriting \"%s\"",argv[file]);
      printf(" to %c: (%u tracks and %u sides)",disk+'A',tracks+1,heads+1);
   }
   else {
      printf("\rreading %c: (%u tracks and %u sides)",disk+'A',tracks+1,heads+1);
      printf(" to \"%s\"",argv[file]);
   }

   printf("; continue? [y/n/^C] ");
   while ((i = getch()) && i != 'y' && i != 'n')
       ;
   if (i == 'n')
      return 1;

   if (file == 2)                                     /* writing file */
   {
      if ((fd = _open(argv[file],_O_RDONLY)) != -1)
      {
         _close(fd);
         printf("\nfile %s exists; overwrite? [y/n/^C] ",argv[file]);
         while ((i = getch()) && i != 'y' && i != 'n')
             ;
         if (i == 'n')
            return 1;
         putchar('\r');
      }
      fd = _open(argv[file],O_CREAT|O_RDWR|O_BINARY|O_TRUNC,S_IREAD|S_IWRITE);
   }
   else
   {
      fd = _open(argv[file],O_RDWR|O_BINARY);
   }

   if (fd == -1)
      die("file error: ",strerror(errno),errno);

   Keep = 1;

   errno = 0;

   signal(SIGINT, ctrlc);

   /* on ^C we get back here with setjmp() returning non-zero */

   if (setjmp(Jmpbuf) == 0)
   {
      /* draw a line */

      for (i = 0; i <= tracks; i++)
      {
         if (i < 79)
            outchar('.');
         else
            charout('.');   /* (last char shouldn't move cursor) */
      }
      outchar('\r');

      /* now that everything is verified and prepared, this is the meat */

      if (file == 1)
         file2disk(fd,disk,tracks,heads,sectors,bufsz,buffer);
      else
         disk2file(fd,disk,tracks,heads,sectors,bufsz,buffer);

      printf("\nDone.");

      /* that's not hard is it... */
   }

   _close(fd);

   if ((i = disk_status(disk)) != 0)
      die("BIOS error: ",disk_error(i),0);

   if (errno)
      die("file error: ",strerror(errno),errno);

   printf("\nreseting controller... ");
   disk_reset(disk);
   printf(" homing disk...\n");
   disk_read_p(disk,0,1,0,buffer,1);

   return 0;

}

int file2disk(int fd, int disk, int tracks, int heads, int sectors,
              size_t bufsz, char *buffer)
{
int i,j;

   for (i = 0; i <= tracks; i++)
   {
      charout('r');
      if (_read(fd,buffer,bufsz) <= 0)
         break;

      charout('0');
      if ((j = trackwrite(disk,i,0,sectors,buffer)) != DISK_OK)
         break;

      if (heads)
      {
         charout('r');
         if (_read(fd,buffer,bufsz) <= 0)
            break;

         charout('1');
         if ((j = trackwrite(disk,i,1,sectors,buffer)) != DISK_OK)
            break;
      }
      if (j == -1)
         outchar('o');
   }
   return 0;
}

int disk2file(int fd, int disk, int tracks, int heads, int sectors,
              size_t bufsz, char *buffer)
{
int i,j;

   for (i = 0; i <= tracks; i++)
   {
      charout('0');
      if ((j = trackread(disk,i,0,sectors,buffer)) != DISK_OK)
         break;

      charout('w');
      if (_write(fd,buffer,bufsz) == -1)
         break;

      if (heads)
      {
         charout('1');
         if ((j = trackread(disk,i,1,sectors,buffer)) != DISK_OK)
            break;

         charout('w');
         if (_write(fd,buffer,bufsz) == -1)
            break;
      }
      if (j == -1)
         outchar('o');
   }
   return 0;
}

int trackread(int disk, int track, int head, int nsectors, char *buffer)
{
int i,j;

   if ((i = disk_read_p(disk,track,1,head,buffer,nsectors)) != DISK_OK)
   {
      char *b = buffer;
      charout('x');
      for (j = 1; j <= nsectors; j++)
      {
         if ((i = disk_read_p(disk,track,j,head,b,1)) != DISK_OK && !Keep)
            break;
         b += (j * 512);
      }
   }
   return i;
}

int trackwrite(int disk, int track, int head, int nsectors, char *buffer)
{
int i,j;

   if ((i = disk_write_p(disk,track,1,head,buffer,nsectors)) != DISK_OK)
   {
      char *b = buffer;
      charout('x');
      for (j = 1; j <= nsectors; j++)
      {
         if ((i = disk_write_p(disk,track,j,head,b,1)) != DISK_OK && !Keep)
            break;
         b += (j * 512);
      }
   }
   return i;
}

void die(const char *msg, const char *fmt, int arg)
{
   printf("\n%s",msg);
   if (fmt)
      printf(fmt,arg);
   printf("\n");
   exit(1);
}

void ctrlc(int sig)
{
   signal(SIGINT, SIG_IGN);
   puts("\nStop.");
   longjmp(Jmpbuf, 1);
}

void outchar(int c)
{
union REGS r;

    r.x.ax = 0x0E00 + c;
    r.h.bh = 0;
    int86(0x10,&r,&r);
}

void charout(int c)
{
union REGS r;

    r.x.ax = 0x0A00 + c;
    r.h.bh = 0;
    r.x.cx = 1;
    int86(0x10,&r,&r);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -