mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
131 lines
3.1 KiB
C
131 lines
3.1 KiB
C
/*=======================================================================*/
|
||
/*+---------------------------------------------------------------------+*/
|
||
/*| |*/
|
||
/*| Disk-Disk copy program for the OLIVETTI M20 (Z8000) |*/
|
||
/*| |*/
|
||
/*| Copyright 1983, Zilog Incorporated. |*/
|
||
/*| |*/
|
||
/*+---------------------------------------------------------------------+*/
|
||
/*=======================================================================*/
|
||
|
||
|
||
char copyright[] = "Copyright 1983, Zilog Incorporated";
|
||
|
||
|
||
/* HISTORY
|
||
**
|
||
** 830221 F. Zlotnick (Zilog) -- with assembler routines stolen
|
||
** from S. Savitzky's BIOS.
|
||
**
|
||
*/
|
||
|
||
/************************************************************************/
|
||
|
||
|
||
|
||
#define SECSIZ 256
|
||
#define NSECS 16
|
||
#define TRKSIZE NSECS*SECSIZ
|
||
#define NTRACKS 40
|
||
|
||
#define READ 0 /* Controller command */
|
||
#define WRITE 1 /* Controller command */
|
||
|
||
long map_adr(); /* for physical addresses */
|
||
|
||
int bigbuff[NSECS*SECSIZ*5]; /* Will hold 5 tracks, 2 sides each */
|
||
int drive1, /* Source drive name */
|
||
drive2, /* Target drive name */
|
||
err; /* error return from disk_io routine */
|
||
|
||
main(argc,argv)
|
||
int argc;
|
||
char *argv[];
|
||
{
|
||
register int i,j;
|
||
|
||
if(argc != 3) usage();
|
||
if( strcmp( argv[1], "a:") == 0 ) {
|
||
drive1 = 0;
|
||
if( strcmp( argv[2], "b:") != 0) usage();
|
||
else drive2 = 1;
|
||
}
|
||
else if( strcmp( argv[1], "b:") == 0 ) {
|
||
drive1 = 1;
|
||
if( strcmp( argv[2], "a:") != 0) usage();
|
||
else drive2 = 0;
|
||
}
|
||
else usage();
|
||
if( dotrk0() ) { /* Track 0 is special */
|
||
printf("Error copying track 0\n");
|
||
exit(1);
|
||
}
|
||
for( i = 1; i<= 40; i += 5)
|
||
if( j = do5trks(i)) { /* Do the rest, 5 tracks at a time */
|
||
printf( "Error %d on track %d\n", err, j);
|
||
exit(1);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* The following routine copies track 0, both sides
|
||
*/
|
||
dotrk0()
|
||
{
|
||
register int j;
|
||
long physaddr;
|
||
|
||
physaddr = map_adr( (long) bigbuff, 0);
|
||
if( j = disk_io(drive1, READ, 16, 0, physaddr) )
|
||
return(j); /* Do the read... */
|
||
if( j = disk_io(drive1, READ, 16, 16, physaddr + TRKSIZE ) )
|
||
return(j);
|
||
if( j = disk_io(drive2, WRITE, 16, 0, physaddr) )
|
||
return(j); /* ...and the write */
|
||
if( j = disk_io(drive2, WRITE, 16, 16, physaddr + TRKSIZE ) )
|
||
return(j);
|
||
return(0);
|
||
}
|
||
|
||
do5trks(i)
|
||
int i;
|
||
{
|
||
register int track, secnum;
|
||
long physaddr, offset;
|
||
|
||
physaddr = map_adr((long) bigbuff, 0);
|
||
offset = 0L;
|
||
for ( track = i; track < i + 5; track++) {
|
||
secnum = track * 32;
|
||
if(err = disk_io(drive1,READ,NSECS,secnum,physaddr + offset))
|
||
return(track);
|
||
secnum += NSECS;
|
||
offset += TRKSIZE;
|
||
if(err = disk_io(drive1,READ,NSECS,secnum,physaddr + offset))
|
||
return(track);
|
||
offset += TRKSIZE;
|
||
}
|
||
offset = 0L;
|
||
for ( track = i; track < i + 5; track++) {
|
||
secnum = track * 32;
|
||
if(err = disk_io(drive2,WRITE,NSECS,secnum,physaddr + offset))
|
||
return(track);
|
||
secnum += NSECS;
|
||
offset += TRKSIZE;
|
||
if(err = disk_io(drive2,WRITE,NSECS,secnum,physaddr + offset))
|
||
return(track);
|
||
offset += TRKSIZE;
|
||
}
|
||
return(0);
|
||
}
|
||
|
||
/*
|
||
* Usage routine tells user he's invoked command incorrectly
|
||
*/
|
||
usage()
|
||
{
|
||
printf("usage:\n\tddcopy source dest\n");
|
||
printf("where source is 'a:' and dest is 'b:' or vice versa.\n");
|
||
exit(1);
|
||
}
|