mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 17:04:19 +00:00
Upload
Digital Research
This commit is contained in:
675
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/xutils/copy.c
Normal file
675
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/xutils/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);
|
||||
}
|
||||
|
||||
|
||||
158
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/xutils/format.s
Normal file
158
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/xutils/format.s
Normal file
@@ -0,0 +1,158 @@
|
||||
*********************************************************
|
||||
* *
|
||||
* Disk Formatting Program for CP/M-68K (tm) *
|
||||
* *
|
||||
* Copyright Digital Research 1982 *
|
||||
* *
|
||||
*********************************************************
|
||||
*
|
||||
*
|
||||
*
|
||||
prntstr = 9
|
||||
readbuf = 10
|
||||
*
|
||||
seldsk = 9
|
||||
settrk = 10
|
||||
setsec = 11
|
||||
setdma = 12
|
||||
write = 14
|
||||
sectran = 16
|
||||
flush = 21
|
||||
format = 63
|
||||
*
|
||||
.text
|
||||
*
|
||||
start: link a6,#0
|
||||
move.l 8(a6),a0
|
||||
add #$81,a0
|
||||
scan: cmpi.b #$20,(a0)+
|
||||
beq scan
|
||||
cmpi.b #$61,-(a0)
|
||||
blt upper
|
||||
sub #$20,(a0)
|
||||
upper: cmpi.b #$41,(a0)
|
||||
blt erxit
|
||||
cmpi.b #$50,(a0)
|
||||
bgt erxit
|
||||
query: move.b (a0),d0
|
||||
move.b d0,msgdskx
|
||||
ext.w d0
|
||||
sub.w #$41,d0
|
||||
move.w d0,dsk
|
||||
move.w #prntstr,d0
|
||||
move.l #msgdsk,d1
|
||||
trap #2
|
||||
move.w #readbuf,d0
|
||||
move.l #buf,d1
|
||||
trap #2
|
||||
move.b buf+2,d0
|
||||
cmpi.b #$59,d0
|
||||
beq doit
|
||||
cmpi.b #$79,d0
|
||||
bne exit
|
||||
*
|
||||
doit: clr.l d0
|
||||
clr.l d1
|
||||
*
|
||||
* Select the disk to format
|
||||
*
|
||||
move.w #seldsk,d0
|
||||
move.w dsk,d1
|
||||
clr.b d2
|
||||
trap #3
|
||||
tst.l d0
|
||||
beq selerx
|
||||
move.l d0,a0
|
||||
move.l (a0),xlt
|
||||
move.l 14(a0),a0
|
||||
move.w (a0),spt
|
||||
move.w 8(a0),drm
|
||||
move.w 14(a0),trk
|
||||
clr.w sect
|
||||
clr.w count
|
||||
*
|
||||
* Call the format function
|
||||
*
|
||||
move.w #format,d0
|
||||
move.w dsk,d1
|
||||
trap #3
|
||||
tst.w d0
|
||||
bne fmterx
|
||||
lea buf,a0
|
||||
move.l #$e5e5e5e5,d0
|
||||
move.w #31,d1
|
||||
bloop: move.l d0,(a0)+
|
||||
dbf d1,bloop
|
||||
move.w #setdma,d0
|
||||
move.l #buf,d1
|
||||
trap #3
|
||||
*
|
||||
dloop: move.w count,d0
|
||||
cmp.w drm,d0
|
||||
bgt exit
|
||||
move.w sect,d1
|
||||
cmp.w spt,d1
|
||||
blt sok
|
||||
clr.w sect
|
||||
add.w #1,trk
|
||||
sok: move.w #settrk,d0
|
||||
move.w trk,d1
|
||||
trap #3
|
||||
move.w #sectran,d0
|
||||
move.w sect,d1
|
||||
move.l xlt,d2
|
||||
trap #3
|
||||
move.w d0,d1
|
||||
move.w #setsec,d0
|
||||
trap #3
|
||||
move.w #write,d0
|
||||
clr.w d1
|
||||
trap #3
|
||||
tst.w d0
|
||||
bne wrterx
|
||||
add #1,sect
|
||||
add #1,count
|
||||
bra dloop
|
||||
*
|
||||
exit: move.w #flush,d0
|
||||
trap #3
|
||||
unlk a6
|
||||
rts
|
||||
*
|
||||
erxit: move.l #erstr,d1
|
||||
erx: move.w #prntstr,d0
|
||||
trap #2
|
||||
bra exit
|
||||
*
|
||||
fmterx: move.l #fmtstr,d1
|
||||
bra erx
|
||||
selerx: move.l #selstr,d1
|
||||
bra erx
|
||||
wrterx: move.l #wrtstr,d1
|
||||
bra erx
|
||||
*
|
||||
.data
|
||||
msgdsk: .dc.b 'Do you really want to format disk '
|
||||
msgdskx:.dc.b 'x ? $'
|
||||
*
|
||||
.even
|
||||
buf: .dc.b 126,0
|
||||
.ds.b 126
|
||||
*
|
||||
xlt: .ds.l 1
|
||||
spt: .ds.w 1
|
||||
drm: .ds.w 1
|
||||
sect: .ds.w 1
|
||||
trk: .ds.w 1
|
||||
dsk: .ds.w 1
|
||||
count: .ds.w 1
|
||||
*
|
||||
fmtstr: .dc.b 'Formatting Error',13,10,'$'
|
||||
erstr: .dc.b 'Error',13,10,'$'
|
||||
selstr: .dc.b 'Select Error',13,10,'$'
|
||||
wrtstr: .dc.b 'Write Error',13,10,'$'
|
||||
*
|
||||
copyrt: .dc.b 'CP/M-68K(tm), Version 1.1, Copyright 1983, Digital Research'
|
||||
serial: .dc.b 'XXXX-0000-654321'
|
||||
*
|
||||
.end
|
||||
141
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/xutils/init.s
Normal file
141
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/xutils/init.s
Normal file
@@ -0,0 +1,141 @@
|
||||
*********************************************************
|
||||
* *
|
||||
* Disk Initialization Program for CP/M-68K (tm) *
|
||||
* *
|
||||
* Copyright Digital Research 1983 *
|
||||
* *
|
||||
*********************************************************
|
||||
*
|
||||
*
|
||||
*
|
||||
prntstr = 9 BDOS Functions
|
||||
readbuf = 10
|
||||
*
|
||||
seldsk = 9 BIOS Functions
|
||||
settrk = 10
|
||||
setsec = 11
|
||||
setdma = 12
|
||||
write = 14
|
||||
sectran = 16
|
||||
flush = 21
|
||||
*
|
||||
.text
|
||||
*
|
||||
start: link a6,#0
|
||||
move.l 8(a6),a0 base page address
|
||||
add #$81,a0 first character of command tail
|
||||
scan: cmpi.b #$20,(a0)+ skip over blanks
|
||||
beq scan
|
||||
cmpi.b #$61,-(a0) get disk letter
|
||||
blt upper upshift
|
||||
sub #$20,(a0)
|
||||
upper: cmpi.b #$41,(a0) compare with range A - P
|
||||
blt erxit
|
||||
cmpi.b #$50,(a0)
|
||||
bgt erxit
|
||||
query: move.b (a0),d0 put disk letter in message
|
||||
move.b d0,msgdskx
|
||||
ext.w d0 put disk letter into range 0 - 15
|
||||
sub.w #$41,d0
|
||||
move.w d0,dsk
|
||||
move.w #prntstr,d0 ask whether it's really ok to init
|
||||
move.l #msgdsk,d1
|
||||
trap #2
|
||||
move.w #readbuf,d0 read reply
|
||||
move.l #buf,d1
|
||||
trap #2
|
||||
move.b buf+2,d0 if answer isn't Y then exit
|
||||
cmpi.b #$59,d0
|
||||
beq doit
|
||||
cmpi.b #$79,d0
|
||||
bne exit
|
||||
*
|
||||
doit: lea buf,a0 init disk buffer to empty directory entries
|
||||
move.l #$e5e5e5e5,d0
|
||||
move.w #31,d1
|
||||
bloop: move.l d0,(a0)+
|
||||
dbf d1,bloop
|
||||
move.w #setdma,d0 set up dma address for write
|
||||
move.l #buf,d1
|
||||
trap #3
|
||||
move.w #seldsk,d0 select the disk
|
||||
move.w dsk,d1
|
||||
clr.b d2
|
||||
trap #3
|
||||
tst.l d0 check for select error
|
||||
beq selerx
|
||||
move.l d0,a0 get translate table address for sectran
|
||||
move.l (a0),xlt
|
||||
move.l 14(a0),a0 get DPB address
|
||||
move.w (a0),spt get sectors per track
|
||||
move.w 8(a0),drm get directory entry count - 1
|
||||
move.w 14(a0),trk get starting track (=offset)
|
||||
clr.w sect start at sector 0
|
||||
clr.w count count of initialized sectors
|
||||
*
|
||||
dloop: move.w count,d0 while count <= drm ...
|
||||
cmp.w drm,d0
|
||||
bgt exit
|
||||
move.w sect,d1 check for end-of-track
|
||||
cmp.w spt,d1
|
||||
blt sok
|
||||
clr.w sect advance to new track
|
||||
add.w #1,trk
|
||||
sok: move.w #settrk,d0 set the track
|
||||
move.w trk,d1
|
||||
trap #3
|
||||
move.w #sectran,d0 do sector translate
|
||||
move.w sect,d1
|
||||
move.l xlt,d2
|
||||
trap #3
|
||||
move.w d0,d1 set sector
|
||||
move.w #setsec,d0
|
||||
trap #3
|
||||
move.w #write,d0 and write
|
||||
clr.w d1
|
||||
trap #3
|
||||
tst.w d0 check for write error
|
||||
bne wrterx
|
||||
add #1,sect increment sector number
|
||||
add #4,count increment count of directory entries
|
||||
bra dloop and loop
|
||||
*
|
||||
exit: move.w #flush,d0 exit location - flush bios buffers
|
||||
trap #3
|
||||
unlk a6
|
||||
rts and exit to CCP
|
||||
*
|
||||
erxit: move.l #erstr,d1 miscellaneous errors
|
||||
erx: move.w #prntstr,d0 print error message and exit
|
||||
trap #2
|
||||
bra exit
|
||||
*
|
||||
selerx: move.l #selstr,d1 disk select error
|
||||
bra erx
|
||||
wrterx: move.l #wrtstr,d1 disk write error
|
||||
bra erx
|
||||
*
|
||||
.data
|
||||
msgdsk: .dc.b 'Do you really want to init disk '
|
||||
msgdskx:.dc.b 'x ? $'
|
||||
*
|
||||
.even
|
||||
buf: .dc.b 126,0 dual use buffer -- console input & dsk output
|
||||
.ds.b 126
|
||||
*
|
||||
xlt: .ds.l 1 translate table address
|
||||
spt: .ds.w 1 sectors per track
|
||||
drm: .ds.w 1 maximum directory entry number
|
||||
sect: .ds.w 1 current sector
|
||||
trk: .ds.w 1 current track
|
||||
dsk: .ds.w 1 selected disk
|
||||
count: .ds.w 1 number of directory entries written so far
|
||||
*
|
||||
erstr: .dc.b 'Error',13,10,'$'
|
||||
selstr: .dc.b 'Select Error',13,10,'$'
|
||||
wrtstr: .dc.b 'Write Error',13,10,'$'
|
||||
*
|
||||
copyrt: .dc.b 'CP/M-68K(tm), Version 1.1, Copyright 1983, Digital Research'
|
||||
serial: .dc.b 'XXXX-0000-654321'
|
||||
*
|
||||
.end
|
||||
@@ -0,0 +1,194 @@
|
||||
*********************************************************
|
||||
* *
|
||||
* Program to Write Boot Tracks for CP/M-68K (tm) *
|
||||
* *
|
||||
* Copyright Digital Research 1982 *
|
||||
* *
|
||||
*********************************************************
|
||||
*
|
||||
*
|
||||
*
|
||||
prntstr = 9 BDOS Functions
|
||||
dseldsk = 14
|
||||
open = 15
|
||||
readseq = 20
|
||||
dsetdma = 26
|
||||
*
|
||||
seldsk = 9 BIOS Functions
|
||||
settrk = 10
|
||||
setsec = 11
|
||||
isetdma = 12
|
||||
write = 14
|
||||
sectran = 16
|
||||
flush = 21
|
||||
*
|
||||
bufcnt = $80
|
||||
bufsize = $80*bufcnt
|
||||
*
|
||||
.text
|
||||
*
|
||||
start: link a6,#0
|
||||
move.l 8(a6),a0 base page address
|
||||
lea $5c(a0),a1
|
||||
move.l a1,fcb
|
||||
clr.b hflag
|
||||
add #$81,a0 first character of command tail
|
||||
scan: cmpi.b #$20,(a0)+ skip over blanks
|
||||
beq scan
|
||||
sub.l #1,a0
|
||||
scan1: tst.b (a0)
|
||||
beq erxit
|
||||
cmpi.b #$2d,(a0)+ check for -H flag
|
||||
bne nohyph
|
||||
cmpi.b #$48,(a0)+
|
||||
bne erxit
|
||||
tst.b hflag
|
||||
bne erxit
|
||||
move.b #$ff,hflag
|
||||
sub.l #$24,fcb change to 2nd default fcb
|
||||
bra scan
|
||||
nohyph: cmpi.b #$20,(a0)
|
||||
bne scan1
|
||||
scan2: cmpi.b #$20,(a0)+
|
||||
beq scan2
|
||||
cmpi.b #$61,-(a0) get disk letter
|
||||
blt upper upshift
|
||||
sub #$20,(a0)
|
||||
upper: cmpi.b #$41,(a0) compare with range A - P
|
||||
blt erxit
|
||||
cmpi.b #$50,(a0)
|
||||
bgt erxit
|
||||
move.b (a0),d0
|
||||
ext.w d0 put disk letter into range 0 - 15
|
||||
sub.w #$41,d0
|
||||
move.w d0,dsk
|
||||
*
|
||||
* open file to copy
|
||||
*
|
||||
move.w #open,d0
|
||||
move.l fcb,d1
|
||||
trap #2
|
||||
cmpi.w #$00ff,d0
|
||||
bne openok
|
||||
move.l #opnfl,d1
|
||||
jmp erx
|
||||
openok: move.l fcb,a0
|
||||
clr.b 32(a0)
|
||||
*
|
||||
* read
|
||||
*
|
||||
move.l #buf,d2
|
||||
clr.w count
|
||||
rloop: move.w #dsetdma,d0
|
||||
move.l d2,d1
|
||||
trap #2
|
||||
move.w #readseq,d0
|
||||
move.l fcb,d1
|
||||
trap #2
|
||||
tst.w d0
|
||||
bne wrtout
|
||||
add.l #128,d2
|
||||
add.w #1,count
|
||||
cmpi.w #bufcnt,count
|
||||
bgt bufoflx
|
||||
bra rloop
|
||||
*
|
||||
* write
|
||||
*
|
||||
wrtout: move.w #seldsk,d0 select the disk
|
||||
move.w dsk,d1
|
||||
clr.b d2
|
||||
trap #3
|
||||
tst.l d0 check for select error
|
||||
beq selerx
|
||||
move.l d0,a0
|
||||
move.l 14(a0),a0 get DPB address
|
||||
move.w (a0),spt get sectors per track
|
||||
move.w 14(a0),off get offset
|
||||
clr.w trk start at trk 0
|
||||
clr.w sect start at sector 0
|
||||
lea buf,a0
|
||||
tst.b hflag
|
||||
bne wrt1
|
||||
cmpi.w #$601a,(a0)
|
||||
bne wrt1
|
||||
add.l #28,a0
|
||||
wrt1: move.l a0,bufp
|
||||
*
|
||||
wloop: tst.w count
|
||||
beq exit
|
||||
move.w sect,d1 check for end-of-track
|
||||
cmp.w spt,d1
|
||||
blt sok
|
||||
clr.w sect advance to new track
|
||||
move.w trk,d0
|
||||
add.w #1,d0
|
||||
move.w d0,trk
|
||||
cmp.w off,d0
|
||||
bge oflex
|
||||
sok: move.w #settrk,d0 set the track
|
||||
move.w trk,d1
|
||||
trap #3
|
||||
move.w sect,d1 set sector
|
||||
move.w #setsec,d0
|
||||
trap #3
|
||||
move.w #isetdma,d0 set up dma address for write
|
||||
move.l bufp,d1
|
||||
trap #3
|
||||
move.w #write,d0 and write
|
||||
clr.w d1
|
||||
trap #3
|
||||
tst.w d0 check for write error
|
||||
bne wrterx
|
||||
add #1,sect increment sector number
|
||||
sub #1,count
|
||||
add.l #128,bufp
|
||||
bra wloop
|
||||
*
|
||||
exit: move.w #flush,d0 exit location - flush bios buffers
|
||||
trap #3
|
||||
unlk a6
|
||||
rts and exit to CCP
|
||||
*
|
||||
erxit: move.l #erstr,d1 miscellaneous errors
|
||||
erx: move.w #prntstr,d0 print error message and exit
|
||||
trap #2
|
||||
bra exit
|
||||
*
|
||||
selerx: move.l #selstr,d1 disk select error
|
||||
bra erx
|
||||
wrterx: move.l #wrtstr,d1 disk write error
|
||||
bra erx
|
||||
bufoflx: move.l #bufofl,d1 buffer overflow
|
||||
bra erx
|
||||
oflex: move.l #trkofl,d1
|
||||
bra erx
|
||||
*
|
||||
*
|
||||
.bss
|
||||
*
|
||||
.even
|
||||
*
|
||||
buf: .ds.b bufsize+128
|
||||
*
|
||||
fcb: .ds.l 1 fcb address
|
||||
spt: .ds.w 1 sectors per track
|
||||
sect: .ds.w 1 current sector
|
||||
trk: .ds.w 1 current track
|
||||
dsk: .ds.w 1 selected disk
|
||||
off: .ds.w 1 1st track of non-boot area
|
||||
count: .ds.w 1
|
||||
bufp: .ds.l 1
|
||||
hflag: .ds.b 1
|
||||
*
|
||||
.data
|
||||
*
|
||||
erstr: .dc.b 'Invalid Command Line',13,10,'$'
|
||||
selstr: .dc.b 'Select Error',13,10,'$'
|
||||
wrtstr: .dc.b 'Write Error',13,10,'$'
|
||||
opnfl: .dc.b 'Cannot Open Source File',13,10,'$'
|
||||
bufofl: .dc.b 'Buffer Overflow',13,10,'$'
|
||||
trkofl: .dc.b 'Too Much Data for System Tracks',13,10,'$'
|
||||
*
|
||||
*
|
||||
.end
|
||||
269
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/xutils/serial.c
Normal file
269
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/xutils/serial.c
Normal file
@@ -0,0 +1,269 @@
|
||||
/*----------------------------------------------------------------------*\
|
||||
| serial.c v1.0 |
|
||||
| SERIALIZATION PROGRAM FOR CP/M-68K |
|
||||
| ================================== |
|
||||
| |
|
||||
| date: 1/3/83 |
|
||||
| ---- |
|
||||
| |
|
||||
| last modified: 2/3/83 |
|
||||
| ------------- |
|
||||
| |
|
||||
| description: |
|
||||
| ----------- This program replaces up to 20 occurances |
|
||||
| of "654321" in all files found in "SERIAL.DAT". |
|
||||
| The string "654321" is replaced by a serial |
|
||||
| number. Leading zeros will be filled in by |
|
||||
| the program. The starting and ending serial |
|
||||
| number's are read in from the command line. |
|
||||
| The user is prompted for the serialization |
|
||||
| drive. |
|
||||
| |
|
||||
| |
|
||||
| COPYRIGHT (C) 1983 |
|
||||
| DIGITAL RESEARCH |
|
||||
| BOX 579 |
|
||||
| PACIFIC GROVE, CA. 93950 |
|
||||
| |
|
||||
\*----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "stdio.h" /* standard I/O library */
|
||||
|
||||
#define islower(c) ('a' <= (c) && (c) <= 'z')
|
||||
#define toupper(c) (islower(c) ? ((c)-040) : (c))
|
||||
#define RESET 13
|
||||
#define SELECT 14
|
||||
|
||||
/********************************/
|
||||
/* GLOBAL VARIABLES */
|
||||
struct _serial /********************************/
|
||||
{ /* */
|
||||
BYTE filename[13]; /* file to serialize */
|
||||
}; /* */
|
||||
struct _serial serial[150]; /* array of structures */
|
||||
/* */
|
||||
BYTE enddata[] = "xxxxxxxxxxxx"; /* end of filenames marker */
|
||||
BYTE marker[] = "654321"; /* place in file to sub serial #*/
|
||||
BYTE snum[] = "000000"; /* serial number */
|
||||
BYTE drive = 0; /* serialization drive */
|
||||
BYTE chtab[] = "0123456789"; /* table of digits */
|
||||
FILE *stream; /* pointer to a stream file */
|
||||
/********************************/
|
||||
|
||||
|
||||
|
||||
/********************************/
|
||||
/* FUNCTIONS */
|
||||
/********************************/
|
||||
FILE *fopen(); /* returns a stream I/O pointer */
|
||||
FILE *fopenb(); /* returns a stream I/O pointer */
|
||||
BYTE *trans(); /* returns a pointer to a string*/
|
||||
LONG atol(); /* returns a long number */
|
||||
LONG ftell(); /* returns a long number */
|
||||
/********************************/
|
||||
|
||||
main(argc,argv)
|
||||
WORD argc;
|
||||
BYTE *argv[];
|
||||
{
|
||||
REG LONG start_num; /* starting serial number */
|
||||
REG LONG final_num; /* final serial number */
|
||||
REG LONG num; /* current serial number */
|
||||
BYTE buffer[32]; /* read buffer */
|
||||
BYTE boot; /* y or n to system tracks */
|
||||
|
||||
|
||||
if(argc != 3)
|
||||
{
|
||||
printf("\nUsage: A>serial starting ending");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
printf("Serial.68K V1.0");
|
||||
|
||||
init(); /* try to open data file */
|
||||
|
||||
boot = 'N'; /* no serializing of system trks*/
|
||||
|
||||
/* check range of serial number's */
|
||||
|
||||
if(atol(argv[1]) > 999999L || atol(argv[2]) > 999999L ||
|
||||
atol(argv[1]) < 0L || atol(argv[2]) < 0L)
|
||||
{
|
||||
printf("\nERROR: Serial # out of range: [0-999999]");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
printf("\nSerialization drive ? "); gets(buffer);
|
||||
drive = toupper(buffer[0]);
|
||||
|
||||
/* verify to user the serial number range */
|
||||
|
||||
printf("\nSTARTING serial number is: %s",argv[1]);
|
||||
printf("\nFINAL serial number is : %s",argv[2]);
|
||||
if(boot == 'Y')
|
||||
printf("\nSystem tracks will be serialized");
|
||||
printf("\n\n");
|
||||
|
||||
|
||||
/************************************************/
|
||||
/* */
|
||||
/* MAIN SERIALIZATION LOOP */
|
||||
/* ----------------------- */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
|
||||
for(num = atol(argv[1]); num <= atol(argv[2]); num++)
|
||||
{
|
||||
__BDOS(RESET,(long)0);
|
||||
printf("\n\nInsert new diskette in drive %c and type RETURN",drive);
|
||||
getchar();
|
||||
printf("\nCURRENT serial number is: %LD\n",num);
|
||||
if(boot == 'Y')
|
||||
boottrk(num);
|
||||
patch(num);
|
||||
}
|
||||
}
|
||||
|
||||
/************************/
|
||||
VOID init() /* Open SERIAL.DAT */
|
||||
/* Read SERIAL.DAT */
|
||||
/************************/
|
||||
{
|
||||
BYTE buf[40];
|
||||
REG UWORD j;
|
||||
REG struct _serial *p;
|
||||
|
||||
if((stream = fopen("SERIAL.DAT","r")) == NULL)
|
||||
{
|
||||
printf("\nUnable to open SERIAL.DAT");
|
||||
exit(0);
|
||||
}
|
||||
/* read in the data line by line */
|
||||
/* and fill the structure serial */
|
||||
fgets(buf,40,stream);
|
||||
p = &serial;
|
||||
do
|
||||
{
|
||||
j = 0;
|
||||
while((p->filename[j] = buf[j++]) != '\n');
|
||||
p->filename[j-1] = '\0';
|
||||
p++;
|
||||
fgets(buf,40,stream);
|
||||
}
|
||||
while(!(feof(stream)));
|
||||
for(j = 0;j < 12;j++)
|
||||
p->filename[j] = 'x';
|
||||
p->filename[12] = '\0';
|
||||
fclose(stream);
|
||||
}
|
||||
/************************/
|
||||
VOID patch(num) /* Plug Serialization */
|
||||
/* bytes into file */
|
||||
/************************/
|
||||
LONG num;
|
||||
{
|
||||
REG struct _serial *p;
|
||||
REG UWORD i,j;
|
||||
LONG offset[21];
|
||||
REG BYTE *pp;
|
||||
REG UWORD ch;
|
||||
REG WORD fd;
|
||||
|
||||
|
||||
__BDOS(SELECT,(long)drive-'A');
|
||||
p = &serial;
|
||||
while(strcmp(p,enddata))
|
||||
{
|
||||
printf("\nSerializing: %s ",p);
|
||||
for(i = 1;i <= (12 - strlen(p));i++)
|
||||
printf(" ");
|
||||
if((stream = fopenb(p,"r")) == NULL)
|
||||
printf("Unable to open file: %s",p);
|
||||
else
|
||||
{
|
||||
for(j = 0;j < 21;j++)
|
||||
offset[j] = -1L;
|
||||
i = j = 0;
|
||||
pp = marker;
|
||||
rewind(stream);
|
||||
while(1)
|
||||
{
|
||||
ch = fgetc(stream);
|
||||
if(feof(stream))
|
||||
break;
|
||||
if(ch == *pp)
|
||||
{
|
||||
i++;
|
||||
if(pp == marker)
|
||||
offset[j] = ftell(stream);
|
||||
pp++;
|
||||
}
|
||||
else
|
||||
{
|
||||
pp = marker;
|
||||
offset[j] = -1L;
|
||||
i = 0;
|
||||
}
|
||||
if(i == 6)
|
||||
{
|
||||
j++;
|
||||
if(j == 20)
|
||||
break;
|
||||
i = 0;
|
||||
pp = marker;
|
||||
}
|
||||
}
|
||||
fclose(stream);
|
||||
if(offset[0] == -1L)
|
||||
printf("file cannot be serialized");
|
||||
else
|
||||
{
|
||||
fd = openb(p, 2);
|
||||
if ( fd == -1 ) printf("cannot write to file");
|
||||
else
|
||||
{
|
||||
j = 0;
|
||||
while(offset[j] != -1L)
|
||||
{
|
||||
lseek(fd, --offset[j++], 0);
|
||||
write(fd, trans(num), 6);
|
||||
}
|
||||
printf("Serialization complete %d",j);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
VOID boottrk(num)
|
||||
LONG num;
|
||||
{
|
||||
printf("\nSerializing Boot tracks");
|
||||
}
|
||||
|
||||
|
||||
|
||||
BYTE *trans(num)
|
||||
LONG num;
|
||||
{
|
||||
REG BYTE *p;
|
||||
LONG x;
|
||||
|
||||
p = snum;
|
||||
x = 100000;
|
||||
|
||||
while(x)
|
||||
{
|
||||
*p++ = chtab[num/x];
|
||||
num %= x;
|
||||
x /= 10;
|
||||
}
|
||||
|
||||
return(snum);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user