Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

766 lines
24 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/************************************************************************/
/************************************************************************/
/* 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 */
}
}