📄 diskfile.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,§ors,&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 + -