mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-27 02:14:19 +00:00
Upload
Digital Research
This commit is contained in:
@@ -0,0 +1,766 @@
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/* genc4.c - This module exports the following routines:
|
||||
/*
|
||||
/* initxios_info(xf,goff) 'xf' is XIOSMOD file descriptor, 'goff'
|
||||
/* is offset of data group in XIOSMOD (including header);
|
||||
/* this module inits the buffering info questions.
|
||||
/* doxbufs(txt,title) 'txt' is a command, 'title' is the prompt for this fn;
|
||||
/* this routine is called within the MENU module, and prompts user
|
||||
/* for xios info.
|
||||
/* xiosvalid() returns a BOOLEAN value indicating whether the xios info
|
||||
/* is valid.
|
||||
/* genxios(doffset) generates the buffers for the xios, starting at 'doffset'
|
||||
/* in the system data area.
|
||||
/* fixupxios_info() writes DPH fixups required by genxios
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
#ifndef MAINMODULE
|
||||
#include <genccpm.h>
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* edsdisk.h : defines the data structures used in this module
|
||||
/**************************************************************************/
|
||||
|
||||
#define ADDR UWORD /* Address (offset) within SysDat */
|
||||
#define SEG UWORD /* Segment address (may be outside SysDat) */
|
||||
|
||||
#define DPH struct dph_item
|
||||
DPH { /* Disk Parameter Header structure */
|
||||
ADDR dph_xlt; /* Translation Table Address */
|
||||
BYTE dph_space[6]; /* reserved & Media Flag */
|
||||
ADDR dph_dpb; /* Disk Parameter Block Address */
|
||||
ADDR dph_csv; /* CheckSum Vector Address */
|
||||
ADDR dph_alv; /* Allocation Vector Address */
|
||||
ADDR dph_dirbcb; /* Dir Buffer Control Block Header Address */
|
||||
ADDR dph_datbcb; /* Data Buffer Control Block Header Address */
|
||||
SEG dph_hstbl; /* Hash Table Segment */
|
||||
};
|
||||
|
||||
#define EDPB struct edbp_item
|
||||
EDPB { /* Extended Disk Parameter Block entries */
|
||||
WORD edpb_extflag; /* Extended DPB flag */
|
||||
WORD edpb_nfats; /* Number of FATS */
|
||||
WORD edpb_nfatrecs; /* Number of records per FAT */
|
||||
WORD edpb_nclstrs; /* Number of clusters */
|
||||
WORD edpb_clsize; /* Cluster size */
|
||||
WORD edpb_fatadd; /* FAT address */
|
||||
};
|
||||
|
||||
#define DPB struct dpb_item
|
||||
DPB { /* Disk Parameter Block structure */
|
||||
WORD dpb_spt; /* Sectors Per Track */
|
||||
BYTE dpb_bsh; /* Allocation Block Shift Factor */
|
||||
BYTE dpb_blm; /* Allocation Block Mask */
|
||||
BYTE dpb_exm; /* Extent Mask */
|
||||
WORD dpb_dsm; /* Disk Storage Maximum */
|
||||
WORD dpb_drm; /* Directory Maximum */
|
||||
WORD dpb_dav; /* Directory Allocation Vector */
|
||||
WORD dpb_cks; /* Checksum Vector Size */
|
||||
WORD dpb_off; /* Track Offset */
|
||||
WORD dpb_psh; /* Physical Record Shift Factor */
|
||||
WORD dpb_phm; /* Physical Record Mask */
|
||||
};
|
||||
|
||||
#define BCBH struct bcbh_item
|
||||
BCBH { /* Buffer Control Block Header structure */
|
||||
ADDR bcbh_lr; /* BCB List Root */
|
||||
BYTE bcbh_pm; /* BCB Process Max */
|
||||
};
|
||||
|
||||
#define BCB struct bcb_item
|
||||
BCB { /* Buffer Control Block structure */
|
||||
BYTE bcb_drv; /* Drive */
|
||||
BYTE bcb_record[3]; /* Record Number */
|
||||
BYTE bcb_wflg; /* Write Pending Flag */
|
||||
BYTE bcb_seq; /* Sequential Access Counter */
|
||||
WORD bcb_track; /* Logical Track Number */
|
||||
WORD bcb_sector; /* Logical Translated Sector Number */
|
||||
UWORD bcb_bufptr; /* Buffer Offset (for DIRBCB) / Segment (for DATBCB) */
|
||||
ADDR bcb_link; /* Link to next BCB */
|
||||
WORD bcb_pdadr; /* Process Descriptor Address */
|
||||
};
|
||||
|
||||
|
||||
#define DINFO struct dirbuf_information
|
||||
DINFO {
|
||||
BOOLEAN d_modified; /* DPH was modified? */
|
||||
BOOLEAN d_hashing; /* user wants hashing? */
|
||||
WORD d_ndirbs; /* Num dir buffers */
|
||||
WORD d_sdirbs; /* Size dir buffers */
|
||||
WORD d_pmdirbs; /* Process Max Number Dir Buffs */
|
||||
WORD d_ndatbs; /* Num data buffers */
|
||||
WORD d_sdatbs; /* Size data buffers */
|
||||
WORD d_pmdatbs; /* Process Max Number Dir Buffs */
|
||||
WORD d_shash; /* Size of hash table */
|
||||
WORD d_alvsize; /* size of Alloc Vector area (in bytes ) */
|
||||
WORD d_blksize; /* size of disk Allocation Block */
|
||||
WORD d_csvsize; /* size of Checksum Vector area */
|
||||
};
|
||||
|
||||
/* end of edsdisk.h ********************************************************/
|
||||
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
WORD csfd; /* command file descriptor */
|
||||
WORD csgoff; /* group offset within command file */
|
||||
|
||||
cseek(offs) /* seek offset within Command File */
|
||||
ADDR offs;
|
||||
{
|
||||
lseek(csfd,(LONG) offs+csgoff, 0); /* compensate for cmd header */
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* Put special byte for buffer fills */
|
||||
#define ZBYTE (doffset&0xFF) /* the byte usually passed in */
|
||||
WORD
|
||||
bufwrite(size,byt)
|
||||
WORD size;
|
||||
BYTE byt;
|
||||
{
|
||||
WORD ss;
|
||||
|
||||
for( ss=size; ss>0; --ss )
|
||||
write(fns,&byt,1);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* Module local variables */
|
||||
#define DPHNUM 16 /* number of possible disks */
|
||||
ADDR *dphtab; /* table of offsets of Disk Parm Hdrs */
|
||||
DPH *dh[DPHNUM]; /* table of Disk Parm Hdrs */
|
||||
DINFO *di[DPHNUM]; /* table of info on DPHs */
|
||||
|
||||
|
||||
/* Module local predicates */
|
||||
#define ASKFOR(aa) ((aa) == 0xFFFF) /* Is this one we're sposed to ask for? */
|
||||
#define SHRMSK 0x8000 /* Is this shared with another drive? */
|
||||
#define SHARED(bb) ((bb)!=0xFFFF && (bb) & SHRMSK) /* Is this nd??bs field shared with another disk? */
|
||||
#define GETSHARED(cc) ((cc) & ~SHRMSK) /* Get the drive we share with */
|
||||
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* EXPORT
|
||||
/* initxios_info: gets whatever information GENSYS needs from xios
|
||||
/***************************************************************************/
|
||||
initxios_info(xf,goff) /* get info from xios file */
|
||||
WORD xf; /* xios file descriptor */
|
||||
WORD goff; /* group offset within xios file */
|
||||
{
|
||||
REG WORD ii; /* counter */
|
||||
DPB dd; /* a place to keep this info */
|
||||
EDPB ee; /* a place to keep this info */
|
||||
DPH *dph;
|
||||
DINFO *dinf;
|
||||
|
||||
csfd = xf; /* assign to global: set up cseek */
|
||||
csgoff = goff; /* assign to global */
|
||||
cseek(XTABLOC); /* go to where the XIOSTAB info is */
|
||||
read(xf,&xt,sizeof xt); /* read in the xios info */
|
||||
dphtab = xt.xt_dphtab; /* point to disk parm header table */
|
||||
|
||||
for( ii=0; ii<DPHNUM; ++ii ) { /* for each dph pointer */
|
||||
if( dphtab[ii] == 0 ) { /* is there a dph? */
|
||||
dh[ii]=NULLPTR;
|
||||
di[ii]=NULLPTR; /* no tickee, no washee */
|
||||
} else { /* aha! let's set up this info */
|
||||
dh[ii] = (DPH *)malloc(sizeof(DPH));
|
||||
di[ii] = (DINFO *)malloc(sizeof(DINFO));
|
||||
zfill(di[ii],sizeof(DINFO));
|
||||
cseek(dphtab[ii]);
|
||||
read(xf,dh[ii],sizeof(DPH));
|
||||
}
|
||||
} /* end of reading dph */
|
||||
for( ii=0; ii<DPHNUM; ++ii ) /* let's go thru it again */
|
||||
if( dh[ii] ) { /* if there's something there */
|
||||
dph = dh[ii];
|
||||
dinf = di[ii];
|
||||
cseek(dph->dph_dpb); /* point to the disk parm block */
|
||||
read(xf,&ee,sizeof(EDPB)); /* Read as though EDPB */
|
||||
if (ee.edpb_extflag == 0xFFFF) { /* Extended DPB */
|
||||
cseek(dph->dph_dpb+12); /* seek past extended info */
|
||||
} else {
|
||||
cseek(dph->dph_dpb);
|
||||
}
|
||||
read(xf,&dd,sizeof(DPB)); /* read DPH */
|
||||
dinf->d_blksize = 128 << dd.dpb_psh;
|
||||
dinf->d_csvsize = 0x7FFF & dd.dpb_cks;
|
||||
dinf->d_alvsize = (dd.dpb_dsm/8 + 1) * 2;
|
||||
dinf->d_shash = 4 * (1 + dd.dpb_drm);
|
||||
dinf->d_ndirbs = -1; /* ask for these by name! */
|
||||
dinf->d_ndatbs = -1;
|
||||
dinf->d_hashing = TRUE; /* default to hashing */
|
||||
} /* end of drive info init */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* EXPORT
|
||||
/* doxbufs: queries user for BDOS buffering info;
|
||||
/* exits only when all data valid
|
||||
/************************************************************************/
|
||||
BYTE *
|
||||
doxbufs(txt,bdtitle)
|
||||
BYTE *txt;
|
||||
BYTE *bdtitle;
|
||||
{
|
||||
BYTE cmds[CMDSLEN];
|
||||
BOOLEAN xiosvalid();
|
||||
EXTERN BYTE *clearit;
|
||||
|
||||
FOREVER {
|
||||
printf("%s",clearit); /* clear screen */
|
||||
printf("%s\n",bdtitle);
|
||||
dbufs_display(); /* display */
|
||||
printf("Drive (<CR> to exit) ? ");
|
||||
if( gets(cmds)!=cmds || *cmds==NULL ) { /* they hit <CR>? */
|
||||
if( xiosvalid() ) break;
|
||||
USERR("Please correct drive buffers information\n");
|
||||
press_return();
|
||||
continue;
|
||||
}
|
||||
askabout(cmds); /* go do what they want */
|
||||
}
|
||||
return NULLPTR; /* error msg for menu handler */
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* dbufs_display: display disk buffering info
|
||||
/************************************************************************/
|
||||
dbufs_display()
|
||||
{
|
||||
REG UWORD ii, jj, tot; /* counters */
|
||||
DPH *dph;
|
||||
DINFO *dinf;
|
||||
|
||||
tot = 0; /* init this */
|
||||
dcalcsizes(); /* check all the sizes */
|
||||
printf("\n\t*** Disk Buffering Information ***\n");
|
||||
printf(" Dir Max/Proc Data Max/Proc Hash Specified\n");
|
||||
printf("Drv Bufs Dir Bufs Bufs Dat Bufs -ing Buf Pgphs\n");
|
||||
printf("=== ==== ======== ==== ======== ==== =========\n");
|
||||
for( ii=0; ii<DPHNUM; ++ii ) { /*** for each drive ***/
|
||||
if( dphtab[ii]==0 ) continue; /* no DP Hdr for this drive */
|
||||
dph = dh[ii]; dinf = di[ii];
|
||||
printf(" %c: ",'A'+ii); /* print which drive */
|
||||
dspdnums(dph->dph_dirbcb,dinf->d_ndirbs,dinf->d_pmdirbs);
|
||||
dspdnums(dph->dph_datbcb,dinf->d_ndatbs,dinf->d_pmdatbs);
|
||||
if( ! ASKFOR(dph->dph_hstbl) )
|
||||
printf(" fixed ");
|
||||
else if( dinf->d_hashing )
|
||||
printf(" yes ");
|
||||
else printf(" no ");
|
||||
jj = dspdsize(dph,dinf);
|
||||
if( jj == -2 )
|
||||
printf(" fixed ");
|
||||
else if( jj == -1 )
|
||||
printf(" ?? ");
|
||||
else {
|
||||
printf(" %4.4x ",jj >> 4);
|
||||
tot += jj;
|
||||
}
|
||||
printf("\n");
|
||||
} /*** end for each drive ***/
|
||||
printf("Total paragraphs allocated to buffers: %x\n",tot >> 4);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* dspdsize: calculates a drive's user-requestable buffer size, in bytes
|
||||
/***************************************************************************/
|
||||
WORD
|
||||
dspdsize(dph,dinf) /* calculate size requested */
|
||||
DPH *dph; /* returns -1 if still needs info */
|
||||
DINFO *dinf; /* returns -2 if pre-allocated */
|
||||
{
|
||||
REG WORD siz;
|
||||
|
||||
siz=0;
|
||||
if( !ASKFOR(dph->dph_dirbcb) &&
|
||||
!ASKFOR(dph->dph_datbcb) &&
|
||||
!ASKFOR(dph->dph_hstbl) )
|
||||
return -2; /* nothing to say here */
|
||||
if( ASKFOR(dph->dph_dirbcb) ){
|
||||
if( ASKFOR(dinf->d_ndirbs) )
|
||||
return -1;
|
||||
if( !SHARED(dinf->d_ndirbs) )
|
||||
siz += dinf->d_sdirbs * dinf->d_ndirbs;
|
||||
}
|
||||
if( ASKFOR(dph->dph_datbcb) ){
|
||||
if( ASKFOR(dinf->d_ndatbs) )
|
||||
return -1;
|
||||
if( !SHARED(dinf->d_ndatbs) )
|
||||
siz += dinf->d_sdatbs * dinf->d_ndatbs;
|
||||
}
|
||||
if( ASKFOR(dph->dph_hstbl) ){
|
||||
if( dinf->d_hashing )
|
||||
siz += dinf->d_shash;
|
||||
}
|
||||
return siz;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* dspdnums: displays the data/dir buf numbers
|
||||
/***************************************************************************/
|
||||
dspdnums(nfix,ninput,npm) /* display subroutine */
|
||||
WORD nfix;
|
||||
WORD ninput;
|
||||
WORD npm;
|
||||
{
|
||||
if( !ASKFOR(nfix) )
|
||||
printf("fixed ");
|
||||
else if( SHARED(ninput) )
|
||||
printf("shares %c: ",'A'+GETSHARED(ninput));
|
||||
else {
|
||||
if( ASKFOR(ninput) )
|
||||
printf(" ?? ");
|
||||
else printf(" %2.2x ",ninput);
|
||||
if( ASKFOR(npm) )
|
||||
printf(" ?? ");
|
||||
else printf(" %2.2x ",npm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* dcalcsizes: calculates buffer sizes across shared buffers
|
||||
/***************************************************************************/
|
||||
dcalcsizes() /* make sure all the sizes are correct */
|
||||
{
|
||||
REG WORD ii, jj;
|
||||
REG WORD *pkk;
|
||||
DPH *dph;
|
||||
DINFO *dinf;
|
||||
|
||||
for( ii=0; ii<DPHNUM; ++ii ) /* init all sizes to zero */
|
||||
if(dphtab[ii]) {
|
||||
dinf = di[ii];
|
||||
dinf->d_sdirbs = dinf->d_sdatbs = 0;
|
||||
}
|
||||
for( ii=0; ii<DPHNUM; ++ii ) /* for each drive */
|
||||
if(dphtab[ii]) {
|
||||
dph = dh[ii];
|
||||
dinf = di[ii];
|
||||
if( ASKFOR(dph->dph_dirbcb) ) /* max out the size of a dirbuf */
|
||||
if( !ASKFOR(dinf->d_ndirbs) ) { /* if it's real data there */
|
||||
if( SHARED(dinf->d_ndirbs) ) {
|
||||
jj = GETSHARED(dinf->d_ndirbs);
|
||||
pkk = & ((di[jj])->d_sdirbs);
|
||||
} else
|
||||
pkk = & dinf->d_sdirbs;
|
||||
if( dinf->d_blksize > *pkk ) /* assign the maximum size found */
|
||||
*pkk = dinf->d_blksize;
|
||||
}
|
||||
if( ASKFOR(dph->dph_datbcb) ) /* max out the size of a data buf */
|
||||
if( !ASKFOR(dinf->d_ndatbs) ) {
|
||||
if( SHARED(dinf->d_ndatbs) ) {
|
||||
jj = GETSHARED(dinf->d_ndatbs);
|
||||
pkk = & ((di[jj])->d_sdatbs);
|
||||
} else
|
||||
pkk = & dinf->d_sdatbs;
|
||||
if( dinf->d_blksize > *pkk )
|
||||
*pkk = dinf->d_blksize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* ask user about a drive
|
||||
/***************************************************************************/
|
||||
askabout(drspec) /* ask user about a drive */
|
||||
BYTE *drspec;
|
||||
{
|
||||
REG WORD dr;
|
||||
DPH *dph;
|
||||
DINFO *dinf;
|
||||
BOOLEAN askhash();
|
||||
|
||||
if( *drspec == '*' ) {
|
||||
askstar(); /* get info, apply to all disks */
|
||||
return;
|
||||
}
|
||||
dr = toupper(*drspec) - 'A'; /* which drive do they want to fix? */
|
||||
if( dr<0 || dr>=DPHNUM || dphtab[dr]==0 || drspec[1] != ':') {
|
||||
USERR("Problem with '%s':\n",drspec);
|
||||
USERR("Please specify an existing drive between 'A:' and 'P:'\n");
|
||||
press_return();
|
||||
return;
|
||||
}
|
||||
dph = dh[dr];
|
||||
dinf = di[dr];
|
||||
if( dspdsize(dph,dinf) == -2 ) { /* is there anything to modify? */
|
||||
USERR("All buffers for %c: are fixed within the XIOS module.\n",
|
||||
dr+'A');
|
||||
USERR("You can't modify this fixed information in GENSYS.\n");
|
||||
press_return();
|
||||
return;
|
||||
}
|
||||
if( ASKFOR(dph->dph_dirbcb) ){
|
||||
dinf->d_ndirbs = asknd(1,FALSE); /* get directory info */
|
||||
dinf->d_pmdirbs = askpm(1,dinf->d_ndirbs);
|
||||
}
|
||||
if( ASKFOR(dph->dph_datbcb) ){
|
||||
dinf->d_ndatbs = asknd(2,(128==dinf->d_blksize)); /* get data info */
|
||||
dinf->d_pmdatbs = askpm(2,dinf->d_ndatbs);
|
||||
}
|
||||
if( ASKFOR(dph->dph_hstbl) ){
|
||||
dinf->d_hashing = askhash();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* askstar: asks buffering questions & applies to all ASKFOR/unanswered drives
|
||||
/****************************************************************************/
|
||||
askstar()
|
||||
{
|
||||
REG WORD dr;
|
||||
DPH *dph;
|
||||
DINFO *dinf;
|
||||
WORD andirbs, andirpms, andatbs, andatpms;
|
||||
BOOLEAN ahash, askhash();
|
||||
|
||||
andirbs = asknd(1,FALSE); /* Number of directory buffers? */
|
||||
andirpms = askpm(1,andirbs); /* Process Max Dir Bufs? */
|
||||
andatbs = asknd(2,FALSE); /* Number of data buffers? */
|
||||
andatpms = askpm(2,andatbs); /* Process Max Data Bufs? */
|
||||
ahash = askhash(); /* Hashing? */
|
||||
for( dr=0; dr<DPHNUM; ++dr )
|
||||
if( dphtab[dr] ) { /* for all existing drives */
|
||||
dph = dh[dr]; dinf = di[dr];
|
||||
if( ASKFOR(dph->dph_dirbcb) )
|
||||
if( ASKFOR(dinf->d_ndirbs) ) {
|
||||
dinf->d_ndirbs = andirbs;
|
||||
dinf->d_pmdirbs = andirpms;
|
||||
}
|
||||
if( ASKFOR(dph->dph_datbcb) )
|
||||
if( ASKFOR(dinf->d_ndatbs) ) {
|
||||
dinf->d_ndatbs = andatbs;
|
||||
dinf->d_pmdatbs = andatpms;
|
||||
}
|
||||
if( ASKFOR(dph->dph_hstbl) )
|
||||
dinf->d_hashing = ahash;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* asknd: ask the user for the number of dir/data buffers
|
||||
/***************************************************************************/
|
||||
WORD
|
||||
asknd(type,zero_ok)
|
||||
WORD type; /* 1=dir, 2=data */
|
||||
BOOLEAN zero_ok;
|
||||
{
|
||||
REG WORD val, jj;
|
||||
BYTE *name;
|
||||
BYTE cmds[CMDSLEN];
|
||||
DPH *dph;
|
||||
|
||||
if( type==1 ) name="directory"; else name="data";
|
||||
FOREVER {
|
||||
printf("Number of %s buffers, or drive to share with ? ",name);
|
||||
gets( cmds );
|
||||
if( cmds[1] != ':' ) {
|
||||
val = atoih(cmds);
|
||||
if( val > 0 && val <= 127 ) break;
|
||||
if(*cmds == '0') {
|
||||
if( zero_ok ) break;
|
||||
USERR("Number of buffers must be greater than 0\n");
|
||||
press_return();
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
val = toupper(*cmds) - 'A'; /* which drive do they want? */
|
||||
if( val>=0 && val<DPHNUM && dphtab[val]!=0) { /* a drive maybe? */
|
||||
dph = dh[val];
|
||||
if( type==1 ) jj = dph->dph_dirbcb;
|
||||
else jj = dph->dph_datbcb;
|
||||
if( ASKFOR(jj) ) {
|
||||
if( type==1 ) jj = di[val]->d_ndirbs;
|
||||
else jj = di[val]->d_ndatbs;
|
||||
if( !SHARED(jj) ) {
|
||||
val |= SHRMSK; /* turn on sharing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
USERR("Drive %c: is not available for sharing\n",'A'+val);
|
||||
press_return();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
USERR("Please input a number, or an existing drive from 'A:' to 'P:'\n");
|
||||
press_return();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/************************************/
|
||||
/* askpm: ask about process maximum
|
||||
/************************************/
|
||||
WORD
|
||||
askpm(type,pmmax)
|
||||
WORD type;
|
||||
WORD pmmax;
|
||||
{
|
||||
REG WORD val;
|
||||
BYTE *cmds[CMDSLEN];
|
||||
BYTE *name;
|
||||
|
||||
switch(type) { case 1: name="directory"; break; case 2: name="data"; }
|
||||
if( SHARED(pmmax) || pmmax<=0 )
|
||||
return 0;
|
||||
FOREVER { /* get input from user */
|
||||
printf("Maximum %s buffers per process [%x]? ",name,pmmax);
|
||||
gets( cmds );
|
||||
if( *cmds==NULL )
|
||||
val = pmmax; /* default value */
|
||||
else val = atoih(cmds);
|
||||
if( val > 0 && val <= pmmax ) break;
|
||||
USERR("Maximum must be > zero and <= %x\n",pmmax);
|
||||
press_return();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/*****************************************/
|
||||
/* askhash: ask user if they'd like to hash
|
||||
/*****************************************/
|
||||
BOOLEAN
|
||||
askhash()
|
||||
{
|
||||
REG WORD val;
|
||||
BYTE *cmds[CMDSLEN], *cp;
|
||||
|
||||
FOREVER {
|
||||
printf("Hashing [yes] ? ");
|
||||
gets( cmds );
|
||||
if( *cmds == NULL )
|
||||
return TRUE;
|
||||
for( cp=cmds; *cp; ++cp ) {
|
||||
if( *cp==' ' || *cp=='\t' ) {
|
||||
*cp = NULL;
|
||||
break;
|
||||
}
|
||||
if( isupper(*cp) )
|
||||
*cp = tolower(*cp);
|
||||
}
|
||||
if( (val=whichof(cmds,",yes,true,on,hashing,no,false,off")) > 0 )
|
||||
break;
|
||||
USERR("Please answer 'hashing', 'yes', or 'no'.\n");
|
||||
press_return();
|
||||
}
|
||||
return val<=4; /* TRUE iff answer was one of 1st four */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* EXPORT
|
||||
/* xiosvalid: validates that all the user-requestable info has been filled in
|
||||
/************************************************************************/
|
||||
BOOLEAN
|
||||
xiosvalid()
|
||||
{
|
||||
REG WORD ii;
|
||||
REG WORD ndph;
|
||||
|
||||
ndph = 0;
|
||||
for( ii=0; ii<DPHNUM; ++ii )
|
||||
if( dphtab[ii]!=0 ) {
|
||||
if( dspdsize(dh[ii],di[ii]) == -1 )
|
||||
return FALSE;
|
||||
++ndph;
|
||||
}
|
||||
if( ndph==0 ) {
|
||||
USERR("no dph information in xios header...");
|
||||
exit(1);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* EXPORT
|
||||
/* genxios: generates disk buffers (to be placed after the rest of the
|
||||
/* system tables.
|
||||
/*************************************************************************/
|
||||
#define OFF_BCBPTR 0xA
|
||||
#define OFF_DPHHTAB 0x12
|
||||
ADDR locrsvd_off; /* local reserved offset, for DIRBUF fix */
|
||||
|
||||
ADDR /* returns final offset */
|
||||
genxios(doffset) /* generate the disk buffers */
|
||||
ADDR doffset; /* offset in data file */
|
||||
{
|
||||
REG WORD ii, jj; /* counter */
|
||||
REG BOOLEAN dm; /* modified flag */
|
||||
REG ADDR lastlink; /* used for threading lists */
|
||||
ADDR locbufs_off; /* local buffer offset for DIRBUF grouping */
|
||||
LONG dmagic; /* where word needing fix goes into file */
|
||||
BCB bcb; /* place for organizing, calc for fixups */
|
||||
BCBH bcbh;
|
||||
DPH *dph;
|
||||
DINFO *dinf;
|
||||
BOOLEAN xiosvalid();
|
||||
|
||||
if( !xiosvalid() ) CRASH("invalid disk buffer information");
|
||||
|
||||
for( ii=0; ii<DPHNUM; ++ii ) /* allocate CHECK SUM VECTORS */
|
||||
if( dh[ii] ) { /* if there's something to look at */
|
||||
dph = dh[ii]; /* convenient ptr */
|
||||
dinf = di[ii];
|
||||
if( ASKFOR(dph->dph_csv) ){
|
||||
dinf->d_modified = TRUE;
|
||||
if( dinf->d_csvsize == 0 )
|
||||
dph->dph_csv=0;
|
||||
else {
|
||||
dph->dph_csv = doffset;
|
||||
doffset += bufwrite(dinf->d_csvsize,ZBYTE);
|
||||
}
|
||||
}
|
||||
}
|
||||
for( ii=0; ii<DPHNUM; ++ii ) /* allocate ALLOCATION TABLE VECTORS */
|
||||
if( dh[ii] ) { /* if there's something to look at */
|
||||
dph = dh[ii]; /* convenient ptr */
|
||||
dinf = di[ii];
|
||||
if( ASKFOR(dph->dph_alv) ){
|
||||
dinf->d_modified = TRUE;
|
||||
dph->dph_alv = doffset;
|
||||
doffset += bufwrite(dinf->d_alvsize,ZBYTE);
|
||||
}
|
||||
}
|
||||
locbufs_off = 0; /* amount (bytes) of local dir buffer*/
|
||||
for( ii=0; ii<DPHNUM; ++ii ) /* allocate DIR BCBs & BUFFERS */
|
||||
if( dh[ii] ) { /* if there's something to look at */
|
||||
dph = dh[ii]; /* convenient ptr */
|
||||
dinf = di[ii];
|
||||
if( ASKFOR(dph->dph_dirbcb) ){ /* DIR BCBs */
|
||||
dinf->d_modified = TRUE;
|
||||
if( ! SHARED(dinf->d_ndirbs) ) { /* take care of sharing later */
|
||||
lastlink=0; /* linker */
|
||||
zfill(&bcb,sizeof(BCB)); /* init to zeroes */
|
||||
bcb.bcb_drv = 0xFF;
|
||||
for( jj=dinf->d_ndirbs; jj>0; --jj ){
|
||||
bcb.bcb_link = lastlink;
|
||||
/* pts to loc of buffer relative to locrsvd_off */
|
||||
bcb.bcb_bufptr = locbufs_off;
|
||||
locbufs_off += dinf->d_sdirbs; /* increase buf size */
|
||||
/* calc where bcb will be written to, for fixlater */
|
||||
dmagic = lseek(fns,0L,1) + OFF_BCBPTR;
|
||||
fixlater(dmagic,F_ADD,&locrsvd_off);
|
||||
/* finally, write out the bcb info */
|
||||
lastlink = doffset; /* point to the bcb */
|
||||
doffset += datwrite(&bcb,sizeof bcb);
|
||||
}
|
||||
bcbh.bcbh_lr = lastlink; /* fill in the bcb hdr */
|
||||
bcbh.bcbh_pm = dinf->d_pmdirbs;
|
||||
dph->dph_dirbcb = doffset; /* link to head of list */
|
||||
/* write out a buffer control block hdr */
|
||||
doffset += datwrite(&bcbh,sizeof bcbh);
|
||||
}
|
||||
}
|
||||
}
|
||||
for( ii=0; ii<DPHNUM; ++ii ) /* allocate DATA BCBs & BUFFERS */
|
||||
if( dh[ii] ) { /* if there's something to look at */
|
||||
dph = dh[ii]; /* convenient ptr */
|
||||
dinf = di[ii];
|
||||
/* the bufs can go out of the system page, but the bcbs need to be in */
|
||||
if( ASKFOR(dph->dph_datbcb) ){ /* DATA BCBs: !!temporary!! */
|
||||
dinf->d_modified = TRUE;
|
||||
if( ! SHARED(dinf->d_ndatbs) ) { /* do sharing later */
|
||||
lastlink=0; /* linker */
|
||||
zfill(&bcb,sizeof(BCB)); /* init to zeroes */
|
||||
bcb.bcb_drv = 0xFF;
|
||||
for( jj=dinf->d_ndatbs; jj>0; --jj ){
|
||||
bcb.bcb_link = lastlink;
|
||||
bcb.bcb_bufptr = bufs_seg; /* point into reserved area */
|
||||
bufs_seg += (dinf->d_sdatbs) >>4; /* cvt to pgphs */
|
||||
/* calculate where the bcb.bcb_bufptr will be written in file */
|
||||
dmagic = lseek(fns,0L,1) + OFF_BCBPTR;
|
||||
fixlater(dmagic,F_ADD,&rsvd_seg); /* fix the bufptr */
|
||||
lastlink = doffset;
|
||||
/* write out a buffer control block */
|
||||
doffset += datwrite(&bcb,sizeof bcb);
|
||||
}
|
||||
bcbh.bcbh_lr = lastlink; /* fill in the bcb hdr */
|
||||
bcbh.bcbh_pm = dinf->d_pmdatbs;
|
||||
dph->dph_datbcb = doffset; /* link to head of list */
|
||||
/* write out a buffer control block hdr */
|
||||
doffset += datwrite(&bcbh,sizeof bcbh);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* now write the local directory buffers */
|
||||
locrsvd_off = doffset; /* address of directory buffer area */
|
||||
doffset += bufwrite(locbufs_off,ZBYTE); /* write out the buffers */
|
||||
|
||||
/* dmagic: magic number to add to dphtab[ii] */
|
||||
dmagic = OFF_DPHHTAB + fldstart;/* where in file does SYSDAT start */
|
||||
|
||||
for( ii=0; ii<DPHNUM; ++ii ) /* allocate HASH TABLES */
|
||||
if( dh[ii] ) { /* if there's something to look at */
|
||||
dph = dh[ii]; /* convenient ptr */
|
||||
dinf = di[ii];
|
||||
if( ASKFOR(dph->dph_hstbl) ) { /* HASH TABLE ALLOC */
|
||||
dinf->d_modified = TRUE;
|
||||
if( dinf->d_hashing ) {
|
||||
dph->dph_hstbl = bufs_seg; /* point into reserved area */
|
||||
bufs_seg += (dinf->d_shash) >>4; /* cvt bytes to pgphs */
|
||||
/* remember where the dph_hstbl word will be stored */
|
||||
/* so we can adjust bufs_seg by starting loc of rsvd_seg */
|
||||
fixlater(dmagic+dphtab[ii],F_ADD,&rsvd_seg);
|
||||
} else dph->dph_hstbl = 0;
|
||||
}
|
||||
} /**** end of processing ****/
|
||||
|
||||
for( ii=0; ii<DPHNUM; ++ii ) /* resolve shared buffers */
|
||||
if( dh[ii] ) {
|
||||
if( ASKFOR(dh[ii]->dph_dirbcb) ) {
|
||||
jj = GETSHARED(di[ii]->d_ndirbs);
|
||||
dh[ii]->dph_dirbcb = dh[jj]->dph_dirbcb;
|
||||
}
|
||||
if( ASKFOR(dh[ii]->dph_datbcb) ) {
|
||||
jj = GETSHARED(di[ii]->d_ndatbs);
|
||||
dh[ii]->dph_datbcb = dh[jj]->dph_datbcb;
|
||||
}
|
||||
} /* end resolve shared buffers */
|
||||
|
||||
return doffset;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* EXPORT
|
||||
/* fixupxios_info: does the fixup for the dph info in the xios
|
||||
/*************************************************************************/
|
||||
fixupxios_info() /* call from fixups */
|
||||
{
|
||||
REG WORD ii; /* counter */
|
||||
REG LONG dmagic; /* addr var */
|
||||
|
||||
for( ii=0; ii<DPHNUM; ++ii )
|
||||
if( dh[ii] ) /* if there's something to look at */
|
||||
if( di[ii]->d_modified ) {
|
||||
dmagic = fldstart + dphtab[ii];
|
||||
lseek(fns,dmagic,0); /* where to write to */
|
||||
write(fns,dh[ii],sizeof(DPH)); /* what to write */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user