home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource4
/
225_01
/
dir2.c
< prev
next >
Wrap
Text File
|
1987-06-10
|
12KB
|
336 lines
/*-----------------------------------------------------------------*/
/* STANDARD HEADER FOR BDS C PROGRAMMES
------------------------------------
Programme: DIR2.C
---------
Purpose: This programme will delete all inactive
------- entries from the directory and then re-write
the directory in (almost) alphabetical order
onto the last available track of the nominated
disk. It also creates the file "DIRECT.ORY"
under user area 15.
Written: 02/01/86
-------
Amended: 08/11/86
-------
Version: 1.2
-------
Copyright 1986 - Cogar Computer Services Pty. Ltd. */
/*-----------------------------------------------------------------*/
#include <bdscio.h>
#include <pec.h>
/*-----------------------------------------------------------------*/
#define VERSION "1.2\0"
#define NAME "DIR2\0"
/*-----------------------------------------------------------------*/
main(argc, argv) /* For Command Line processing */
int argc;
char *argv[];
{
/*-----------------------------------------------------------------*/
/* Space reserved for variables used in programme */
/*-----------------------------------------------------------------*/
int i, j, k, l, BLOCK1, FD;
char c, DATA_MAP;
int CPM; /* To check the CP/M Version number */
char DRIVE; /* The active drive */
char OLD_DRIVE; /* The starting drive No. */
char OLD_USER; /* The User No. at start of programme */
char USER; /* The User No. for this programme */
char my_dma[128]; /* The dma buffer to use */
char my_fcb[36]; /* The file control block */
char **skew_table;
int PHYS_SEC; /* The physical sector to read/write */
unsigned STORAGE; /* The size of the big buffer */
struct dpb *THIS; /* Disk parameter information */
int DIRECTORY; /* The directory track */
int SECTORS; /* Sectors per track */
unsigned RECORDS; /* Total available records */
int LAST_TRACK; /* The highest track No. on the disk */
int BLK_SIZE; /* Allocation block size in records */
int DIR_SIZE; /* No. of allocation blocks in directory */
int FIRST_BLOCK; /* First block No. in directory */
int ENTRIES; /* The active entries in directory */
char *BIG_BUF;
/*-----------------------------------------------------------------*/
pec_clear(); /* Universal routine */
printf("%s - Version %s\n",NAME, VERSION);
printf("Copyright 1986 - Cogar Computer Services Pty.Ltd.\n");
printf("----------------------------------------------------------\n");
printf("This programme will first 'clean up' the directory\n");
printf("tracks by removing any inactive (0xe5) entries.\n");
printf("Then it sorts the active entries into (approximate)\n");
printf("alphabetical order and writes them....as a copy of the\n");
printf("directory onto the last track of the disk, as DIR2.\n");
printf("Finally it creates the file 'DIRECT.ORY' in User Area\n");
printf("15 to protect the second directory against being over\n");
printf("written by other files.\n");
printf("----------------------------------------------------------\n");
/*-----------------------------------------------------------------*/
/* First check the CP/M Version in use. If it is less than
Version 2.0 then inform the user and terminate programme. */
/*-----------------------------------------------------------------*/
CPM = get_cpm(); /* Obtain the CP/M version and No. */
i = (CPM & 0xff) - 0x20; /* Mask off the MP/M bit */
if(i < 0) /* Must be less than V 2.0 */
{
printf("This programme requires at least V 2.x of CP/M.\n");
printf("Sorry but it won't run for you.\n");
exit();
}
/*-----------------------------------------------------------------*/
/* The CP/M Version is OK, so save the starting User No. and the
starting drive in case these are changed later. */
/*-----------------------------------------------------------------*/
OLD_USER = user_id(0xff);
OLD_DRIVE = get_default() + 0x41;
/*-----------------------------------------------------------------*/
/* Now check the Command Line to see if a Drive Code was entered.
Other checks can also be used, as required but then it will be
necessary to change this coding. */
/*-----------------------------------------------------------------*/
if(argc != 2)
{
printf("Enter the DRIVE you wish to check...A, B, C...\n");
DRIVE = toupper(getchar());
}
else if(argc == 2)
DRIVE = toupper(argv[1][0]);
lines(2);
/*-----------------------------------------------------------------*/
/* Check that the selected drive is available/on-line. If not
then terminate the programme. You may need to add a message
about what is going on if your version of CP/M doesn't do
this automatically, as mine does. */
/*-----------------------------------------------------------------*/
if(!(skew_table = seldsk(DRIVE)))
exit(); /* Must be something wrong */
if(select_dsk(DRIVE) != 0)
exit();
/*-----------------------------------------------------------------*/
/* Calculate the values we need to scan the directory. */
/*-----------------------------------------------------------------*/
THIS = dpb_adr();
DIRECTORY = THIS->OFF;
SECTORS = THIS->SPT;
RECORDS = THIS->DSM + 1; /* Starting value */
for(i = 0; i < THIS->BSH; i++)
RECORDS = RECORDS + RECORDS;
if(RECORDS%SECTORS != 0)
LAST_TRACK = RECORDS/SECTORS + DIRECTORY;
else LAST_TRACK = RECORDS/SECTORS + DIRECTORY - 1;
printf("The highest track No. = %d\n", LAST_TRACK);
BLK_SIZE = (128 << THIS->BSH)/128; /* In records */
DIR_SIZE = SECTORS/BLK_SIZE; /* In blocks */
FIRST_BLOCK = (THIS->DSM + 1) - DIR_SIZE;
if((THIS->DSM >> 8) == 0)
DATA_MAP = 16;
else DATA_MAP = 8;
/*-----------------------------------------------------------------*/
/* Now create a file control block for the file "DIRECT.ORY"
under User Area 15 */
/*-----------------------------------------------------------------*/
setmem(&my_fcb[0], 36, 0);
my_fcb[0] = 15; /* The User Number */
strcpy(&my_fcb[1], "DIRECT ORY\0"); /* The file name */
my_fcb[12] = my_fcb[13] = my_fcb[14] = 0;
my_fcb[15] = BLK_SIZE*DIR_SIZE; /* No. of records */
BLOCK1 = FIRST_BLOCK; /* Starting value */
if(DATA_MAP == 16)
{
for(i = 0; i < DIR_SIZE; i++)
{
my_fcb[16 + i] = BLOCK1;
BLOCK1++;
}
}
else if(DATA_MAP == 8)
{
for(i = 0; i < DIR_SIZE*2; i = i + 2)
{
my_fcb[16 + i] = BLOCK1 & 0xff;
my_fcb[17 + i] = (BLOCK1 >> 8) & 0xff;
BLOCK1++;
}
}
/*-----------------------------------------------------------------*/
set_dma(&my_dma[0]); /* Create DMA buffer */
set_trk(DIRECTORY);
/*-----------------------------------------------------------------*/
/* Read the directory track and count the number of active
entries. This information is required for the size of
the big buffer. */
/*-----------------------------------------------------------------*/
printf("Counting the active directory entries.\n");
ENTRIES = 0; /* Starting conditions */
for(i = 0; i < SECTORS; i++)
{
PHYS_SEC = biosh(16, i, *skew_table);
set_sec(PHYS_SEC);
setmem(&my_dma[0], 128, 0xe5);
read_sec(); /* Put information into DMA buffer */
for(j = 0; j < 4; j++)
{
if(my_dma[j*32] != 0xe5)
ENTRIES++;
}
}
printf("Active entries (all extents) = %d\n", ENTRIES