mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-27 18:34:07 +00:00
Upload
Digital Research
This commit is contained in:
@@ -0,0 +1,569 @@
|
||||
/*********************************************************************/
|
||||
/*********************************************************************/
|
||||
/* genc3.c
|
||||
/* EXPORTS gentable() - the routine which builds all the tables
|
||||
/*********************************************************************/
|
||||
/*********************************************************************/
|
||||
#ifndef MAINMODULE
|
||||
#include <genccpm.h>
|
||||
#endif
|
||||
|
||||
|
||||
MLOCAL UWORD rsp_last; /* link to previous RSP */
|
||||
MLOCAL UWORD rsp_seg; /* where next RSP seg gets written */
|
||||
|
||||
#define ALIGN(xx) (((xx)+0xF)&0xFFF0)
|
||||
#define BYTE_ADJUST(yy) if(yy>0xFF) yy=0xFF
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
UWORD /* return new offset */
|
||||
segwrite(nbs) /* pad to paragraph boundary */
|
||||
UWORD nbs; /* old offset */
|
||||
{
|
||||
REG UWORD nps;
|
||||
|
||||
if( nbs & 0xF ) { /* does it need padding? */
|
||||
nps = 0x10 - (nbs & 0xF); /* number pad bytes needed */
|
||||
write(fns,"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",nps);
|
||||
return (nbs+nps);
|
||||
} else return nbs;
|
||||
}
|
||||
|
||||
UWORD /* return num paragraphs */
|
||||
padwrite(nbs) /* pad to paragraph boundary */
|
||||
UWORD nbs; /* num bytes needing padding */
|
||||
{
|
||||
return segwrite(nbs) >> 4; /* convert to pgphs */
|
||||
}
|
||||
|
||||
UWORD
|
||||
datwrite(from,size)
|
||||
BYTE *from;
|
||||
WORD size;
|
||||
{
|
||||
if( write(fns,from,size) != size ) {
|
||||
fprintf(stderr,"ERROR: Write to new SYS file failed\n");
|
||||
fprintf(stderr,"Out of room on disk?\n");
|
||||
exit(1);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
MLOCAL LONG oldladdr=0; /* save previous address for comparison */
|
||||
#define BIGWORD 0x0000ffffL
|
||||
chkaddr(uaddr) /* check for SYSDAT overflow */
|
||||
UWORD uaddr;
|
||||
{
|
||||
LONG laddr;
|
||||
|
||||
laddr = BIGWORD & uaddr;
|
||||
if( laddr < oldladdr ) {
|
||||
USERR("ERROR - System Data Area has grown too large\n");
|
||||
USERR("Try reducing the size of some of the tables\n");
|
||||
exit(1);
|
||||
}
|
||||
oldladdr = laddr; /* save for wrap around compare */
|
||||
}
|
||||
/* this is a kluge: I did it because I couldn't get the LONG cast */
|
||||
/* to work without doing sign extension... whf 1/20/83 */
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* EXPORT gentables: generates various tables in system data area,
|
||||
/* and handles RSPs
|
||||
/**************************************************************************/
|
||||
VOID gentables()
|
||||
{
|
||||
LOCAL WORD nmparts; /* number of memory partitions */
|
||||
LOCAL WORD nsat_items; /* number of SAT items in qmau */
|
||||
LOCAL UWORD damds; /* offset of beginning of tables */
|
||||
LOCAL UWORD daqbuf; /* offset of beginning of qbuf */
|
||||
LOCAL LONG daend; /* sys data offset: end of data area */
|
||||
LOCAL UWORD doffset; /* current offset into data area */
|
||||
LOCAL UWORD lastlink; /* helps link lists together */
|
||||
LOCAL WORD count; /* counts num list items being generated */
|
||||
LOCAL UWORD ucount; /* unsigned counter */
|
||||
LOCAL MLIST *mn; /* for trapsing down memroot */
|
||||
LOCAL WORD nump; /* local number partitions */
|
||||
LOCAL UWORD saddr; /* local starting addr */
|
||||
LOCAL WORD length; /* local partition length */
|
||||
BYTE buf[SECSIZ]; /* an area for writing */
|
||||
LOCAL LONG dmagic; /* fixup location for xt_alloc info */
|
||||
UWORD genmfl(); /* gen a memory free list */
|
||||
UWORD genxios(); /* go gen the xios disk buffers */
|
||||
DLIST *rs; /* ptr to rsp list */
|
||||
MD md; /* sample memory descriptor */
|
||||
PD pd; /* " process descriptor */
|
||||
QCB qcb; /* " queue control block */
|
||||
CCB ccb; /* " channel control block */
|
||||
LOCK lock; /* " lock list item */
|
||||
FLAG flg; /* " flag item */
|
||||
SATITEM sat; /* " sub allocation table item */
|
||||
|
||||
if(verbose) printf("Generating tables\n");
|
||||
FCHECK(fns); /* File error check */
|
||||
|
||||
/* pre-calculate certain vars */
|
||||
bufs_seg = 0; /* total buf segs allocated in rsvd_seg */
|
||||
if( (nmparts=cntmlist(memroot)) <= 0 )
|
||||
CRASH("invalid memory list, aborting\n");
|
||||
totpds = xtrapds + nmparts; /* 1 pd per memory partition, plus xtras */
|
||||
BYTE_ADJUST(totpds);
|
||||
totmds = (3*totpds) + nmparts + (nmparts>>1); /* 3 mds per process, plus */
|
||||
/* 1 per partition, plus extra for */
|
||||
/* memory allocator worst case */
|
||||
BYTE_ADJUST(totmds);
|
||||
nsat_items = (1+ (1+2*totqcbs)); /* 1 for header entry plus worst case */
|
||||
|
||||
dltotal = dlsysdat+dlxios; /* keep track of total data length in pgphs */
|
||||
doffset = dltotal << 4; /* calculate current data offset */
|
||||
dsotables = doffset; /* mark the start of tables */
|
||||
chkaddr(doffset); /* init the function */
|
||||
|
||||
/* MEMORY FREE LIST */
|
||||
locmfl = lseek(fns,0L,1); /* remember where we are writing this */
|
||||
doffset = genmfl(doffset); /* gen the mem free list */
|
||||
|
||||
lastlink = 0; /* UNUSED MEMORY DESCRIPTOR LIST */
|
||||
zfill(&md,sizeof md); /* init the mem descriptor */
|
||||
for( count=totmds-nmparts; count>0; --count ) { /* generate rest of mds */
|
||||
md.md_link = lastlink;
|
||||
lastlink = doffset;
|
||||
doffset += datwrite(&md,sizeof(md));
|
||||
}
|
||||
*sd_mdul = lastlink; /* store ptr to mds unused */
|
||||
|
||||
lastlink = 0; /* UNUSED PROCESS DESCRIPTOR LIST */
|
||||
zfill(&pd,sizeof(pd));
|
||||
for( count=totpds; count>0; --count ) {
|
||||
pd.pd_link = lastlink;
|
||||
lastlink = doffset;
|
||||
doffset += datwrite(&pd,sizeof(pd));
|
||||
}
|
||||
*sd_pul = lastlink; /* store ptr to pds unused */
|
||||
|
||||
lastlink = 0; /* UNUSED QUEUE CONTROL BLOCKS */
|
||||
zfill(&qcb,sizeof(qcb));
|
||||
for( count=totqcbs; count>0; --count ) {
|
||||
qcb.qc_link = lastlink;
|
||||
lastlink = doffset;
|
||||
doffset += datwrite(&qcb,sizeof(qcb));
|
||||
}
|
||||
*sd_qul = lastlink; /* store ptr to unused qcb list */
|
||||
|
||||
lastlink = 0; /* UNUSED LOCKED ITEMS LIST */
|
||||
zfill(&lock,sizeof(lock));
|
||||
for( count=totopen; count>0; --count ) {
|
||||
lock.lo_link = lastlink;
|
||||
lastlink = doffset;
|
||||
doffset += datwrite(&lock,sizeof(lock));
|
||||
}
|
||||
*sd_lul = lastlink; /* store ptr to unused lock items list */
|
||||
|
||||
*sd_ncns = xt.xt_nvcns; /* transfer info from XIOS to SYSDAT*/
|
||||
*sd_ncondev = xt.xt_nccbs;
|
||||
*sd_ccb = xt.xt_ccb;
|
||||
*sd_nlst = xt.xt_nlcbs;
|
||||
*sd_nlstdev = xt.xt_nlcbs;
|
||||
*sd_lcb = xt.xt_lcb;
|
||||
*sd_nciodev = *sd_ncondev + *sd_nlstdev;
|
||||
*sd_tickspsec = xt.xt_ticks_sec;
|
||||
|
||||
*sd_xpcns = xt.xt_xpcns; /* # physical consoles;FMB */
|
||||
*sd_flags = doffset; /* FLAG TABLE */
|
||||
flg.fl_status = -1;
|
||||
flg.fl_pd = -1;
|
||||
for( count= *sd_nflags; count>0; --count ) {
|
||||
doffset += datwrite(&flg,sizeof(flg));
|
||||
}
|
||||
|
||||
|
||||
|
||||
doffset = genxios(doffset); /* go gen the xios buffering info */
|
||||
chkaddr(doffset); /* is table space too big? */
|
||||
|
||||
doffset = segwrite(doffset); /* Q Sub Alloc Tab HEADER */
|
||||
*sd_qmastart = dsstart + (doffset>>4); /* fill in seg addr */
|
||||
daqbuf = doffset + sizeof(sat)*nsat_items;
|
||||
zfill(&sat,sizeof(sat));
|
||||
sat.sa_start = --nsat_items; /* decr before write */
|
||||
doffset += datwrite(&sat,sizeof(sat)); /* write the header */
|
||||
/* Q Sub Alloc Tab ENTRIES */
|
||||
sat.sa_start = daqbuf;
|
||||
sat.sa_length = qbuflen; /* byte value */
|
||||
*sd_qmalen = qbuflen>>4; /* pgph value */
|
||||
doffset += datwrite(&sat,sizeof(sat)); /* write the first sat entry */
|
||||
|
||||
zfill(&sat,sizeof(sat));
|
||||
for( count= --nsat_items; count>0; --count ) {
|
||||
doffset += datwrite(&sat,sizeof(sat));/* write the rest of the sat entries */
|
||||
}
|
||||
|
||||
zfill(buf,SECSIZ); /* Q BUFFER AREA */
|
||||
for( ucount=qbuflen; ucount>0; ucount -= length ) {
|
||||
length = (ucount>SECSIZ ? SECSIZ : ucount);
|
||||
doffset += datwrite(buf,length);
|
||||
}
|
||||
|
||||
chkaddr(doffset); /* too big? */
|
||||
daend = padwrite(doffset); /* end Q BUF AREA and TABLES */
|
||||
|
||||
dltables = daend - dltotal; /* compute length of tables in pgphs */
|
||||
dltotal = daend; /* keep track of total data length */
|
||||
|
||||
/*** now fill in the rsps ***/
|
||||
if(verbose) printf("Appending RSPs to system file\n");
|
||||
FCHECK(fns); /* File error check */
|
||||
rsp_last = 0;
|
||||
rsp_seg = dsstart + daend;
|
||||
for( rs=rsps; rs!=NULLPTR; rs=rs->dlnext ) /* follow the rsp list */
|
||||
xfer_rsp(rs->dlname);
|
||||
*sd_rspseg = rsp_last;
|
||||
dlrsps = rsp_seg - (dsstart + daend);
|
||||
dltotal += dlrsps;
|
||||
rsvd_seg = rsp_seg;
|
||||
length = xt.xt_alloc; /* how much memory is XIOS requesting */
|
||||
xt.xt_alloc = rsvd_seg+bufs_seg; /* this is the place they can use */
|
||||
dmagic = fldstart; /* location of SYSDAT in SYS file */
|
||||
dmagic += XTABALLOC; /* add in where xt_alloc goes to */
|
||||
fixlater(dmagic,F_PUT,&(xt.xt_alloc)); /* fix this number later on */
|
||||
bufs_seg += length; /* allocate requested space */
|
||||
*sd_endseg = rsvd_seg+bufs_seg; /* this is where we reserve to */
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* genmfl: writes out a memory free list, assuming file 'fns' is seeking
|
||||
/* correctly into file.
|
||||
/**************************************************************************/
|
||||
UWORD
|
||||
genmfl(doffset)
|
||||
UWORD doffset;
|
||||
{
|
||||
REG MLIST *mn; /* ptr into EDSYS mem list */
|
||||
LOCAL WORD nump;
|
||||
LOCAL UWORD lastlink, length, saddr; /* counter vars */
|
||||
MD md; /* mem desc struct */
|
||||
|
||||
*sd_mfl = doffset; /* gen this list forward */
|
||||
zfill(&md,sizeof(md)); /* init the data structure */
|
||||
for( mn=memroot; mn!=NULLPTR; mn=mn->mlnext ) {
|
||||
nump = (mn->mllast - mn->mlfirst) / mn->mlsize;
|
||||
saddr = mn->mlfirst; /* use this starting address */
|
||||
length = md.md_length = mn->mlsize; /* size in pgphs */
|
||||
for( ; nump>0; --nump ) { /* for each partition */
|
||||
doffset += sizeof(md); /* incr by sizeof object */
|
||||
lastlink = doffset; /* record address of where this will go */
|
||||
if( nump == 1 ) { /* on this group's last partition */
|
||||
length = md.md_length = mn->mllast-saddr; /* stick in rmdr */
|
||||
if( mn->mlnext == NULLPTR ) /* on the very last partition */
|
||||
lastlink=0; /* set end of list */
|
||||
}
|
||||
md.md_link = lastlink; /* thread the list */
|
||||
md.md_start = saddr; /* set the starting addr */
|
||||
write(fns,&md,sizeof(md)); /* put it into the NEWSYS file */
|
||||
saddr += length; /* next md starts here */
|
||||
}
|
||||
} /* finished with memory partitions */
|
||||
return doffset;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
VOID
|
||||
zfill(addr,num)
|
||||
BYTE *addr;
|
||||
WORD num;
|
||||
{
|
||||
for( ; num>0; --num )
|
||||
*addr++ = '\0';
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
#define RSPHDR struct rsp_header
|
||||
RSPHDR {
|
||||
UWORD rs_link; /* link to other RSPs */
|
||||
WORD rs_sdatvar; /* SYSDAT offset: num copies */
|
||||
BYTE rs_ncopies; /* local: num copies */
|
||||
BYTE rs_space[11]; /* fill up rest of header */
|
||||
};
|
||||
|
||||
RSPHDR *rhdr; /* RSP's header */
|
||||
PD *rpd; /* RSP's process descriptor area */
|
||||
UDA *ruda; /* RSP's uda area */
|
||||
#define RHDRSIZE (sizeof(RSPHDR)+sizeof(PD)+sizeof(UDA))
|
||||
#define RHDRPGPHS (RHDRSIZE>>4)
|
||||
MLOCAL BYTE rh[RHDRSIZE]; /* where to read the RSP header */
|
||||
MLOCAL BYTE rspnbuf[9]; /* room for copy of pd name */
|
||||
MLOCAL BYTE *rspname; /* name of RSP */
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
xfer_rsp(rspnm)
|
||||
BYTE *rspnm; /* name of rsp */
|
||||
{
|
||||
LOCAL WORD fr; /* rsp file descriptor */
|
||||
LOCAL WORD ncs; /* number of copies */
|
||||
|
||||
rhdr = rh; /* init these vars */
|
||||
rpd = rh+sizeof(*rhdr); /* points to process descriptor */
|
||||
ruda = rh+sizeof(*rhdr)+sizeof(*rpd); /* points to user data area */
|
||||
if( (fr=BROPEN(rspnm)) < 0 ) {
|
||||
printf("can't open RSP %s\n",rspnm);
|
||||
exit(1);
|
||||
}
|
||||
if( grpseek(fr,GTYPDATA) > 0L){ /* is there a data group? */
|
||||
ncs = grab_hdr(fr);
|
||||
if( rpd->pd_mem == 0 )
|
||||
xfer_separate_rsp(fr,ncs);
|
||||
else xfer_pure_rsp(fr,ncs);
|
||||
} else {
|
||||
grpseek(fr,GTYPCODE);
|
||||
ncs = grab_hdr(fr);
|
||||
if( rpd->pd_mem == 0 )
|
||||
xfer_mixed_rsp(fr,ncs);
|
||||
else {
|
||||
USERR("RSP %s has non zero MEM field and no data group\n",
|
||||
rspnm);
|
||||
}
|
||||
}
|
||||
close(fr);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
WORD
|
||||
grab_hdr(fr)
|
||||
WORD fr;
|
||||
{
|
||||
REG WORD rv; /* return val */
|
||||
EXTERN BYTE sdat_area[];
|
||||
|
||||
rspname = NULLPTR; /* blank out this name */
|
||||
read(fr,rh,RHDRSIZE);
|
||||
strncpy(rspnbuf,rpd->pd_name,8);/* store this in case we need it */
|
||||
if( rhdr->rs_sdatvar != 0 ) {
|
||||
rspname = rspnbuf;
|
||||
rv = sdat_area[rhdr->rs_sdatvar] - 1;
|
||||
} else {
|
||||
if( rhdr->rs_ncopies > 0 )
|
||||
rspname = rspnbuf;
|
||||
rv = rhdr->rs_ncopies;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
xfer_separate_rsp(fr,ncs) /* (many) data and (many) code segs */
|
||||
WORD fr; /* file desc of RSP file */
|
||||
WORD ncs; /* number of copies */
|
||||
{
|
||||
WORD ii; /* counter */
|
||||
|
||||
for( ii=0; ii<=ncs; ++ii) {
|
||||
ruda->ud_dsinit = ruda->ud_esinit = ruda->ud_ssinit = rsp_seg;
|
||||
ruda->ud_csinit = rsp_seg + (grpseek(fr,GTYPDATA)>>4);
|
||||
rhdr->rs_ncopies = ii;
|
||||
if( rspname ) /* do we need to insert a modfied name? */
|
||||
putname(rpd->pd_name,rspname,ii);
|
||||
rhdr->rs_link = rsp_last; /* link together the list */
|
||||
rsp_last = rsp_seg; /* remember this for next time */
|
||||
write(fns,rh,RHDRSIZE); /* write out the RSP header */
|
||||
rsp_seg += RHDRPGPHS + xferpart_grp(fr,GTYPDATA,RHDRPGPHS);
|
||||
rsp_seg += xferpart_grp(fr,GTYPCODE,0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
xfer_pure_rsp(fr,ncs) /* (many) data segs and one code segs */
|
||||
WORD fr; /* file desc of RSP file */
|
||||
WORD ncs; /* number of copies */
|
||||
{
|
||||
WORD ii; /* counter */
|
||||
|
||||
ruda->ud_csinit = rsp_seg + (1+ncs) * (grpseek(fr,GTYPDATA) >> 4);
|
||||
for( ii=0; ii<=ncs; ++ii) {
|
||||
ruda->ud_dsinit = ruda->ud_esinit = ruda->ud_ssinit = rsp_seg;
|
||||
rhdr->rs_ncopies = ii;
|
||||
if( rspname ) /* do we need to insert a modfied name? */
|
||||
putname(rpd->pd_name,rspname,ii);
|
||||
rpd->pd_mem = 8; /* magic ptr to md in rsphdr */
|
||||
rhdr->rs_link = rsp_last; /* link together the list */
|
||||
rsp_last = rsp_seg; /* remember this for next time */
|
||||
write(fns,rh,RHDRSIZE); /* write out the RSP header */
|
||||
rsp_seg += RHDRPGPHS + xferpart_grp(fr,GTYPDATA,RHDRPGPHS);
|
||||
}
|
||||
rsp_seg += xferpart_grp(fr,GTYPCODE,0);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
xfer_mixed_rsp(fr,ncs) /* (many) mixed code/data segs */
|
||||
WORD fr; /* file desc of RSP file */
|
||||
WORD ncs; /* number of copies */
|
||||
{
|
||||
WORD ii; /* counter */
|
||||
|
||||
for( ii=0; ii<=ncs; ++ii) {
|
||||
ruda->ud_csinit = ruda->ud_dsinit = ruda->ud_esinit =
|
||||
ruda->ud_ssinit = rsp_seg;
|
||||
rhdr->rs_ncopies = ii;
|
||||
if( rspname ) /* do we need to insert a modfied name? */
|
||||
putname(rpd->pd_name,rspname,ii);
|
||||
rhdr->rs_link = rsp_last; /* link together the list */
|
||||
rsp_last = rsp_seg; /* remember this for next time */
|
||||
write(fns,rh,RHDRSIZE); /* write out the RSP header */
|
||||
rsp_seg += RHDRPGPHS + xferpart_grp(fr,GTYPCODE,RHDRPGPHS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
putname(to,from,num)
|
||||
BYTE *to;
|
||||
BYTE *from;
|
||||
WORD num;
|
||||
{
|
||||
BYTE buf[15];
|
||||
BYTE *bp;
|
||||
WORD jj;
|
||||
|
||||
for( bp=buf, jj=0; *from && *from != ' ' && jj<8; ++jj )
|
||||
*bp++ = *from++;
|
||||
if( jj>6 )
|
||||
bp = buf+7;
|
||||
sprintf(bp,"%x ",num);
|
||||
for( bp=buf, jj=0; jj<8; jj++ )
|
||||
*to++ = *bp++;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* dolbl: modify operating system version label */
|
||||
/************************************************************************/
|
||||
#define MAXLBL 83
|
||||
|
||||
BYTE *
|
||||
dolbl(txt,lbtitle)
|
||||
BYTE *txt; /* cmd val */
|
||||
BYTE *lbtitle;
|
||||
{
|
||||
DLIST *sl, *psl; /* ptrs to system labels */
|
||||
BYTE mb[MAXLBL]; /* max size of each line */
|
||||
EXTERN BYTE *clearit;
|
||||
|
||||
sl = psl = syslbls; /* init ptrs */
|
||||
printf("%s\n%s\n",clearit,lbtitle);
|
||||
printf("Current message is:\n");
|
||||
if( syslbls==NULLPTR )
|
||||
printf("<null>\n");
|
||||
else for( ; sl != NULLPTR; sl = (psl=sl)->dlnext )
|
||||
printf("%s\n",sl->dlname);
|
||||
printf("\nAdd lines to message. Terminate by entering only RETURN:\n");
|
||||
FOREVER {
|
||||
if( gets(mb) != mb || *mb==NULL )
|
||||
break;
|
||||
sl = (DLIST *)malloc(sizeof(*sl)); /* alloc a list item */
|
||||
sl->dlname = malloc(sizeof(mb));
|
||||
strcpy(sl->dlname,mb); /* copy message to new space */
|
||||
sl->dlnext = NULLPTR;
|
||||
if( psl==NULLPTR ) /* new list? */
|
||||
syslbls = psl = sl; /* this will be the first line */
|
||||
else {
|
||||
psl->dlnext = sl;
|
||||
psl = psl->dlnext;
|
||||
}
|
||||
}
|
||||
return NULLPTR;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* writelbl: writes the OS label to the NEWSYS file, returning the length
|
||||
/* of the label (in pgphs)
|
||||
/************************************************************************/
|
||||
WORD
|
||||
_wrlbl(str) /* subroutine to writelbl */
|
||||
BYTE *str;
|
||||
{
|
||||
REG WORD slen;
|
||||
|
||||
slen=strlen(str); /* length of string to be written */
|
||||
write(fns,str,slen); /* write string to file NEWSYS */
|
||||
write(fns,"\015\012",2); /* cr,lf */
|
||||
return slen+2;
|
||||
}
|
||||
|
||||
WORD
|
||||
writelbl() /* returns num pgphs written */
|
||||
{
|
||||
REG WORD cc; /* count of chars output */
|
||||
DLIST *sl; /* list ptr */
|
||||
|
||||
cc = 0;
|
||||
|
||||
cc += _wrlbl(""); /* crlf */
|
||||
cc += _wrlbl(version); /* write out the version label */
|
||||
cc += _wrlbl(copyright); /* followed by copyright notice */
|
||||
for( sl=syslbls; sl!=NULLPTR; sl=sl->dlnext )
|
||||
cc += _wrlbl(sl->dlname); /* followed by all lines in OS label */
|
||||
cc += _wrlbl("$"); /* terminate message for printstr fn */
|
||||
return padwrite(cc); /* writes enough zeroes to pad to pgph bdry */
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* fixup routines: remembers and posthumously patches the SYS file
|
||||
/***************************************************************************/
|
||||
|
||||
FIX *fixroot = NULLPTRI; /* list of fixes */
|
||||
|
||||
fixlater(fa,ft,fp) /* records the fix in the list */
|
||||
LONG fa; /* addr within NEWSYS to fix */
|
||||
WORD ft; /* type of fix: F_ADD or F_PUT */
|
||||
WORD *fp; /* ptr to val used in fixing */
|
||||
{
|
||||
FIX *fx;
|
||||
|
||||
fx = (FIX *)malloc(sizeof *fx); /* alloc a list item */
|
||||
fx->f_addr = fa;
|
||||
fx->f_type = ft;
|
||||
fx->f_ptr = fp;
|
||||
fx->f_next = fixroot; /* insert at head of list */
|
||||
fixroot = fx;
|
||||
}
|
||||
|
||||
fixfile() /* does the fixes in the file */
|
||||
{
|
||||
FIX *fx;
|
||||
WORD fval; /* the value to stuff */
|
||||
LONG lastval;
|
||||
|
||||
lastval=lseek(fns,0L,2); /* end of file */
|
||||
|
||||
for( fx=fixroot; fx!=NULLPTR; fx = fx->f_next ) {
|
||||
if(fx->f_addr > lastval) { /* oops! past eof */
|
||||
printf("fixup addressing internal error: %X %x %x\n",fx->f_addr,fx->f_type,fx->f_ptr);
|
||||
continue;
|
||||
}
|
||||
if( lseek(fns,fx->f_addr,0) < 0L )
|
||||
CRASH("fixup seek failure\n");
|
||||
if( fx->f_type == F_ADD ) { /* F_ADD the value to what's there */
|
||||
read(fns,&fval,2);
|
||||
fval += *(fx->f_ptr);
|
||||
lseek(fns,-2L,1); /* backup to write */
|
||||
} else /* must be a F_PUT */
|
||||
fval = *(fx->f_ptr);
|
||||
write(fns,&fval,2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user