mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
Upload
Digital Research
This commit is contained in:
675
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/plmutils/copy.c
Normal file
675
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/plmutils/copy.c
Normal file
@@ -0,0 +1,675 @@
|
||||
/*----------------------------------------------------------------------*\
|
||||
| |
|
||||
| DISK COPY PROGRAM |
|
||||
| ================= |
|
||||
| |
|
||||
| Created: November 4,1982 |
|
||||
| ------- |
|
||||
| |
|
||||
| Last Modified: January 15,1982 |
|
||||
| ------------- |
|
||||
| |
|
||||
| Description: |
|
||||
| ----------- This program will copy all or portions of |
|
||||
| one disk to another compatible disk. |
|
||||
| |
|
||||
| Needed Files: |
|
||||
| ------------ <STDIO.H>,<PORTAB.H> |
|
||||
| |
|
||||
| Must be linked to the 'C' runtime library. |
|
||||
| ------------------------------------------ |
|
||||
| |
|
||||
| (c) COPYRIGHT DIGITAL RESEARCH 1983 |
|
||||
| ALL RIGHTS RESERVED |
|
||||
| |
|
||||
\*----------------------------------------------------------------------*/
|
||||
|
||||
char *copyrt="CP/M-68K(tm), Version 1.1, Copyright 1983, Digital Research";
|
||||
char *serial="XXXX-0000-654321";
|
||||
|
||||
/************************************************************************\
|
||||
* Here are the Include Files *
|
||||
\************************************************************************/
|
||||
/********************************/
|
||||
#include <stdio.h> /* Standard I/O library */
|
||||
/********************************/
|
||||
/************************************************************************\
|
||||
* DEFINES for Copy.c *
|
||||
\************************************************************************/
|
||||
/********************************/
|
||||
#define ON 1 /* Option is valid for this copy*/
|
||||
#define OFF 0 /* Option is not valid */
|
||||
#define BAD 0 /* Illegal mode flag */
|
||||
#define MATCH 0 /* used by strcmp */
|
||||
#define SDRIVE 1 /* source drive */
|
||||
#define DDRIVE 2 /* destination drive */
|
||||
#define _ALL 0 /* copy whole disk */
|
||||
#define _BOOT 1 /* copy boot tracks */
|
||||
#define _FILES 2 /* copy non-boot tracks */
|
||||
#define _END 3 /* end this program */
|
||||
#define RDERR 0 /* read error flag */
|
||||
#define WRERR 1 /* write error flag */
|
||||
#define NULLB '\0' /* NULL byte */
|
||||
#define isupper(c) ('A' <= (c) && (c) <= 'Z')/*upper case */
|
||||
#define islower(c) ('a' <= (c) && (c) <= 'z')/*lower case */
|
||||
#define tolower(c) (isupper(c) ? ((c)+040):(c))/* */
|
||||
#define toupper(c) (islower(c) ? ((c)-040):(c))/* */
|
||||
/********************************/
|
||||
/************************************************************************\
|
||||
* GLOBAL definitions *
|
||||
\************************************************************************/
|
||||
/********************************/
|
||||
GLOBAL BYTE *choice[] = /* Copy Modes available */
|
||||
{"all","boot","files","end"}; /* ---------------------- */
|
||||
/********************************/
|
||||
GLOBAL BYTE mode; /* Hold the current copy mode */
|
||||
/********************************/
|
||||
/* ------- OPTIONS ------- */
|
||||
GLOBAL BYTE verbose = ON; /* Prompt the user if ON */
|
||||
GLOBAL BYTE verify = OFF; /* Check newly written track */
|
||||
/* againist source track. */
|
||||
/********************************/
|
||||
/* Prompts........... */
|
||||
GLOBAL BYTE *msg1 = "Enter SOURCE drive: "; /* SDRIVE */
|
||||
GLOBAL BYTE *msg2 = "Enter DESTINATION drive: "; /* DDRIVE */
|
||||
GLOBAL BYTE *msg3 = "READ error ----> "; /* Read error */
|
||||
GLOBAL BYTE *msg4 = "WRITE error ----> "; /* Write error */
|
||||
/********************************/
|
||||
/********************************/
|
||||
GLOBAL BYTE *bracket = "["; /* Marks beginning of option */
|
||||
/* indicators on the cmd line */
|
||||
/********************************/
|
||||
GLOBAL struct _dpb /* Define disk parm block */
|
||||
{ /*------------------------------*/
|
||||
WORD spt; /* Logical sectors per track */
|
||||
BYTE bsh; /* Allocation block shift factor*/
|
||||
BYTE blm; /* Block mask */
|
||||
BYTE exm; /* Extent mask */
|
||||
BYTE dpbjunk; /* Alignment byte */
|
||||
WORD dsm; /* Total storage of the disk */
|
||||
WORD drm; /* Total directory entries */
|
||||
BYTE al0; /* Flag reserved for dir blocks */
|
||||
BYTE al1; /* Flag reserved for dir blocks */
|
||||
WORD cks; /* Directory check vector size */
|
||||
WORD off; /* The number of reserved tracks*/
|
||||
}; /* */
|
||||
/********************************/
|
||||
GLOBAL struct _dph /* Define disk parm header */
|
||||
{ /*------------------------------*/
|
||||
BYTE *xltp; /* Pointer to sector trans table*/
|
||||
WORD dphscr[3]; /* Scratchpad values for BDOS */
|
||||
BYTE *dirbufp; /* Pointer to dir scratchpad */
|
||||
struct _dpb *dpbp; /* Pointer to disk parm block */
|
||||
BYTE *csvp; /* Pointer to scratchpad area */
|
||||
BYTE *alvp; /* Pointer to scratchpad area */
|
||||
}; /********************************/
|
||||
EXTERN LONG __BDOS(); /* BDOS Caller in CLIB */
|
||||
#define bdos(a,b) (struct _dph*)__BDOS(a,b) /* Declare a bogus function */
|
||||
/********************************/
|
||||
GLOBAL struct _biospb /* Bios Pararmeter Block */
|
||||
{ /*------------------------------*/
|
||||
UWORD funcnum; /* Bios function number */
|
||||
LONG parm1; /* Bios parameter 1 */
|
||||
LONG parm2; /* Bios parameter 2 */
|
||||
}; /* */
|
||||
GLOBAL struct _biospb biospb; /* Define it */
|
||||
/********************************/
|
||||
GLOBAL BYTE trkbuf[128*26*6]; /* buffer big enough to hold 6 */
|
||||
/* tracks of bytes */
|
||||
GLOBAL BYTE verbuf[128*26*6]; /* buffer for verification opt */
|
||||
/********************************/
|
||||
/************************************************************************\
|
||||
* FUNCTION definitions *
|
||||
\************************************************************************/
|
||||
/********************************/
|
||||
UWORD illegal(); /* Decides if the mode is a */
|
||||
/* legal one. */
|
||||
/*------------------------------*/
|
||||
VOID get_mode(); /* If the mode was not there */
|
||||
/* or an illegal one,get_mode */
|
||||
/* will print a menu and keep */
|
||||
/* prompting the user for a */
|
||||
/* legal mode. */
|
||||
/*------------------------------*/
|
||||
BYTE get_drive(); /* Reads in a drive character */
|
||||
/* from the console. If the */
|
||||
/* drive is in the range(A-P), */
|
||||
/* the drive is returned. If */
|
||||
/* not,the value BAD is returned*/
|
||||
/*------------------------------*/
|
||||
VOID wait_for(); /* Holds the copy program in a */
|
||||
/* wait state so the user can */
|
||||
/* make sure his or her disk is */
|
||||
/* in the proper drive. */
|
||||
/*------------------------------*/
|
||||
BYTE scan(); /* Picks off the source and */
|
||||
/* destination drives from the */
|
||||
/* command line. If they do */
|
||||
/* not exist,or the specified */
|
||||
/* drives are illegal,scan */
|
||||
/* prompts the user. */
|
||||
/*------------------------------*/
|
||||
VOID get_options(); /* Scans the command line until */
|
||||
/* a '[' is found. A list of */
|
||||
/* of options is checked. Flags */
|
||||
/* are turned on by the option */
|
||||
/* indicators found after the */
|
||||
/* square bracket. */
|
||||
/*------------------------------*/
|
||||
VOID copy(); /* If the two disk parameter */
|
||||
/* blocks are identical,a track */
|
||||
/* for track copy is made. */
|
||||
/* If an serious error occurs, */
|
||||
/* the copy is aborted and the */
|
||||
/* program ends. */
|
||||
/********************************/
|
||||
VOID read_wr(); /* This routine does the actual */
|
||||
/* reading and writing of the */
|
||||
/* compatible disks. */
|
||||
/********************************/
|
||||
/************************************************************************/
|
||||
|
||||
/************************************************************************\
|
||||
* *
|
||||
* BEGIN MAIN PROGRAM *
|
||||
* *
|
||||
\************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
main(argc,argv)
|
||||
WORD argc;
|
||||
BYTE *argv[];
|
||||
{
|
||||
BYTE answer,source,dest,optfound;
|
||||
|
||||
optfound = FALSE;
|
||||
printf("Copy Ver 1.1\n"); /* Copy version message */
|
||||
/*------------------------------*\
|
||||
| If there is an mode on |
|
||||
| on the command line or the |
|
||||
| command line mode is not |
|
||||
| recognized,print a menu |
|
||||
| and have the user input a |
|
||||
| a legal copy mode. |
|
||||
\*------------------------------*/
|
||||
argc--; argv++; /* point to first arg after cmd */
|
||||
if(illegal(*argv))
|
||||
get_mode();
|
||||
else /* point to 2nd arg past cmd */
|
||||
{
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
if(mode == _END)
|
||||
cpyexit();
|
||||
/*------------------------------*\
|
||||
| Look for the '[' as the |
|
||||
| start of the options. |
|
||||
| This allows the following |
|
||||
| |
|
||||
| copy <mode> [options |
|
||||
| ==================== |
|
||||
| or |
|
||||
| copy [options |
|
||||
| ============= |
|
||||
| |
|
||||
| I will not allow the drives|
|
||||
| to be specified after the |
|
||||
| options though!!!!! |
|
||||
\*------------------------------*/
|
||||
if(strncmp(bracket,*argv,1) == MATCH)
|
||||
{
|
||||
argc = 0;
|
||||
get_options(*argv++);
|
||||
source = scan(argc,*argv++,SDRIVE);
|
||||
dest = scan(argc,*argv,DDRIVE);
|
||||
}
|
||||
else
|
||||
/*------------------------------*\
|
||||
| Otherwise I assume that the |
|
||||
| command line looks like |
|
||||
| this: |
|
||||
| |
|
||||
| copy <mode> <sd> <dd> [opt |
|
||||
| ========================== |
|
||||
\*------------------------------*/
|
||||
{
|
||||
source = scan(argc--,*argv++,SDRIVE);
|
||||
dest = scan(argc--,*argv,DDRIVE);
|
||||
if(strncmp(bracket,*argv,1) == MATCH)
|
||||
{
|
||||
optfound = TRUE;
|
||||
get_options(*argv);
|
||||
}
|
||||
while(argc-- > 0)
|
||||
/* scan cmd line to find a '[' */
|
||||
if(strncmp(bracket,*++argv,1) == MATCH &&
|
||||
(!optfound))
|
||||
{
|
||||
get_options(*argv);
|
||||
break;
|
||||
}
|
||||
else
|
||||
printf("\nExtraneous argument ignored: %s",*argv);
|
||||
}
|
||||
if(source == dest)
|
||||
{
|
||||
printf("\nSource and Destination must be different");
|
||||
cpyexit();
|
||||
}
|
||||
/*------------------------------*\
|
||||
| REPEAT the copy as many |
|
||||
| times as the user wishes |
|
||||
\*------------------------------*/
|
||||
while(TRUE)
|
||||
{
|
||||
if(verbose)
|
||||
wait_for(source,dest);
|
||||
copy((toupper(source) - 'A'),(toupper(dest) - 'A'));
|
||||
printf("\nCopy complete");
|
||||
if(verbose)
|
||||
printf("\nDo you wish to repeat the copy? ");
|
||||
else
|
||||
break;
|
||||
answer = __BDOS(1,(long)0);
|
||||
if(toupper(answer) != 'Y')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/************************/
|
||||
UWORD illegal(_mode) /* Check command line */
|
||||
/* aganist mode table */
|
||||
/* Return mode code if */
|
||||
/* found,return false */
|
||||
/* if the mode is not */
|
||||
/* found in the table */
|
||||
/************************/
|
||||
BYTE *_mode;
|
||||
{
|
||||
REG UWORD i;
|
||||
|
||||
for(i = 0;i <= 3;i++)
|
||||
if(strcmp(_mode,choice[i]) == MATCH)
|
||||
{
|
||||
mode = i;
|
||||
return(FALSE);
|
||||
}
|
||||
mode = -1;
|
||||
return(TRUE);
|
||||
}
|
||||
/************************/
|
||||
VOID get_mode() /* Prompt the user for */
|
||||
/* a legal mode. Keep */
|
||||
/* prompting until you */
|
||||
/* get one. */
|
||||
/************************/
|
||||
{
|
||||
REG UWORD i;
|
||||
BYTE buf[256];
|
||||
|
||||
printf("\nMODE\tFUNCTION\n");
|
||||
printf("\nALL\tCopy the whole disk");
|
||||
printf("\nBOOT\tCopy the boot tracks");
|
||||
printf("\nFILES\tCopy the non-boot tracks");
|
||||
printf("\nEND\tEnd this program\n");
|
||||
do
|
||||
{
|
||||
printf("\nEnter your copy mode: ");
|
||||
gets(buf);
|
||||
for(i = 0;buf[i] != NULLB;i++)
|
||||
buf[i] = tolower(buf[i]);
|
||||
}
|
||||
while(illegal(buf));
|
||||
}
|
||||
|
||||
/************************/
|
||||
BYTE get_drive() /* Read in a drive. */
|
||||
/************************/
|
||||
{
|
||||
BYTE drive[10];
|
||||
|
||||
gets(drive);
|
||||
if(strlen(drive) > 1)
|
||||
return(BAD);
|
||||
drive[0] = toupper(drive[0]);
|
||||
if(drive[0] < 'A' || drive[0] > 'P')
|
||||
return(BAD);
|
||||
else
|
||||
return(drive[0]);
|
||||
}
|
||||
/************************/
|
||||
VOID wait_for(source,dest) /* Wait for the user */
|
||||
/* to put the disks */
|
||||
/* in the proper drives*/
|
||||
/************************/
|
||||
BYTE source;
|
||||
BYTE dest;
|
||||
{
|
||||
BYTE wait_buf[5];
|
||||
BYTE *upchoice[3];
|
||||
|
||||
upchoice[0] = "ALL";
|
||||
upchoice[1] = "BOOT";
|
||||
upchoice[2] = "FILES";
|
||||
|
||||
wait_buf[0] = 3;
|
||||
do
|
||||
{
|
||||
printf("\n(^C to ABORT)");
|
||||
printf("\nRETURN to copy %s",upchoice[mode]);
|
||||
printf(" from %c to %c",source,dest);
|
||||
__BDOS(10,&wait_buf[0]);
|
||||
}
|
||||
while(wait_buf[1] != 0);
|
||||
}
|
||||
|
||||
/************************/
|
||||
BYTE scan(argc,argv,which_drive) /* Scan the command */
|
||||
/* for the drives. */
|
||||
/* If I can't find them*/
|
||||
/* or they are illegal */
|
||||
/* keep prompting the */
|
||||
/* user for them. */
|
||||
/************************/
|
||||
WORD argc;
|
||||
BYTE *argv;
|
||||
UWORD which_drive;
|
||||
{
|
||||
BYTE *prompt,drive;
|
||||
|
||||
if(argc > 0 && strlen(argv) == 1)
|
||||
{
|
||||
sscanf(argv,"%c",&drive);
|
||||
drive = toupper(drive);
|
||||
if(drive >= 'A' && drive <= 'P')
|
||||
return(drive);
|
||||
}
|
||||
switch(which_drive)
|
||||
{
|
||||
case SDRIVE : prompt = &msg1[0];
|
||||
break;
|
||||
case DDRIVE : prompt = &msg2[0];
|
||||
}
|
||||
printf("\n");
|
||||
do
|
||||
{
|
||||
printf("%s",prompt);
|
||||
}
|
||||
while((drive = get_drive()) == BAD);
|
||||
|
||||
return(drive);
|
||||
}
|
||||
/************************/
|
||||
VOID get_options(argv) /* Scan cmd line for */
|
||||
/* supported options */
|
||||
/************************/
|
||||
BYTE *argv;
|
||||
{
|
||||
argv++; /* skip the square bracket */
|
||||
while(*argv != NULLB)
|
||||
{
|
||||
switch(*argv)
|
||||
{
|
||||
case 'A' :
|
||||
case 'a' :
|
||||
verbose = OFF;
|
||||
break;
|
||||
case 'v' :
|
||||
case 'V' : verify = ON;
|
||||
break;
|
||||
case ']' : return(0);
|
||||
default : printf("\nUndefined option: %c",*argv);
|
||||
}
|
||||
argv++;
|
||||
}
|
||||
|
||||
}
|
||||
/************************/
|
||||
VOID copy(source,dest) /* Select the disks. */
|
||||
/* If I can't select or*/
|
||||
/* the disk have diff- */
|
||||
/* erent parameter blks*/
|
||||
/* then print error msg*/
|
||||
/************************/
|
||||
BYTE source;
|
||||
BYTE dest;
|
||||
{
|
||||
REG struct _dpb *dskpblk;
|
||||
REG struct _dph *h1,*h2;
|
||||
REG LONG *ptr1,*ptr2;
|
||||
REG LONG endtrk,begtrk;
|
||||
LONG numtrks,temp;
|
||||
BYTE *sectran;
|
||||
REG UWORD i;
|
||||
|
||||
|
||||
biospb.funcnum = 9; /* Select the disks */
|
||||
biospb.parm1 = (long)source; /* first the source disk */
|
||||
biospb.parm2 = (long)0; /* set least sig bit to 0 */
|
||||
|
||||
if((h1 = bdos(50,&biospb))!= NULL)
|
||||
{
|
||||
biospb.parm1 = (long)dest;
|
||||
if((h2 = bdos(50,&biospb))!= NULL)
|
||||
{ /*----------------------------------------------*/
|
||||
/* check the parameter blocks(must be identical)*/
|
||||
/*----------------------------------------------*/
|
||||
dskpblk = (*h1).dpbp; /* pointer to dpb */
|
||||
sectran = (*h1).xltp; /* pointer to sect tran tb*/
|
||||
h1 = (*h1).dpbp; /* h1 points to dpb */
|
||||
ptr1 = (long)h1; /* compare long words */
|
||||
h2 = (*h2).dpbp; /* h2 points to dpb */
|
||||
ptr2 = (long)h2; /* compare long words */
|
||||
for(i = 0;i <= 3;i++)
|
||||
{
|
||||
if(*ptr1 != *ptr2)
|
||||
{
|
||||
printf("\nIncompatible disks");
|
||||
cpyexit();
|
||||
}
|
||||
ptr1++;
|
||||
ptr2++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\nDisk select error on Destination");
|
||||
cpyexit();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\nDisk select error on Source");
|
||||
cpyexit();
|
||||
}
|
||||
/*------------------------------------------------------*\
|
||||
| |
|
||||
| Compute beginning and ending track |
|
||||
| |
|
||||
\*------------------------------------------------------*/
|
||||
|
||||
temp = (((*dskpblk).dsm + 1)*((*dskpblk).blm + 1));
|
||||
numtrks = temp/(*dskpblk).spt;
|
||||
if((numtrks*(*dskpblk).spt) < temp)
|
||||
numtrks++;
|
||||
numtrks += (*dskpblk).off;
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case _ALL : begtrk = 0;
|
||||
endtrk = numtrks - 1;
|
||||
break;
|
||||
case _BOOT: begtrk = 0;
|
||||
endtrk = (*dskpblk).off - 1;
|
||||
break;
|
||||
case _FILES: begtrk = (*dskpblk).off;
|
||||
endtrk = numtrks - 1;
|
||||
}
|
||||
read_wr(source,dest,begtrk,endtrk,sectran,dskpblk);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* Do the actual read write operations */
|
||||
/* =================================== */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
VOID read_wr(source,dest,begtrk,endtrk,sectran,dskpblk)
|
||||
/********************************/
|
||||
BYTE source; /* source disk */
|
||||
BYTE dest; /* destination disk */
|
||||
REG LONG begtrk; /* beginning track to copy */
|
||||
REG LONG endtrk; /* ending track to copy */
|
||||
REG BYTE *sectran; /* sector translate table */
|
||||
struct _dpb *dskpblk; /* ptr to disk parameter block */
|
||||
/********************************/
|
||||
{
|
||||
REG BYTE *dma;
|
||||
REG UWORD i,k;
|
||||
|
||||
printf("\n***Copying Tracks***\n");
|
||||
for(i = begtrk;i <= endtrk;i++)
|
||||
{
|
||||
dma = &trkbuf;
|
||||
biospb.funcnum = 12; /* set the dma address */
|
||||
biospb.parm1 = dma; /* set it to beginning of trkbuf*/
|
||||
biospb.parm2 = 0;
|
||||
__BDOS(50,&biospb); /* call the bios via the bdos */
|
||||
biospb.funcnum = 9; /* select the source diskette */
|
||||
biospb.parm1 = (long)source;
|
||||
biospb.parm2 = (long)0xFFFFFFFF;
|
||||
__BDOS(50,&biospb); /* call the bios via the bdos */
|
||||
biospb.funcnum = 10; /* set the track */
|
||||
biospb.parm1 = (long)(i);
|
||||
biospb.parm2 = 0;
|
||||
__BDOS(50,&biospb); /* call bios via bdos */
|
||||
/*----------------------------------------------*\
|
||||
| Read a track's worth of sectors |
|
||||
\*----------------------------------------------*/
|
||||
for(k = 0;k < (*dskpblk).spt;k++)
|
||||
{
|
||||
biospb.funcnum = 16; /* translate sector*/
|
||||
biospb.parm1 = (long)k; /* logical sect */
|
||||
biospb.parm2 = sectran;
|
||||
biospb.parm1 = __BDOS(50,&biospb);
|
||||
biospb.funcnum = 11; /* set physical sec*/
|
||||
biospb.parm2 = 0;
|
||||
__BDOS(50,&biospb); /* call the bios */
|
||||
/*--------------------------------------*\
|
||||
| READ a sector |
|
||||
\*--------------------------------------*/
|
||||
biospb.funcnum = 13;
|
||||
if(__BDOS(50,&biospb) != 0)
|
||||
error(i,k,RDERR);
|
||||
dma += 128;
|
||||
biospb.funcnum = 12;
|
||||
biospb.parm1 = dma;
|
||||
__BDOS(50,&biospb);
|
||||
}
|
||||
dma = &trkbuf;
|
||||
biospb.funcnum = 12; /* reset the dma addr to trkbuf */
|
||||
biospb.parm1 = dma;
|
||||
biospb.parm2 = 0;
|
||||
__BDOS(50,&biospb); /* call the bios */
|
||||
biospb.funcnum = 9; /* select the destination disk */
|
||||
biospb.parm1 = (long)dest;
|
||||
biospb.parm2 = (long)0xFFFFFFFF;
|
||||
__BDOS(50,&biospb); /* call the bios */
|
||||
/*----------------------------------------------*\
|
||||
| Write out a Track's worth of Sectors |
|
||||
\*----------------------------------------------*/
|
||||
for(k = 0;k < (*dskpblk).spt;k++)
|
||||
{
|
||||
biospb.funcnum = 16;
|
||||
biospb.parm1 = (long)k;
|
||||
biospb.parm2 = sectran;
|
||||
biospb.parm1 = __BDOS(50,&biospb);
|
||||
biospb.funcnum = 11;
|
||||
biospb.parm2 = 0;
|
||||
__BDOS(50,&biospb);
|
||||
/*--------------------------------------*\
|
||||
| Write a Sector |
|
||||
\*--------------------------------------*/
|
||||
biospb.funcnum = 14;
|
||||
biospb.parm1 = (long)2;
|
||||
if(__BDOS(50,&biospb) != 0)
|
||||
error(i,k,WRERR);
|
||||
dma += 128;
|
||||
biospb.funcnum = 12;
|
||||
biospb.parm1 = dma;
|
||||
__BDOS(50,&biospb);
|
||||
}
|
||||
if(verify)
|
||||
{
|
||||
dma = &verbuf;
|
||||
biospb.funcnum = 12;
|
||||
biospb.parm1 = dma;
|
||||
__BDOS(50,&biospb); /* reset dma addr */
|
||||
for(k = 0;k < (*dskpblk).spt;k++)
|
||||
{
|
||||
biospb.funcnum = 16;
|
||||
biospb.parm1 = (long)k;
|
||||
biospb.parm2 = sectran;
|
||||
biospb.parm1 = __BDOS(50,&biospb);
|
||||
biospb.funcnum = 11;
|
||||
biospb.parm2 = 0;
|
||||
__BDOS(50,&biospb);
|
||||
/*------------------------------*\
|
||||
| Read a sector |
|
||||
\*------------------------------*/
|
||||
biospb.funcnum = 13;
|
||||
if(__BDOS(50,&biospb) != 0)
|
||||
error(i,k,RDERR);
|
||||
dma += 128;
|
||||
biospb.funcnum = 12;
|
||||
biospb.parm1 = dma;
|
||||
__BDOS(50,&biospb);
|
||||
}
|
||||
/*--------------------------------------*\
|
||||
| Verify the TRACK write |
|
||||
\*--------------------------------------*/
|
||||
for(k = 0;k < (((*dskpblk).spt)*128);k++)
|
||||
if(trkbuf[k] != verbuf[k])
|
||||
error(i,(k/128),WRERR);
|
||||
}
|
||||
printf("\r %d",i);
|
||||
}
|
||||
}
|
||||
|
||||
/************************/
|
||||
error(track,sector,phase) /* Read/Write Error */
|
||||
/* handler */
|
||||
/************************/
|
||||
UWORD track;
|
||||
UWORD sector;
|
||||
BYTE phase;
|
||||
{
|
||||
REG BYTE *addr;
|
||||
|
||||
if(phase == RDERR)
|
||||
addr = &msg3[0];
|
||||
else
|
||||
addr = &msg4[0];
|
||||
printf("\n\n\n%s",addr);
|
||||
printf("Track: %d Sector: %d",track,sector);
|
||||
cpyexit();
|
||||
}
|
||||
|
||||
cpyexit() /* bios select what the bdos thinks is the default disk */
|
||||
{
|
||||
biospb.funcnum = 9;
|
||||
biospb.parm1 = __BDOS(25,(long)0);
|
||||
biospb.parm2 = 0;
|
||||
bdos(50,&biospb);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user