Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,162 @@
/****************************************************************
* *
* CP/M-68K Loader *
* *
* This is the main routine for the CP/M-68K Loader. *
* It has one entry point, ldcpm, which is called from *
* the assembly language routine called startld found in *
* ldrif.s. startld just sets up the stack. *
* *
* Configured for Alcyon C on the VAX *
* *
****************************************************************/
#include "stdio.h" /* Standard I/O declarations */
#define ALCYON TRUE /* TRUE if compiling with the ALCYON 68K C compiler */
#define SECLEN 128 /* CP/M sector length */
/* Declare EXTERN functions */
EXTERN WORD _bdos(); /* Loader BDOS entry point */
EXTERN startld(); /* Assembly routine to set up stack & retry */
EXTERN BYTE *bios1(); /* bios entry point for get segment table */
EXTERN move(); /* general purpose byte mover */
#define conout(ch) _bdos(2,ch)
#define seldsk(dsk) _bdos(14,dsk)
#define open(fcbp) _bdos(15,0,fcbp)
#define read(fcbp) _bdos(20,0,fcbp)
#define setdma(p) _bdos(26,0,p)
/* Define the data structures used in ldcpm */
struct fcb
{
UBYTE drvcode; /* drive code, must be 0 for loader BDOS */
/* (auto disk select not supported) */
UBYTE fname[11]; /* includes file name and type fields */
UBYTE sys_info[4]; /* ex, s1, s2, rc. These are don't cares */
UBYTE dskmap[16]; /* disk map, also a don't care */
UBYTE cur_rec; /* current record field */
};
struct hdr
{
WORD magic; /* magic number. We only recognize 0x601a */
LONG size[5]; /* sizes of code, data, bss, sym tbl, stack */
BYTE *tstart; /* start address of text segment */
WORD rlbflg; /* relocation bits suppressed flag */
};
struct segtbl
{ /* memory segment table from LDRBIOS */
WORD entrys; /* number of segments, must be 1 */
BYTE *start; /* low memory address */
LONG length; /* length of segment */
};
/**********************/
/* Global Variables */
/**********************/
BYTE buffer[SECLEN]; /* 128 byte dma buffer to read program headers */
/* We need 1 FCB to read CPM.SYS. */
/* Unfortunately, due to a bug in the Alcyon compiler, we can't initialize */
/* them in a straightforward way. So: */
/*sw No longer true. Deleted klutz. */
struct fcb cpmfcb =
{ 0, /* drive code */
'C','P','M',' ',' ',' ',' ',' ','S','Y','S'
};
/**************************/
/* Utility Routines */
/**************************/
pstring(p)
/* print string */
REG BYTE *p;
{
while (*p) conout(*p++);
}
badload(errtype)
/* Load failed. Print message and try again */
REG WORD errtype;
{
REG WORD i;
switch (errtype)
{
case 0: pstring("\r\nBoot error.");
startld();
case 1: pstring("\n\rOpen or Read error on ");
break;
case 2: pstring("\n\rBad file format on ");
}
pstring("CPM.SYS");
startld();
}
/********************
* load subroutine *
********************/
BYTE *load(fcbp)
/* load the file pointed to by fcbp and return pointer to load point */
REG struct fcb *fcbp;
{
REG BYTE *p;
REG struct hdr *hp;
REG LONG length;
setdma( buffer );
if ( open(fcbp) >= 255 ) badload(1);
fcbp->cur_rec = 0;
if ( read(fcbp) ) badload(1);
hp = buffer;
if ( (hp->magic != 0x601a) || ! (hp->rlbflg) )
badload(2);
p = hp->tstart;
length = hp->size[0] + hp->size[1];
move(&buffer[sizeof *hp], p, SECLEN - (sizeof *hp));
/* move the first record minus header to load point */
p += SECLEN - (sizeof *hp);
length -= SECLEN - (sizeof *hp);
while (length > 0L)
{
setdma(p);
if ( read(fcbp) ) badload(1);
p += SECLEN;
length -= SECLEN;
}
return(hp->tstart);
}
/***************************
* ldcpm main routine *
***************************/
ldcpm()
{
WORD (*gocpm)();
if (seldsk(0)) badload(0);
gocpm = load(&cpmfcb); /* load the CP/M system */
pstring("\r\n\nCP/M-68K(tm) Version 1.2 03/20/84 ");
pstring("\n\rCopyright (c) 1984 Digital Research, Inc.\r\n\n");
(*gocpm)(); /* jump to the CCP */
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,254 @@
/****************************************************************************
*
* C R U N T I M E G R E P R O U T I N E
* -------------------------------------------
* Copyright 1983 by Digital Research Inc. All rights reserved.
*
* The routine "grep" searches for an ascii character pattern in
* a series of files. "Grep" allows the following options:
*
* OPTION FUNCTION
* ------ --------
* -v Print only lines not matching the pattern
* -c Print only a count of the lines
* -n Print with line numbers
* -s Write out the sector number in which the pattern was found
* -l Write out a list of the files in which the pattern was found
* -y Do not distinguish between upper & lower case
*
* Calling Sequence:
*
* grep(options,expression,files);
*
* Where:
*
* options Is a pointer to a string of options
* expression Is a pointer to the search pattern
* files Is an array of pointers to filenames
*
*****************************************************************************/
/****************************/
/* INCLUDE FILES */
/****************************/
#include <stdio.h> /* standard I/O library */
#include <portab.h> /* CP/M portability defines */
#include <ctype.h> /* char type definitions */
/****************************/
/* GLOBAL VARIABLES */
/****************************/
GLOBAL BYTE __match = TRUE; /* Print Matching lines only*/
GLOBAL BYTE __count = FALSE; /* Just count the lines */
GLOBAL BYTE __num = FALSE; /* Print line #'s */
GLOBAL BYTE __sector = FALSE; /* Display the sector */
GLOBAL BYTE __list = FALSE; /* Display only a file list */
GLOBAL BYTE __nocase = FALSE; /* Distinguish between cases*/
GLOBAL FILE *fstream; /* file stream ptr */
GLOBAL BYTE line[129]; /* line buffer */
GLOBAL BYTE line1[129]; /* Temp line buffer */
GLOBAL BYTE first = TRUE; /* used on the list option */
GLOBAL UWORD numfound = 0; /* number of lines found */
/****************************/
/* FUNCTIONS */
/****************************/
FILE *fopenb(); /* returns a ptr to a file */
/****************************/
/* MAIN */
main(argc,argv) /* Entry point */
WORD argc; /* = # args */
BYTE **argv; /* -> args */
{ /****************************/
BYTE *options; /* Option pointer */
BYTE *expression; /* -> expression */
BYTE **files; /* -> files */
/* */
if(argc < 2) /* Must have at least 2 */
{ /* */
usage: printf("Usage: find [-options] pattern files\n");
exit(); /* */
} /****************************/
/* */
options = "-ny"; /* Set up option */
if(*argv[1] == '-') /* Options specified? */
{ /* */
options = argv[1]; /* Yes, use them */
if(argc < 3) goto usage; /* check for valid args */
expression = argv[2]; /* -> Pattern */
files = &argv[3]; /* -> file list */
} /****************************/
else { /* No options */
expression = argv[1]; /* Expression */
files = &argv[2]; /* file list */
} /****************************/
return(grep(options,expression,files)); /* Call the real function */
} /* */
/****************************/
grep(options,expression,files) /* */
REG BYTE *options; /* option list */
REG BYTE *expression; /* pattern to search for */
BYTE *files[]; /* array of files */
{ /* */
REG BYTE *p; /* temp pointer */
REG UWORD patt_cnt; /* pattern counter */
REG UWORD char_cnt; /* character count */
REG UWORD line_cnt; /* line count */
REG UWORD i; /* counter */
UWORD length; /* length of pattern */
BYTE found; /* set if pattern is found */
/* */
/* */
if(*options != '-') /* Legal option list? */
{ /* */
fprintf(stderr,"FIND--Illegal option list: %s\n",options); /* */
exit(-1); /* Just quit */
} /****************************/
while(*options) /* if found ........ */
{ /* */
switch(*++options) /* */
{ /* */
case 'v' : __match = FALSE; /* print non-matching lines */
break; /* */
case 'c' : __count = TRUE; /* print a count of lines */
break; /* */
case 'n' : __num = TRUE; /* number the lines */
break; /* */
case 's' : __sector= TRUE; /* print sector number */
break; /* */
case 'l' : __list = TRUE; /* list the files */
break; /* */
case 'y' : __nocase= TRUE; /* no case distinction */
/*break;*/ /* */
} /* */
} /* */
/****************************/
if(__list) /* list option has priority */
{ /* over these..... */
__count = FALSE; /* */
__num = FALSE; /* */
__sector = FALSE; /* */
} /* */
else /* */
if(__count) /* count option has priority*/
{ /* over these..... */
__num = FALSE; /* */
__sector = FALSE; /* */
} /* */
else /* */
if(__num) /* num option has priority */
__sector = FALSE; /* over the sector option */
if(__nocase) /* if no case destinction */
{ /* */
p = expression; /* */
while(*p) /* change expression to */
{ /* */
*p = toupper(*p); /* upper case letters */
p++; /* */
} /* */
} /* */
length = strlen(expression); /* count the characters in */
/* the pattern to match */
while(*files) /* search all the files */
{ /* */
if((fstream = fopenb(*files,"r")) != NULL)/*try to open the file */
{ /* */
char_cnt = 0; /* initialize char count */
line_cnt = 0; /* initialize line # count */
numfound = 0; /* initialize # found */
first = TRUE; /* initialize for list */
if(!__list && !__count) /* if these options are not */
{ /* ON then print the file- */
printf("\nFILE: %s\n",*files); /* name before each search */
printf("----\n"); /* */
} /* */
while(!feof(fstream)) /* go until end of file */
{ /* */
found = FALSE; patt_cnt = 0; /* */
p = expression; /* */
for(i=0;i<129;i++) /* Zap out the buffers */
line[i]=line1[i]=0; /* */
fgets(line1,129,fstream); /* read a line */
/****************************/
for(i = 0;line1[i];i++) /* */
if(__nocase) /* Translate? */
line[i] = toupper(line1[i]);/* */
else /* Don't translate */
line[i] = line1[i]; /* Just copy */
/****************************/
i = 0; /* */
while(line[i]) /* scan until a NULL */
{ /* */
char_cnt++; /* bump the char count */
if(line[i] == *p) /* check pattern */
{ /* */
p++; /* look for next char */
patt_cnt++; /* we found a character */
if(patt_cnt == length) /* Have we found the end ? */
{ /* */
found = TRUE; /* set a flag */
p = expression; /* */
patt_cnt = 0; /* */
} /* */
} /* */
else /* */
{ /* */
p = expression; /* reset the pattern ptr */
patt_cnt = 0; /* start the count over */
} /* */
i++; /* check next character */
} /* */
line[i-1] = NULL; /* mask out extra LF */
line_cnt++; /* bump the line count */
prtline(found,char_cnt,line_cnt,files);/*then print routine */
} /* */
if(__count) /* is count option ON ? */
printf("\n%s: %d",*files,numfound);/*print a count of # fnd */
} /* */
fclose(fstream); /* Close the file */
files++; /* go to next file */
} /* */
} /****************************/
/* PRINT ROUTINE */
prtline(found,char_cnt,line_cnt,files) /****************************/
BYTE found; /* does line contain pattern*/
UWORD char_cnt; /* number of chars searched */
UWORD line_cnt; /* number of lines searched */
BYTE *files[]; /* current file */
{ /****************************/
if((__match && found) || /* have we a line ? */
(!__match && !found)) /* */
{ /* */
numfound++; /* count the # lines found */
if(__count) return; /* nothing to do */
if(__list) /* if the list option */
{ /* */
if(first) /* FIRST pattern found ? */
printf("\n%s",*files); /* print the filename */
first = FALSE; /* turn off flag */
return; /* and return.. */
} /* */
if(__sector) /* do we print the sector# ?*/
{ /* */
printf("\n%d",char_cnt/128);/* divide count by 128 */
return; /* */
} /* */
if(__num) /* do we print a line # ? */
{ /* */
printf("%5d: ",line_cnt); /* */
} /* otherwise..... */
fputs(line1,stdout); /* just print the line */
} /* */
} /****************************/
 */
} /****************************/
 */
} /****************************/
 */
} /****************************/

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,441 @@
/****************************************************************************/
/* */
/* R e l o c P r o g r a m */
/* ------------------------- */
/* */
/* This program is used to relocate an Alcyon format load module into */
/* an absolute module using the minimum disk space possible. The */
/* relocation information, symbol table, and trailing zeros in the */
/* data segment are deleted. */
/* */
/* Invokation: */
/* */
/* A>reloc -bhhhhhh in.68k out.68k */
/* */
/* Where: */
/* hhhhhh Is the desired new base address (TPA + 100) in hex */
/* in.68k Is the input file */
/* out.68k Is the output file */
/* */
/****************************************************************************/
#include <stdio.h>
#include <ctype.h>
/****************************************************************************/
/* */
/* The following code defines the organization of a "long" variable on */
/* either the VAX (11) or 68000. This allows us to use "getw" on the */
/* separate parts of the long and to recombine them for 32-bit */
/* arithmetic operations. */
/* */
/****************************************************************************/
#include "machine.h"
#ifdef UNIX
#include <portab.h>
#endif
#ifdef VAX /****************************/
struct { /* low word first on VAX */
WORD loword; /* */
WORD hiword; /* */
}; /****************************/
#endif
#ifdef PDP11 /****************************/
struct { /* low word first on PDP11 */
WORD loword; /* */
WORD hiword; /* */
}; /****************************/
#endif
#ifdef MC68000 /****************************/
struct { /* */
WORD hiword; /* High word first on 68K */
WORD loword; /* */
}; /****************************/
#endif
#ifdef UNIX /****************************/
#define fopenb fopen /* Not in UNIX library */
#endif /****************************/
/****************************************************************************/
/* */
/* Relocation bit definitions */
/* */
/* Note that this program is intended only for load module files. Any */
/* references to external symbols or relative references are illegal. */
/* */
/****************************************************************************/
/* */
#define DABS 0 /* Data absolute */
#define DRELOC 1 /* Data segment relative */
#define TRELOC 2 /* Text segment relative */
#define BRELOC 3 /* BSS segment relative */
#define EXTVAL 4 /* External variable */
#define LUPPER 5 /* Upper word of long */
#define EXTREL 6 /* External relative symbol */
#define INSABS 7 /* 1st word of instruction */
/****************************/
/****************************************************************************/
/* */
/* G l o b a l D a t a */
/* */
/****************************************************************************/
/* */
BYTE *ifname=0; /* -> Input filename */
BYTE *ofname=0; /* -> Output filename */
LONG base=0; /* New relocation base */
FILE *fopenb(); /* File open procedure */
LONG ftell(); /* File offset procedure */
#ifdef CPM /* Only defined with CP/M */
EXTERN BYTE _start; /* Start of program */
#endif /* */
/****************************/
#include "cout.h" /* Output header area */
/****************************/
/****************************************************************************/
/* */
/* M a i n P r o c e d u r e */
/* --------------------------- */
/* */
/* Here we get things started: */
/* */
/* 1). Get relocation base */
/* 2). Open input and output files */
/* 3). Determine data area (new) size */
/* */
/* Any errors here are fatal, and cause program termination. */
/* */
/****************************************************************************/
VOID main(argc,argv)
/****************************/
DEFAULT argc; /* Int var from RTL startup */
BYTE **argv; /* -> Arg strings */
{ /****************************/
REG LONG i,l; /* Temps */
REG FILE *ifp,*ofp,*rfp; /* File pointers */
/* */
if(argc != 4 && argc != 3) /* Gotta have right format */
usage(); /* Print out nasty message */
/****************************/
if(argc == 4) /* "-bxxxx" form */
{ /****************************/
if(decode(argv[1], &base) == FAILURE) /* Convert to binary */
{ /* */
printf("Illegal option: %s\n", /* Print offending option */
argv[1]); /* */
usage(); /* Print reminder messages */
} /****************************/
ifname = argv[2]; /* -> Input file name */
ofname = argv[3]; /* -> Output file name */
} else /* Default form */
{ /* */
#ifdef CPM /* On CP/M, */
base = &_start; /* Use start of reloc itself*/
#else /****************************/
base = 0x500; /* 500H is default */
#endif /* */
ifname = argv[1]; /* -> Input filename */
ofname = argv[2]; /* -> Output filename */
} /****************************/
/* */
if((base & 1) != 0) /* In range? */
{ /* no */
printf("Illegal base address=%lx\n", /* print */
base); /* message */
exit(-1); /* And quit */
} /****************************/
/* */
if((ifp=fopenb(ifname,"r")) == NULL) /* Try to open input */
{ /* */
printf("Cannot open %s\n",ifname); /* Complain */
exit(-1); /* & quit */
} /****************************/
/* */
if((ofp=fopenb(ofname,"w")) == NULL) /* Try to create output */
{ /* */
printf("Cannot create %s\n",ifname); /* Complain */
exit(-1); /* & quit */
} /****************************/
/****************************************************************************/
/* */
/* Now read the file header and compute the new data segment size ... */
/* */
/****************************************************************************/
/* */
i = fread(&couthd,1,(sizeof couthd), /* Do the read */
ifp); /* */
if(i != (sizeof couthd)) /* Did it work?? */
{ /* */
printf("Read error on %s\n",ifname); /* No, complain */
exit(-1); /* and quit */
} /****************************/
/* */
if(couthd.ch_magic != MAGIC) /* Valid file? */
{ /* */
printf("File format error: %s\n", /* Print nasty message */
ifname); /* */
exit(-1); /* Quit */
} /****************************/
/* */
l = couthd.ch_tsize + sizeof couthd; /* Seek address for data */
fseek(ifp,l,0); /* Seek to data start */
/* */
i = couthd.ch_dsize; /* Fetch data size */
l = ftell(ifp); /* l <= new data end addr */
/* */
while (i > 0) /* Until all data examined */
{ /* */
if(getw(ifp) != 0) /* This data word = 0? */
l = ftell(ifp); /* No, record seek address */
i -= 2; /* Down count */
} /****************************/
/****************************************************************************/
/* */
/* Open the file a second time, and perform the proper seeks to align */
/* one copy of the open file to the beginning of the text segment, and */
/* the other copy to the beginning of the relocation information */
/* */
/****************************************************************************/
/* */
if((rfp=fopenb(ifname,"r")) == NULL) /* Try to open again */
{ /* */
printf("Cannot re-open %s\n",ifname); /* Print nasty message */
exit(-1); /* and quit */
} /****************************/
fseek(ifp,(LONG)(sizeof couthd),0); /* Seek to text beginning */
fseek(rfp,(LONG)(sizeof couthd) + /* Seek to */
couthd.ch_tsize+couthd.ch_dsize + /* relocation */
couthd.ch_ssize, 0); /* info*/
/****************************/
reloc(ifp,rfp,ofp,l); /* Do relocation */
} /****************************/
/****************************************************************************/
/* */
/* U s a g e F u n c t i o n */
/* --------------------------- */
/* */
/* Routine "usage" is used to print out an error message when the */
/* program is invoked in an improper manner. */
/* */
/* Calling Sequence: */
/* */
/* usage(); */
/* */
/* No return is made, "exit()" is called to go back to the O/S. */
/* */
/****************************************************************************/
VOID usage()
{
printf("Usage: reloc [-bhhhhhh] input output\n");
printf(" where: hhhhhh is new base address\n");
printf(" (TPA+100 is default base address)\n");
printf(" input is relocatable file\n");
printf(" output is absolute file\n");
exit(-1);
}
/****************************************************************************/
/* */
/* D e c o d e F u n c t i o n */
/* ------------------------------ */
/* */
/* Routine "decode" is called to process the relocation base argument */
/* from the command line. */
/* */
/* Calling sequence: */
/* */
/* ret = decode(string,&address); */
/* */
/* Where: */
/* string -> argument string (usually argv[1]) */
/* &address -> long word to receive converted value */
/* */
/* ret = 0 if successful conversion */
/* = -1 if anything amiss */
/* */
/****************************************************************************/
WORD decode(string,addr) /* */
/* */
REG BYTE *string; /* -> Command argument */
LONG *addr; /* = return value */
{ /****************************/
REG LONG a; /* Temp return value */
REG BYTE c; /* Temp character */
/* */
if(*string++ != '-' || *string++ != 'b')/* Check for valid switch */
return(FAILURE); /* quit if NFG */
/* */
a = 0; /* Zero out accumulator */
/* */
while(*string) /* Until no more chars */
{ /* */
c = *string & 0177; /* Pick up next char */
if (c >= '0' && c <= '9') /* Digit */
a = (a << 4) + c - '0'; /* Un-ASCIIfy */
else if (c >= 'A' && c <= 'F') /* Hex */
a = (a << 4) + c - 'A'+ 10; /* Un-ASCIIfy */
else if (c >= 'a' && c <= 'f') /* Lower case hex */
a = (a << 4) + c - 'a'+ 10; /* Un-ASCII it */
else /* Bad character */
return(FAILURE); /* So long, sucker!! */
string++; /* Increment pointer */
} /* */
*addr = a; /* Store result */
return(SUCCESS); /* Return all ok */
} /****************************/
/****************************************************************************/
/* */
/* R e l o c F u n c t i o n */
/* --------------------------- */
/* */
/* Function "reloc" is called to perform the relocation operation and */
/* write the output file simultaneously. */
/* */
/* Calling Sequence: */
/* */
/* reloc(ifp,rfp,ofp,length); */
/* */
/* Where: */
/* */
/* ifp Is the input stream pointer (positioned at text) */
/* rfp Is a stream pointer positioned at relocation bits */
/* ofp Is a stream pointer for the output file */
/* length Is the total length of the output file */
/* */
/****************************************************************************/
VOID reloc(ifp,rfp,ofp,length) /* */
/* */
REG FILE *ifp; /* -> Text information */
REG FILE *rfp; /* -> Relocation info */
REG FILE *ofp; /* -> Output file */
LONG length; /* = # bytes in the file */
{ /****************************/
struct hdr x; /* Duplicate header */
REG LONG bytes; /* File offset */
LONG j; /* Temp for long relocation */
REG WORD r; /* Relocation word */
REG WORD k; /* Temp data word */
WORD longf; /* Long relocation flag */
WORD z; /* Temp for error codes */
LONG bias; /* Relocation bias */
/* */
bias = base - couthd.ch_entry; /* Compute relocation bias */
/* */
/************************************************* */
/* */
/* Prepare and write the new file header in structure "x". */
/* */
/************************************************* */
/* */
x.ch_magic = MAGIC; /* Magic word */
x.ch_tsize = couthd.ch_tsize; /* Text size */
j = sizeof couthd + couthd.ch_tsize + /* Compute number of bytes */
couthd.ch_dsize - length; /* moved from data to bss */
x.ch_dsize = couthd.ch_dsize - j; /* New data size */
x.ch_bsize = couthd.ch_bsize + j; /* New bss size */
x.ch_ssize = 0; /* No symbols */
x.ch_stksize = 0; /* No stack */
x.ch_entry = base; /* New base address */
x.ch_rlbflg = -1; /* No relocation bits */
/****************************/
if(fwrite(&x,1,sizeof x,ofp) != /* Do the write */
sizeof x) /* */
{ /* Here if failed */
printf("Write error on %s\n",ofname); /* print message */
exit(-1); /* Quit */
} /****************************/
/****************************************************************************/
/* */
/* Here begins the actual file relocation procedure. Read a word */
/* from the relocation bits and from the file together. If long, */
/* read another word from each. Perform indicated relocation. */
/* */
/****************************************************************************/
/* */
bytes = 0; /* No bytes written yet ... */
length -= sizeof(couthd); /* Just program, please... */
while (bytes < length) /* until we are done */
{ /****************************/
k = getw(ifp); /* get next text/data word */
r = getw(rfp); /* get next relocation word */
/****************************/
if ((r & ~7) != 0) /* Check for validity */
badrel(r,bytes); /* Not valid, quit */
/* */
if(r == LUPPER) /* Doing a long? */
{ /* */
j.hiword = k; /* Yes, get another word */
j.loword = getw(ifp); /* From both */
r = getw(rfp); /* streams */
longf = 2; /* Set flag */
} /****************************/
else /* Not a long */
{ /* */
j.loword = k; /* Put in low order word */
j.hiword = 0; /* Make top part 0 */
longf = 0; /* Clear flag */
} /****************************/
switch (r) /* Now do indicated reloc */
{ /* */
case TRELOC: /* If relocatable, */
case DRELOC: /* relocate */
case BRELOC: /* */
j += bias; /* Add in bias */
case DABS: /* If not relocatable, */
case INSABS: /* don't */
break; /****************************/
default: /* Any others illegal */
badrel(r,bytes); /* Print message */
} /****************************/
if(longf == 0 && j.hiword !=0) /* 16-bit overflow? */
{ /* */
printf("16-bit overflow at %ld\n", /* Print out message */
bytes); /* with offset */
exit(-1); /* */
} /****************************/
if(longf != 0) /* Long? */
putw(j.hiword,ofp); /* yes, output high */
#ifndef UNIX /* A bug in UNIX RTL!! */
if((z=putw(j.loword,ofp)) != j.loword) /* Check for write error */
{ /* */
printf("Write error on %s ",ofname); /* Had one, */
printf("Offset = %lx data= %x err =%x\n", /* */
bytes,j.loword,z); /* Print out message */
exit(-1); /* & quit */
} /****************************/
#else /* Just output and pray... */
putw(j.loword,ofp); /* Output low word */
#endif /****************************/
bytes += 2 + longf; /* Increment byte count */
/* */
} /* End while loop */
} /* End reloc procedure */
/****************************/
VOID badrel(r,offset) /* Print bad reloc message */
/* */
WORD r; /* Relocation bits */
LONG offset; /* File offset */
{ /****************************/
printf("Illegal reloc = %x at %lx\n", /* Print error message */
r,offset); /* */
exit(-1); /* quit */
} /****************************/
****************/
****************/

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,20 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
#define MC68000 1 /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
#define CPM 1 /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M Operating

View File

@@ -0,0 +1,20 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
#define MC68000 1 /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
#define CPM 1 /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M Operating

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,20 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
#define MC68000 1 /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
#define CPM 1 /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M Operating

View File

@@ -0,0 +1,20 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
#define MC68000 1 /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
#define CPM 1 /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M Operating

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,20 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
#define MC68000 1 /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
#define CPM 1 /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M Operating

View File

@@ -0,0 +1,20 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
#define MC68000 1 /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
#define CPM 1 /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M OperatingSystem*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/
 CPM 1 /* CP/M Operating

Binary file not shown.

View File

@@ -0,0 +1,41 @@
/* macro's and define's useful to write test programs and to build test
suites */
/* NOV 83 - Bill Fitler */
/* FEB 84 - Ken Chai */
/*********************** From "C Puzzle Book": ****************************/
#define PR(format,value) printf("\n\tvalue = %format\t",(value))
#define NL printf("\n")
#define PRINT1(f,x1) PR(f,x1); NL
#define PRINT2(f,x1,x2) PR(f,x1); PRINT1(f,x2)
#define PRINT3(f,x1,x2,x3) PR(f,x1); PRINT2(f,x2,x3)
#define PRINT4(f,x1,x2,x3,x4) PR(f,x1); PRINT3(f,x2,x3,x4)
/********************** end of C Puzzle's "defs.h" ***********************/
#define PRINT_EXPR(format,expr) printf("\n\texpr = format\n",(expr))
#define PRE(fmt,expr,val) printf("\n\texpected value of expr = %fmt",val)
#define PRA(fmt,expr) printf("\n\tactual value of expr = %fmt\n",(expr))
#define MODEL_NAME ((sizeof(char *) == 2) ? \
(sizeof(char (*)())==2 ? "small" : "medium") : \
(sizeof(char (*)())==2 ? "compact" : "big") )
#define TRUE_COND(expr) printf("\n\tassertion succeeded: expr\n")
#define FALSE_COND(expr) printf("\n\tassertion failed: expr\n")
#define TEST_OK(expr) if (expr) TRUE_COND(expr)
#define TEST_NOK(expr) if (expr) FALSE_COND(expr)
#define PRS(b,c) printf("\n\t%s: succeeded for %s model", c, b)
#define PRF(b,c) printf("\n\t%s: failed for %s model", c, b)
#define ASSER(a,b) {if (a) PRS(model,b) ; else PRF(model,b); }
#define PRI(format,val) printf("\n\twe expect to see %format", val)
#define ASSERT(cond) {{model=MODEL_NAME;} ; ASSER(cond,bugnum); }
#define ASSRT(cond) ASSER(cond,bugnum)
/* #define PRS68(c) printf("\n\t%s: succeeded", c)
#define PRF68(b) printf("\n\t%s: failed", b)
#define ASSER68(a,b) {if (a) PRS68(b) ; else PRF68(b); }
#define PRI(format,val) printf("\n\twe expect to see %format", val)
#define ASSERT68(cond) ASSER68(cond,bugnum)
#define ASSRT68(cond) ASSER68(cond,bugnum) */
*/
*/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,592 @@
/* streamio.c: tests Unix Stream I/O functions */
/* Modifications: */
/* 1/84 verbose error msgs for 68K whf */
/* 9/83 improved error msgs whf */
/* Runs by itself: just compile and exec. It will tell you which functions
it is testing. */
#include <portab.h>
#include <stdio.h>
/************************************************/
/* Possible file size parameters for each pass: */
#define NUMPASS 4 /* Number of passes for this test */
#define MAXRECMAX 128 /* Maximum record size */
#define NRCHECKS 7 /* Number of random i/o checks */
WORD pass_types[NUMPASS][2] = /* Num records, Len records for each pass */
{
100, MAXRECMAX,
16, 32,
10, 20,
10000, 20
};
/*************************/
/* O.S. dependent values */
#define BYTE_LEVEL 128 /* Size of sectors: PCDOS = 1, CP/M = 128 */
/*********************************************/
/* Possible kinds of File I/O for each case: */
/* Ascii/Binary I/O indicator */
#define AB_ASCII 1
#define AB_BINARY 0
/* Record/Char/Line indicator */
#define RCL_RECORD 1
#define RCL_CHAR 2
#define RCL_LINE 3
#define NUMCASE 6 /* Number of cases per pass */
WORD case_types[NUMCASE][2] = /* AB type, RCL type for each case */
{
AB_BINARY, RCL_RECORD,
AB_BINARY, RCL_LINE,
AB_BINARY, RCL_CHAR,
AB_ASCII, RCL_LINE,
AB_ASCII, RCL_RECORD,
AB_ASCII, RCL_CHAR
};
/*************************************************************************/
/*************************************************************************/
GLOBAL WORD nerrors = 0; /* number of errors reported */
main(ac,av)
int ac;
char **av;
{
int ii, jj, nfiles;
BYTE **files, *calloc();
BYTE *test_dir, *make_fn();
av[0] = "STREAMIO"; /* kludge: DRC doesn't handle */
test_dir = "g:"; /* where we want to do the testing */
nfiles = 0;
files = calloc(NUMPASS*NUMCASE,sizeof(BYTE *));
printf("%s tests the following Stream I/O functions:\n",av[0]);
printf("\tfopen, fclose, freopen, fseek, ftell, rewind\n");
printf("as well as functions listed below.\n");
printf("****************** %s test starting ****************\n",av[0]);
for( ii=0; ii<NUMPASS; ++ii )
{
prt_pass(ii);
for( jj=0; jj<NUMCASE; ++jj )
{
files[nfiles] = make_fn(ii,jj,test_dir);
test(ii,jj,files[nfiles]);
nfiles++;
};
};
for( ii=0; ii<nfiles; ++ii )
{
/* unlink files here */
}
printf("****************** %s test completed *************\n",av[0]);
printf("******************** number errors: %d *************\n",nerrors);
}
prt_pass(pass)
WORD pass;
{
LONG rmax;
WORD rlen;
rmax = pass_types[pass][0];
rlen = pass_types[pass][1];
printf("pass %d:\t\t",pass);
printf("number records = %ld, record length = %d\n",rmax,rlen);
}
BYTE *make_fn(pass,cse,prefix) /* make a filename from all the parameters */
WORD pass,cse;
BYTE *prefix;
{
LONG rmax;
WORD rlen, ab_f, rcl_f;
BYTE ab_ch, rcl_ch, *fp, *calloc();
rmax = pass_types[pass][0];
rlen = pass_types[pass][1];
ab_f = case_types[cse][0];
ab_ch = (ab_f==AB_ASCII) ? 'A' : 'B';
rcl_f = case_types[cse][1];
switch(rcl_f)
{
case RCL_RECORD: rcl_ch = 'R'; break;
case RCL_CHAR: rcl_ch = 'C'; break;
case RCL_LINE: rcl_ch = 'L'; break;
};
fp = calloc(strlen(prefix)+12,1);
sprintf(fp,"%sZ%c%c%.5D.%.3d",prefix,ab_ch,rcl_ch,rmax,rlen);
return fp;
}
prt_case(cse)
WORD cse;
{
WORD ab_f, rcl_f;
ab_f = case_types[cse][0];
rcl_f = case_types[cse][1];
printf("\tcase %d: %s file i/o on ",cse,
(AB_ASCII==ab_f) ? "ASCII" : "BINARY" );
switch(rcl_f)
{
case RCL_RECORD: printf("fread,fwrite"); break;
case RCL_CHAR: printf("fgetc,fputc"); break;
case RCL_LINE: printf("fgets,fputs"); break;
};
printf(" ");
}
/*************************************************************************/
/*************************************************************************/
GLOBAL LONG wrecs; /* records actually written */
GLOBAL LONG rrecs; /* records actually read */
GLOBAL LONG recmax; /* max number of records to write */
GLOBAL WORD reclen; /* length of each record */
GLOBAL WORD ab_flag; /* Ascii/Binary i/o indicator */
GLOBAL WORD rcl_flag; /* Record/Char/Line indicator */
GLOBAL BYTE *filename; /* Name of test file */
GLOBAL WORD all_but_N; /* num records to write in steps 2,3 */
GLOBAL FILE *tfsp; /* Test File Stream Pointer */
GLOBAL BYTE ch_first, ch_last; /* range of chars to write to file */
GLOBAL BYTE rec1[MAXRECMAX+2], rec2[MAXRECMAX+2]; /* record buffers */
GLOBAL WORD chk_cnt; /* count of num rand read checks */
GLOBAL WORD chk_incr; /* read random every chk_incr records*/
GLOBAL LONG chk_recn[NRCHECKS]; /* record numbers to read random */
GLOBAL LONG chk_rpos[NRCHECKS]; /* positions of above records */
LONG ftell();
test(pass,cse,fn)
WORD pass, cse;
BYTE *fn;
{
wrecs = 0; rrecs = 0;
recmax = pass_types[pass][0];
reclen = pass_types[pass][1];
ab_flag = case_types[cse][0];
rcl_flag = case_types[cse][1];
filename = fn;
all_but_N = 5;
ch_first = 0; ch_last = 0xFF;
if( AB_ASCII == ab_flag || RCL_LINE == rcl_flag )
{ /* don't write extra \n in bin files */
ch_first = ' '; ch_last = '~';
}
chk_incr = recmax / NRCHECKS;
for( chk_cnt=0; chk_cnt<NRCHECKS; ++chk_cnt )
chk_recn[chk_cnt] = chk_rpos[chk_cnt] = 0;
chk_cnt = 0;
prt_case(cse); printf("%s tested: ",fn);
#define CHK(xx) if(xx) break
while(1) /* loop once (allow break) */
{
CHK( build_it() );
CHK( grow_it() );
CHK( rand_write() );
CHK( check_it() );
CHK( rcheck_it() );
printf("OK\n");
return;
}
printf("\n\tRecords written/read before failure: %ld/%ld\n\n",
wrecs,rrecs);
++nerrors; /* incr error count */
}
/***************************************************************************/
build_it() /*** build the file ***/
{
LONG rn;
FILE *fopen(), *fopenb();
/* step 1: create the file */
if( ab_flag == AB_ASCII )
tfsp = fopen(filename,"w");
else tfsp = fopenb(filename,"w");
if( NULLPTR == tfsp ) return eprintf("fopen(%s,w) in build_it",
filename);
/* step 2: write & fflush the first record */
rn = 0;
if( capture_pos(rn) ) return FAILURE;
if( write_it(rn) ) return FAILURE;
if( FAILURE == fflush(tfsp) ) return eprintf("fflush in build_it");
/* step 2: write all but all_but_N of the records */
for( rn=1; rn<recmax-all_but_N; ++rn )
{
if( capture_pos(rn) ) return FAILURE;
if( write_it(rn) ) return FAILURE;
}
/* step 3: close file once */
if( FAILURE == fclose(tfsp) ) return eprintf("fclose in build_it");
return SUCCESS;
}
/***************************************************************************/
capture_pos(rn)
LONG rn;
{
if( rn % chk_incr == 0 && chk_cnt < NRCHECKS)
{
chk_recn[chk_cnt] = rn;
if( -1L == (chk_rpos[chk_cnt]=ftell(tfsp)) )
return eprintf("ftell in capture_pos");
++chk_cnt;
}
return SUCCESS;
}
/***************************************************************************/
write_it(rnum)
LONG rnum;
{
WORD rlen, ii;
/* step 1: make a record */
rlen = reclen;
if( rcl_flag == RCL_LINE ) --rlen; /* leave room for newline */
makerec(rec1,rlen,rnum,filename,ch_first,ch_last);
if( rcl_flag == RCL_LINE ) rec1[reclen-1]='\n';
/* step 2: write the record */
switch( rcl_flag )
{
case RCL_RECORD:
if( reclen != fwrite(rec1,1,reclen,tfsp) )
return eprintf("fwrite in write_it");
break;
case RCL_CHAR:
for( ii=0; ii<reclen; ++ii )
if( FAILURE == fputc(rec1[ii],tfsp) )
return eprintf("fputc in write_it");
break;
case RCL_LINE:
if( FAILURE == fputs(rec1,tfsp) )
return eprintf("fputs in write_it");
break;
}
++wrecs; /* incr num records actually written */
return SUCCESS;
}
/***************************************************************************/
grow_it() /*** append to the file ***/
{
LONG rn;
LONG rpos;
FILE *fopen(), *fopenb(), *freopen(), *freopb();
/* step 1: open for append */
if( AB_ASCII == ab_flag )
tfsp = fopen(filename,"a");
else tfsp = fopenb(filename,"a"); /* watch: reclen % 128 != 0 */
if( NULLPTR == tfsp )
return eprintf("fopen(%s,a) in grow_it",filename);
/* step 2: write all_but_N-1 records */
rn = recmax - all_but_N;
if( rn < 0 )
rn = 0;
if( AB_BINARY == ab_flag ) /* make sure we handle reclen */
{
rpos = rn * reclen;
if( fseek(tfsp,rpos,0) )
return eprintf("fseek in grow_it");
}
for( ; rn < recmax - 1; ++rn )
{
if( capture_pos(rn) ) return FAILURE;
if( write_it(rn) ) return FAILURE;
}
/* step 3: reopen file */
if( AB_ASCII == ab_flag )
tfsp = freopen(filename,"a",tfsp);
else tfsp = freopb(filename,"a",tfsp);
if( NULLPTR == tfsp )
return eprintf("freopen(%s,a) in grow_it",filename);
/* step 4: write last record */
if( AB_BINARY == ab_flag ) /* make sure we handle reclen */
{
rpos = rn * reclen;
if( fseek(tfsp,rpos,0) )
return eprintf("fseek in grow_it");
}
for( ; rn < recmax; ++rn )
{
if( capture_pos(rn) ) return FAILURE;
if( write_it(rn) ) return FAILURE;
}
/* step 5: close file again */
if( FAILURE == fclose(tfsp) )
return eprintf("fclose in grow_it");
return SUCCESS;
}
/***************************************************************************/
rand_write() /* write some randomly */
{
WORD ii;
LONG tt, eof_slack;
FILE *fopen(), *fopenb();
/* step 1: open for append */
if( AB_ASCII == ab_flag )
tfsp = fopen(filename,"a");
else tfsp = fopenb(filename,"a"); /* watch: reclen % 128 != 0 */
if( NULLPTR == tfsp )
return eprintf("fopen(%s,a) in rand_write",filename);
/* Step 2: write randomly absolute */
for( ii=0; ii<chk_cnt; ++ii )
{
if( FAILURE == fseek(tfsp,chk_rpos[ii],0) ) {
eprintf("fseek(%ld,0) in rand_write",chk_rpos[ii]);
for( ii=0; ii<chk_cnt; ++ii )
printf("%2.2d %5.5ld %5.5ld\n",ii,chk_recn[ii],
chk_rpos[ii]);
return FAILURE;
}
if( write_it(chk_recn[ii]) )
return FAILURE;
}
/* step 3: write randomly relative */
if( AB_BINARY == ab_flag ) {
/*** compute 'slack' at eof due to inexact nature of
eof for binary files with 128 byte sectors
(goes away on byte level i/o O.S.s ) ********/
if( BYTE_LEVEL > 1 ) {
eof_slack = BYTE_LEVEL - ((recmax*reclen) % BYTE_LEVEL);
if( eof_slack == BYTE_LEVEL )
eof_slack = 0;
} else eof_slack = 0;
tt = -reclen - eof_slack;
if( FAILURE == fseek(tfsp,tt,2) ) /* addr of last record*/
eprintf("fseek(%ld,2) in rand_write",tt);
if( write_it(recmax-1) )
return FAILURE;
tt = 1 - recmax; tt *= reclen; tt -= eof_slack;
if( FAILURE == fseek(tfsp,tt,2) )
eprintf("fseek(%ld,2) in rand_write",tt);
if( write_it(1L) )
return FAILURE;
}
/* step 4: close file again */
if( FAILURE == fclose(tfsp) )
return eprintf("fclose in rand_write");
return SUCCESS;
}
/***************************************************************************/
check_it() /*** check that everything reads ok sequential ***/
{
LONG rn;
FILE *fopen(), *fopenb();
/* step 1: open for read */
if( AB_ASCII == ab_flag )
tfsp = fopen(filename,"r");
else tfsp = fopenb(filename,"r"); /* watch: reclen % 128 != 0 */
if( NULLPTR == tfsp )
return eprintf("fopen(%s,r) in check_it",filename);
/* step2: read sequential */
for( rn=0; rn < recmax; ++rn )
{
if( read_it(rn) )
return FAILURE;
}
/* step 3: close file */
if( FAILURE == fclose(tfsp) )
return eprintf("fclose in check_it");
return SUCCESS;
}
/***************************************************************************/
read_it(rnum)
LONG rnum;
{
WORD rlen, ii;
/* step 1: make a record */
rlen = reclen;
if( rcl_flag == RCL_LINE ) --rlen; /* leave room for newline */
makerec(rec1,rlen,rnum,filename,ch_first,ch_last);
if( rcl_flag == RCL_LINE ) rec1[reclen-1]='\n';
/* step 2: read the record */
switch( rcl_flag )
{
case RCL_RECORD:
if( reclen != fread(rec2,1,reclen,tfsp) )
return eprintf("fread in read_it");
break;
case RCL_CHAR:
for( ii=0; ii<reclen; ++ii )
if( FAILURE == (rec2[ii]=fgetc(tfsp)) )
return eprintf("fgetc in read_it");
break;
case RCL_LINE:
if( FAILURE == fgets(rec2,reclen+1,tfsp) )
return eprintf("fgets in read_it");
break;
}
if( strncmp(rec1,rec2,reclen) != 0 )
return eprintf("ripple mismatch:\n\texpected: '%s'\n\tgot: '%s'",
rec1,rec2);
++rrecs; /* incr num recs actually read */
return SUCCESS;
}
/***************************************************************************/
rcheck_it() /*** check that some of it reads ok randomly ***/
{
WORD ii;
LONG rn;
LONG rpos;
FILE *fopen(), *fopenb();
/* Step 1: open the file */
if( AB_ASCII == ab_flag )
tfsp = fopen(filename,"r");
else tfsp = fopenb(filename,"r");
if( NULLPTR == tfsp )
return eprintf("fopen in rcheck_it");
/* Step 2: read randomly absolute */
for( ii=0; ii<chk_cnt; ++ii )
{
if( FAILURE == fseek(tfsp,chk_rpos[ii],0) )
return eprintf("fseek(%ld,0) in rcheck_it",
chk_rpos[ii]);
if( ftell(tfsp) != chk_rpos[ii] )
return eprintf("ftell in rcheck_it");
if( read_it(chk_recn[ii]) )
return FAILURE;
}
/* Step 3: read randomly relative */
if( FAILURE == rewind(tfsp) )
return eprintf("rewind in rcheck_it");
if( AB_BINARY == ab_flag ) /* do this for BINARY files: */
for( rn=chk_incr,rpos=chk_incr*reclen; rn<recmax; rn+=(1+chk_incr) )
{
if( FAILURE == fseek(tfsp,rpos,1) )
return eprintf("fseek(%ld,1) in rcheck_it",rpos);
if( read_it(rn) )
return FAILURE;
}
/* Step 4: close */
if( FAILURE == fclose(tfsp) )
return eprintf("fclose in rcheck_it");
return SUCCESS;
}
/***************************************************************************/
/***************************************************************************/
/****************************************************************/
/* makerec: builds a rippled record for a given record number */
/* Record looks like: */
/* <record_label><record_number><ripple_pattern> */
/* or <ripple_pattern> if reclabel==NULL */
/****************************************************************/
makerec(record,rlen,recnum,reclabel,clo,chi)
BYTE *record; /* place to make the record */
UWORD rlen; /* size of the record to make */
LONG recnum; /* record number to make */
BYTE *reclabel; /* label to prepend to each record */
WORD clo, chi; /* range of char values for ripple pattern */
{
BYTE lbuf[10]; /* place to hold chars */
BYTE *cp; /* char ptr */
WORD cc; /* char temp */
clo &= 0xFF; chi &= 0xFF; /* defeat sign extension */
if( reclabel != NULLPTR )
{
for( ; *reclabel && rlen>0; --rlen )/* copy label to record */
*record++ = *reclabel++;
sprintf(lbuf,"#%5.5D#",recnum); /* cvt recnum to ascii */
for( cp=lbuf; *cp && rlen>0; --rlen)/* copy recnum into rec */
*record++ = *cp++;
}
cc = recnum % (1 + chi - clo); /* choose new place to start */
cc += clo; /* DRC bug... */
for( ; rlen>0; --rlen ) /* generate ripple pattern */
{
if( cc > chi ) cc = clo; /* ripple range check */
*record++ = cc++;
}
*record++ = NULL; /* insure NULL terminated */
*record++ = NULL; /* insure NULL terminated */
}
/***************************************************************************/
/***************************************************************************/
/************************************************************************
*
* Calling sequence:
* nchrs = eprintf(fmt,arg1,arg2,...argn);
* Where:
* nchrs = # chars output by printf
* fmt -> a string specifying how arg1-n are to be printed.
*
**************************************************************************/
WORD eprintf(fmt,args)
BYTE *fmt,
*args;
{
_doprt(stdout,"\nERROR:\t");
return(_doprt(stdout,fmt,&args));
}
WORD ep_init() /* initiate eprintf for new set of error messages */
{
}
WORD ep_fini() /* wrap up a set of error messages */
{
}
ap up a set of error messages */
{
}
ap up a set of error messages */
{
}


File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,653 @@
/* Compiler Test Program Part II - version 4.0 plus */
#define DOHIST '\!'
#define QUOTED 128
struct lbits {
unsigned b1 : 4;
unsigned b2 : 12;
} low;
struct hbits {
unsigned b1 : 12;
unsigned b2 : 4;
} ;
struct hbits high; /* be sure global decl ok... */
int err;
int globali = -32768;
unsigned globalu = 44000;
char ca[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
long lconst1 = 5 * 9;
long lconst2 = 5L * 9;
long lconst3 = 5 * 9L;
long lconst4 = 5L * 9L;
long lconst5 = (long)(5 * 9);
char c0[] = {
0, 1, 2, 3, 4,
5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15,
};
int i0[] = {
0, 1, 2, 3, 4,
5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15,
};
long l0[] = {
0, 1, 2, 3, 4,
5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15,
};
struct Proto {
char P_id;
int (*P_turnon)();
int (*P_rdmsg)();
int (*P_wrmsg)();
int (*P_rddata)();
int (*P_wrdata)();
int (*P_turnoff)();
};
extern int gturnon(), gturnoff();
extern int grdmsg(), grddata();
extern int gwrmsg(), gwrdata();
struct Proto Ptbl[] = {
'g', gturnon, grdmsg, gwrmsg, grddata, gwrdata, gturnoff,
'\0'
};
struct nroff {
int a;
char *p;
char *ctag[5];
char *zz;
};
struct nroff star = {
1,
"pstring...",
"zero",
"one",
"two",
"three",
"four",
"zzstring"
};
struct {
int a[2];
char b[2];
long c[2];
char *d[2];
} sa = {
1, 2,
'a', 'b',
3, 4,
"abc", "def"
};
int gturnon() {}
int gturnoff() {}
int grdmsg() {}
int grddata() {}
int gwrmsg() {}
int gwrdata() {}
main()
{
l_vs_i();
rl_vs_i();
l_vs_ri();
rl_vs_ri();
v40();
v41();
v42();
v42_a();
if (!err)
printf("Far Freaking Out\n");
else
printf("Tough Luck.....\n");
}
l_vs_i() /* longs versus ints... v. 4.0 addition */
{
long autol, autol1;
int i;
i = 3;
autol = autol1 = 100;
autol1 *= i;
autol =autol * i;
if (autol1 != autol) error(0x00);
autol = autol1 = 100;
autol1 /= i;
autol =autol / i;
if (autol1 != autol) error(0x01);
autol = autol1 = 100;
autol1 += i;
autol =autol + i;
if (autol1 != autol) error(0x02);
autol = autol1 = 100;
autol1 -= i;
autol =autol - i;
if (autol1 != autol) error(0x03);
autol = autol1 = 100;
autol1 %= i;
autol =autol % i;
if (autol1 != autol) error(0x04);
autol = autol1 = 100;
autol1 <<= i;
autol =autol << i;
if (autol1 != autol) error(0x05);
autol = autol1 = 100;
autol1 >>= i;
autol =autol >> i;
if (autol1 != autol) error(0x06);
autol = autol1 = 100;
autol1 &= i;
autol =autol & i;
if (autol1 != autol) error(0x07);
autol = autol1 = 100;
autol1 |= i;
autol =autol | i;
if (autol1 != autol) error(0x08);
autol = autol1 = 100;
autol1 ^= i;
autol =autol ^ i;
if (autol1 != autol) error(0x09);
}
rl_vs_i() /* register longs versus ints... v. 4.0 addition */
{
register long regl, regl1;
int i;
i = 3;
regl = regl1 = 100;
regl1 *= i;
regl = regl * i;
if (regl1 != regl) error(0x10);
regl = regl1 = 100;
regl1 /= i;
regl = regl / i;
if (regl1 != regl) error(0x11);
regl = regl1 = 100;
regl1 += i;
regl = regl + i;
if (regl1 != regl) error(0x12);
regl = regl1 = 100;
regl1 -= i;
regl = regl - i;
if (regl1 != regl) error(0x13);
regl = regl1 = 100;
regl1 %= i;
regl = regl % i;
if (regl1 != regl) error(0x14);
regl = regl1 = 100;
regl1 <<= i;
regl = regl << i;
if (regl1 != regl) error(0x15);
regl = regl1 = 100;
regl1 >>= i;
regl = regl >> i;
if (regl1 != regl) error(0x16);
regl = regl1 = 100;
regl1 &= i;
regl = regl & i;
if (regl1 != regl) error(0x17);
regl = regl1 = 100;
regl1 |= i;
regl = regl | i;
if (regl1 != regl) error(0x18);
regl = regl1 = 100;
regl1 ^= i;
regl = regl ^ i;
if (regl1 != regl) error(0x19);
}
l_vs_ri() /* longs versus register ints... v. 4.0 addition */
{
long autol, autol1;
register int i;
i = 2;
autol = autol1 = 100;
autol1 *= i;
autol =autol * i;
if (autol1 != autol) error(0x20);
autol = autol1 = 100;
autol1 /= i;
autol =autol / i;
if (autol1 != autol) error(0x21);
autol = autol1 = 100;
autol1 += i;
autol =autol + i;
if (autol1 != autol) error(0x22);
autol = autol1 = 100;
autol1 -= i;
autol =autol - i;
if (autol1 != autol) error(0x23);
autol = autol1 = 100;
autol1 %= i;
autol =autol % i;
if (autol1 != autol) error(0x24);
autol = autol1 = 100;
autol1 <<= i;
autol =autol << i;
if (autol1 != autol) error(0x25);
autol = autol1 = 100;
autol1 >>= i;
autol =autol >> i;
if (autol1 != autol) error(0x26);
autol = autol1 = 100;
autol1 &= i;
autol =autol & i;
if (autol1 != autol) error(0x27);
autol = autol1 = 100;
autol1 |= i;
autol =autol | i;
if (autol1 != autol) error(0x28);
autol = autol1 = 100;
autol1 ^= i;
autol =autol ^ i;
if (autol1 != autol) error(0x29);
}
rl_vs_ri() /* reg longs versus reg ints... v. 4.0 addition */
{
register long regl, regl1;
register int i;
i = 3;
regl = regl1 = 100;
regl1 *= i;
regl = regl * i;
if (regl1 != regl) error(0x30);
regl = regl1 = 100;
regl1 /= i;
regl = regl / i;
if (regl1 != regl) error(0x31);
regl = regl1 = 100;
regl1 += i;
regl = regl + i;
if (regl1 != regl) error(0x32);
regl = regl1 = 100;
regl1 -= i;
regl = regl - i;
if (regl1 != regl) error(0x33);
regl = regl1 = 100;
regl1 %= i;
regl = regl % i;
if (regl1 != regl) error(0x34);
regl = regl1 = 100;
regl1 <<= i;
regl = regl << i;
if (regl1 != regl) error(0x35);
regl = regl1 = 100;
regl1 >>= i;
regl = regl >> i;
if (regl1 != regl) error(0x36);
regl = regl1 = 100;
regl1 &= i;
regl = regl & i;
if (regl1 != regl) error(0x37);
regl = regl1 = 100;
regl1 |= i;
regl = regl | i;
if (regl1 != regl) error(0x38);
regl = regl1 = 100;
regl1 ^= i;
regl = regl ^ i;
if (regl1 != regl) error(0x39);
}
v40() /* 4.0 fixed and tested */
{
long l, l1;
register int i;
/* bit assignments */
low.b1 = high.b2;
high.b1 = low.b2;
l = l1 = 45L;
/* non-code-generating simple expressions */
l *= 1L;
if (l != l1) error(0x40);
l += 0L;
if (l != l1) error(0x41);
l -= 0L;
if (l != l1) error(0x42);
l *= 0L;
if (l != 0L) error(0x43);
l1 %= 1L;
if (l1 != 0L) error(0x44);
/*SMC Bug - not properly extending i register on stack*/
i = 2;
ca[i] = f();
if( ca[i] != f() ) error(0x45);
}
f()
{
return(0);
}
struct xyzzytype {
long x, y, z;
char *xyz, xyzzy;
} saray1[3], saray2[4];
#define max(x,y) ((x > y) ? 'x' : 'y')
#define strings(s1,s2) "s1s2"
#define substitute(x) "x,"
v40a() /* bug fixes and enhancements for v 4.0 ammended */
{
char ch, *s, *t;
ch = max(3,9);
if(ch != '9') error(0x50);
s = strings(s,t);
if (strcmp(s,"s1s2") != 0) error(0x51);
s = substitute(5);
if (strcmp(s,"5,") != 0) error(0x52);
saray2[0].y = 4L; saray2[0].xyzzy = 'p'; saray2[0].x = 450L;
saray1[2] = saray2[0];
}
int v41_testvalue;
v41()
{
register char *p;
register int i;
register int j;
int form;
long m, n;
long al[10];
int aray[3][4][5];
aray[2][3][4] = 4; /* multi dimensional arrays */
if (aray[2][3][4] != 4) error(0x53);
if (lconst1 != 45) error(0x54); /* long constant initialization */
if (lconst2 != 45) error(0x55);
if (lconst3 != 45) error(0x56);
if (lconst4 != 45) error(0x57);
if (lconst5 != 45) error(0x58);
m = 12; n = -1; /* arrays involving long mult for indices */
al[2] = 33L;
n = al[m + n * 10];
if (n != 33L) error(0x59);
al[2L] = 31L; /* arrays involving long indices */
n = al[2];
if (n != 31L) error(0x5a);
1 ? 0 : 2;
1 ? (form = 0) : (form = 1);
if (form != 0) error(0x5b);
form = 3;
0 ? (form = form | ( 1 << 0)) : (form = form & ~(1<<0));
if (form != 2) error(0x5c);
form = 3;
0 ? (form |= (1 << 0)) : (form &= ~(1 << 0));
if (form != 2) error(0x5d);
for( i = 0; i < sizeof(ca); i++ )
ca[i] = i;
i = 0;
p = ca;
if( ca[*p++]++ != 0 ) error(0x61);
if( p != &ca[1] ) error(0x62);
if( ca[0] != 1 ) error(0x63);
if( ca[i+=1]++ != 1 ) error(0x64);
if( i != 1 ) error(0x65);
if( ca[1] != 2 ) error(0x66);
if( ca[i+= *p++]++ != 3 ) error(0x67);
if( i != 3 ) error(0x68);
if( p != &ca[2] ) error(0x69);
if( ca[3] != 4 ) error(0x6a);
j = 1;
i = j++ && j++;
if( j != 3 ) error(0x6b);
if( i != 1 ) error(0x6c);
j = 0;
i = j++ && j++;
if( j != 1 ) error(0x6d);
if( i != 0 ) error(0x6e);
j = 1;
i = --j || --j;
if( j != -1 ) error(0x6f);
if( i != 1 ) error(0x70);
j = 1;
i = j ? --j : --j;
if( j != 0 ) error(0x71);
if( i != 0 ) error(0x72);
v41_testvalue = 128;
if (v41_testvalue != ((long) 128)) error(0x73);
if (v41_testvalue != ((int)(long) 128)) error(0x74);
if (v41_testvalue != (int)((long) 128)) error(0x75);
v41_testvalue = 128 * 3;
if (v41_testvalue != (int)((long) 128*3)) error(0x76);
if ((long)p & 0x80000000);
}
struct qtest {
int sar[10];
};
struct zip {
int i; char c[6]; int j;
} zippo[] = {
0, "zero", 00,
1, "one", 11,
2, "two", 22,
3, "three", 33,
4, 'fo', "ur", 44,
5, "five", 55,
6, 'si', 'x', 0, 0, 0, 66,
7, 'se', 've', 'n\0', 77,
0
};
struct Abit {
char x0;
char x1:1;
int x2:1;
int x3:1;
} bit1;
struct Bbit {
char bx1;
int bx2:1;
int bx3:1;
} bit2;
v42()
{
int case_val, index, tmp;
int aar[10];
struct qtest a;
v41_testvalue = 128 * 3;
if (v41_testvalue != ((int)(long) 128*3)) error(0x80);
case_val = 0200| 'P';
switch(case_val) {
case (0200|'P'): break;
default: error(0x81); break;
}
if (sizeof(a.sar) != sizeof(aar)) error(0x82);
index = 2;
aar[index+1] = 'c';
if (aar[index+'\01'] != 'c') error(0x83);
if (c0[3] != 3) error(0x84);
if (i0[5] != 5) error(0x85);
if (l0[12] != 12) error(0x86);
if (eqstr(zippo[1].c,"one")==0) error(0x87);
if (eqstr(zippo[4].c,"four")==0) error(0x88);
if (eqstr(zippo[6].c,"six")==0) error(0x89);
if (eqstr(zippo[7].c,"seven")==0) error(0x8a);
tmp = 'd';
index = tmp - 'a';
if (ca[index] != ca[tmp - 'a']) error(0x8b);
if (sizeof(struct Proto) != 26) error(0x8c);
if ((sizeof(struct Proto)*2) != sizeof(Ptbl)) error(0x8d);
tmp = 0x7000;
switch(tmp & 0xf000) {
default:
case_val = tmp&0xf000; error(0x8e); printf("val == %x\n",case_val);
case 0x7000:
break;
}
}
struct termio {
int c_iflag;
int c_oflag;
int c_cflag;
int c_lflag;
int c_line;
char c_cc[8];
};
struct termio ttys;
int ttysave;
v42_a()
{
long l;
bit1.x2 = 1;
bit1.x3 = 0;
bit2.bx2 = 1;
bit2.bx3 = 0;
if( bit1.x2 != bit2.bx2) error(0x90);
if( bit1.x3 != bit2.bx3) error(0x91);
if (ch_test() != (DOHIST|QUOTED)) error(0x92);
l = 0x8000L;
if (!(l & 0x8000)) error(0x93);
if (iox(0, (('T'<<8)|1), &ttys) >= 0)
ttysave = ttys.c_oflag;
if (eqstr(star.ctag[3],"three")==0) error(0x94);
if (sa.a[1] != 2) error(0x95);
if (sa.b[1] != 'b') error(0x96);
if (sa.c[1] != 4) error(0x97);
if (eqstr(sa.d[1],"def")==0) error(0x98);
}
iox(i,j,k)
int i, j;
long k;
{
return (1);
}
eqstr(ap1,ap2)
char *ap1, *ap2;
{
register char *p1, *p2;
p1 = ap1;
p2 = ap2;
while(*p1) {
if(*p1++ != *p2++)
return(0);
}
if(*p2)
return(0);
return(1);
}
ch_test()
{
return(DOHIST|QUOTED);
}
error(ernum)
int ernum;
{
printf("error %x\n",ernum);
err++;
}

error(ernum)
int ernum;
{
printf("error %x\n",ernum);
err++;
}

error(ernum)
int ernum;
{
printf("error %x\n",ernum);
err++;
}

error(ernum)
int ernum;
{
printf("error %x\n",ernum);
err++;

View File

@@ -0,0 +1,681 @@
/* Compiler Test Program Part III - version 4.2 plus */
char *version = "%W% %G%";
int x1[5] = { 0, 1, 2, 3, 4, };
int x2[5] = { 0, 1, 2, 3, 4 };
int x3[5] = { 0, 1, 2, 3, };
unsigned u = -1;
char arc[5][3] = {
0x1111, 0x1111, 0x1111, 0x1111, 0x1111,
0xffff, 0x1ffff, 0xffff, 0xffff, 0xffff /* should have warnings on init */
};
int ari[5][3] = {
0x1111, 0x1111, 0x1111, 0x1111, 0x1111,
0xffff, 0x1ffff, 0xffff, 0xffff, 0xffff /* should have 1 warning on init */
};
unsigned int aru[5][3] = {
0x1111, 0x1111, 0x1111, 0x1111, 0x1111,
0xffff, 0x1ffff, 0xffff, 0xffff, 0xffff /* should have 1 warning on init */
};
long arl[5][3] = {
0x1111, 0x1111, 0x1111, 0x1111, 0x1111,
0xffff, 0x1ffff, 0xffff, 0xffff, 0xffff
};
short ars[2][2] = {
0|0100000, 1|0100000, 0xffff, 0x8000|0x040
};
struct Mstruct {
int ar[3];
char c;
} *mtab[] = {
0, 1, 2, 'c'
};
typedef int tdefa[(5)];
typedef int tdefb [10+(2)];
tdefa a;
tdefb b;
int ff[(5)];
struct atype {
int a;
long b;
int c;
} A[] = {
{ 1, 1, 1 },
{ 2, 2, 2 },
{ 3, 3, 3 },
};
struct atype *mikeC[] = { /* better not have any warnings on init... */
0xf1e010,
0xf1e011,
0xf1e012,
0xf1e013,
0,
};
struct btype {
char *p1;
int i;
char c;
} B = {
"This is a string.....",
35,
'p'
};
int err;
char string[] = "9876543210";
int fun1(), fun2();
struct {
int sz;
int (*func)();
} fun[2] = { 1, fun1, 2, fun2 };
int fglobal;
int global1 = 4, global2 = 5;
main()
{
v42();
test();
test2();
aray();
do_stass();
do_sizeof();
dbra_tst();
new_test();
if (err)
printf("Tough Luck...\n");
else
printf("Far Freaking Out...\n");
}
error(ernum)
int ernum;
{
printf("error %x\n",ernum);
err++;
}
short mstype;
typedef struct MODES {
short imap;
} MODER, *pMODER;
static MODER amode;
pMODER vmode;
v42()
{
int i;
struct test {
int a;
long b;
struct {
char c;
int d;
}y;
} x;
if (A[0].b != 1) error(0x1);
if (A[1].c != 2) error(0x2);
if (A[2].a != 3) error(0x3);
x.y.d = 3;
x.a = 0;
{
if (!x.y.d) error(0x4);
}
if (x.a) error(0x5);
{
char *s = &string;
int i;
i = *s - '0';
if (i != 9) error(0x5);
}
{
register int regi;
int i;
if ((i=f(3)) > f(1)) ; else error(0x6);
if ((regi=f(3)) > f(1)) ; else error(0x7);
}
if (1) {
short count = 0;
mstype = 33;
}
if (mstype != 33) error(0x8);
ff[i=0] = 33;
if (ff[0] != 33) error(0x9);
if(!main) error(0x10);
vmode = &amode;
}
f(val)
int val;
{
return(val);
}
struct fi_index {
long fi_flags;
unsigned fi_count;
char fi_groupid;
char fi_nlinks;
int fi_ownerid;
long fi_fsize;
long fi_findblk;
int fi_dev;
int fi_lock;
int fi_spdev;
char *fi_rlocks;
};
char ca[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int ica[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
char cb[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
char cc[10] = { '01', '23', '45', '67', '89' };
struct A {
int a;
long b;
} atype[] = {
0, 3,
1, 4,
2, 5
};
int three[3][3][3] = {
0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2
};
/*char ar_test[0xf0000];*/
aray()
{
register int n;
register char c, *bp;
register struct fi_index *fip;
struct fi_index xxx;
fip = &xxx;
xxx.fi_fsize = 3;
n = 5000;
if( n > (4096 - fip->fi_fsize) ) {
n = 4096 - fip->fi_fsize;
if (n != (4096 - fip->fi_fsize)) error(0x20);
}
else
error(0x21);
if (ca[3] != 3) error(0x22);
if (ica[7] != 7) error(0x23);
if (cb[5] != '5') error(0x24);
if (cc[8] != '8') error(0x25);
if (atype[2].a != 2) error(0x26);
if (atype[0].b != 3) error(0x27);
if (three[0][0][2] != 0) error(0x28);
if (three[1][1][1] != 1) error(0x29);
if (three[2][2][0] != 2) error(0x2a);
/*
ar_test[0xa000L] = '7'; bp = &ar_test[0];
c = bp[0xa000L];
if (c != '7') error(0x2b);
ar_test[0x10000] = 'T';
c = bp[0x10000];
if (c != 'T') error(0x2c);
*/
}
struct {
int _a, _a1, _a2, _a3, _a4;
long _b, _b1, _b2, _b3, _b4;
char _c, _c2, _c3, _c4;
} st, *pt, st2, *pt2, sa[3];
do_stass()
{
pt = &st; pt2 = &st2;
st._b4 = 3; st2._b4 = 9;
st = st2;
if (st._b4 != st2._b4) error(0x28);
pt->_b1 = 55; pt2->_b1 = 34;
*pt = *pt2;
if (pt->_b1 != pt2->_b1) error(0x29);
st = *pt;
*pt = st;
sa[0]._c4 = 'd'; sa[1]._c4 = '8';
sa[1] = sa[0];
if (sa[0]._c4 != sa[1]._c4) error(0x2a);
}
struct sz_struc {
int za[10];
char zc;
char zb[3];
struct xxx {
char zd[5];
long ze[2];
}zf;
} *s, t;
int szaray[10];
typedef struct TDS {
char st;
unsigned fConstant : 1;
unsigned width : 7;
unsigned bt : 4;
unsigned tq1 : 2;
unsigned tq2 : 2;
unsigned tq3 : 2;
unsigned tq4 : 2;
unsigned tq5 : 2;
unsigned tq6 : 2;
} TDR, *pTDR;
typedef struct {
char sbVar[8];
TDR td;
long valTy;
} TYR, *pTYR;
TYR vrgTySpc[] = { /* test of short element initialization */
{"$cBad", '\0', '\0', '\0', '\0', 0},
0
};
struct one {
struct two *p2;
struct one *p1;
};
struct two {
int atwo, btwo, ctwo, dtwo;
};
struct one xyzzy[] = {
0, 0
};
char szof[10];
struct AAAAA {
char a[3];
int b[3];
long c[3];
double d[3];
char e[3][3];
int f[3][3];
long g[3][3];
double h[3][3];
char i;
int j;
long k;
float l;
} *abcdef;
do_sizeof()
{
char nx[sizeof szof];
char ny[sizeof (szof)];
int i;
long l;
char *p;
int *pi;
if ( sizeof(vrgTySpc) != (2 * sizeof(TYR)) ) error(0x30);
if ( sizeof(s->za) != 20 ) error(0x31);
if ( sizeof(s->zb) != 3 ) error(0x32);
if ( sizeof(s->zf) != 14 ) error(0x33);
if ( sizeof(s->zf.ze) != 8 ) error(0x34);
if ( sizeof(szaray) != 20 ) error(0x35);
if ( sizeof(t.za) != 20 ) error(0x36);
if ( sizeof(s->za[4]) != 2 ) error(0x37);
if ( sizeof(t.zc) != 1 ) error(0x38);
if ( sizeof(p) != 4 ) error(0x39);
if ( sizeof(pi) != 4 ) error(0x3a);
if ( sizeof(xyzzy) != 8 ) error(0x3b);
if ( sizeof(l) != 4 ) error(0x3c);
if ( sizeof(*p) != 1 ) error(0x3d);
if ( sizeof(*pi) != 2 ) error(0x3e);
if ( sizeof(szaray[4]) != 2 ) error(0x3f);
if ( sizeof(struct one) != 8) error(0x40);
if ( sizeof(nx) != sizeof ny) error(0x41);
if ( sizeof(ny) != 10) error(0x42);
if ( sizeof(abcdef->a) != 3) error(0x43);
if ( sizeof(abcdef->b) != 6) error(0x44);
if ( sizeof(abcdef->c) != 12) error(0x45);
if ( sizeof(abcdef->d) != 12) error(0x46);
if ( sizeof(abcdef->e) != 9) error(0x47);
if ( sizeof(abcdef->f) != 18) error(0x48);
if ( sizeof(abcdef->g) != 36) error(0x49);
if ( sizeof(abcdef->h) != 36) error(0x4a);
if ( sizeof(abcdef->i) != 1) error(0x4b);
if ( sizeof(abcdef->j) != 2) error(0x4c);
if ( sizeof(abcdef->k) != 4) error(0x4d);
if ( sizeof(abcdef->l) != 4) error(0x4e);
}
typedef long ADRT;
ADRT vfp;
int PutState()
{
vfp = 1; /* just needs to compile.... */
}
struct saxer {
struct saxer *ptr;
unsigned int u_incr;
int i_incr;
} john[4];
typedef long X;
X typey;
#define STL 0x400L
struct xx {
int a, b;
};
test()
{
register struct saxer *p, *q;
register short mask;
int dp, z, *zp;
long l, lo;
register char rc;
register int ri;
char c;
int i;
struct xx xa[8/sizeof(struct xx)];
struct xx xd[8/4];
dp = 0x720;
mask = ((dp&0xff)<<1) -1;
if (mask != 0x3f) error(0x50);
l = 0x7777ff30;
casttest((int)(l&0xff)); /* error 0x51 */
lo = 0;
l = STL - lo;
if (l != 0x400L) error(0x52);
l = 0xffffffff;
if (!(l & 0x80000000)) error(0x53);
l &= 0x80000000;
if (l != 0x80000000) error(0x54);
mask = 1;
l = 0xf;
mask += (l&1);
if (mask != 2) error(0x55);
z = 1;
(*fun[z].func)();
if (fglobal != 3) error(0x56);
typey = 0x71234;
fun1(typey); /* error 0x57 */
z = 34;
z &= 0;
if (z) error(0x58);
p = &john[0]; q = &john[0];
p->u_incr = 2;
p->i_incr = 2;
p += p->u_incr;
q += q->i_incr;
if (p != q) error(0x59);
if (sizeof(xa) != sizeof(xd)) error(0x5a);
zp = &z;
*zp = 34;
*zp != 0;
if (*zp != 34) error(0x5b);
if (global1 != 4) error(0x5c);
if (global2 != 5) error(0x5d);
rc = 6; c = 8; ri = 2; i = 4;
c /= ri;
if (c != 4) error(0x5e);
c /= i;
if (c != 1) error(0x5f);
rc /= 2;
if (rc != 3) error(0x60);
}
casttest(i)
int i;
{
if (i != 0x30) error(0x51);
}
fun1(l)
long l;
{
fglobal = 2;
if (l != 0x71234) error(0x57);
}
fun2()
{
fglobal = 3;
}
char *shifts[4] = { "as", "ls", "rox", "ro" };
test2()
{
int i;
long l;
int y();
char *mnem;
int opcode;
l = 0xfe00; /* hex constant should be int value, which should go neg */
if (l > 0) error(0x61);
l = 32768;
if (l < 0) error(0x62);
f2(fun2,fun2); /* error 0x63 */
mnem = shifts[(opcode>>9)&3];
is_512L(0x64,512L); /* error 0x64 */
is_512L(0x65,(long)512); /* error 0x65 */
i = 512;
l = 512;
is_512L(0x66,l); /* error 0x66 */
is_512L(0x67,(long)i); /* error 0x67 */
l = 500; i = 12;
is_512L(0x68,l+i); /* error 0x68 */
is_512L(0x69,512L*1); /* error 0x69 */
is_512L(0x6a,511L+1); /* error 0x6a */
is_512L(0x6b,1*512L); /* error 0x6b */
is_512L(0x6c,1+511L); /* error 0x6c */
is_512L(0x6d,(long)(512*1));/* error 0x6d */
is_512L(0x6e,513L-1); /* error 0x6e */
is_512L(0x6f,512L/1); /* error 0x6f */
}
is_512L(enum,lval)
int enum;
long lval;
{
if (lval != 512L)
error(enum);
}
static f2(a1,a2)
char *a1, *a2;
{
if (a1 != a2) error(0x63);
}
int i_global;
dbra_tst()
{
register long reg_l;
register int localreg;
int local;
long local_l;
local_l = i_global = local = localreg = reg_l = 1L;
if(--i_global == -1) error(0x70);
if(--local == -1) error(0x71);
if(--localreg == -1) error(0x72);
if(--local_l == -1) error(0x73);
if(--reg_l == -1) error(0x74);
if(--i_global == -1) ; else error(0x75);
if(--local == -1) ; else error(0x76);
if(--localreg == -1) ; else error(0x77);
if(--local_l == -1L) ; else error(0x78);
if(--reg_l == -1L) ; else error(0x79);
}
typedef char TBOOL;
TBOOL tboolx[2], tbooly[(2)];
struct xtype {
char *p1;
char *ar[20];
char *p2;
};
struct xtype newff = {
"p1",
"zero",
"one",
};
char *xfp = "abc";
struct xtype ff0 = {
0L,
1L,
2L,
3L,
4L,
5L,
6L,
7L,
};
struct xtype ff1 = {
"p1",
"zero",
"one",
"two",
"three",
"four",
"five",
"p2",
};
struct xtype ff2 = {
"p1",
"zero",
"one",
"two",
"three",
"four",
"five",
"p2"
};
struct xtype ff3 = {
"p1",
"zero",
"one",
"two",
"three",
"four",
"five",
};
struct xtype ff4 = {
"p1",
"zero",
"one",
"two",
"three",
"four",
"five"
};
struct xtype ff5 = {
"p1",
"zero",
"one",
"two",
};
struct xtype ff6 = {
"p1",
"zero",
"one",
"two"
};
new_test()
{
char *cp;
extern int err;
char str[9];
int i;
unsigned u;
/* typedef and paren'd strangeness */
if(sizeof(tboolx) != sizeof(tbooly)) error(0x80);
if(sizeof(tbooly) != 2) error(0x81);
tboolx[1] = 1; tbooly[1] = 1;
cp = tboolx;
if(*(cp+1) != 1) error(0x82);
cp = tbooly;
if(*(cp+1) != 1) error(0x83);
/* assignment as a subscript */
str[i=0] = 3;
if(str[i] != 3) error(0x84);
if(i != 0) error(0x85);
/* structure pointer array initializations */
newff.ar[1] = "xyz";
if(*xfp != 'a' || *(xfp+1) != 'b' || *(xfp+2) != 'c') error(0x86);
/* unsigned increment to pointer */
cp = str; i = u = 3;
*(cp+i) = 'c';
if (*(cp+u) != 'c') error(0x87);
}
ned increment to pointer */
cp = str; i = u = 3;
*(cp+i) = 'c';
if (*(cp+u) != 'c') error(0x87);
}
ned increment to pointer */
cp = str; i = u = 3;
*(cp+i) = 'c';
if (*(cp+u) != 'c') error(0x87);
}
ned increment to pointer */
cp = str; i = u = 3;
*(cp+i) = 'c';

View File

@@ -0,0 +1,644 @@
/* Post 4.2 compilers */
char *version = "%W% %G%";
struct xxx {
int x;
char m,n,o,p;
};
struct zzz {
int b;
struct aaa {
int f;
char g, h, i, j;
} bb[3];
int c;
} A = {
1,
2, 'a', 'b', 'c', 'd',
3, 'e', 'f', 'g', 'h'
};
struct yyy {
int a;
struct xxx y[3];
int q;
} B = {
1,
2, 'a', 'b', 'c', 'd',
3, 'e', 'f', 'g', 'h'
};
char ar[3][3] = { 'a', 'b', 'c', 'd', 'e' };
int x[2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, };
int errors;
main()
{
xtest();
ytest();
ztest();
dec_inc();
div_test();
s_u_test();
next_to_last_test();
last_test();
if(!errors)
printf("Far Freaking Out\n");
else
printf("Tough Luck\n");
}
error(enum)
int enum;
{
printf("error %x\n",enum);
errors++;
}
char *xstr1 = "8999999988";
char *xstr2 = "8999999988";
char *xstr3 = "8999999988";
xtest()
{
register char *rcp, rc;
char *cp, c;
int i;
long *laddr;
int *iaddr;
short *saddr;
long addr;
if(A.bb[1].i != 'g') error(0x1);
if(A.bb[1].i != B.y[1].o) error(0x2);
if(A.c != 0) error(0x3);
if(B.y[3].f != 0) error(0x4);
i = 257;
i = (char)(i + 3);
if (i != 4) error(0x5);
saddr = laddr = iaddr = addr = 0xff000;
if(laddr != addr) error(0x6);
if(iaddr != addr) error(0x7);
if(saddr != addr) error(0x8);
rcp = &xstr1[6];
while((*rcp)++ == '9')
*rcp-- = '0';
rcp = &xstr2[7];
while((*--rcp)++ == '9')
*rcp = '0';
cp = &xstr3[7];
while((*--cp)++ == '9')
*cp = '0';
if(strcmp(xstr1,"9000000988") != 0) error(0x9);
if(strcmp(xstr2,"9000000988") != 0) error(0xa);
if(strcmp(xstr3,"9000000988") != 0) error(0xb);
rc = '9';
rc = *rcp++ = '3';
if(rc != '3') error(0xc);
if(*(rcp-1) != '3') error(0xd);
c = '8';
c = (char)0;
if(c != '\0') error(0xe);
if(multest() != 4) error(0xf);
}
struct bfs {
int bf1: 1;
} bfx, *bfa[3] = { (char *)-1, &bfx, (char *)-1} ;
char xar[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
dec_inc()
{
register struct bfs **bfp;
register char *p, *q, c;
bfx.bf1 = 0;
bfp = &bfa[2];
(*--bfp)->bf1 += 1;
if( bfx.bf1 != 1 ) error(0x10);
p = &xar[10];
(*--p)++;
if( xar[9] != 10 || p != &xar[9] ) error(0x11);
c = (*--p)++;
if( c != 8 || xar[8] != 9 || p != &xar[8] ) error(0x12);
c = 7;
if( (*--p)++ != c || xar[7] != 8 || p != &xar[7] ) error(0x13);
p = &xar[0];
(*p++)++;
if( xar[0] != 1 || p != &xar[1] ) error(0x14);
c = (*p++)++;
if( c != 1 || xar[1] != 2 || p != &xar[2] ) error(0x15);
c = 2;
if( (*p++)++ != c || xar[2] != 3 || p != &xar[3] ) error(0x16);
--(*--p);
if( xar[2] != 2 || p != &xar[2] ) error(0x17);
c = --(*--p);
if( c != 1 || xar[1] != 1 || p != &xar[1] ) error(0x18);
c = 0;
if( --(*--p) != c || xar[0] != 0 || p != &xar[0] ) error(0x19);
--(*p++);
if( xar[0] != -1 || p != &xar[1] ) error(0x1a);
c = --(*p++);
if( c != 0 || xar[1] != 0 || p != &xar[2] ) error(0x1b);
c = 1;
if( --(*p++) != c || xar[2] != 1 || p != &xar[3] ) error(0x1c);
}
multest()
{
char *s;
register int i;
int j;
s = &j;
*s = 2;
s[1] = 0;
i = 2;
return(i * *s);
}
div_test()
{
int i, i2;
long l, l2;
register int ri, ri2;
register long rl, rl2;
rl2 = l2 = 70000;
ri = rl2 / 10;
rl = rl2 / 10;
i = l2 / 10;
l = l2 / 10;
if(ri != i) error(0x20);
if(rl != l) error(0x21);
if(i != 7000) error(0x22);
if(i != l) error(0x23);
i2 = ri2 = 1;
ri = rl2 / ri2;
rl = rl2 / ri2;
i = l2 / i2;
l = l2 / i2;
if(ri != i) error(0x24);
if(rl != l) error(0x25);
if(rl != rl2) error(0x26);
if(ri == rl) error(0x27);
}
struct fcbflags {
unsigned online : 1;
unsigned buffer_dirty : 1;
unsigned open_mode : 2;
unsigned device_type : 3;
unsigned file_type : 2;
unsigned unbuffered : 1;
};
struct fcb {
int fcbfd;
char *fcpfp;
struct fcbflags fcbflg;
char name;
};
#define ONE 1
#define TWO 2
#define IADDRESS ((int *)0xfff900)
#define CADDRESS ((char *)0xfff900)
#define LADDRESS ((long *)0xfff900)
#define SADDRESS ((struct device *)0xfff900)
struct device {
int mts;
char mtc;
long mtl;
int mti;
};
struct exec {
int xx[19];
int y;
};
typedef char *charp;
struct t {
char *p1;
char *p2;
} ht1 = { 0, ((charp) 30) },
ht2 = { 0, 0 };
ytest()
{
register struct fcb *p;
register long rl;
register int *rpi;
register long *rpl;
register int ri1, ri2;
struct fcb fs;
long a;
int i, j, ari[5];
long l, arl[5];
char buf[40];
struct exec hdr, hdr2;
/* bit field arguments */
i = 1; p = &fs;
p->fcbflg.unbuffered = (i == 0) ? 0 : 1;
if (!p->fcbflg.unbuffered) error(0x30);
i = 0;
p->fcbflg.unbuffered = (i == 0) ? 0 : 1;
if (p->fcbflg.unbuffered) error(0x31);
/* constant coersion */
l = 32768;
if (l != 32768L) error(0x32);
l = 32 * 1024;
if (l != 32768L) error(0x33);
/* long to integer conversions including as parameters and return values */
l = 0xf00030;
ctest(0x34,0x35,(int)l,27); /* errors 34 & 35 */
ctest2(0x36,(int)l); /* error 36 */
l = 0xfff30;
ctest(0x37,0x38,((int)l)&0xff,27); /* errors 37 & 38 */
ctest2(0x39,((int)l)&0xff); /* error 39 */
ctest(0x3a,0x3b,(int)(l&0xff),27); /* errors 3a & 3b */
ctest2(0x3c,(int)(l&0xff)); /* errors 3c */
if(func1(1) != 0x30) error(0x3d);
if(func1(2) != 0x30) error(0x3e);
if(func1(3) != 0x30) error(0x3f);
/* equal-shift tests */
rpi = &ari[3]; rpl = &arl[3];
*rpi = 0x3f02;
*rpi++ >>= 1;
if(ari[3] != 0x1f81) error(0x40);
*--rpi <<= 2;
if(ari[3] != 0x7e04) error(0x41);
*rpl = 0x6af010;
*rpl++ >>= 4;
if(arl[3] != 0x6af01) error(0x42);
*--rpl <<=5;
if(arl[3] != 0xd5e020) error(0x43);
/* sethy-ulman easy expression */
i = 10; j = 3;
a = (long)i * (long)i - (long)j * (long)j;
if(a != 91) error(0x44);
/* tricky coercion of constant to integer pointer with array subscript */
/* indexing off of int/long/char/struct pointers */
l = &IADDRESS[TWO];
if(l != 0xfff904) error(0x45);
l = &LADDRESS[TWO];
if(l != 0xfff908) error(0x46);
l = &CADDRESS[TWO];
if(l != 0xfff902) error(0x47);
l = &(SADDRESS->mtc);
if(l != 0xfff902) error(0x48);
l = &(SADDRESS->mtl);
if(l != 0xfff904) error(0x49);
l = &(SADDRESS->mti);
if(l != 0xfff908) error(0x4a);
/* structure assigned to non structure item... */
hdr.y = 3; hdr2.y = 5;
*(struct exec *)buf = hdr;
hdr2 = *(struct exec *)buf;
if(hdr2.y != 3) error(0x4b);
/* typedef cast inside structure initialization */
if(ht1.p2 != 30) error(0x4c);
/* indexing test with register index variables */
i = j = ri1 = ri2 = 1;
if (x[ri1][ri2][ri1] != x[1][1][1]) error(0x4d);
if (x[i][j][i] != x[1][1][1]) error(0x4e);
}
struct zxx {
int a,b,c,d,e;
};
ztest()
{
register long longtmp;
int i, j, k;
char *cp1, *cp2;
int *ip1, *ip2;
long *lp1, *lp2, l;
struct zxx *sp1, *sp2;
/* int's cast to pointers... */
i = 0x234;
cp1 = i; cp2 = (char *)i;
ip1 = i; ip2 = (int *)i;
lp1 = i; lp2 = (long *)i;
sp1 = i; sp2 = (struct zxx *)i;
if(cp1 != cp2) error(0x70);
if(ip1 != ip2) error(0x71);
if(lp1 != lp2) error(0x72);
if(sp1 != sp2) error(0x73);
/* long easy code skeleton tests */
i = 0x24; j = 0x11;
/* addition.... */
k = i * i + j * j;
longtmp = (long)i * (long)i + (long)j * (long)j;
l = (long)i * (long)i + (long)j * (long)j;
if(longtmp != l) error(0x74);
if(k != l) error(0x75);
/* subtraction.... */
k = i * i - j * j;
longtmp = (long)i * (long)i - (long)j * (long)j;
l = (long)i * (long)i - (long)j * (long)j;
if(longtmp != l) error(0x76);
if(k != l) error(0x77);
/* exclusive or.... */
k = i * i ^ j * j;
longtmp = (long)i * (long)i ^ (long)j * (long)j;
l = (long)i * (long)i ^ (long)j * (long)j;
if(longtmp != l) error(0x78);
if(k != l) error(0x79);
/* inclusive or.... */
k = i * i | j * j;
longtmp = (long)i * (long)i | (long)j * (long)j;
l = (long)i * (long)i | (long)j * (long)j;
if(longtmp != l) error(0x7a);
if(k != l) error(0x7b);
}
struct _b {
long y;
int x;
} bs;
union rec {
struct _b l;
struct {
char c;
int w;
} f;
} recs;
struct ty {
int c;
} tys;
struct _a {
int x;
} as;
union one {
int a;
long b;
struct {
int y;
int x;
} q;
} ones, f1, f2;
struct two {
int a;
long b;
struct {
int y;
int x;
} q;
} twos;
struct _x {
long a;
int b,c,d,e,f;
};
struct _y {
int t;
struct _x s;
} _yz = {
33,
{ 1, 2, 3, 4, 5 }
};
struct _y _yq = { 33, 1, 2, 3, 4, 5 };
struct _s1 {
int a;
int b;
};
struct _s2 {
struct _s1 c;
int d;
};
struct _s2 test0 = { { 10, 20 }, 30 };
struct _s2 test1 = { { 10, 20 } };
struct _s2 test2 = { { 10 }, 30 };
struct _s2 test3 = { 10, 20, 30 };
s_u_test()
{
bs.y = 1;
bs.x = 2;
recs.l.y = 3;
recs.l.x = 4;
tys.c = 'a';
as.x = 5;
if(bs.y != 1) error(0x50);
if(bs.x != 2) error(0x51);
if(recs.l.y != 3) error(0x52);
if(recs.l.x != 4) error(0x53);
if(tys.c != 'a') error(0x54);
if(as.x != 5) error(0x55);
recs.f.c = 'b';
recs.f.w = 6;
if(recs.f.c != 'b') error(0x56);
if(recs.f.w != 6) error(0x57);
if(tys.c != 'a') error(0x58);
twos.a = 7;
twos.b = 8;
twos.q.y = 9;
twos.q.x = 10;
ones.a = 11; f1.b = 0; f2.b = 0;
if(twos.a != 7) error(0x59);
if(twos.b != 8) error(0x5a);
if(twos.q.y != 9) error(0x5b);
if(twos.q.x != 10) error(0x5c);
if(ones.a != 11) error(0x5d);
ones.b = 12;
if(ones.b != 12) error(0x5e);
if(f1.b != 0) error(0x5f);
if(f2.b != 0) error(0x60);
f1.b = f2.b = 0;
ones.q.y = 13;
if(ones.q.y != 13) error(0x61);
if(f1.b != 0) error(0x62);
if(f2.b != 0) error(0x63);
f1.b = f2.b = 0;
ones.q.x = 14;
if(ones.q.x != 14) error(0x64);
if(f1.b != 0) error(0x65);
if(f2.b != 0) error(0x66);
/* initialization tests */
if(_yz.s.c != 3) error(0x67);
if(_yq.s.c != 3) error(0x68);
if(test0.d != 30) error(0x69);
if(test0.c.b != 20) error(0x6a);
if(test1.d != 0) error(0x6b);
if(test2.c.b != 0) error(0x6c);
if(test3.c.b != 20) error(0x6d);
if(test3.d != 30) error(0x6e);
if(test2.d != 30) error(0x6f);
}
ctest(err1,err2,value1,value2) /* value1 had better be an integer !!! */
int err1, err2, value1, value2;
{
if(value1 != 0x30) error(err1);
if(value2 != 27) error(err2);
}
ctest2(err,value) /* value had better be an integer !!! */
int err, value;
{
if(value != 0x30) error(err);
}
func1(ret) /* had better return an integer....... */
int ret;
{
long l;
l = 0xf0030;
if(ret==1) return((int)l);
l = 0xfff30;
if(ret==2) return(((int)l)&0xff);
return((int)(l&0xff)); /* return 3 */
}
struct {
char x_p[3][3];
} *p_ca2, ca2;
int artl();
struct {
int ss_x_z;
int (*ss_ff)();
} sff[] = {3, 0L, 4, &artl};
next_to_last_test()
{
char ch;
int x, y;
char ar[9];
register char c;
/* defined character constants handled properly ?? */
x = '\0';
if(x != 0) error(0x80);
x = '\f';
if(x != 014) error(0x81);
x = '\t';
if(x != 011) error(0x82);
x = '\n';
if(x != 012) error(0x83);
x = '\r';
if(x != 015) error(0x84);
x = '\b';
if(x != 010) error(0x85);
x = '\\';
if(x != 0134) error(0x86);
/* character indices... */
ar[1] = '5'; ar[2] = '6'; x = 1;
ar[ c = (x==1) ? 2 : 1 ] = '3';
if (c != 2) error(0x87);
if(ar[2] != '3') error(0x88);
ar[c & ~128] = '5';
if(ar[2] != '5') error(0x89);
/* array indices incrementing with pointers and other strange things */
p_ca2 = &ca2;
ca2.x_p[1][1] = 'c';
x = 1; y = 1;
p_ca2->x_p[x][y++] = 'd';
if(ca2.x_p[1][1] != 'd') error(0x8a);
if(y != 2) error(0x8b);
/* struct with function arg return */
x = 1;
x = (*sff[x].ss_ff)();
if (x != 4) error(0x8c);
/* character's compared to integer and long constants */
ch = 127;
if(ch > 0xffffff) error(0x8d);
if(ch > 0xfff) error(0x8e);
if(ch != 127) error(0x8f);
}
struct {
char *a;
char *b;
char *c[3];
} flxtv = {
"one",
"two",
"three",
"four",
"five"
};
char ln[3] = "ab";
struct atbh1 { unsigned sevensta:16, sevenstb:4; };
struct atbh2 { unsigned a:4, b:4, c:4; };
last_test()
{
struct atbh1 x;
struct atbh2 y;
int i;
char c, *cp;
/* bit field manipulation */
x.sevensta = 2;
x.sevenstb = 1;
if(x.sevensta != 2) error(0x90);
if(x.sevenstb != 1) error(0x91);
y.a = 3; y.b = 2; y.c = 1;
i = (int)y.a;
if (i != 3) error(0x92);
i = (int)y.b;
if (i != 2) error(0x93);
i = (int)y.c;
if (i != 1) error(0x94);
/* character manipulation */
i = ln[0] * ln[1];
if(i != 9506) error(0x95);
cp = ln;
c = 0xf4;
*cp++ |= (c & 0xf);
if(ln[0] != 0x65) error(0x96); /* 'a' | 0x4 */
cp = flxtv.c[1];
if(*cp != 'f' || *(cp+1) != 'o' || *(cp+2) != 'u' || *(cp+3) != 'r')
error(0x97);
}
artl(last_test)
int last_test; /* argument with same name as function !!! */
{
last_test = 4;
return(last_test);
}
 as function !!! */
{
last_test = 4;
return(last_test);
}
 as function !!! */
{
last_test = 4;
return(last_test);
}
 as function !!! */
{
last_test = 4;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,684 @@
/*----------------------------------------------------------------------*\
| |
| DISK COPY PROGRAM |
| ================= |
| |
| Created: November 4,1982 |
| ------- |
| |
| Last Modified: January 15,1982 |
| ------------- |
| |
| Description: |
| ----------- This program will copy all or portions of |
| one disk to another compatible disk. |
| |
| Needed Files: |
| ------------ <STDIO.H>,<PORTAB.H> |
| |
| Must be linked to the 'C' runtime library. |
| ------------------------------------------ |
| |
| (c) COPYRIGHT DIGITAL RESEARCH 1983 |
| ALL RIGHTS RESERVED |
| |
\*----------------------------------------------------------------------*/
char *copyrt="CP/M-68K(tm), Version 1.2, Copyright 1984, Digital Research";
char *serial="XXXX-0000-654321";
/************************************************************************\
* Here are the Include Files *
\************************************************************************/
/********************************/
#include <stdio.h> /* Standard I/O library */
/********************************/
/************************************************************************\
* DEFINES for Copy.c *
\************************************************************************/
/********************************/
#define ON 1 /* Option is valid for this copy*/
#define OFF 0 /* Option is not valid */
#define BAD 0 /* Illegal mode flag */
#define MATCH 0 /* used by strcmp */
#define SDRIVE 1 /* source drive */
#define DDRIVE 2 /* destination drive */
#define _ALL 0 /* copy whole disk */
#define _BOOT 1 /* copy boot tracks */
#define _FILES 2 /* copy non-boot tracks */
#define _END 3 /* end this program */
#define RDERR 0 /* read error flag */
#define WRERR 1 /* write error flag */
#define NULLB '\0' /* NULL byte */
#define isupper(c) ('A' <= (c) && (c) <= 'Z')/*upper case */
#define islower(c) ('a' <= (c) && (c) <= 'z')/*lower case */
#define tolower(c) (isupper(c) ? ((c)+040):(c))/* */
#define toupper(c) (islower(c) ? ((c)-040):(c))/* */
/********************************/
/************************************************************************\
* GLOBAL definitions *
\************************************************************************/
/********************************/
GLOBAL BYTE *choice[] = /* Copy Modes available */
{"all","boot","files","end"}; /* ---------------------- */
/********************************/
GLOBAL BYTE mode; /* Hold the current copy mode */
/********************************/
/* ------- OPTIONS ------- */
GLOBAL BYTE verbose = ON; /* Prompt the user if ON */
GLOBAL BYTE verify = OFF; /* Check newly written track */
/* againist source track. */
/********************************/
/* Prompts........... */
GLOBAL BYTE *msg1 = "Enter SOURCE drive: "; /* SDRIVE */
GLOBAL BYTE *msg2 = "Enter DESTINATION drive: "; /* DDRIVE */
GLOBAL BYTE *msg3 = "READ error ----> "; /* Read error */
GLOBAL BYTE *msg4 = "WRITE error ----> "; /* Write error */
/********************************/
/********************************/
GLOBAL BYTE *bracket = "["; /* Marks beginning of option */
/* indicators on the cmd line */
/********************************/
GLOBAL struct _dpb /* Define disk parm block */
{ /*------------------------------*/
WORD spt; /* Logical sectors per track */
BYTE bsh; /* Allocation block shift factor*/
BYTE blm; /* Block mask */
BYTE exm; /* Extent mask */
BYTE dpbjunk; /* Alignment byte */
WORD dsm; /* Total storage of the disk */
WORD drm; /* Total directory entries */
BYTE al0; /* Flag reserved for dir blocks */
BYTE al1; /* Flag reserved for dir blocks */
WORD cks; /* Directory check vector size */
WORD off; /* The number of reserved tracks*/
}; /* */
/********************************/
GLOBAL struct _dph /* Define disk parm header */
{ /*------------------------------*/
BYTE *xltp; /* Pointer to sector trans table*/
WORD dphscr[3]; /* Scratchpad values for BDOS */
BYTE *dirbufp; /* Pointer to dir scratchpad */
struct _dpb *dpbp; /* Pointer to disk parm block */
BYTE *csvp; /* Pointer to scratchpad area */
BYTE *alvp; /* Pointer to scratchpad area */
}; /********************************/
EXTERN LONG __BDOS(); /* BDOS Caller in CLIB */
#define bdos(a,b) (struct _dph*)__BDOS(a,b) /* Declare a bogus function */
/********************************/
GLOBAL struct _biospb /* Bios Pararmeter Block */
{ /*------------------------------*/
UWORD funcnum; /* Bios function number */
LONG parm1; /* Bios parameter 1 */
LONG parm2; /* Bios parameter 2 */
}; /* */
GLOBAL struct _biospb biospb; /* Define it */
/********************************/
GLOBAL BYTE trkbuf[128*26*6]; /* buffer big enough to hold 6 */
/* tracks of bytes */
GLOBAL BYTE verbuf[128*26*6]; /* buffer for verification opt */
/********************************/
/************************************************************************\
* FUNCTION definitions *
\************************************************************************/
/********************************/
UWORD illegal(); /* Decides if the mode is a */
/* legal one. */
/*------------------------------*/
VOID get_mode(); /* If the mode was not there */
/* or an illegal one,get_mode */
/* will print a menu and keep */
/* prompting the user for a */
/* legal mode. */
/*------------------------------*/
BYTE get_drive(); /* Reads in a drive character */
/* from the console. If the */
/* drive is in the range(A-P), */
/* the drive is returned. If */
/* not,the value BAD is returned*/
/*------------------------------*/
VOID wait_for(); /* Holds the copy program in a */
/* wait state so the user can */
/* make sure his or her disk is */
/* in the proper drive. */
/*------------------------------*/
BYTE scan(); /* Picks off the source and */
/* destination drives from the */
/* command line. If they do */
/* not exist,or the specified */
/* drives are illegal,scan */
/* prompts the user. */
/*------------------------------*/
VOID get_options(); /* Scans the command line until */
/* a '[' is found. A list of */
/* of options is checked. Flags */
/* are turned on by the option */
/* indicators found after the */
/* square bracket. */
/*------------------------------*/
VOID copy(); /* If the two disk parameter */
/* blocks are identical,a track */
/* for track copy is made. */
/* If an serious error occurs, */
/* the copy is aborted and the */
/* program ends. */
/********************************/
VOID read_wr(); /* This routine does the actual */
/* reading and writing of the */
/* compatible disks. */
/********************************/
/************************************************************************/
/************************************************************************\
* *
* BEGIN MAIN PROGRAM *
* *
\************************************************************************/
main(argc,argv)
WORD argc;
BYTE *argv[];
{
BYTE answer,source,dest,optfound;
optfound = FALSE;
printf("Copy Ver 1.2\n"); /* Copy version message */
/*------------------------------*\
| If there is an mode on |
| on the command line or the |
| command line mode is not |
| recognized,print a menu |
| and have the user input a |
| a legal copy mode. |
\*------------------------------*/
argc--; argv++; /* point to first arg after cmd */
if(illegal(*argv))
get_mode();
else /* point to 2nd arg past cmd */
{
argv++;
argc--;
}
if(mode == _END)
cpyexit();
/*------------------------------*\
| Look for the '[' as the |
| start of the options. |
| This allows the following |
| |
| copy <mode> [options |
| ==================== |
| or |
| copy [options |
| ============= |
| |
| I will not allow the drives|
| to be specified after the |
| options though!!!!! |
\*------------------------------*/
if(strncmp(bracket,*argv,1) == MATCH)
{
argc = 0;
get_options(*argv++);
source = scan(argc,*argv++,SDRIVE);
dest = scan(argc,*argv,DDRIVE);
}
else
/*------------------------------*\
| Otherwise I assume that the |
| command line looks like |
| this: |
| |
| copy <mode> <sd> <dd> [opt |
| ========================== |
\*------------------------------*/
{
source = scan(argc--,*argv++,SDRIVE);
dest = scan(argc--,*argv,DDRIVE);
if(strncmp(bracket,*argv,1) == MATCH)
{
optfound = TRUE;
get_options(*argv);
}
while(argc-- > 0)
/* scan cmd line to find a '[' */
if(strncmp(bracket,*++argv,1) == MATCH &&
(!optfound))
{
get_options(*argv);
break;
}
else
printf("\nExtraneous argument ignored: %s",*argv);
}
if(source == dest)
{
printf("\nSource and Destination must be different");
cpyexit();
}
/*------------------------------*\
| REPEAT the copy as many |
| times as the user wishes |
\*------------------------------*/
while(TRUE)
{
if(verbose)
wait_for(source,dest);
copy((toupper(source) - 'A'),(toupper(dest) - 'A'));
printf("\nCopy complete");
if(verbose)
printf("\nDo you wish to repeat the copy? ");
else
break;
answer = __BDOS(1,(long)0);
if(toupper(answer) != 'Y')
break;
}
}
/************************/
UWORD illegal(_mode) /* Check command line */
/* aganist mode table */
/* Return mode code if */
/* found,return false */
/* if the mode is not */
/* found in the table */
/************************/
BYTE *_mode;
{
REG UWORD i;
for(i = 0;i <= 3;i++)
if(strcmp(_mode,choice[i]) == MATCH)
{
mode = i;
return(FALSE);
}
mode = -1;
return(TRUE);
}
/************************/
VOID get_mode() /* Prompt the user for */
/* a legal mode. Keep */
/* prompting until you */
/* get one. */
/************************/
{
REG UWORD i;
BYTE buf[256];
printf("\nMODE\tFUNCTION\n");
printf("\nALL\tCopy the whole disk");
printf("\nBOOT\tCopy the boot tracks");
printf("\nFILES\tCopy the non-boot tracks");
printf("\nEND\tEnd this program\n");
do
{
printf("\nEnter your copy mode: ");
gets(buf);
for(i = 0;buf[i] != NULLB;i++)
buf[i] = tolower(buf[i]);
}
while(illegal(buf));
}
/************************/
BYTE get_drive() /* Read in a drive. */
/************************/
{
BYTE drive[10];
gets(drive);
if(strlen(drive) > 1)
return(BAD);
drive[0] = toupper(drive[0]);
if(drive[0] < 'A' || drive[0] > 'P')
return(BAD);
else
return(drive[0]);
}
/************************/
VOID wait_for(source,dest) /* Wait for the user */
/* to put the disks */
/* in the proper drives*/
/************************/
BYTE source;
BYTE dest;
{
BYTE wait_buf[5];
BYTE *upchoice[3];
upchoice[0] = "ALL";
upchoice[1] = "BOOT";
upchoice[2] = "FILES";
wait_buf[0] = 3;
do
{
printf("\n(^C to ABORT)");
printf("\nRETURN to copy %s",upchoice[mode]);
printf(" from %c to %c",source,dest);
__BDOS(10,&wait_buf[0]);
}
while(wait_buf[1] != 0);
}
/************************/
BYTE scan(argc,argv,which_drive) /* Scan the command */
/* for the drives. */
/* If I can't find them*/
/* or they are illegal */
/* keep prompting the */
/* user for them. */
/************************/
WORD argc;
BYTE *argv;
UWORD which_drive;
{
BYTE *prompt,drive;
if(argc > 0 && strlen(argv) == 1)
{
sscanf(argv,"%c",&drive);
drive = toupper(drive);
if(drive >= 'A' && drive <= 'P')
return(drive);
}
switch(which_drive)
{
case SDRIVE : prompt = &msg1[0];
break;
case DDRIVE : prompt = &msg2[0];
}
printf("\n");
do
{
printf("%s",prompt);
}
while((drive = get_drive()) == BAD);
return(drive);
}
/************************/
VOID get_options(argv) /* Scan cmd line for */
/* supported options */
/************************/
BYTE *argv;
{
argv++; /* skip the square bracket */
while(*argv != NULLB)
{
switch(*argv)
{
case 'A' :
case 'a' :
verbose = OFF;
break;
case 'v' :
case 'V' : verify = ON;
break;
case ']' : return(0);
default : printf("\nUndefined option: %c",*argv);
}
argv++;
}
}
/************************/
VOID copy(source,dest) /* Select the disks. */
/* If I can't select or*/
/* the disk have diff- */
/* erent parameter blks*/
/* then print error msg*/
/************************/
BYTE source;
BYTE dest;
{
REG struct _dpb *dskpblk;
REG struct _dph *h1,*h2;
REG LONG *ptr1,*ptr2;
REG LONG endtrk,begtrk;
LONG numtrks,temp;
BYTE *sectran;
REG UWORD i;
biospb.funcnum = 9; /* Select the disks */
biospb.parm1 = (long)source; /* first the source disk */
biospb.parm2 = (long)0; /* set least sig bit to 0 */
if((h1 = bdos(50,&biospb))!= NULL)
{
biospb.parm1 = (long)dest;
if((h2 = bdos(50,&biospb))!= NULL)
{ /*----------------------------------------------*/
/* check the parameter blocks(must be identical)*/
/*----------------------------------------------*/
dskpblk = (*h1).dpbp; /* pointer to dpb */
sectran = (*h1).xltp; /* pointer to sect tran tb*/
h1 = (*h1).dpbp; /* h1 points to dpb */
ptr1 = (long)h1; /* compare long words */
h2 = (*h2).dpbp; /* h2 points to dpb */
ptr2 = (long)h2; /* compare long words */
for(i = 0;i <= 3;i++)
{
if(*ptr1 != *ptr2)
{
printf("\nIncompatible disks");
cpyexit();
}
ptr1++;
ptr2++;
}
}
else
{
printf("\nDisk select error on Destination");
cpyexit();
}
}
else
{
printf("\nDisk select error on Source");
cpyexit();
}
/*------------------------------------------------------*\
| |
| Compute beginning and ending track |
| |
\*------------------------------------------------------*/
temp = (((*dskpblk).dsm + 1)*((*dskpblk).blm + 1));
numtrks = temp/(*dskpblk).spt;
if((numtrks*(*dskpblk).spt) < temp)
numtrks++;
numtrks += (*dskpblk).off;
switch(mode)
{
case _ALL : begtrk = 0;
endtrk = numtrks - 1;
break;
case _BOOT: begtrk = 0;
endtrk = (*dskpblk).off - 1;
break;
case _FILES: begtrk = (*dskpblk).off;
endtrk = numtrks - 1;
}
read_wr(source,dest,begtrk,endtrk,sectran,dskpblk);
}
/************************************************************************/
/* */
/* Do the actual read write operations */
/* =================================== */
/* */
/************************************************************************/
VOID read_wr(source,dest,begtrk,endtrk,sectran,dskpblk)
/********************************/
BYTE source; /* source disk */
BYTE dest; /* destination disk */
REG LONG begtrk; /* beginning track to copy */
REG LONG endtrk; /* ending track to copy */
REG BYTE *sectran; /* sector translate table */
struct _dpb *dskpblk; /* ptr to disk parameter block */
/********************************/
{
REG BYTE *dma;
REG UWORD i,k;
printf("\n***Copying Tracks***\n");
for(i = begtrk;i <= endtrk;i++)
{
dma = &trkbuf;
biospb.funcnum = 12; /* set the dma address */
biospb.parm1 = dma; /* set it to beginning of trkbuf*/
biospb.parm2 = 0;
__BDOS(50,&biospb); /* call the bios via the bdos */
biospb.funcnum = 9; /* select the source diskette */
biospb.parm1 = (long)source;
biospb.parm2 = (long)0xFFFFFFFF;
__BDOS(50,&biospb); /* call the bios via the bdos */
biospb.funcnum = 10; /* set the track */
biospb.parm1 = (long)(i);
biospb.parm2 = 0;
__BDOS(50,&biospb); /* call bios via bdos */
/*----------------------------------------------*\
| Read a track's worth of sectors |
\*----------------------------------------------*/
for(k = 0;k < (*dskpblk).spt;k++)
{
biospb.funcnum = 16; /* translate sector*/
biospb.parm1 = (long)k; /* logical sect */
biospb.parm2 = sectran;
biospb.parm1 = __BDOS(50,&biospb);
biospb.funcnum = 11; /* set physical sec*/
biospb.parm2 = 0;
__BDOS(50,&biospb); /* call the bios */
/*--------------------------------------*\
| READ a sector |
\*--------------------------------------*/
biospb.funcnum = 13;
if(__BDOS(50,&biospb) != 0)
error(i,k,RDERR);
dma += 128;
biospb.funcnum = 12;
biospb.parm1 = dma;
__BDOS(50,&biospb);
}
dma = &trkbuf;
biospb.funcnum = 12; /* reset the dma addr to trkbuf */
biospb.parm1 = dma;
biospb.parm2 = 0;
__BDOS(50,&biospb); /* call the bios */
biospb.funcnum = 9; /* select the destination disk */
biospb.parm1 = (long)dest;
biospb.parm2 = (long)0xFFFFFFFF;
__BDOS(50,&biospb); /* call the bios */
/*----------------------------------------------*\
| Write out a Track's worth of Sectors |
\*----------------------------------------------*/
for(k = 0;k < (*dskpblk).spt;k++)
{
biospb.funcnum = 16;
biospb.parm1 = (long)k;
biospb.parm2 = sectran;
biospb.parm1 = __BDOS(50,&biospb);
biospb.funcnum = 11;
biospb.parm2 = 0;
__BDOS(50,&biospb);
/*--------------------------------------*\
| Write a Sector |
\*--------------------------------------*/
biospb.funcnum = 14;
biospb.parm1 = (long)2;
if(__BDOS(50,&biospb) != 0)
error(i,k,WRERR);
dma += 128;
biospb.funcnum = 12;
biospb.parm1 = dma;
__BDOS(50,&biospb);
}
if(verify)
{
dma = &verbuf;
biospb.funcnum = 12;
biospb.parm1 = dma;
__BDOS(50,&biospb); /* reset dma addr */
for(k = 0;k < (*dskpblk).spt;k++)
{
biospb.funcnum = 16;
biospb.parm1 = (long)k;
biospb.parm2 = sectran;
biospb.parm1 = __BDOS(50,&biospb);
biospb.funcnum = 11;
biospb.parm2 = 0;
__BDOS(50,&biospb);
/*------------------------------*\
| Read a sector |
\*------------------------------*/
biospb.funcnum = 13;
if(__BDOS(50,&biospb) != 0)
error(i,k,RDERR);
dma += 128;
biospb.funcnum = 12;
biospb.parm1 = dma;
__BDOS(50,&biospb);
}
/*--------------------------------------*\
| Verify the TRACK write |
\*--------------------------------------*/
for(k = 0;k < (((*dskpblk).spt)*128);k++)
if(trkbuf[k] != verbuf[k])
error(i,(k/128),WRERR);
}
printf("\r %d",i);
}
}
/************************/
error(track,sector,phase) /* Read/Write Error */
/* handler */
/************************/
UWORD track;
UWORD sector;
BYTE phase;
{
REG BYTE *addr;
if(phase == RDERR)
addr = &msg3[0];
else
addr = &msg4[0];
printf("\n\n\n%s",addr);
printf("Track: %d Sector: %d",track,sector);
cpyexit();
}
cpyexit() /* bios select what the bdos thinks is the default disk */
{
biospb.funcnum = 9;
biospb.parm1 = __BDOS(25,(long)0);
biospb.parm2 = 0;
bdos(50,&biospb);
exit(0);
}
ospb.funcnum = 9;
biospb.parm1 = __BDOS(25,(long)0);
biospb.parm2 = 0;
bdos(50,&biospb);
exit(0);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,411 @@
/*SPLH*/ /*$TITLE='CP/M-86 2.0 --- ED' */
ED:
DO;
/* MODIFIED FOR .PRL OPERATION MAY, 1979 */
/* MODIFIED FOR OPERATION WITH CP/M 2.0 AUGUST 1979 */
/* MODIFIED FOR MP/M 2.0 JUNE 1981 */
/* MODIFIED FOR CP/M 1.1 OCT 1981 */
/* MODIFIED FOR CP/M-68K JULY 1982 BY H.CHAKI */
DECLARE
MPMPRODUCT LITERALLY '01H', /* REQUIRES MP/M */
CPM3 LITERALLY '30H'; /* REQUIRES 3.0 CP/M */
/* DECLARE 8080 INTERFACE
JMP EDCOMMAND - 3 (TO ADDRESS LXI SP)
EDJMP BYTE DATA(0C3H),
EDADR ADDRESS DATA(.EDCOMMAND-3); */
/**************************************
* *
* B D O S INTERFACE *
* *
**************************************/
MON1:
PROCEDURE (FUNC,INFO) EXTERNAL;
DECLARE FUNC BYTE;
DECLARE INFO ADDRESS;
END MON1;
MON2:
PROCEDURE (FUNC,INFO) BYTE EXTERNAL;
DECLARE FUNC BYTE;
DECLARE INFO ADDRESS;
END MON2;
MON3:
PROCEDURE (FUNC,INFO) ADDRESS EXTERNAL;
DECLARE FUNC BYTE;
DECLARE INFO ADDRESS;
END MON3;
MON5 : PROC(FN,IN) EXT ;
DCL FN BYTE;
DCL IN POINTER ;
END;
MON6 : PROC(FN,IN) BYTE EXT ;
DCL FN BYTE;
DCL IN POINTER ;
END ;
MON7 : PROC(FN,IN) ADDR EXT;
DCL FN BYTE ;
DCL IN POINTER;
END ;
/* DECLARE CMDRV BYTE EXTERNAL; /* COMMAND DRIVE */
DECLARE FCB (128) BYTE EXTERNAL; /* 1ST DEFAULT FCB */
DECLARE FCB16 (128) BYTE EXTERNAL; /* 2ND DEFAULT FCB */
/* DECLARE PASS0 ADDRESS EXTERNAL; /* 1ST PASSWORD PTR */
/* DECLARE LEN0 BYTE EXTERNAL; /* 1ST PASSWD LENGTH */
/* DECLARE PASS1 ADDRESS EXTERNAL; /* 2ND PASSWORD PTR */
/* DECLARE LEN1 BYTE EXTERNAL; /* 2ND PASSWD LENGTH */
DECLARE TBUFF (128) BYTE EXTERNAL; /* DEFAULT DMA BUFFER */
DECLARE
/* BDISK BYTE EXTERNAL, /* BOOT DISK 0004H */
MAXB ADDRESS EXTERNAL, /* MAX BASE 0006H */
BUFF (128)BYTE EXTERNAL, /* BUFFER 0080H */
SECTSHF LITERALLY '7', /* SHL(1,SECTSHF) = SECTSIZE */
SECTSIZE LITERALLY '80H'; /* SECTOR SIZE */
/* 68K */ DCL DUM1P POINTER,DUM1L LONG AT(@DUM1P);
/* 68K */ DCL DUM2P POINTER,DUM2L LONG AT(@DUM2P);
BOOT: PROCEDURE PUBLIC;
CALL MON1(0,0); /* CHANGED FOR MP/M-86 VERSION */
/* SYSTEM REBOOT */
END BOOT;
/*SPLH*/ /*$EJECT */
/* E D : T H E C P / M C O N T E X T E D I T O R */
/* COPYRIGHT (C) 1976, 1977, 1978, 1979, 1980, 1981
DIGITAL RESEARCH
BOX 579 PACIFIC GROVE
CALIFORNIA 93950
REVISED:
07 APRIL 81 BY THOMAS ROLANDER
21 JULY 81 BY DOUG HUSKEY
29 OCT 81 BY DOUG HUSKEY
10 NOV 81 BY DOUG HUSKEY
31 JULY 81 BY H.CHAKI
*/
/*SPLH*/ /*$EJECT */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * GLOBAL VARIABLES * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
DECLARE /* LIT LITERALLY 'LITERALLY',
DCL LIT 'DECLARE',
PROC LIT 'PROCEDURE',
ADDR LIT 'ADDRESS', */
CTLL LIT '0CH',
CTLR LIT '12H', /* REPEAT LINE IN INSERT MODE */
CTLU LIT '15H', /* LINE DELETE IN INSERT MODE */
CTLX LIT '18H', /* EQUIVALENT TO CTLU */
CTLH LIT '08H', /* BACKSPACE */
TAB LIT '09H', /* TAB CHARACTER */
LCA LIT '110$0001B', /* LOWER CASE A */
LCZ LIT '111$1010B', /* LOWER CASE Z */
ESC LIT '1BH', /* ESCAPE CHARACTER */
ENDFILE LIT '1AH'; /* CP/M END OF FILE */
DECLARE
TRUE LITERALLY '1',
FALSE LITERALLY '0',
FOREVER LITERALLY 'WHILE TRUE',
CTRL$C LITERALLY '3',
CR LITERALLY '13',
LF LITERALLY '10',
WHAT LITERALLY '63';
DECLARE
US LITERALLY '8', /* FILE FROM USER 0 */
RO LITERALLY '9', /* R/O FILE INDICATOR */
SY LITERALLY '10', /* SYSTEM FILE ATTRIBUTE */
EX LITERALLY '12', /* EXTENT NUMBER POSITION */
UB LITERALLY '13', /* UNFILLED BYTES */
CK LITERALLY '13', /* CHECKSUM */
MD LITERALLY '14', /* MODULE NUMBER POSITION */
NR LITERALLY '32', /* NEXT RECORD FIELD */
FS LITERALLY '33', /* FCB SIZE */
XFERON BYTE EXT INIT, /* TRUE IF XFER ACTIVE */
PASSWORD (16) BYTE EXT INIT; /* SOURCE PASSWORD */
DECLARE
LIBFCB (12) BYTE EXT DATA ;/* DEFAULT LIB NAME */
DECLARE
PRINTSUPPR BYTE EXT INIT; /* TRUE IF PRINT SUPPRESSED */
DECLARE
COLUMN BYTE EXT; /* CONSOLE COLUMN POSITION */
/* COMMAND BUFFER */
DCL DCNT BYTE EXT ;
DECLARE (MAXLEN,COMLEN) BYTE EXT, COMBUFF(128) BYTE EXT,
(TCBP,CBP) BYTE EXT ;
/* MP/M PARSE FUNCTION CALL */
DECLARE
PARSE$FN STRUCTURE(
BUFF$ADR POINTER,
FCB$ADR POINTER);
DECLARE
LPP LIT '23', /* LINES PER PAGE */
FORWARD LIT '1',
BACKWARD LIT '0',
RUBOUT LIT '07FH',
POUND LIT '23H',
MACSIZE LIT '128', /* MAX MACRO SIZE */
SCRSIZE LIT '100', /* SCRATCH BUFFER SIZE */
COMSIZE LIT 'ADDRESS'; /* DETERMINES MAX COMMAND NUMBER*/
DCL FLAG BYTE EXT;
DCL RESET LABEL EXT;
DECLARE
EOS LITERALLY '0FFH';
/*SPLH*/ /*$EJECT */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * CP/M INTERFACE ROUTINES * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* IO SECTION */
READCHAR: PROCEDURE BYTE PUBLIC; RETURN MON2(1,0);
END READCHAR;
CONIN:
PROCEDURE BYTE PUBLIC;
RETURN MON2(6,0FDH);
END CONIN;
PRINTCHAR: PROCEDURE(CHAR) PUBLIC;
DECLARE CHAR BYTE;
IF PRINTSUPPR THEN RETURN;
CALL MON1(2,CHAR);
END PRINTCHAR;
TTYCHAR: PROCEDURE(CHAR) PUBLIC;
DECLARE CHAR BYTE;
IF CHAR >= ' ' THEN COLUMN = COLUMN + 1;
IF CHAR = LF THEN COLUMN = 0;
CALL PRINTCHAR(CHAR);
END TTYCHAR;
BACKSPACE: PROCEDURE PUBLIC;
/* MOVE BACK ONE POSITION */
IF COLUMN = 0 THEN RETURN;
CALL TTYCHAR(CTLH); /* COLUMN = COLUMN - 1 */
CALL TTYCHAR(' ' ); /* COLUMN = COLUMN + 1 */
CALL TTYCHAR(CTLH); /* COLUMN = COLUMN - 1 */
COLUMN = COLUMN - 2;
END BACKSPACE;
PRINTABS: PROCEDURE(CHAR) PUBLIC ;
DECLARE (CHAR,I,J) BYTE;
I = CHAR = TAB AND 7 - (COLUMN AND 7);
IF CHAR = TAB THEN CHAR = ' ';
DO J = 0 TO I;
CALL TTYCHAR(CHAR);
END;
END PRINTABS;
GRAPHIC: PROCEDURE(C) BYTE PUBLIC;
DECLARE C BYTE;
/* RETURN TRUE IF GRAPHIC CHARACTER */
IF C >= ' ' THEN RETURN TRUE;
RETURN C = CR OR C = LF OR C = TAB;
END GRAPHIC;
PRINTC: PROCEDURE(C) PUBLIC;
DECLARE C BYTE;
IF NOT GRAPHIC(C) THEN
DO; CALL PRINTABS('^');
C = C + '@';
END;
CALL PRINTABS(C);
END PRINTC;
CRLF: PROCEDURE PUBLIC;
CALL PRINTC(CR); CALL PRINTC(LF);
END CRLF;
PRINTM: PROCEDURE(A) PUBLIC;
DECLARE A POINTER;
CALL MON5(9,A);
END PRINTM;
PRINT: PROCEDURE(A) PUBLIC;
DECLARE A POINTER;
CALL CRLF;
CALL PRINTM(A);
END PRINT;
READ: PROCEDURE(A) PUBLIC;
DECLARE A POINTER;
CALL MON5(10,A);
END READ;
/* USED FOR LIBRARY FILES */
OPEN: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
IF MON6(15,FCB) = 255 THEN DO;
FLAG = 'O';
GO TO RESET;
END;
END OPEN;
/* USED FOR MAIN SOURCE FILE */
OPEN$FILE: PROCEDURE(FCB) ADDRESS PUBLIC;
DECLARE FCB POINTER;
RETURN MON7(15,FCB);
END OPEN$FILE;
CLOSE: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
DCNT = MON6(16,FCB);
END CLOSE;
SEARCH: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
DCNT = MON6(17,FCB);
END SEARCH;
DELETE: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
DCNT = MON6(19,FCB);
END DELETE;
DISKREAD: PROCEDURE(FCB) BYTE PUBLIC ;
DECLARE FCB POINTER;
RETURN MON6(20,FCB);
END DISKREAD;
DISKWRITE: PROCEDURE(FCB) BYTE PUBLIC;
DECLARE FCB POINTER;
RETURN MON6(21,FCB);
END DISKWRITE;
MAKE: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
DCNT = MON6(22,FCB);
END MAKE;
RENAME: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
CALL MON5(23,FCB);
END RENAME;
READCOM: PROCEDURE PUBLIC;
MAXLEN = 128; CALL READ(@MAXLEN);
END READCOM;
BREAK$KEY: PROCEDURE BYTE PUBLIC;
IF MON2(11,0) THEN
DO; /* CLEAR CHAR */
IF MON2(1,0) = CTRL$C THEN
RETURN TRUE;
END;
RETURN FALSE;
END BREAK$KEY;
CSELECT: PROCEDURE BYTE PUBLIC;
/* RETURN CURRENT DRIVE NUMBER */
RETURN MON2(25,0);
END CSELECT;
SELECT: PROCEDURE(DISK) PUBLIC;
DECLARE DISK BYTE;
/* SET DRIVE NUMBER */
CALL MON1(14,DISK);
END SELECT;
SETDMA: PROCEDURE(A) PUBLIC;
DECLARE A POINTER;
/* SET DMA ADDRESS */
CALL MON5(26,A);
END SETDMA;
SET$ATTRIBU: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
CALL MON5(30,FCB);
END SET$ATTRIBU;
/* THIS ROUTINE IS INCLUDED SOLELY FOR
ENCONOMY OF SPACE OVER THE USE OF THE
EQUIVALENT (IN-LINE) CODE GENERATED BY
THE BUILT-IN FUNCTION */
MOVE: PROC(C,S,D) PUBLIC;
DCL (S,D) POINTER, C BYTE;
DCL A BASED DUM1P BYTE, B BASED DUM2P BYTE;
DUM1P=S;DUM2P=D;
DO WHILE (C:=C-1)<>255;
B=A; DUM1L=DUM1L+1;DUM2L=DUM2L+1;
END;
END MOVE;
WRITE$XFCB: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
CALL MOVE(8,@PASSWORD,@PASSWORD(8));
IF MON6(103,FCB)= 0FFH THEN
CALL PRINT(@('ERROR CREATING PASSWORD$'));
END WRITE$XFCB;
READ$XFCB: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
CALL MON5(102,FCB);
END READ$XFCB;
/* 0FF => RETURN BDOS ERRORS */
RETURN$ERRO:
PROCEDURE(MODE) PUBLIC;
DECLARE MODE BYTE;
CALL MON1 (45,MODE);
END RETURN$ERRO;
REBOOT: PROCEDURE PUBLIC;
IF XFERON THEN
CALL DELETE(@LIBFCB);
CALL BOOT;
END REBOOT;
VERSION: PROCEDURE ADDRESS PUBLIC;
/* RETURNS CURRENT CP/M VERSION # */
RETURN MON7(12,0);
END VERSION;
PARSE: PROCEDURE PUBLIC;
CALL MON5(152,@PARSE$FN);
END PARSE;
END;

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,2 @@
lo68 -s -tB00 -uldr -o cpmldr.sys booter.o ldrlib ldbiosa.o ldbios.o 0:clib
o68 -s -tB00 -uldr -o cpmldr.sys booter.o ldrlib ldbiosa.o ldbios.o 0:clib

View File

@@ -0,0 +1,539 @@
/*SPLH*/ /*$TITLE='PERIPHERAL INTERCHANGE PROGRAM' */
PIPMOD:
DO;
/* P E R I P H E R A L I N T E R C H A N G E P R O G R A M
COPYRIGHT (C) 1976, 1977, 1978, 1979, 1980, 1981
DIGITAL RESEARCH
BOX 579
PACIFIC GROVE, CA
93950
REVISED:
17 JAN 80 BY THOMAS ROLANDER (MP/M 1.1)
05 OCT 81 BY RAY PEDRIZETTI (MP/M-86 2.0)
18 DEC 81 BY RAY PEDRIZETTI (CP/M-86 1.1)
31 JULY 82 BY H.CHAKI (CP/M-68K) */
/* COMMAND LINES USED FOR .68K FILE GENERATION */
/* Command line to generate PIP.68K
[[ assume that the all default VOLUME is SYS:0.. on EXORmacs]]
(1)S-PL/H Compile and ASM on EXORmacs
=SPLH PIP,,;A,S,X,NOV,NOF,MAR=1/80
=ASM PIPSUB,,;A,S,X,NOV,NOF,MAR=1/80
=ASM UT68K,,;
[[ caution ]]
PIP: main routine of PIP utility in S-PL/H
PIPSUB: sub routine of PIP utility in ASM
UT68K: standard interface routine in ASM
A: assemble listing option
S: symbol listing option
X: xref listing option
NOV: non save option
NOF: non floatable option
MAR: margin option [[ important ]]
(2)LINK on EXORmacs
=LINK PIP/PIPSUB/UT68K,PIP68K,PIP68K;MIXRL=SPLHLIB.RO
[[ caution ]]
R option: generate relocatable object
(3)XLINK on EXORmacs
=XLINK PIP68K.RO,PIP68K.OX,O=PIP68K.OL
(4)Convert file on EXORmacs to send to VAX
=CONV PIP68K.OX,PIP68K.OC
(5)Send to VAX from EXORMACS
=VAX
VAX command
S
Source file
PIP68K.OC
(6)Download to CP/M file from VAX
(7)Re-convert file on CP/M
A>RECONV
input file :PIP68K.OC
output file :PIP.68K
end command line */
DECLARE
VERSION LITERALLY '0022H', /* REQUIRED FOR OPERATION */
MVERSION LITERALLY '1130H'; /* FOR MP/M-86 OPERATION */
DECLARE
MAXB POINTER EXTERNAL, /* ADDR FIELD OF JMP BDOS */
/*68K*/ MAXBL LONG AT(@MAXB),
FCB (33) BYTE EXTERNAL, /* DEFAULT FILE CONTROL BLOCK */
BUFF(128)BYTE EXTERNAL; /* DEFAULT BUFFER */
DECLARE
ENDFILE LITERALLY '1AH'; /* END OF FILE MARK */
DECLARE /* MAIN PROGRAM ENTRY LABEL */
PLM LABEL PUBLIC;
DECLARE COPYRIGHT(*) BYTE DATA (
' (7/31/82) CP/M-68K PIP VERS 1.0 ');
/* LITERAL DECLARATIONS */
DECLARE
/*SPLH*/ /* LIT LITERALLY 'LITERALLY', */
LPP LIT '60', /* LINES PER PAGE */
TAB LIT '09H', /* HORIZONTAL TAB */
FF LIT '0CH', /* FORM FEED */
LA LIT '05FH', /* LEFT ARROW */
LB LIT '05BH', /* LEFT BRACKET */
RB LIT '05DH', /* RIGHT BRACKET */
FSIZE LIT '33',
FRSIZE LIT '36', /* SIZE OF RANDOM FCB */
NSIZE LIT '8',
FNSIZE LIT '11',
FEXT LIT '9',
FEXTL LIT '3',
/* SCANNER RETURN TYPE CODE */
OUTT LIT '0', /* OUTPUT DEVICE */
PRNT LIT '1', /* PRINTER */
LSTT LIT '2', /* LIST DEVICE */
AXOT LIT '3', /* AUXILARY OUTPUT DEVICE */
FILE LIT '4', /* FILE TYPE */
CONS LIT '5', /* CONSOLE */
AXIT LIT '6', /* AUXILARY INPUT DEVICE */
INPT LIT '7', /* INPUT DEVICE */
NULT LIT '8', /* NUL CHARACTERS */
EOFT LIT '9', /* EOF CHARACTER */
ERR LIT '10', /* ERROR TYPE */
SPECL LIT '11', /* SPECIAL CHARACTER */
DISKNAME LIT '12'; /* DISKNAME LETTER */
DECLARE
SEARFCB LITERALLY 'FCB'; /* SEARCH FCB IN MULTI COPY */
DECLARE
TRUE LITERALLY '1',
FALSE LITERALLY '0',
FOREVER LITERALLY 'WHILE TRUE',
CR LITERALLY '13',
LF LITERALLY '10',
WHAT LITERALLY '63';
DECLARE
COLUMN BYTE, /* COLUMN COUNT FOR PRINTER TABS */
LINENO BYTE, /* LINE WITHIN PAGE */
FEEDBASE BYTE, /* USED TO FEED SEARCH CHARACTERS */
FEEDLEN BYTE, /* LENGTH OF FEED STRING */
MATCHLEN BYTE, /* USED IN MATCHING STRINGS */
QUITLEN BYTE, /* USED TO TERMINATE QUIT COMMAND */
CDISK BYTE, /* CURRENT DISK */
SBLEN ADDRESS, /* SOURCE BUFFER LENGTH */
DBLEN ADDRESS, /* DEST BUFFER LENGTH */
TBLEN ADDRESS, /* TEMP BUFFER LENGTH */
SBASE POINTER, /* SOURCE BUFFER BASE */
/*68K*/ SBASEL LONG AT(@SBASE),
/*SPLH*/ MEMORY (1024) BYTE EXT,
/*SPLH*/ DCHAKIP POINTER,
DCHAKIL LONG AT(@DCHAKIP),
/* THE VECTORS DBUFF AND SBUFF ARE DECLARED WITH DIMENSION
1024, BUT ACTUALLY VARY WITH THE FREE MEMORY SIZE */
DBUFF(1024) BYTE AT (@MEMORY), /* DESTINATION BUFFER */
SBUFF BASED SBASE (1024) BYTE, /* SOURCE BUFFER */
/* SOURCE FCB, PASSWORD AND PASSWORD MODE */
SOURCE STRUCTURE (
FCB(FRSIZE) BYTE,
USER BYTE,
TYPE BYTE ),
/* TEMPORARY DESTINATION FCB, PASSWORD AND PASSWORD MODE */
DEST STRUCTURE (
FCB(FRSIZE) BYTE,
USER BYTE,
TYPE BYTE ),
/* ORIGINAL DESTINATION FCB, PASSWORD AND PASSWORD MODE */
ODEST STRUCTURE (
FCB(FRSIZE) BYTE,
USER BYTE,
TYPE BYTE ),
FILSIZE(3) BYTE, /* FILE SIZE RANDOM RECORD NUMBER */
DESTR ADDRESS AT(@DEST.FCB(34)), /* RANDOM RECORD POSITION */
SOURCER ADDRESS AT(@SOURCE.FCB(34)), /* RANDOM RECORD POSITION */
DESTR2 BYTE AT(@DEST.FCB(33)), /* RANDOM RECORD POSITION R2 */
SOURCER2 BYTE AT(@SOURCE.FCB(33)), /* RANDOM RECORD POSITION R2 */
EXTSAVE BYTE, /* TEMP EXTENT BYTE FOR BDOS BUG */
NSBUF ADDRESS, /* NEXT SOURCE BUFFER */
NSOURCE ADDRESS, /* NEXT SOURCE CHARACTER */
NDEST ADDRESS; /* NEXT DESTINATION CHARACTER */
DECLARE
FASTCOPY BYTE, /* TRUE IF COPY DIRECTLY TO DBUF */
DBLBUF BYTE, /* TRUE IF BOTH SOURCE AND DEST BUFFER USED */
CONCAT BYTE, /* TRUE IF CONCATINATION COMMAND */
AMBIG BYTE, /* TRUE IF FILE IS AMBIG TYPE */
DFILE BYTE, /* TRUE IF DEST IS FILE TYPE */
SFILE BYTE, /* TRUE IF SOURCE IS FILE TYPE */
MADE BYTE, /* TRUE IF FILE ALREADY MADE */
ENDOFSRC BYTE, /* TRUE IF END OF SOURCE FILE */
NENDCMD BYTE, /* TRUE IF NOT END OF COMMAND TAIL */
INSPARC BYTE, /* TRUE IF IN MIDDLE OF SPARCE FILE */
SPARFIL BYTE, /* TRUE IF SPARCE FILE BEING COPIED */
MULTCOM BYTE, /* FALSE IF PROCESSING ONE LINE */
PUTNUM BYTE, /* SET WHEN READY FOR NEXT LINE NUM */
CONCNT BYTE, /* COUNTER FOR CONSOLE READY CHECK */
CHAR BYTE, /* LAST CHARACTER SCANNED */
FLEN BYTE; /* FILE NAME LENGTH */
DECLARE
F1 BYTE, /* F1 USER ATTRIBUTE FLAG */
F2 BYTE, /* F2 USER ATTRIBUTE FLAG */
F3 BYTE, /* F3 USER ATTRIBUTE FLAG */
F4 BYTE, /* F4 USER ATTRIBUTE FLAG */
RO BYTE, /* READ ONLY ATTRIBUTE FLAG */
SYS BYTE, /* SYSTEM ATTRIBUTE FLAG */
DCNT BYTE; /* ERROR CODE OR DIRECTORY CODE */
DECLARE CBUFF(130) BYTE, /* COMMAND BUFFER */
MAXLEN BYTE AT (@CBUFF(0)), /* MAX BUFFER LENGTH */
COMLEN BYTE AT (@CBUFF(1)), /* CURRENT LENGTH */
COMBUFF(128) BYTE AT (@CBUFF(2)); /* COMMAND BUFFER CONTENTS */
DECLARE
CBP BYTE; /* COMMAND BUFFER POINTER */
DECLARE
CUSER BYTE; /* CURRENT USER NUMBER */
DECLARE
LAST$USER BYTE;
DECLARE /* CONTROL TOGGLE VECTOR */
CONT(26) BYTE, /* ONE FOR EACH ALPHABETIC */
/* 00 01 02 03 04 05 06 07 08 09 10 11 12 13
A B C D E F G H I J K L M N
14 15 16 17 18 19 20 21 22 23 24 25
O P Q R S T U V W X Y Z */
ARCHIV BYTE AT(@CONT(0)), /* FILE ARCHIVE */
DELET BYTE AT(@CONT(3)), /* DELETE CHARACTERS */
ECHO BYTE AT(@CONT(4)), /* ECHO CONSOLE CHARACTERS */
FORMF BYTE AT(@CONT(5)), /* FORM FILTER */
GETU BYTE AT(@CONT(6)), /* GET FILE, USER # */
HEXT BYTE AT(@CONT(7)), /* HEX FILE TRANSFER */
IGNOR BYTE AT(@CONT(8)), /* IGNORE :00 RECORD ON FILE */
KILDS BYTE AT(@CONT(10)), /* KILL FILENAME DISPLAY */
LOWER BYTE AT(@CONT(11)), /* TRANSLATE TO LOWER CASE */
NUMB BYTE AT(@CONT(13)), /* NUMBER OUTPUT LINES */
OBJ BYTE AT(@CONT(14)), /* OBJECT FILE TRANSFER */
PAGCNT BYTE AT(@CONT(15)), /* PAGE LENGTH */
QUITS BYTE AT(@CONT(16)), /* QUIT COPY */
RSYS BYTE AT(@CONT(17)), /* READ SYSTEM FILES */
STARTS BYTE AT(@CONT(18)), /* START COPY */
TABS BYTE AT(@CONT(19)), /* TAB SET */
UPPER BYTE AT(@CONT(20)), /* UPPER CASE TRANSLATE */
VERIF BYTE AT(@CONT(21)), /* VERIFY EQUAL FILES ONLY */
WRROF BYTE AT(@CONT(22)), /* WRITE TO R/O FILE */
ZEROP BYTE AT(@CONT(25)); /* ZERO PARITY ON INPUT */
DECLARE ZEROSUP BYTE, /* ZERO SUPPRESSION */
(C3,C2,C1) BYTE; /* LINE COUNT ON PRINTER */
DCL DUMMYP POINTER,
DUMMYL LONG AT(@DUMMYP);
DCL DUM1P POINTER,
DUM1L LONG AT(@DUM1P);
DCL DUM2P POINTER,
DUM2L LONG AT(@DUM2P);
OUTD: PROCEDURE(B) EXTERNAL;
DECLARE B BYTE;
/* SEND B TO OUT: DEVICE */
END OUTD;
INPD: PROCEDURE BYTE EXTERNAL;
END INPD;
MON1: PROCEDURE(F,A) EXTERNAL;
DECLARE F BYTE,
A ADDRESS;
END MON1;
MON2: PROCEDURE(F,A) BYTE EXTERNAL;
DECLARE F BYTE,
A ADDRESS;
END MON2;
MON3: PROCEDURE(F,A) ADDRESS EXTERNAL;
DECLARE F BYTE,
A ADDRESS;
END MON3;
/* 68K*/
MON5: PROC(F,A) EXT;
DCL F BYTE,A POINTER;
END;
MON6: PROC(F,A) BYTE EXT;
DCL F BYTE,A POINTER;
END;
MON7: PROC(F,A) ADDR EXT;
DCL F BYTE,A POINTER;
END;
BOOT: PROCEDURE;
/* SYSTEM REBOOT */
CALL MON1(0,0);
END BOOT;
RDCHAR: PROCEDURE BYTE;
/* READ CONSOLE CHARACTER */
RETURN MON2(1,0);
END RDCHAR;
PRINTCHAR: PROCEDURE(CHAR);
DECLARE CHAR BYTE;
CALL MON1(2,CHAR AND 7FH);
END PRINTCHAR;
CRLF: PROCEDURE;
CALL PRINTCHAR(CR);
CALL PRINTCHAR(LF);
END CRLF;
PRINTX: PROCEDURE(A);
DECLARE A POINTER;
CALL MON5(9,A);
END PRINTX;
PRINT: PROCEDURE(A);
DECLARE A POINTER;
/* PRINT THE STRING STARTING AT ADDRESS A UNTIL THE
NEXT DOLLAR SIGN IS ENCOUNTERED */
CALL CRLF;
CALL PRINTX(A);
END PRINT;
RDCOM: PROCEDURE;
/* READ INTO COMMAND BUFFER */
MAXLEN = 128;
CALL MON5(10,@MAXLEN);
END RDCOM;
CONBRK: PROCEDURE BYTE;
/* CHECK CONSOLE CHARACTER READY */
RETURN MON2(11,0);
END CONBRK;
CVERSION: PROCEDURE ADDRESS;
RETURN MON3(12,0); /* VERSION NUMBER */
END CVERSION;
SETDMA: PROCEDURE(A);
DECLARE A POINTER;
CALL MON5(26,A);
END SETDMA;
OPEN: PROCEDURE(FCB);
DECLARE FCB POINTER;
DCNT = MON6(15,FCB);
END OPEN;
CLOSE: PROCEDURE(FCB);
DECLARE FCB POINTER;
DCNT = MON6(16,FCB);
END CLOSE;
CK$USER: PROCEDURE;
DO FOREVER;
IF DCNT = 0FFH THEN RETURN;
IF LAST$USER = BUFF(ROR (DCNT,3) AND 110$0000B)
THEN RETURN;
DCNT = MON2(18,0);
END;
END CK$USER;
SEARCH: PROCEDURE(FCB);
DECLARE FCB POINTER;
DCNT = MON6(17,FCB);
CALL CK$USER;
END SEARCH;
SEARCHN: PROCEDURE;
DCNT = MON2(18,0);
CALL CK$USER;
END SEARCHN;
DELETE: PROCEDURE(FCB);
DECLARE FCB POINTER;
CALL MON5(19,FCB);
END DELETE;
DISKRD: PROCEDURE(FCB);
DECLARE FCB POINTER;
DCNT = MON6(20,FCB);
END DISKRD;
DISKWRITE: PROCEDURE(FCB);
DECLARE FCB POINTER;
DCNT = MON6(21,FCB);
END DISKWRITE;
MAKE: PROCEDURE(FCBA);
DECLARE FCBA POINTER;
DCNT = MON6(22,FCBA);
END MAKE;
RENAME: PROCEDURE(FCB);
DECLARE FCB POINTER;
DCNT = MON6(23,FCB);
END RENAME;
GETDISK: PROCEDURE BYTE;
RETURN MON2(25,0);
END GETDISK;
SETIND: PROCEDURE(FCB);
DECLARE FCB POINTER;
DCNT = MON6(30,FCB);
END SETIND;
GETUSER: PROCEDURE BYTE;
RETURN MON2(32,0FFH);
END GETUSER;
SETUSER: PROCEDURE(USER);
DECLARE USER BYTE;
CALL MON1(32,(LAST$USER:=USER));
END SETUSER;
SETCUSER: PROCEDURE;
CALL SETUSER(CUSER);
END SETCUSER;
SETDUSER: PROCEDURE;
CALL SETUSER(ODEST.USER);
END SETDUSER;
SETSUSER: PROCEDURE;
CALL SETUSER(SOURCE.USER);
END SETSUSER;
RD$RANDOM: PROCEDURE(FCB) BYTE;
DECLARE FCB POINTER;
RETURN MON6(33,FCB);
END RD$RANDOM;
WRITE$RANDOM: PROCEDURE(FCB) BYTE;
DECLARE FCB POINTER;
RETURN MON6(34,FCB);
END WRITE$RANDOM;
RETFSIZE: PROCEDURE(FCB) BYTE;
DECLARE FCB POINTER;
RETURN MON6(35,FCB);
END RETFSIZE;
SET$RANDOM: PROCEDURE(FCB);
DECLARE FCB POINTER;
/* SET RANDOM RECORD POSITION */
CALL MON5(36,FCB);
END SET$RANDOM;
MOVE: PROCEDURE(S,D,N);
DECLARE (S,D) POINTER, N BYTE;
DECLARE A BASED DUM1P BYTE, B BASED DUM2P BYTE;
/*68K*/ DUM1P=S; DUM2P=D;
DO WHILE (N:=N-1) <> 255;
/*68K*/ B = A; DUM1L=DUM1L+1; DUM2L=DUM2L+1;
END;
END MOVE;
ERROR: PROCEDURE(ERRTYPE,FILEADR);
DECLARE I BYTE,
TEMP BYTE,
ERRTYPE BYTE,
FILEADR POINTER,
FCB BASED FILEADR (FSIZE) BYTE;
/* ERRTYPE ERROR MESSAGES */
DECLARE ER00(*) BYTE DATA ('DISK READ$');
DECLARE ER01(*) BYTE DATA ('DISK WRITE$');
DECLARE ER02(*) BYTE DATA ('VERIFY$');
DECLARE ER03(*) BYTE DATA ('INVALID DESTINATION$');
DECLARE ER04(*) BYTE DATA ('INVALID SOURCE$');
DECLARE ER05(*) BYTE DATA ('USER ABORTED$');
DECLARE ER06(*) BYTE DATA ('BAD PARAMETER$');
DECLARE ER07(*) BYTE DATA ('INVALID USER NUMBER$');
DECLARE ER08(*) BYTE DATA ('INVALID FORMAT$');
DECLARE ER09(*) BYTE DATA ('HEX RECORD CHECKSUM$');
DECLARE ER10(*) BYTE DATA ('FILE NOT FOUND$');
DECLARE ER11(*) BYTE DATA ('START NOT FOUND$');
DECLARE ER12(*) BYTE DATA ('QUIT NOT FOUND$');
DECLARE ER13(*) BYTE DATA ('INVALID HEX DIGIT$');
DECLARE ER14(*) BYTE DATA ('CLOSE FILE$');
DECLARE ER15(*) BYTE DATA ('UNEXPECTED END OF HEX FILE$');
DECLARE ER16(*) BYTE DATA ('INVALID SEPARATOR$');
DECLARE ER17(*) BYTE DATA ('NO DIRECTORY SPACE$');
DECLARE ER18(*) BYTE DATA ('INVALID FORMAT WITH SPARSE FILE$');
DECLARE ERRMSG(*) POINTER DATA(
@ER00,@ER01,@ER02,@ER03,@ER04,
@ER05,@ER06,@ER07,@ER08,@ER09,
@ER10,@ER11,@ER12,@ER13,@ER14,
@ER15,@ER16,@ER17,@ER18);
CALL SETDUSER;
IF MADE THEN
DO; CALL CLOSE(@DEST);
CALL DELETE(@DEST); /* DELETE DESTINATION SCRATCH FILE */
END;
/* PRINT OUT ERROR MESSAGE */
CALL PRINT(@('ERROR: $'));
CALL PRINTX(ERRMSG(ERRTYPE));
CALL PRINTX(@(' - $'));
IF FILEADR <> 0 THEN
DO; CALL PRINTCHAR('A' + FCB(0) - 1);
CALL PRINTCHAR(':');
DO I = 1 TO FNSIZE;
IF (TEMP := FCB(I) AND 07FH) <> ' ' THEN
DO; IF I = FEXT THEN CALL PRINTCHAR('.');
CALL PRINTCHAR(TEMP);
END;
END;
END;
/* ZERO THE COMLEN IN CASE THIS IS A SINGLE COMMAND */
COMLEN = 0;
CALL CRLF;
GO TO RETRY;
END ERROR;
FORMERR: PROCEDURE;
CALL ERROR(8,0); /* INVALID FORMAT */
END FORMERR;
MAXSIZE: PROCEDURE BYTE;
IF (SOURCE.FCB(35) = FILSIZE(2)) AND
(SOURCE.FCB(34) = FILSIZE(1)) AND
(SOURCE.FCB(33) = FILSIZE(0)) THEN RETURN TRUE;
RETURN FALSE;
END MAXSIZE;
SETUPDEST: PROCEDURE;
CALL SETDUSER; /* DESTINATION USER */
CALL MOVE(@ODEST,@DEST,(FRSIZE + 1)); /* SAVE ORIGINAL DEST */
/* MOVE THREE CHARACTER EXTENT INTO DEST FCB */
CALL MOVE(@('$$$'),@DEST.FCB(FEXT),FEXTL);
CALL DELETE(@DEST); /* REMOVE OLD $$

View File

@@ -0,0 +1,25 @@
*
* SUBROUTINE FOR CP/M68K PIP UTILITY
*
SECTION 9
XDEF INPLOC,OUTPLOC,INPD,OUTD
*
INPLOC EQU *
NOP
RTS
*
OUTPLOC EQU *
NOP
RTS
*
INPD EQU *
NOP
RTS
*
OUTD EQU *
NOP
MOVE.L (A7)+,A0
LEA 2(A7),A7
JMP (A0)
END

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,115 @@
DPB86:
DO;
/* THE PURPOSE OF THIS MODULE IS TO ALLOW INDEPENDENCE */
/* OF PROCESSOR, I.E., 8080 OR 8086 */
DECLARE
/*SPLH*/ /* LIT LITERALLY 'LITERALLY',
DCL LIT 'DECLARE',
PROC LIT 'PROCEDURE',
ADDR LIT 'ADDRESS', */
TRUE LIT '0FFH',
FALSE LIT '0',
/* BOOLEAN LIT 'BYTE', */
FOREVER LIT 'WHILE TRUE',
CR LIT '13',
LF LIT '10',
TAB LIT '9',
FF LIT '12',
SECTORLEN LIT '128';
/* FUNCTION CALL 32 IN 2.0 OR LATER BDOS, RETURNS THE ADDRESS OF THE DISK
PARAMETER BLOCK FOR THE CURRENTLY SELECTED DISK, WHICH CONSISTS OF:
SPT (2 BYTES) NUMBER OF SECTORS PER TRACK
BLKSHF (1 BYTE) BLOCK SIZE = SHL(DOUBLE(128),BLKSHF)
BLKMSK (1 BYTE) SECTOR# AND BLKMSK = BLOCK NUMBER
EXTMSK (1 BYTE) LOGICAL/PHYSICAL EXTENTS
BLKMAX (2 BYTES) MAX ALLOC NUMBER
DIRMAX (2 BYTES) SIZE OF DIRECTORY-1
DIRBLK (2 BYTES) RESERVATION BITS FOR DIRECTORY
CHKSIZ (2 BYTES) SIZE OF CHECKSUM VECTOR
OFFSET (2 BYTES) OFFSET FOR OPERATING SYSTEM
*/
/* INDICES INTO DISK PARAMETER BLOCK, USED AS PARAMETERS TO DPB PROCEDURE */
DCL SPT$W LIT '0',
BLKSHF$B LIT '2',
BLKMSK$B LIT '3',
EXTMSK$B LIT '4', /* 68K*/
BLKMAX$W LIT /*'5', */ '6',
DIRMAX$W LIT /*'7', */ '8',
DIRBLK$W LIT /*'9', */ '10',
CHKSIZ$W LIT /*'11',*/ '12',
OFFSET$W LIT /*'13';*/ '14';
DECLARE K$PER$BLOCK BYTE PUBLIC;
DECLARE DPB$BASE POINTER;/*SPLH*/
DECLARE DPB$ARRAY (16) BYTE; /*SPLH */
MON4: PROCEDURE (F,A) EXTERNAL;
DCL F BYTE, A ADDRESS;
END MON4;
MON5: PROC(F,A) EXT;
DCL F BYTE,A POINTER;
END MON5;
DCL GET$DPB LIT '31';
/* MERGE SYS:3.CHRSYN.STATSUB1.SA = [SOURCE.CPM86.CPM11.STAT]CON86.PLM*/
/* $COMPACT */
/* $TITLE ('CONSOLE 8086 - GET CONSOLE WIDTH') */
/* THE PURPOSE OF THIS MODULE IS TO ALLOW INDEPENDENCE */
/* OF PROCESSOR, I.E., 8080 OR 8086 */
/* IT WILL RETURN A WORD VALUE EQUAL TO THE CONSOLE WIDTH FROM
THE SYSTEM DATA PAGE. */
GET$SYSDAT:
PROCEDURE POINTER;
RETURN /* (MON4(49,0)); */ 10; /*SPLH*/
END GET$SYSDAT;
DECLARE CONWIDTH$POINTER POINTER;
DECLARE CONWIDTH$PTR STRUCTURE (
OFFSET WORD,
SEGMENT WORD) AT (@CONWIDTH$POINTER);
DECLARE WIDTH BASED CONWIDTH$POINTER BYTE;
DECLARE CONWIDTH$OFFSET LIT '0040H';
COLUMNS: PROCEDURE BYTE PUBLIC;
/* CONWIDTH$POINTER = GET$SYSDAT;
CONWIDTH$PTR.OFFSET = CONWIDTH$PTR.OFFSET + CONWIDTH$OFFSET;
IF WIDTH = 0 THEN
RETURN 80;
RETURN WIDTH; */ RETURN 80 ; /*SPLH*/
END COLUMNS;
/* MERGE END */
DPB$BYTE: PROCEDURE(PARAM) BYTE PUBLIC;
DCL PARAM BYTE;
RETURN(DPB$ARRAY(PARAM)); /* S-PL/H */
END DPB$BYTE;
DPB$WORD: PROCEDURE(PARAM) ADDRESS PUBLIC; /* S-PL/H */
DCL PARAM BYTE;
RETURN(DPB$ARRAY(PARAM+1) + SHL(DOUBLE(DPB$ARRAY(PARAM)),8));
END DPB$WORD;
BASE$DPB: PROCEDURE PUBLIC; /* S-PL/H */
/* 68K*/ DPB$BASE=@DPB$ARRAY;
/* DPB$BASE = MON4(GET$DPB,0); */ CALL MON5(GET$DPB,DPB$BASE);
K$PER$BLOCK = SHR(DPB$BYTE(BLKMSK$B)+1 ,3);
END BASE$DPB;
END DPB86;

View File

@@ -0,0 +1,134 @@
*******************************************************************************
*
* STANDARD INTERFACE ROUTINE FOR CP/M68K UTILITY PROGRAM
* (OVER 64K MODEL)
*
* (1) SET THE ENVIRONMENT FOR S-PL/H OBJECT
* (2) DECLARE THE PUBLIC PROCEDURE FOR BDOS CALL
* (3) SET THE BASE PAGE VARIABLES
* (4) DECLARE PATCH AREA
*
*******************************************************************************
SECTION 8
*******************************************************************************
********* EXTERNAL DEFINITION
*******************************************************************************
XDEF .SMAIN
XDEF ENTRYC
XDEF MON1,MON2,MON3,MON4,XDOS
XDEF MON5,MON6,MON7
XDEF MAXB,MEMSIZE
XDEF FCB,FCB16,BUFF,TBUFF
XDEF PATCH1,PATCH2
XDEF MEMORY
*******************************************************************************
********* EXTERNAL REFERENCE DIFINITION
*******************************************************************************
XREF .SPSCT
XREF .SDSCT
*******************************************************************************
********* CONSTANT EQUATION DEFINITION
*******************************************************************************
OMAXB EQU 4 /* OFFSET OF MAXB FROM BASE
OFCB16 EQU $38 /* OFFSET OF FCB16 FROM BASE
OFCB EQU $5C /* OFFSET OF FCB FROM BASE
OBUFF EQU $80 /* OFFSET OF BUFF FROM BASE
FCBSZ EQU 72 /* (FCB16 + FCB) AREA SIZE
BUFFSZ EQU 128 /* BUFF AREA SIZE
*
*******************************************************************************
*
ENTRYC EQU * /* ENTRY POINT FROM CCP
.SMAIN EQU * /* REFER FROM .SINIT ROUTINE
*******************************************************************************
********* SET THE BASE PAGE VARIABLES
*******************************************************************************
MOVE.L (A7)+,RTNCCP /* STORE RETURN ADDR OF CCP
MOVE.L (A7)+,SBASEP /* STORE POINTER OF BASE PAGE
*
MOVEA.L SBASEP,A0 /* GET THE BASE ADDR OF BASE PAGE
MOVE.W OMAXB(A0),MAXB /* SET MAXB
*
LEA OFCB16(A0),A0 /* GET THE SOURCE ADDR OF FCB16
LEA FCB16,A1 /* GET THE DESTINATION ADDR OF FCB16
MOVE.W #(FCBSZ-1),D0 /* SET LOOP NUMBER
LOP1 MOVE.B (A0)+,(A1)+ /* SET FCB16 AND FCB
DBF D0,LOP1
*
MOVEA.L SBASEP,A0
LEA OBUFF(A0),A0 /* GET THE SOURCE ADDR OF BUFF
LEA BUFF,A1 /* GET THE DESTINATION ADDR OF BUFF
MOVE.W #(BUFFSZ-1),D0 /* SET LOOP NUMBER
LOP2 MOVE.B (A0)+,(A1)+ /* SET BUFF AND TBUFF
DBF D0,LOP2
*
********* END BASE PAGE SET
*******************************************************************************
********* INIT FOR S-PL/H
*******************************************************************************
LEA RMA,A5 /* SET RMA BASE
LEA RMA,A6
LEA RMA,A7 /* SET STACK POINTER
SUBA.L #4,A6 /* SET FRAME POINTER
LEA .SPSCT,A4 /* S-PL/H OBJECT AREA
LEA .SDSCT,A2 /* S-PL/H DATA AREA
JSR (A4) /* GO TO S-PL/H
*******************************************************************************
********* PUBLIC SUBROUTINE FOR BDOS CALL
*******************************************************************************
MON1 EQU *
MON2 EQU *
MON3 EQU *
MON4 EQU *
XDOS EQU *
CLR.L D0
CLR.L D1
MOVE.W 4(A7),D1
MOVE.B 6(A7),D0
TRAP #2 /* BDOS CALL
MOVEA.L (A7)+,A0
LEA 4(A7),A7
JMP (A0) /* RETURN TO MAINROUTINE
MON5 EQU *
MON6 EQU *
MON7 EQU *
CLR.L D0
MOVE.L 4(A7),D1
MOVE.B 8(A7),D0
TRAP #2 /* BDOS CALL
MOVEA.L (A7)+,A0
LEA 6(A7),A7
JMP (A0)
*******************************************************************************
********* PATCH AREA
*******************************************************************************
PATCH1 DC.B 'COPYRIGHT 1983'
DC.B 'DIGITAL RESEARCH'
PATCH2 DC.B '010282'
DC.B 'XXXX-'
DC.B '0000-'
DC.B '654321'
*
*******************************************************************************
*******************************************************************************
* DEFINITION OF DATA AREA
*******************************************************************************
SECTION 7
STACK DS.L 300 /* STACK AREA OF S-PL/H
RMA DS.B 144 /* S-PL/H RUN TIME MAINTENANCE AREA
*******************************************************************************
MAXB DS.L 1 /* TOP ADDR OF TPA
MEMSIZE EQU MAXB /* SAME AS MAXB
FCB16 DS.B 36 /* 2-nd PARSED FCB OF COMMAND LINE
FCB DS.B 36 /* 1-st PARSED FCB OF COMMAND LINE
BUFF DS.B 128 /* COMMAND LINE TAIL AND DMA BUFF
TBUFF EQU BUFF /* SAME AS BUFF
RTNCCP DS.L 1 /* RETURN ADDR TO CCP
SBASEP DS.L 1 /* POINTER TO BASE PASE
MEMORY DS.L 1 /* MEMORY ARRAY
*
*******************************************************************************
*
END .SMAIN

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,188 @@
/********************************************************
* *
* CP/M-68K header file *
* Copyright (c) 1982 by Digital Research, Inc. *
* Structure definitions for BDOS globals *
* and BDOS data structures *
* *
* Desecrated 6-Aug-83 (sw) for type-ahead *
* Again 17-Mar-84 (sw) for chaining *
* *
********************************************************/
/**************************************************************************
The BDOS data structures, especially those relating to global variables,
are structured in a way that hopefully will enable this BDOS, in the future,
to easily become a re-entrant multi-tasking file system. Consequently,
the BDOS global variables are divided into two classes. Those that are
truly global, even in the case of multiple tasks using the file system
concurrently, are simply declared as global variables in bdosmain.c.
Only a few "globals" are really global in this sense.
The majority of the "global" variables are actually state variables that
relate to the state of the task using the file system. In CP/M-68K, these
are "global", since there's only one task, but in a multi-thread model they're
not. This type of variables is put into a data structure, with the
intention that in the multi-task environment this structure will be based.
The following declarations take this philosophy into account, and define
a simple structure for the single thread environment while leaving the
possibilities open for the multi-thread environment.
****************************************************************************/
#define snglthrd TRUE
/* TRUE for single-thread environment
FALSE to create based structure for re-entrant model */
#if snglthrd
#define GBL gbls
/* In single thread case, GBL just names
the structure */
#define BSETUP EXTERN struct stvars gbls;
/* and BSETUP defines the extern structure */
#endif
#if ! snglthrd
#define GBL (*statep)
/* If multi-task, state vars are based */
#define BSETUP REG struct stvars *statep; \
statep = &gbls;
/* set up pointer to state variables */
/* This is intended as an example to show the intent */
#endif
/* Note that there are a few critical regions in the file system that must
execute without interruption. They pertain mostly to the manipulation of
the allocation vector. This isn't a problem in a single-thread model, but
must be provided for in a multi-tasking file system. Consequently, the
primitives LOCK and UNLOCK are defined and used where necessary in the
file system. For the single thread model, they are null routines */
#define LOCK /**/
#define UNLOCK /**/
/* Be sure LOCK and UNLOCK are implemented to allow recursive calls to LOCK.
That is, if a process that calls LOCK already owns the lock, let it proceed,
but remember that only the outer-most call to UNLOCK really releases the
file system. */
#define VERSION 0x2022 /* Version number for CP/M-68K */
#define robit 0 /* read-only bit in file type field of fcb */
#define arbit 2 /* archive bit in file type field of fcb */
#define SECLEN 128 /* length of a CP/M sector */
/* File Control Block definition */
struct fcb
{
UBYTE drvcode; /* 0 = default drive, 1..16 are drives A..P */
UBYTE fname[8]; /* File name (ASCII) */
UBYTE ftype[3]; /* File type (ASCII) */
UBYTE extent; /* Extent number (bits 0..4 used) */
UBYTE s1; /* Reserved */
UBYTE s2; /* Module field (bits 0..5), write flag (7) */
UBYTE rcdcnt; /* Nmbr rcrds in last block, 0..128 */
union
{
UBYTE small[16]; /* 16 block numbers of 1 byte */
WORD big[8]; /* or 8 block numbers of 1 word */
} dskmap;
UBYTE cur_rec; /* current record field */
UBYTE ran0; /* random record field (3 bytes) */
UBYTE ran1;
UBYTE ran2;
};
/* Declaration of directory entry */
struct dirent
{
UBYTE entry; /* 0 - 15 for user numbers, E5 for empty */
/* the rest are reserved */
UBYTE fname[8]; /* File name (ASCII) */
UBYTE ftype[3]; /* File type (ASCII) */
UBYTE extent; /* Extent number (bits 0..4 used) */
UBYTE s1; /* Reserved */
UBYTE s2; /* Module field (bits 0..5), write flag (7) */
UBYTE rcdcnt; /* Nmbr rcrds in last block, 0..128 */
union
{
UBYTE small[16]; /* 16 block numbers of 1 byte */
WORD big[8]; /* or 8 block numbers of 1 word */
} dskmap;
};
/* Declaration of disk parameter tables */
struct dpb /* disk parameter table */
{
UWORD spt; /* sectors per track */
UBYTE bsh; /* block shift factor */
UBYTE blm; /* block mask */
UBYTE exm; /* extent mask */
UBYTE dpbdum; /* dummy byte for fill */
UWORD dsm; /* max disk size in blocks */
UWORD drm; /* max directory entries */
UWORD dir_al; /* initial allocation for dir */
UWORD cks; /* number dir sectors to checksum */
UWORD trk_off; /* track offset */
};
struct dph /* disk parameter header */
{
UBYTE *xlt; /* pointer to sector translate table */
UWORD hiwater; /* high water mark for this disk */
UWORD dum1; /* dummy (unused) */
UWORD dum2;
UBYTE *dbufp; /* pointer to 128 byte directory buffer */
struct dpb *dpbp; /* pointer to disk parameter block */
UBYTE *csv; /* pointer to check vector */
UBYTE *alv; /* pointer to allocation vector */
};
/* Declaration of structure containing "global" state variables */
#define TBUFSIZ 126 /*sw # typed-ahead characters */
struct stvars
{
UBYTE kbchar; /* keyboard type-ahead buffer count */
UBYTE delim; /* Delimiter for function 9 */
BOOLEAN lstecho; /* True if echoing console output to lst: */
BOOLEAN echodel; /* Echo char when getting <del> ? */
UWORD column; /* CRT column number for expanding tabs */
UBYTE curdsk; /* Currently selected disk */
UBYTE dfltdsk; /* Default disk (last selected by fcn 14) */
UBYTE user; /* Current user number */
struct dph *dphp; /* pointer to disk parm hdr for cur disk */
struct dirent *dirbufp; /* pointer for directory buff for process */
/* stored here so that each process can */
/* have a separate dirbuf. */
struct dpb *parmp; /* pointer to disk parameter block for cur */
/* disk. Stored here to save ref calc */
UWORD srchpos; /* position in directory for search next */
UBYTE *dmaadr; /* Disk dma address */
struct fcb *srchp; /* Pointer to search FCB for function 17 */
UBYTE *excvec[18]; /* Array of exception vectors */
UBYTE *insptr; /*sw Insertion pointer for typeahead */
UBYTE *remptr; /*sw Removal pointer for typeahead */
UBYTE t_buff[TBUFSIZ]; /*sw Type-ahead buffer itself */
};
/*sw removed next line from structure */
UBYTE *chainp; /* Used for chain to program call */
/* Console buffer structure declaration */
struct conbuf
{
UBYTE maxlen; /* Maximum length from calling routine */
UBYTE retlen; /* Length actually found by BDOS */
UBYTE cbuf[]; /* Console data */
};
 */
};
 */
};


Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,308 @@
/****************************************************************
* *
* CP/M-68K BDOS Main Routine *
* *
* This is the main routine for the BDOS for CP/M-68K *
* It has one entry point, _bdos, which is called from *
* the assembly language trap handler found in bdosif.s. *
* The parameters are a function number (integer) and an *
* information parameter (which is passed from bdosif as *
* both an integer and a pointer). *
* The BDOS can potentially return a pointer, long word, *
* or word *
* *
* Configured for Alcyon C on the VAX *
* *
****************************************************************/
#include "bdosinc.h" /* Standard I/O declarations */
#include "bdosdef.h" /* Type and structure declarations for BDOS */
#include "biosdef.h" /* Declarations of BIOS functions */
/* Declare EXTERN functions */
EXTERN warmboot(); /* Warm Boot function */
EXTERN BOOLEAN constat(); /* Console status */
EXTERN UBYTE conin(); /* Console Input function */
EXTERN tabout(); /* Console output with tab expansion */
EXTERN UBYTE rawconio(); /* Raw console I/O */
EXTERN prt_line(); /* Print line until delimiter */
EXTERN readline(); /* Buffered console read */
EXTERN seldsk(); /* Select disk */
EXTERN BOOLEAN openfile(); /* Open File */
EXTERN UWORD close_fi(); /* Close File */
EXTERN UWORD search(); /* Search first and next fcns */
EXTERN UWORD dirscan(); /* General directory scanning routine */
EXTERN UWORD bdosrw(); /* Sequential and Random disk read/write */
EXTERN BOOLEAN create(); /* Create file */
EXTERN BOOLEAN delete(); /* Delete file */
EXTERN BOOLEAN rename(); /* Rename file */
EXTERN BOOLEAN set_attr(); /* Set file attributes */
EXTERN getsize(); /* Get File Size */
EXTERN setran(); /* Set Random Record */
EXTERN free_sp(); /* Get Disk Free Space */
EXTERN UWORD flushit(); /* Flush Buffers */
EXTERN UWORD pgmld(); /* Program Load */
EXTERN UWORD setexc(); /* Set Exception Vector */
EXTERN set_tpa(); /* Get/Set TPA Limits */
EXTERN move(); /* general purpose byte mover */
/* Declare "true" global variables; i.e., those which will pertain to the
entire file system and thus will remain global even when this becomes
a multi-tasking file system */
GLOBAL UWORD log_dsk; /* 16-bit vector of logged in drives */
GLOBAL UWORD ro_dsk; /* 16-bit vector of read-only drives */
GLOBAL UWORD crit_dsk; /* 16-bit vector of drives in "critical"
state. Used to control dir checksums */
GLOBAL BYTE *tpa_lp; /* TPA lower boundary (permanent) */
GLOBAL BYTE *tpa_lt; /* TPA lower boundary (temporary) */
GLOBAL BYTE *tpa_hp; /* TPA upper boundary (permanent) */
GLOBAL BYTE *tpa_ht; /* TPA upper boundary (temporary) */
/* Declare the "state variables". These are globals for the single-thread
version of the file system, but are put in a structure so they can be
based, with a pointer coming from the calling process */
GLOBAL struct stvars gbls;
struct tempstr
{
UBYTE tempdisk;
BOOLEAN reselect;
struct fcb *fptr;
};
/****************************************************************
* *
* _bdos MAIN ROUTINE *
* *
* Called with _bdos(func, info, infop) *
* *
* Where: *
* func is the BDOS function number (d0.w) *
* info is the word parameter (d1.w) *
* infop is the pointer parameter (d1.l) *
* note that info is the word form of infop*
* *
****************************************************************/
UWORD _bdos(func,info,infop)
REG WORD func; /* BDOS function number */
REG UWORD info; /* d1.w word parameter */
REG UBYTE *infop; /* d1.l pointer parameter */
{
REG UWORD rtnval;
LOCAL struct tempstr temp;
BSETUP
temp.reselect = FALSE;
temp.fptr = infop;
rtnval = 0;
switch (func) /* switch on function number */
{
case 0: warmboot(0); /* warm boot function */
/* break; */
case 1: return((UWORD)conin()); /* console input function */
/* break; */
case 2: tabout((UBYTE)info); /* console output with */
break; /* tab expansion */
case 3: return((UWORD)brdr()); /* get reader from bios */
/* break; */
case 4: bpun((UBYTE)info); /* punch output to bios */
break;
case 5: blstout((UBYTE)info); /* list output from bios */
break;
case 6: return((UWORD)rawconio(info)); /* raw console I/O */
/* break; */
case 7: return(bgetiob()); /* get i/o byte */
/* break; */
case 8: bsetiob(info); /* set i/o byte function */
break;
case 9: prt_line(infop); /* print line function */
break;
case 10: readline(infop); /* read buffered con input */
break;
case 11: return((UWORD)constat()); /* console status */
/* break; */
case 12: return(VERSION); /* return version number */
/* break; */
case 13: log_dsk = 0; /* reset disk system */
ro_dsk = 0;
crit_dsk= 0;
GBL.curdsk = 0xff;
GBL.dfltdsk = 0;
break;
case 14: seldsk((UBYTE)info); /* select disk */
GBL.dfltdsk = (UBYTE)info;
break;
case 15: tmp_sel(&temp); /* open file */
infop->extent = 0;
infop->s2 = 0;
rtnval = dirscan(openfile, infop, 0);
break;
case 16: tmp_sel(&temp); /* close file */
rtnval = close_fi(infop);
break;
case 17: GBL.srchp = infop; /* search first */
rtnval = search(infop, 0, &temp);
break;
case 18: infop = GBL.srchp; /* search next */
temp.fptr = infop;
rtnval = search(infop, 1, &temp);
break;
case 19: tmp_sel(&temp); /* delete file */
rtnval = dirscan(delete, infop, 2);
break;
case 20: tmp_sel(&temp); /* read sequential */
rtnval = bdosrw(infop, TRUE, 0);
break;
case 21: tmp_sel(&temp); /* write sequential */
rtnval = bdosrw(infop, FALSE, 0);
break;
case 22: tmp_sel(&temp); /* create file */
infop->extent = 0;
infop->s1 = 0;
infop->s2 = 0;
infop->rcdcnt = 0;
/* Zero extent, S1, S2, rcrdcnt. create zeros rest */
rtnval = dirscan(create, infop, 8);
break;
case 23: tmp_sel(&temp); /* rename file */
rtnval = dirscan(rename, infop, 2);
break;
case 24: return(log_dsk); /* return login vector */
/* break; */
case 25: return(UBWORD(GBL.dfltdsk)); /* return current disk */
/* break; */
case 26: GBL.dmaadr = infop; /* set dma address */
break;
/* No function 27 -- Get Allocation Vector */
case 28: ro_dsk |= 1<<GBL.dfltdsk; /* set disk read-only */
break;
case 29: return(ro_dsk); /* get read-only vector */
/* break; */
case 30: tmp_sel(&temp); /* set file attributes */
rtnval = dirscan(set_attr, infop, 2);
break;
case 31: if (GBL.curdsk != GBL.dfltdsk) seldsk(GBL.dfltdsk);
move( (GBL.parmp), infop, sizeof *(GBL.parmp) );
break; /* return disk parameters */
case 32: if ( (info & 0xff) <= 15 ) /* get/set user number */
GBL.user = (UBYTE)info;
return(UBWORD(GBL.user));
/* break; */
case 33: tmp_sel(&temp); /* random read */
rtnval = bdosrw(infop, TRUE, 1);
break;
case 34: tmp_sel(&temp); /* random write */
rtnval = bdosrw(infop, FALSE, 1);
break;
case 35: tmp_sel(&temp); /* get file size */
getsize(infop);
break;
case 36: tmp_sel(&temp); /* set random record */
setran(infop);
break;
case 37: info = ~info; /* reset drive */
log_dsk &= info;
ro_dsk &= info;
crit_dsk &= info;
break;
case 40: tmp_sel(&temp); /* write random with 0 fill */
rtnval = bdosrw(infop, FALSE, 2);
break;
case 46: free_sp(info); /* get disk free space */
break;
case 47: chainp = GBL.dmaadr; /*sw chain to program */
warmboot(0); /* terminate calling program */
/* break; */
case 48: return( flushit() ); /* flush buffers */
/* break; */
case 59: return(pgmld(infop,GBL.dmaadr)); /* program load */
/* break; */
case 61: return(setexc(infop)); /* set exception vector */
/* break; */
case 63: set_tpa(infop); /* get/set TPA limits */
break;
default: return(-1); /* bad function number */
/* break; */
}; /* end of switch statement */
if (temp.reselect) infop->drvcode = temp.tempdisk;
/* if reselected disk, restore it now */
return(rtnval); /* return the BDOS return value */
} /* end _bdos */
tmp_sel(temptr) /* temporarily select disk pointed to by fcb */
REG struct tempstr *temptr;
{
REG struct fcb *fcbp;
REG UBYTE tmp_dsk;
BSETUP
fcbp = temptr->fptr; /* get local copy of fcb pointer */
tmp_dsk = (temptr->tempdisk = fcbp->drvcode);
seldsk( tmp_dsk ? tmp_dsk - 1 : GBL.dfltdsk );
fcbp->drvcode = GBL.user;
temptr->reselect = TRUE;
}
ct = TRUE;
}
ct = TRUE;

View File

@@ -0,0 +1,325 @@
/****************************************************************
* *
* CP/M-68K BDOS Miscellaneous Module *
* *
* This module contains miscellaneous loose ends for *
* CP/M-68K. Included are: *
* *
* bdosinit() - BDOS initialization routine *
* called from CCP for system init *
* warmboot() - BDOS warm boot exit routine *
* error() - BDOS error printing routine *
* ro_err() - BDOS read-only file error routine *
* setexc() - BDOS set exception vector *
* set_tpa() - BDOS get/set TPA limits *
* serial # and copyright notice, machine readable *
* *
* *
* Configured for Alcyon C on the VAX *
* *
* Modified 2/5/84 sw for ^C disk reset. *
* Again 3/17/84 for chain hack *
* *
****************************************************************/
#include "bdosinc.h" /* Standard I/O declarations */
#include "bdosdef.h" /* Type and structure declarations for BDOS */
#include "biosdef.h" /* BIOS definitions, needed for bios wboot */
/* serial # and copyright notice */
char *copyrt="CP/M-68K(tm), Version 1.2, Copyright (c) 1984, Digital Research";
char *serial="XXXX-0000-654321";
/* Declare external functions */
EXTERN conout(); /* Console Output function */
EXTERN UBYTE conin(); /* Console Input function */
EXTERN prt_line(); /* Print String function */
EXTERN UWORD _bdos(); /* BDOS main routine */
EXTERN UBYTE *traphndl(); /* assembly language trap handler */
EXTERN initexc(); /* init the exception handler in */
/* exceptn.s */
EXTERN UWORD dirscan(); /* Directory scanning routine */
EXTERN BOOLEAN set_attr(); /* Set File attributes function */
EXTERN UWORD dir_rd(); /* Read directory sector routine */
/* Declare external variables */
EXTERN UWORD log_dsk; /* logged-on disk vector */
EXTERN UWORD ro_dsk; /* read-only disk vector */
EXTERN UWORD crit_dsk; /* vector of critical disks */
EXTERN BYTE *tpa_lt; /* TPA lower limit (temporary) */
EXTERN BYTE *tpa_lp; /* TPA lower limit (permanent) */
EXTERN BYTE *tpa_ht; /* TPA upper limit (temporary) */
EXTERN BYTE *tpa_hp; /* TPA upper limit (permanent) */
EXTERN BOOLEAN submit; /* external variables from CCP */
EXTERN BOOLEAN morecmds;
#define trap2v 34 /* trap 2 vector number */
#define ctrlc 3 /* control-c */
/********************************
* bdos initialization routine *
********************************/
bdosinit()
/* Initialize the File System */
{
REG struct
{
WORD nmbr;
BYTE *low;
LONG length;
} *segp;
BSETUP
bsetvec(trap2v, &traphndl); /* set up trap vector */
GBL.kbchar = 0; /* initialize the "global" variables */
GBL.insptr = GBL.remptr = &(GBL.t_buff[0]);
GBL.delim = '$';
GBL.lstecho = FALSE;
GBL.echodel = TRUE;
chainp = NULL; /*sw Used to be GBL.chainp */
_bdos(13); /* reset disk system function */
segp = bgetseg(); /* get pointer to memory segment table */
tpa_lt = tpa_lp = segp->low;
tpa_ht = tpa_hp = tpa_lp + segp->length;
initexc( &(GBL.excvec[0]) );
}
/************************
* warmboot entry point *
************************/
warmboot(parm)
/* Warm Boot the system */
WORD parm; /* 1 to reset submit flag */
{
BSETUP
if(parm != 2) /*sw Not ^C */
log_dsk &= ~ro_dsk; /* log off any disk marked read-only */
else
log_dsk &= (1 << GBL.curdsk); /*sw Log off all but current drive, as */
/* per manual. (^C only) */
/* note that this code is specifically for a single-
thread system. It won't work in a multi-task sys */
/*sw The above is still very much true */
ro_dsk = 0;
crit_dsk = 0;
if (parm)
submit = morecmds = FALSE;
GBL.curdsk = 0xff; /* set current disk to "unknown" */
tpa_lt = tpa_lp;
tpa_ht = tpa_hp;
initexc( &(GBL.excvec[0]) );
bwboot();
}
/*************************/
/* disk error handlers */
/*************************/
prt_err(p)
/* print the error message */
BYTE *p;
{
BSETUP
prt_line(p);
prt_line(" error on drive $");
conout(GBL.curdsk + 'A');
}
abrt_err(p)
/* print the error message and always abort */
BYTE *p;
{
prt_err(p);
warmboot(1);
}
char *warning = "\r\nWARNING -- Do not attempt to change disks$";
ext_err(cont,p)
/* print the error message, and allow for retry, abort, or ignore */
REG BOOLEAN cont; /* Boolean for whether continuing is allowed */
BYTE *p; /* pointer to error message */
{
REG UBYTE ch;
prt_err(p);
prt_line(warning);
do
{
prt_line("\n\rDo you want to: Abort (A), Retry (R)$");
if (cont) prt_line(", or Continue with bad data (C)$");
prt_line("? $");
ch = conin() & 0x5f;
prt_line("\r\n$");
switch ( ch )
{
case ctrlc: warmboot(1);
case 'A': warmboot(1);
case 'C': if (cont) return(1);
break;
case 'R': return(0);
}
} while (TRUE);
}
/********************************/
/* Read-only File Error Routine */
/********************************/
ro_err(fcbp,dirindx)
/* File R/O error */
REG struct fcb *fcbp;
WORD dirindx;
{
REG BYTE *p;
REG UWORD i;
REG UBYTE ch;
p = (BYTE *)fcbp;
prt_line("CP/M Disk file error: $");
i = 8;
do conout(*++p & 0x7f); while (--i);
conout('.');
i = 3;
do conout(*++p & 0x7f); while (--i);
prt_line(" is read-only.$");
prt_line(warning);
do
{
prt_line("\r\nDo you want to: Change it to read/write (C), or Abort (A)? $");
ch = conin() & 0x5f;
prt_line("\r\n$");
switch ( ch )
{
case ctrlc: warmboot(1);
case 'A': warmboot(1);
case 'C': fcbp->ftype[robit] &= 0x7f;
dirscan(set_attr, fcbp, 2);
return(dir_rd(dirindx >> 2));
} /* Reset the directory buffer !!!! */
} while (TRUE);
}
/************************
* error entry point *
************************/
error(errnum)
/* Print error message, do appropriate response */
UWORD errnum; /* error number */
{
BSETUP
prt_line("\r\nCP/M Disk $");
switch (errnum)
{
case 0: return( ext_err(TRUE,"read$") );
/* break; */
case 1: return( ext_err(TRUE,"write$") );
/* break; */
case 2: abrt_err("select$");
/* break; */
case 3: return( ext_err(FALSE,"select$") );
/* break; */
case 4: abrt_err("change$");
/* break; */
}
}
/*****************************
* set exception entry point *
*****************************/
setexc(epbp)
/* Set Exception Vector */
REG struct
{
WORD vecnum;
BYTE *newvec;
BYTE *oldvec;
} *epbp;
{
REG WORD i;
BSETUP
i = epbp->vecnum-2;
if ( i==32 || i==33) return(-1);
if ( (30 <= i) && (i <= 37) ) i -= 20;
else if ( (i < 0) || (i > 9) ) return(255);
epbp->oldvec = GBL.excvec[i];
GBL.excvec[i] = epbp->newvec;
return(0);
}
/*****************************
* get/set TPA entry point *
*****************************/
set_tpa(p)
/* Get/Set TPA Limits */
REG struct
{
UWORD parms;
BYTE *low;
BYTE *high;
} *p;
#define set 1
#define sticky 2
{
if (p->parms & set)
{
tpa_lt = p->low;
tpa_ht = p->high;
if (p->parms & sticky)
{
tpa_lp = tpa_lt;
tpa_hp = tpa_ht;
}
}
else
{
p->low = tpa_lt;
p->high = tpa_ht;
}
}
ht;
}
}
ht;
}
}


View File

@@ -0,0 +1,330 @@
/****************************************************************
* *
* CP/M-68K BDOS Disk Read/Write Module *
* *
* This module contains functions to perform sequential *
* or random access read or write to the disk for CP/M-68K *
* *
* It includes the following external functions: *
* *
* bdosrw() - sequential and random disk I/O *
* *
* *
* Compiled with Alcyon C on the VAX *
* *
****************************************************************/
#include "bdosinc.h" /* Standard I/O declarations */
#include "bdosdef.h" /* Type and structure declarations for BDOS */
/* External function definitions */
EXTERN UWORD rdwrt(); /* disk read/write routine */
EXTERN WORD getaloc(); /* allocate a block of disk space */
EXTERN WORD swap(); /* assembly language byte swapper */
EXTERN UWORD dirscan(); /* directory scanning routine */
EXTERN BOOLEAN openfile(); /* open file function passed to dirscan */
EXTERN UWORD close_fi(); /* close file function */
EXTERN BOOLEAN create(); /* create file function passed to dirscan */
EXTERN UWORD ro_err(); /* read-only file error handler */
/* External variable definitions */
EXTERN UWORD ro_dsk; /* read-only disk vector */
/**********************************************************/
/* First, some utility functions used by seqio and ranio */
/**********************************************************/
/******************************
* FCB block number routines *
******************************/
WORD blkindx(fcbp)
/* return index into fcb disk map */
REG struct fcb *fcbp; /* pointer to fcb */
{
REG struct dpb *dparmp; /* pointer to disk parameter block */
REG WORD i;
REG WORD blkshf;
BSETUP
dparmp = GBL.parmp;
blkshf = dparmp->bsh;
i = ((fcbp->extent) & dparmp->exm) << (7 - blkshf);
return (i + (UBWORD(fcbp->cur_rec) >> blkshf) );
}
UWORD blknum(fcbp, index, wrdfcb)
/* return block number in fcb indicated by index */
REG struct fcb *fcbp; /* pointer to fcb */
REG WORD index; /* index into disk map of fcb */
WORD wrdfcb; /* boolean, fcb disk map of words */
{
if (wrdfcb)
return( swap(fcbp->dskmap.big[index]) );
else return( UBWORD(fcbp->dskmap.small[index]) );
}
setblk(fcbp, index, wrdfcb, block)
/* put block number into fcb */
REG struct fcb *fcbp; /* pointer to fcb */
REG WORD index; /* index into disk map of fcb */
WORD wrdfcb; /* boolean, fcb disk map of words */
REG UWORD block; /* block number */
{
fcbp->s2 &= 0x7f; /* set file write flag */
if (wrdfcb)
fcbp->dskmap.big[index] = swap(block);
else fcbp->dskmap.small[index] = (UBYTE)block;
}
/***************************
* disk read/write routine *
***************************/
UWORD do_io(block, rcrd, parm)
UWORD block; /* block number */
UBYTE rcrd; /* record number */
REG WORD parm; /* write parameter */
{
REG LONG lsec;
REG struct dpb *dparmp;
BSETUP
dparmp = GBL.parmp; /* init dpb pointer */
lsec = ((LONG)block << (dparmp->bsh)) +
(LONG)(rcrd & (dparmp->blm));
return( rdwrt(lsec, GBL.dmaadr, parm) );
}
/*******************************************
* routine for crossing extent boundaries *
*******************************************/
WORD new_ext(fcbp, reading, ran)
/* If sequential I/O, open the next extent */
/* If random I/O, compute new extent from random record field */
REG struct fcb *fcbp; /* pointer to fcb */
BOOLEAN reading; /* read/write flag */
WORD ran; /* random I/O flag */
{
REG UBYTE mod; /* module number */
REG UBYTE ext; /* extent number */
REG UBYTE t_mod; /* temp mod number */
REG UBYTE t_ext; /* temp extent */
BSETUP
if (ran)
{
mod = ( (fcbp->ran0) << 4) | ( (fcbp->ran1) >> 4);
ext = ( ((fcbp->ran1) & 0x0f) << 1);
if ((fcbp->ran2) & 0x80) ext |= 1;
/* the calculation of ext was coded this way because of a */
/* compiler bug from Alcyon */
}
else
{
mod = (fcbp->s2) & 0x3f;
ext = (fcbp->extent) + 1; /* for sequential, incr extent */
}
if (ext >= 32)
{
ext = 0;
mod += 1;
}
if (mod >= 64) return(6); /* past maximum file size */
if ( mod == ((fcbp->s2) & 0x3f) )
if ( ! ((ext ^ (fcbp->extent)) & ~((GBL.parmp)->exm) & 0x1f) )
{ /* we're in same logical extent */
fcbp->extent = ext;
return(0);
}
/* Extent or Module numbers don't match */
/* Close the old extent and open a one */
if ( close_fi(fcbp) >= 255 ) return(3);
/* can't close old extent */
t_mod = fcbp->s2;
t_ext = fcbp->extent;
fcbp->s2 = mod;
fcbp->extent = ext;
if ( dirscan(openfile, fcbp, 0) >= 255 ) /* open extent */
{
if (reading)
{ /* reading unwritten extent */
fcbp->s2 = t_mod;
fcbp->extent = t_ext;
return(4);
}
if ( dirscan(create, fcbp, 8) >= 255 )
return(5); /* can't create new extent */
}
return(0);
}
/************************************
* Routine to calculate the maximum *
* extent number of an FCB in a *
* extent-folded environment *
************************************/
UWORD calcext(fcbp)
REG struct fcb *fcbp;
{
REG UWORD i;
REG BYTE *p;
BSETUP
i = 15;
p = &(fcbp->dskmap.small[16]);
do
{
if (*--p) break;
i -= 1;
} while (i);
/* Now i contains the index of the last non-zero block in the FCB */
if ((GBL.parmp)->dsm > 255) i >>= 1;
i >>= 7 - ((GBL.parmp)->bsh);
return ( (fcbp->extent) & ~((GBL.parmp)->exm) & 0x1f | i );
}
/*********************************
* Routine to get the actual *
* record count of the currently *
* active logical extent of a FCB *
*********************************/
UWORD get_rc(fcbp)
REG struct fcb *fcbp;
{
REG UWORD ext;
ext = calcext(fcbp); /* find last active extent in fcb */
if (ext == fcbp->extent) return(UBWORD(fcbp->rcdcnt));
/* if this is the last active fcb, return fcb's rc */
else if (ext > fcbp->extent) return(128);
/* if the fcb has more extents past this one, then */
/* the current one is logically full */
else return (0);
/* if we seeked past the last active extent, rc = 0 */
}
/************************
* bdosrw entry point *
************************/
UWORD bdosrw(fcbp, reading, random)
REG struct fcb *fcbp; /* fcbp is a pointer to a fcb */
REG BOOLEAN reading; /* boolean to tell whether to read or write */
WORD random; /* 0 = sequential, 1 = random (normal), */
/* 2 = random with zero fill */
{
REG UWORD block; /* block number from fcb */
REG WORD index; /* index into disk map of fcb */
REG BYTE *old_dma; /* temp holding spot for dmaadr */
REG WORD parm; /* parameter to do-io */
REG WORD bigfile; /* file system is in word mode */
REG UWORD rtn; /* return parameter */
REG UBYTE rc; /* temp storage for rcdcnt */
BSETUP
bigfile = ((GBL.parmp)->dsm) & ~0xff;
if ( ( ! reading) && (fcbp->ftype[robit] & 0x80) )
ro_err(fcbp,((GBL.dpbp)->dpbp)->drm);
/* check for read-only file */
if (random)
{
if ( rtn = new_ext(fcbp, reading, TRUE) ) return(rtn);
/* open new extent if necessary, return if error */
fcbp->cur_rec = (fcbp->ran2) & 0x7f;
}
else /* sequential */
if (fcbp->cur_rec == 128)
{ /* time to try next extent */
if ( new_ext(fcbp, reading, FALSE) )
return(1); /* if can't open new extent, error */
fcbp->cur_rec = 0; /* opened new extent, zero cur_rec */
}
/* record is now in active fcb */
rc = fcbp->rcdcnt;
if ( UBWORD(fcbp->cur_rec) >= get_rc(fcbp) )
{
if (reading) return(1); /* reading unwritten data */
fcbp->s2 &= 0x7f; /* set file write flag */
rc = fcbp->cur_rec + 1;
}
index = blkindx(fcbp); /* get index into fcb disk map */
block = blknum(fcbp, index, bigfile);
if (block) parm = (reading ? 0 : 1);
else /* if allocated block, parm is just read or write */
{ /* unallocated block */
if (reading) return(1); /* reading unwritten data */
/* Writing to new block */
/* The parm passed to getaloc is the previously allocated block */
/* or 0, if the previous block is not allocated */
block = getaloc(blknum(fcbp, (index ? (index - 1) : 0), bigfile));
if (block == ~0) return(2); /* out of space */
setblk(fcbp, index, bigfile, block);
parm = 3;
if (random == 2)
{ /* Write random with zero fill */
old_dma = GBL.dmaadr;
GBL.dmaadr = GBL.dirbufp; /* Do DMA from dir_buf */
index = SECLEN;
do GBL.dmaadr[--index] = 0;
while (index); /* zero the dma buffer */
for (index = 0; index <= ((GBL.parmp)->blm); index++)
{
do_io(block, (UBYTE)index, parm);
/* write zeros to the block */
parm = 1; /* next write is not to new block */
}
GBL.dmaadr = old_dma; /* restore dma address */
}
}
rtn = do_io(block, fcbp->cur_rec, parm);
if ( rtn == 0 )
{
fcbp->rcdcnt = rc;
if ( ! random ) fcbp->cur_rec += 1;
}
return(rtn);
}
bp->rcdcnt = rc;
if ( ! random ) fcbp->cur_rec += 1;
}
return(rtn);
}
bp->rcdcnt = rc;
if ( ! random ) fcbp->cur_rec += 1;
}
return(rtn);
}
bp->rcdcnt = rc;
if ( ! random ) fcbp->cur_rec += 1;
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,217 @@
*****************************************************************
* *
* COMMAND FILE LOADER FOR CPM68K *
* ============================== *
* *
* (c) COPYRIGHT Digital Research 1983 *
* all rights reserved *
* *
* THIS IS THE DUAL PROCESSOR,ROMABLE CP/M-68K SYSTEM *
* ================================================== *
* *
* Description: *
* ----------- The command file loader is envoked by *
* the CCP after the CCP has successfully *
* opened that file. The loader must *
* call the BDOS to obtain the boundries *
* of the TPA. The load parameter block *
* defined in this loader holds all the *
* memory size and location details. *
* Next the loader returns the system to *
* its original user #. The CCP might *
* have switched to user zero during its *
* search for the file. Next the default *
* dma address is set for the loaded *
* program. Next the command tail is *
* placed,along with the first two parsed *
* fcb's,into the user basepage. *
* Lastly the user stack pointer is set up *
* and the return address is put on the *
* user stack. An RTE transferes control. *
* If a load was not successfull, the *
* appropriate error message is printed. *
* *
* Created by: Tom Saulpaugh *
* *
* Last Modified: 2/17/84 sw 68010 support *
* *
*****************************************************************
.globl _load68k * make this procedure public
.globl _user * global user # before load occured
.globl _cmdfcb * parsed fcb
.globl _tail * global pointer to command tail
.globl _fill_fcb * procedure to fill fcb's
.globl flags * ROM SYSTEM INITIALIZATION
.globl TPAB * ROM SYSTEM INITIALIZATION
.globl gouser *sw 68000/68010 rte routine
reboot = 0
printstr = 9
setdma = 26
chuser = 32
pgmldf = 59
gettpa = 63
_load68k:
*
* Load the 68k file into the TPA
* ------------------------------
*
.text
move.l #TPAB,d1 * move in address of tpa parameter block
move.w #gettpa,d0 * get function number
trap #2 * get the tpa limits
move.l low,lowadr * put it in the lpb
move.l high,hiadr * put high tpa addr in lpb
move.l #_cmdfcb,LPB * get address of opened fcb
move.l #pgmldf,d0 * move in bdos function no
move.l #LPB,d1 * d1 points to load block
trap #2 * do the program load
tst d0 * was the load successful?
bne lderr * if not print error message and return
*
* return to original user #
* -------------------------
move.w _user,d1 * put user # to switch to in d1
move.l #chuser,d0 * put bdos func # in d0
trap #2 * do the user # change
*
* set the default dma address
* ---------------------------
clr.l d1 * clear d1 register
move.l baspag,d1 * d1 points to user base page
add #$80,d1 * d1 points to default dma in base page
movea.l d1,a1 * save it for later use
move #setdma,d0 * move in bdos function no
trap #2 * set the default dma address
*
* move in the command tail
* ------------------------
move.l a1,a2 * save a pointer to the count field
add.l #$01,a1 * point past count field
move.l _tail,a0 * point to command tail
clr.l d0 * clear out d0
mvtail: cmpi.b #$00,(a0) * check for a NULL ending byte
beq done * NULL byte terminates command
cmpi.b #$21,(a0) * check for an '!'
beq done * '!' ends the command
move.b (a0)+,(a1)+ * move a byte of the command tail
addq #1,d0 * bump up the character count
bra mvtail * continue byte move
done: move.b d0,(a2) * put in the character count
move.b #$00,(a1) * terminate cmd tail with a NULL byte
*
* fill fcb1 & fcb2
* ----------------
move.l #_cmdfcb,-(sp) * put address of fcb buffer onto stack
move.w #1,-(sp) * put 1 on stack(parm1)
jsr _fill_fcb * jump to 'C' code & fill cmdfcb with parm1
add.l #6,sp * clean off the stack
clr.l d0 * clear register d0
moveq #$5c,d0 * put basepage address of fcb1 in d0
bsr movfcb * put fcb1 in the basepage
move.l #_cmdfcb,-(sp) * put address of fcb buffer onto stack
move.w #2,-(sp) * put 2 on stack(parm2)
jsr _fill_fcb * jump to 'C' code & fill cmdfcb with parm2
add.l #6,sp * clean off the stack
clr.l d0 * clear register d0
moveq #$38,d0 * put basepage address of fcb1 in d0
bsr movfcb * put fcb2 in the basepage
*
* now push rte stuff on stack
* ---------------------------
movea.l usrstk,a0 * get user stack pointer
move.l baspag,a1 * get basepage address
*sw move.l 8(a1),-(sp) * push address we want to jump to
*sw move sr,d0 * get the status register in d0
*sw andi #$5f00,d0 * mask trace,system bits,user flags
*sw move.w d0,-(sp) * push it on stack
move.l a1,-(a0) * push addr of basepage onto user stack
move.l #cmdrtn,-(a0) * push return address onto user stack
move.l a0,usp * set up user stack pointer
move.l 8(a1),a0 *sw a0 -> User program epa
jmp gouser *sw Jump to exit routine in exceptn.s
*sw rte
*
* load error
* ----------
lderr:
rts * return with error code in d0
cmdrtn:
move #reboot,d0 * reboot CPM
trap #2
movfcb:
add.l baspag,d0 * get offset into basepage
move.l d0,a0 * move address into a0
move.l #_cmdfcb,a1 * a1 points to fcb to be moved
clr.l d0 * clear register d0
moveq #35,d0 * get length of fcb
mov1:
move.b (a1)+,(a0)+ * move a byte into the basepage
dbf d0,mov1 * if not done branch to mov1
rts
.bss
.even
*
* LOAD PARAMETER BLOCK
*
LPB: .ds.l 1
lowadr: .ds.l 1
hiadr: .ds.l 1
baspag: .ds.l 1
usrstk: .ds.l 1
flags: .ds.w 1
*
* TPA Parameter Block
*
.even
TPAB: .ds.w 1
low: .ds.l 1
high: .ds.l 1
.end
high: .ds.l 1
.end
high: .ds.l 1
.end


View File

@@ -0,0 +1,362 @@
/********************************************************
* *
* CP/M-68K BDOS Character I/O Routines *
* *
* This module does BDOS functions 1 thru 11 *
* *
* It contains the following functions which *
* are called from the BDOS main routine: *
* constat(); *
* conin(); *
* tabout(); *
* rawconio(); *
* prt_line(); *
* readline(); *
* *
* Copyright (c) 1982 Digital Research, Inc. *
* *
* Modified 2/5/84 sw Allow typeahead *
* ^C warmboot modifications *
* Again 3/17/84 sw Chain hack *
* *
********************************************************/
#include "bdosinc.h"
#include "bdosdef.h"
#include "biosdef.h"
#define ctrlc 0x03
#define ctrle 0x05
#define ctrlp 0x10
#define ctrlq 0x11
#define ctrlr 0x12
#define ctrls 0x13
#define ctrlu 0x15
#define ctrlx 0x18
#define cr 0x0d
#define lf 0x0a
#define tab 0x09
#define rub 0x7f
#define bs 0x08
#define space 0x20
EXTERN warmboot(); /* External function definition */
/******************/
/* console status */
/******************/
BOOLEAN constat()
{
BSETUP
return( GBL.kbchar ? TRUE : bconstat() );
}
/********************/
/* check for ctrl/s */
/* used internally */
/********************/
conbrk()
{
REG UBYTE ch;
REG BOOLEAN stop;
BSETUP
stop = FALSE;
if ( bconstat() ) do
{
if ( (ch = bconin()) == ctrlc ) warmboot(2); /*sw from (1) */
if ( ch == ctrls ) stop = TRUE;
else if (ch == ctrlq) stop = FALSE;
else if (ch == ctrlp) GBL.lstecho = !GBL.lstecho;
/*sw What Follows is new... */
else /* Insert character in ring buffer */
{ /* */
if(GBL.kbchar < TBUFSIZ) /* Room? */
{ /************************************/
*GBL.insptr++ = ch; /* Yes, insert the character in buff*/
GBL.kbchar++; /* Up count */
} /************************************/
} /* Note if no room, character is */
/* Ignomiously discarded (!) */
/*sw End of new stuff */
/************************************/
} while (stop);
}
/******************/
/* console output */
/* used internally*/
/******************/
conout(ch)
REG UBYTE ch;
{
BSETUP
conbrk(); /* check for control-s break */
bconout(ch); /* output character to console */
if (GBL.lstecho) blstout(ch); /* if ctrl-p on, echo to list dev */
if ((UWORD)ch >= (UWORD)' ')
GBL.column++; /* keep track of screen column */
else if (ch == cr) GBL.column = 0;
else if (ch == bs) GBL.column--;
}
/*************************************/
/* console output with tab expansion */
/*************************************/
tabout(ch)
REG UBYTE ch; /* character to output to console */
{
BSETUP
if (ch == tab) do
conout(' ');
while (GBL.column & 7);
else conout(ch);
}
/*******************************/
/* console output with tab and */
/* control character expansion */
/*******************************/
cookdout(ch)
REG UBYTE ch; /* character to output to console */
{
if (ch == tab) tabout(ch); /* if tab, expand it */
else
{
if ( (UWORD)ch < (UWORD)' ' )
{
conout( '^' );
ch |= 0x40;
}
conout(ch); /* output the character */
}
}
/*****************/
/* console input */
/*****************/
UBYTE getch() /* Get char from buffer or bios */
/* For internal use only */
{
REG UBYTE temp;
BSETUP
if(GBL.kbchar)
{
temp = *GBL.remptr++; /* Fetch the character */
GBL.kbchar--; /* Decrement the count */
if(!GBL.kbchar) /* Gone to zero? */
GBL.remptr = GBL.insptr = &(GBL.t_buff[0]);
return(temp);
}
return( bconin() ); /* else get char from bios */
}
UBYTE conin() /* BDOS console input function */
{
REG UBYTE ch;
BSETUP
conout( ch = getch() );
if (ch == ctrlp) GBL.lstecho = !GBL.lstecho;
return(ch);
}
/******************
* raw console i/o *
******************/
UBYTE rawconio(parm) /* BDOS raw console I/O function */
REG UWORD parm;
{
BSETUP
if (parm == 0xff) return(getch());
else if (parm == 0xfe) return(constat());
else bconout(parm & 0xff);
}
/****************************************************/
/* print line up to delimiter($) with tab expansion */
/****************************************************/
prt_line(p)
REG UBYTE *p;
{
BSETUP
while( *p != GBL.delim ) tabout( *p++ );
}
/**********************************************/
/* read line with editing and bounds checking */
/**********************************************/
/* Two subroutines first */
newline(startcol)
REG UWORD startcol;
{
BSETUP
conout(cr); /* go to new line */
conout(lf);
while(startcol)
{
conout(' ');
startcol -= 1; /* start output at starting column */
}
}
backsp(bufp, col)
/* backspace one character position */
REG struct conbuf *bufp; /* pointer to console buffer */
REG WORD col; /* starting console column */
{
REG UBYTE ch; /* current character */
REG WORD i;
REG UBYTE *p; /* character pointer */
BSETUP
if (bufp->retlen) --(bufp->retlen);
/* if buffer non-empty, decrease it by 1 */
i = UBWORD(bufp->retlen); /* get new character count */
p = &(bufp->cbuf[0]); /* point to character buffer */
while (i--) /* calculate column position */
{ /* across entire char buffer */
ch = *p++; /* get next char */
if ( ch == tab )
{
col += 8;
col &= ~7; /* for tab, go to multiple of 8 */
}
else if ( (UWORD)ch < (UWORD)' ' ) col += 2;
/* control chars put out 2 printable chars */
else col += 1;
}
while (GBL.column > col)
{
conout(bs); /* backspace until we get to proper column */
conout(' ');
conout(bs);
}
}
readline(p) /* BDOS function 10 */
REG struct conbuf *p;
{
REG UBYTE ch;
REG UWORD i;
REG UWORD j;
REG UBYTE *q;
UWORD stcol;
BSETUP
stcol = GBL.column; /* set up starting column */
#ifdef NFG /*sw This didn't work for SUBMIT files...*/
if (GBL.chainp != NULL) /* chain to program code */
{
i = UBWORD(*(GBL.chainp++));
j = UBWORD(p->maxlen);
if (j < i) i = j; /* don't overflow console buffer! */
p->retlen = (UBYTE)i;
q = p->cbuf;
while (i)
{
cookdout( *q++ = *(GBL.chainp++) );
i -= 1;
}
GBL.chainp = NULL;
return;
}
#endif /*sw NFG chain code */
p->retlen = 0; /* start out with empty buffer */
while ( UBWORD(p->retlen) < UBWORD(p->maxlen) )
{ /* main loop for read console buffer */
if ( ((ch=getch()) == ctrlc) && !(p->retlen) )
{
cookdout(ctrlc);
warmboot(2); /*sw From warmboot(1) */
}
else if ( (ch == cr) || (ch == lf) )
{ /* if cr or lf, exit */
conout(cr);
break;
}
else if (ch == bs) backsp(p, stcol); /* backspace */
else if (ch == rub) /* delete character */
{
if (GBL.echodel)
{
if (p->retlen)
{
i = UBWORD(--(p->retlen));
conout( p->cbuf[i] );
}
}
else backsp(p, stcol);
}
else if (ch == ctrlp) GBL.lstecho = !GBL.lstecho;
/* control-p */
else if (ch == ctrlx) /* control-x */
do backsp(p,stcol); while (p->retlen);
else if (ch == ctrle) newline(stcol); /* control-e */
else if (ch == ctrlu) /* control-u */
{
conout('#');
newline(stcol);
p->retlen = 0;
}
else if (ch == ctrlr) /* control-r */
{
conout('#');
newline(stcol);
for (i=0; i < UBWORD(p->retlen); i++)
cookdout( p->cbuf[i] );
}
else /* normal character */
cookdout( p->cbuf[UBWORD((p->retlen)++)] = ch );
}
}
uf[UBWORD((p->retlen)++)] = ch );
}
}
uf[UBWORD((p->retlen)++)] = ch );
}
}


Binary file not shown.

View File

@@ -0,0 +1,304 @@
/****************************************************************
* *
* CP/M-68K BDOS Disk Utilities Module *
* *
* This module contains the miscellaneous utilities *
* for manipulating the disk in CP/M-68K. Included are: *
* *
* dirscan() - general purpose dir scanning *
* setaloc() - set bit in allocation vector *
* clraloc() - clear bit in allocation vector *
* getaloc() - get free allocation block *
* dchksum() - directory checksum calculator *
* dir_rd() - read directory sector *
* dir_wr() - write directory sector *
* rdwrt() - read/write disk sector *
* *
* *
* Configured for Alcyon C on the VAX *
* *
****************************************************************/
#include "bdosinc.h" /* Standard I/O declarations */
#include "bdosdef.h" /* Type and structure declarations for BDOS */
#include "pktio.h" /* Packet I/O definitions */
/* declare external functions and variables */
EXTERN UWORD do_phio(); /* external physical disk I/O routine */
EXTERN UWORD error(); /* external error routine */
EXTERN UWORD log_dsk; /* logged-on disk vector */
EXTERN UWORD ro_dsk; /* read-only disk vector */
EXTERN UWORD crit_dsk; /* critical disk vector */
UBYTE dchksum();
/**********************
* read/write routine *
**********************/
UWORD rdwrt(secnum, dma, parm)
/* General disk sector read/write routine */
/* It simply sets up a I/O packet and sends it to do_phio */
LONG secnum; /* logical sector number to read/write */
UBYTE *dma; /* dma address */
REG WORD parm; /* 0 for read, write parm + 1 for write */
{
struct iopb rwpkt;
BSETUP
rwpkt.devnum = GBL.curdsk; /* disk to read/write */
if (parm)
{
rwpkt.iofcn = (BYTE)write; /* if parm non-zero, we're doing a write */
rwpkt.ioflags = (BYTE)(parm-1); /* pass write parm */
if ( ro_dsk & (1 << (rwpkt.devnum)) ) error(4);
/* don't write on read-only disk */
}
else
{
rwpkt.iofcn = (BYTE)read;
rwpkt.ioflags = (BYTE)0;
}
rwpkt.devadr = secnum; /* sector number */
rwpkt.xferadr = dma; /* dma address */
/* parameters that are currently not used by do_phio
rwpkt.devtype = disk;
rwpkt.xferlen = 1;
*/
rwpkt.infop = GBL.dphp; /* pass ptr to dph */
while ( do_phio(&rwpkt) )
if ( error( parm ? 1 : 0 ) ) break;
return(0);
}
/***************************
* directory read routine *
***************************/
UWORD dir_rd(secnum)
WORD secnum;
{
BSETUP
return( rdwrt((LONG)secnum, GBL.dirbufp, 0) );
}
/****************************
* directory write routine *
****************************/
UWORD dir_wr(secnum)
REG WORD secnum;
{
REG UWORD rtn;
BSETUP
rtn = rdwrt( (LONG)secnum, GBL.dirbufp, 2);
if ( secnum < (GBL.parmp)->cks )
*((GBL.dphp)->csv + secnum) = dchksum();
return(rtn);
}
/*******************************
* directory checksum routine *
*******************************/
UBYTE dchksum()
/* Compute checksum over one directory sector */
/* Note that this implementation is dependant on the representation */
/* of a LONG and is therefore not very portable. But it's fast */
{
REG LONG *p; /* local temp variables */
REG LONG lsum;
REG WORD i;
BSETUP
p = GBL.dirbufp; /* point to directory buffer */
lsum = 0;
i = SECLEN / (sizeof lsum);
do
{
lsum += *p++; /* add next 4 bytes of directory */
i -= 1;
} while (i);
lsum += (lsum >> 16);
lsum += (lsum >> 8);
return( (UBYTE)(lsum & 0xff) );
}
/************************
* dirscan entry point *
************************/
UWORD dirscan(funcp, fcbp, parms)
BOOLEAN (*funcp)(); /* funcp is a pointer to a Boolean function */
REG struct fcb *fcbp; /* fcbp is a pointer to a fcb */
REG UWORD parms; /* parms is 16 bit set of bit parameters */
/* Parms & 1 = 0 to start at beginning of dir, 1 to continue from last */
/* Parms & 2 = 0 to stop when *funcp is true, 1 to go until end */
/* Parms & 4 = 0 to check the dir checksum, 1 to store new checksum */
/* Parms & 8 = 0 to stop at hiwater, 1 to go until end of directory */
#define continue 1
#define full 2
#define initckv 4
#define pasthw 8
{
REG UWORD i; /* loop counter */
REG struct dpb *dparmp; /* pointer to disk parm block */
REG UWORD dirsec; /* sector number we're working on */
REG UWORD rtn; /* return value */
REG UBYTE *p; /* scratch pointer */
REG UWORD bitvec; /* disk nmbr represented as a vector */
BSETUP
dparmp = GBL.parmp; /* init ptr to dpb */
rtn = 255; /* assume it doesn't work */
i = ( (parms & continue) ? GBL.srchpos + 1 : 0 );
while ( (parms & pasthw) || (i <= ((GBL.dphp)->hiwater + 1)) )
{ /* main directory scanning loop */
if ( i > dparmp->drm ) break;
if ( ! (i & 3) )
{ /* inside loop happens when we need to
read another directory sector */
retry: dirsec = i >> 2;
dir_rd(dirsec); /* read the directory sector */
if ( dirsec < (dparmp->cks) ) /* checksumming on this sector? */
{
p = ((GBL.dphp)->csv) + dirsec;
/* point to checksum vector byte */
if (parms & initckv) *p = dchksum();
else if (*p != dchksum())
{ /* checksum error! */
(GBL.dphp)->hiwater = dparmp->drm; /* reset hi water */
bitvec = 1 << (GBL.curdsk);
if (crit_dsk & bitvec) /* if disk in critical mode */
ro_dsk |= bitvec; /* then set it to r/o */
else
{
log_dsk &= ~bitvec; /* else log it off */
seldsk(GBL.curdsk); /* and re-select it */
goto retry; /* and re-do current op */
}
}
}
}
GBL.srchpos = i;
if ( (*funcp)(fcbp, (GBL.dirbufp) + (i&3), i) )
/* call function with parms of (1) fcb ptr,
(2) pointer to directory entry, and
(3) directory index */
{
if (parms & full) rtn = 0; /* found a match, but keep going */
else return(i & 3); /* return directory code */
}
i += 1;
}
return(rtn);
}
/****************************************
* Routines to manage allocation vector *
* setaloc() *
* clraloc() *
* getaloc() *
****************************************/
setaloc(bitnum)
/* Set bit in allocation vector */
REG UWORD bitnum;
{
BSETUP
if (bitnum >= 0 && bitnum <= (GBL.parmp)->dsm)
*((GBL.dphp)->alv + (bitnum>>3)) |= 0x80 >> (bitnum & 7);
}
clraloc(bitnum)
/* Clear bit in allocation vector */
REG UWORD bitnum;
{
BSETUP
if (bitnum > 0 && bitnum <= (GBL.parmp)->dsm)
*((GBL.dphp)->alv + (bitnum>>3)) &= ~(0x80 >> (bitnum & 7));
}
UWORD chkaloc(i)
/* Check bit i in allocation vector */
/* Return non-zero if block free, else return zero */
REG UWORD i;
{
BSETUP
return( ~(*( (GBL.dphp)->alv + (i >> 3) )) & (0x80 >> (i&7)) );
}
UWORD getaloc(leftblk)
/* Get a free block in the file system and set the bit in allocation vector */
/* It is passed the block number of the last block allocated to the file */
/* It tries to allocate the block closest to the block that was passed */
REG UWORD leftblk;
{
REG UWORD blk; /* block number to allocate */
REG UWORD rtblk; /* high block number to try */
REG UWORD diskmax; /* # bits in alv - 1 */
BSETUP
LOCK /* need to lock the file system while messing
with the allocation vector */
diskmax = (GBL.parmp)->dsm;
/* get disk max field from dpb */
rtblk = leftblk;
blk = ~0; /* -1 returned if no free block found */
while (leftblk || rtblk < diskmax)
{
if (leftblk)
if (chkaloc(--leftblk))
{
blk = leftblk;
break;
}
if (rtblk < diskmax)
if (chkaloc(++rtblk))
{
blk = rtblk;
break;
}
}
if (blk != ~0) setaloc(blk);
UNLOCK
return(blk);
}
 UNLOCK
return(blk);
}
 UNLOCK
return(blk);

View File

@@ -0,0 +1,379 @@
*************************************************
* *
* CP/M-68k Basic Disk Operating System *
* Exception Handling Module *
* *
* Version 0.0 -- July 21, 1982 *
* Version 0.1 -- July 25, 1982 *
* Version 0.2 -- October 6, 1982 *
* Version 0.3 -- December 21, 1982 *
* *
* Modified 2/15/84 sw for 68010 support *
* *
*************************************************
.globl _initexc
.globl _tpa_lp
.globl _tpa_hp
.globl gouser *sw RTE routine
bgetseg = 18
bsetexc = 22
buserr = 2
spurious = 24
trap0 = 32
trap2 = 34
trap3 = 35
endvec = 48
_initexc:
* Initialize Exception Vector Handlers
* It has 1 passed parameter: the address of the exception vector array
move #bsetexc,d0
moveq #2,d1
move.l #exchndl,d2
init1:
movem.l d0-d2,-(sp)
trap #3 * BIOS call to set exception vector
movem.l (sp)+,d0-d2
init2: addq #1,d1
add.l #4,d2
cmpi #spurious,d1
bne init3
move #trap0,d1
init3: cmpi #trap2,d1
beq init2 * don't init trap 2 or trap 3
cmpi #trap3,d1
beq init2
cmpi #endvec,d1
blt init1
* initialize the exception vector array
moveq #bgetseg,d0
trap #3 * get the original TPA limits
movea.l d0,a0
tst.w (a0)+
move.l (a0)+,d1 * d1 = original low TPA limit
move.l d1,d2
add.l (a0),d2 * d2 = original high TPA limit
move.l _tpa_lp,d3 * d3 = new low TPA limit
move.l _tpa_hp,d4 * d4 = new high TPA limit
move #17,d0
movea.l 4(sp),a0
move.l a0,evec_adr * save exception vector address
init4:
cmp.l (a0),d1
bhi do_init * if old exception outside orig TPA, clear it
cmp.l (a0),d2
bls do_init
* current exception array entry is in original TPA
cmp.l (a0),d3
bhi dontinit * if old exception in old TPA but outside new
cmp.l (a0),d4 * TPA, don't clear it
bls dontinit
do_init:
clr.l (a0)
dontinit:
tst.l (a0)+
dbf d0,init4
rts
.page
exchndl:.equ *
#ifndef M68010
bsr.w except * 2 Buserr
excrtn0:
bsr.w except * 3 Addressing error
bsr.w except * 4 Illegal Instruction
#else
.globl m68010 * Note case difference!
m68010: * For build process
bsr.w berr * 2 Buserr
excrtn0:
bsr.w berr * 3 Addressing error
bsr.w except * 4 Illegal Instruction
#endif
bsr.w except * 5
bsr.w except * 6
bsr.w except * 7
#ifndef M68010
bsr.w except * 8
#else * Privilege violation
bsr.w privviol * 8
#endif
bsr.w except * 9
bsr.w except * 10
bsr.w except * 11
bsr.w except * 12
bsr.w except * 13
bsr.w except * 14
bsr.w except * 15
bsr.w except * 16
bsr.w except * 17
bsr.w except * 18
bsr.w except * 19
bsr.w except * 20
bsr.w except * 21
bsr.w except * 22
bsr.w except * 23
bsr.w except * 24
bsr.w except * 25
bsr.w except * 26
bsr.w except * 27
bsr.w except * 28
bsr.w except * 29
bsr.w except * 30
bsr.w except * 31
bsr.w except * 32
bsr.w except * 33
bsr.w except * 34
bsr.w except * 35
bsr.w except * 36
bsr.w except * 37
bsr.w except * 38
bsr.w except * 39
.page
#ifdef M68010
*
* Here if the exception in question was a buserr/addressing error.
* We reformat the stack to look like a 68000.
*
* Entered with a standard 68010 exception stack frame with a return
* address on top (at 0(sp)).
*
berr:
move.l $0(sp),$2a(sp) * Move return address
move.w $0c(sp),$2e(sp) * Move Status word
andi.w #7,$2e(sp) * Clear all but FC0-2
move.l $0e(sp),$30(sp) * Copy Fault address
move.w $1c(sp),$34(sp) * Move IR
move.w $4(sp),$36(sp) * Move SR
move.l $6(sp),$38(sp) * Move PC
move.w $0a(sp),$3c(sp) * Move format word
adda.l #$2a,sp * Make sp -> new frame
bra except * Merge
******************************************************************************
* Here we make up for a faux pas in the C compiler. Change all *
* move from SR instructions ($40CX) to move from CCR ($42CX). *
* Precludes executing 68000 programs in ROM on a 68010. *
* *
* Relies on the fact that the exception PC (Stack offset 0E below) *
* points to the instruction on an illegal instruction exception. *
******************************************************************************
privviol:
movem.l d0/a0,-(sp) * Save some regs
move.l $0e(sp),a0 * A0 -> Instruction
move.w (a0),d0 * d0 = Instruction
andi.w #$FFC0,d0 * Mask off <EA> field
cmpi.w #$40C0,d0 * Move from SR?
bne notsr * No, handle normally
ori.w #$0200,(a0) * Change to move from CCR
movem.l (sp)+,d0/a0 * Restore regs
tst.l (sp)+ * Pop return address
rte * Try it again
notsr: movem.l (sp)+,d0/a0 * Abandon hope, all ye ..
.page
#endif
except:
clr.w -(sp)
movem.l a0/d0,-(sp) * 10 (11) words now on stack in following order
* _______________________________
* |____________D0.L_______________|
* |____________A0.L_______________|
* |____0000______|________________
* |_______Handler Return__________|
* If bus error, extra 2 longs are here
* ______________
* |__Status Reg__|________________
* |_____Exception Return__________|
* |_(format word)|
move.l 10(sp),d0 * get return address from above array
sub.l #excrtn0,d0 * d0 now has 4 * (encoded excptn nmbr), where
* encoded excptn nmbr is in [0..21,22..37]
* representing [2..23,32..47]
cmpi #36,d0 * if d0/4 is in [0..9,22..29] then
ble chkredir * the exception may be redirected
cmpi #88,d0
blt dfltexc
cmpi #116,d0
bgt dfltexc
* in range of redirected exceptions
subi #48,d0 * subtract 4*12 to normalize [0..9,22..29]
* into [0..9,10..17]
chkredir:
movea.l evec_adr,a0
adda d0,a0 * index into exception vector array
tst.l (a0) * if 00000000, then not redirected
bne usrexc
* not redirected, do default handler
supexc: * Here for supervisor state
cmpi #40,d0
blt dfltexc
addi #48,d0 * add 4*12 that was sub'd above
dfltexc:
adda #14,sp * throw away 7 words that we added to stack
asr #2,d0 * divide d0 by 4
* now d0 is in [0..21,22..37]
* to represent [2..23,32..47]
cmpi #2,d0 * bus or address error?
bge nobusexc
movem.l (sp)+,a0-a1 * if yes, throw away 4 words from stack
nobusexc:
tst.w (sp)+ * throw away stacked SR
addi #2,d0
cmpi #23,d0 * get back real excptn nmbr in [2..23,32..47]
ble lowexc
addi #8,d0
lowexc: move d0,-(sp) * save excptn nmbr
lea excmsg1,a0
bsr print * print default exception message
move (sp)+,d0
bsr prtbyte
lea excmsg2, a0
bsr print
move.l (sp)+,d0
bsr prtlong
lea excmsg3, a0
bsr print
clr.l d0
trap #2 * warm boot
rte
usrexc:
* Call user exception handler
* make sure exception information is on his stack
cmpi #8,d0 * address or bus error?
blt addrexc * if yes, skip
btst #13,14(sp) * exception occured in user state?
bne supexc *sw if no, go to supervisor handler
move.l (a0),10(sp) * put user handler address on our stack
move.l usp,a0 * user stack pointer to a0
move.l 16(sp),-(a0) * put exception return on user stack
move.w 14(sp),-(a0) * put SR on user stack
move.l a0,usp * update user stack pointer
movem.l (sp)+,a0/d0 * restore regs
move.l 2(sp),8(sp) * move address of user handler to excptn rtn
#ifdef M68010
clr.w 12(sp) *sw Clear out the format word
#endif
addq #6,sp * clear junk from stack
andi #$7fff,(sp) * clear trace bit
rte * go to user handler
addrexc:
btst #13,22(sp) * exception occured in user state?
bne supexc *sw if no, go to supervisor handler
move.l (a0),10(sp) * put user handler address on our stack
move.l usp,a0 * user stack pointer to a0
move.l 24(sp),-(a0) * put exception return on user stack
move.w 22(sp),-(a0) * put SR on user stack
move.l 18(sp),-(a0) * put extra 2 longs on user stack
move.l 14(sp),-(a0)
move.l a0,usp * update user stack pointer
movem.l (sp)+,a0/d0 * restore regs
move.l 2(sp),16(sp) * move address of user handler to excptn rtn
#ifdef M68010
clr.w 20(sp) *sw Clear format word
#endif
adda #14,sp * clear junk from stack
andi #$7fff,(sp) * clear trace bit
rte * go to user handler
.page
*******************************************************************************
*
* gouser routine. This routine performs an RTE to go to the user program
* User EPA is passed in A0.L.
*
*******************************************************************************
gouser:
#ifdef M68010
clr.w -(sp) * Push format word
#endif
move.l a0,-(sp) * Push epa
clr.w -(sp) * and SR
rte * Do it. Into user program.
.page
*
* Subroutines
*
print:
clr.l d1
move.b (a0)+, d1
beq prtdone
move #2, d0
trap #2
bra print
prtdone:
rts
prtlong:
* Print d0.l in hex format
move d0,-(sp)
swap d0
bsr prtword
move (sp)+,d0
prtword:
* Print d0.w in hex format
move d0,-(sp)
lsr #8,d0
bsr prtbyte
move (sp)+,d0
prtbyte:
* Print d0.b in hex format
move d0,-(sp)
lsr #4,d0
bsr prtnib
move (sp)+,d0
prtnib:
andi #$f,d0
cmpi #10,d0
blt lt10
addi.b #'A'-'9'-1,d0
lt10:
addi.b #'0',d0
move d0,d1
move #2,d0
trap #2
rts
.data
excmsg1:
.dc.b 13,10,10,'Exception $',0
excmsg2:
.dc.b ' at user address $',0
excmsg3:
.dc.b '. Aborted.',0
.bss
evec_adr:
.ds.l 1
.end
0
excmsg2:
.dc.b ' at user address $',0
excmsg3:
.dc.b '. Aborted.',0
.bss
evec_adr:
.ds.l 1
.end


View File

@@ -0,0 +1,669 @@
/****************************************************************
* *
* CP/M-68K BDOS File I/O Module *
* *
* This module contains all file handling BDOS functions *
* except for read and write for CP/M-68K. Included are: *
* *
* seldsk() - select disk *
* openfile() - open file *
* close_fi() - close file *
* search() - search for first/next file match *
* create() - create file *
* delete() - delete file *
* rename() - rename file *
* set_attr() - set file attributes *
* getsize() - get file size *
* setran() - set random record field *
* free_sp() - get disk free space *
* move() - general purpose byte mover *
* *
* *
* Compiled with Alcyon C on the VAX *
* *
* Modified 2/5/84 sw Allow odd DMA on get free space *
* *
****************************************************************/
#include "bdosinc.h" /* Standard I/O declarations */
#include "bdosdef.h" /* Type and structure declarations for BDOS */
#include "pktio.h" /* Packet I/O definitions */
/* declare external fucntions */
EXTERN UWORD dirscan(); /* directory scanning routine */
EXTERN UWORD error(); /* disk error routine */
EXTERN UWORD ro_err(); /* read-only file error routine */
EXTERN UWORD do_phio(); /* packet disk i/o handler */
EXTERN clraloc(); /* clear bit in allocation vector */
EXTERN setaloc(); /* set bit in allocation vector */
EXTERN UWORD swap(); /* assembly language byte swapper */
EXTERN UWORD dir_wr(); /* directory write routine */
EXTERN tmp_sel(); /* temporary select disk routine */
EXTERN UWORD calcext(); /* calc max extent allocated for fcb */
EXTERN UWORD udiv(); /* unsigned divide routine */
/* declare external variables */
EXTERN UWORD log_dsk; /* logged-on disk vector */
EXTERN UWORD ro_dsk; /* read-only disk vector */
EXTERN UWORD crit_dsk; /* vector of disks in critical state */
/************************************
* This function passed to dirscan *
* from seldsk (below) *
************************************/
BOOLEAN alloc(fcbp, dirp, dirindx)
/* Set up allocation vector for directory entry pointed to by dirp */
struct fcb *fcbp; /* not used in this function */
REG struct dirent *dirp; /* pointer to directory entry */
WORD dirindx; /* index into directory for *dirp */
{
REG WORD i; /* loop counter */
BSETUP
if ( UBWORD(dirp->entry) < 0x10 ) /* skip MP/M 2.x and CP/M 3.x XFCBs */
{
(GBL.dphp)->hiwater = dirindx; /* set up high water mark for disk */
i = 0;
if ((GBL.parmp)->dsm < 256)
{
do setaloc( UBWORD(dirp->dskmap.small[i++]) );
while (i <= 15);
}
else
{
do setaloc(swap(dirp->dskmap.big[i++]));
while (i <= 7);
}
}
}
/************************
* seldsk entry point *
************************/
seldsk(dsknum)
REG UBYTE dsknum; /* disk number to select */
{
struct iopb selpkt;
REG WORD i;
UWORD j;
REG UBYTE logflag;
BSETUP
logflag = ~(log_dsk >> dsknum) & 1;
if ((GBL.curdsk != dsknum) || logflag)
{ /* if not last used disk or not logged on */
selpkt.iofcn = sel_info;
GBL.curdsk = (selpkt.devnum = dsknum);
if (UBWORD(dsknum) > 15) error(2);
selpkt.ioflags = logflag ^ 1;
do
{
do_phio(&selpkt); /* actually do the disk select */
if ( (GBL.dphp = selpkt.infop) != NULL ) break;
} while ( ! error(3) );
GBL.dirbufp = (GBL.dphp)->dbufp;
/* set up GBL copies of dir_buf and dpb ptrs */
GBL.parmp = (GBL.dphp)->dpbp;
}
if (logflag)
{ /* if disk not previously logged on, do it now */
LOCK /* must lock the file system while messing with alloc vec */
i = (GBL.parmp)->dsm;
do clraloc(i); while (i--); /* clear the allocation vector */
i = udiv( (LONG)(((GBL.parmp)->drm) + 1),
4 * (((GBL.parmp)->blm) + 1), &j);
/* calculate nmbr of directory blks */
if (j) i++; /* round up */
do setaloc(--i); while (i); /* alloc directory blocks */
dirscan(alloc, NULL, 0x0e); /* do directory scan & alloc blocks */
log_dsk |= 1 << dsknum; /* mark disk as logged in */
}
}
/*******************************
* General purpose byte mover *
*******************************/
move(p1, p2, i)
REG BYTE *p1;
REG BYTE *p2;
REG WORD i;
{
while (i--)
*p2++ = *p1++;
}
/*************************************
* General purpose filename matcher *
*************************************/
BOOLEAN match(p1, p2, chk_ext)
REG UBYTE *p1;
REG UBYTE *p2;
BOOLEAN chk_ext;
{
REG WORD i;
REG UBYTE temp;
BSETUP
i = 12;
do
{
temp = (*p1 ^ '?');
if ( ((*p1++ ^ *p2++) & 0x7f) && temp )
return(FALSE);
i -= 1;
} while (i);
if (chk_ext)
{
if ( (*p1 != '?') && ((*p1 ^ *p2) & ~((GBL.parmp)->exm)) )
return(FALSE);
p1 += 2;
p2 += 2;
if ((*p1 ^ *p2) & 0x3f) return(FALSE);
}
return(TRUE);
}
/************************
* openfile entry point *
************************/
BOOLEAN openfile(fcbp, dirp, dirindx)
REG struct fcb *fcbp; /* pointer to fcb for file to open */
struct dirent *dirp; /* pointer to directory entry */
WORD dirindx;
{
REG UBYTE fcb_ext; /* extent field from fcb */
REG BOOLEAN rtn;
BSETUP
if ( rtn = match(fcbp, dirp, TRUE) )
{
fcb_ext = fcbp->extent; /* save extent number from user's fcb */
move(dirp, fcbp, sizeof *dirp);
/* copy dir entry into user's fcb */
fcbp->extent = fcb_ext;
fcbp->s2 |= 0x80; /* set hi bit of S2 (write flag) */
crit_dsk |= 1 << (GBL.curdsk);
}
return(rtn);
}
/*************************/
/* flush buffers routine */
/*************************/
UWORD flushit()
{
REG UWORD rtn; /* return code from flush buffers call */
struct iopb flushpkt; /* I/O packet for flush buffers call */
flushpkt.iofcn = flush;
while ( rtn = do_phio(&flushpkt) )
if ( error(1) ) break;
return(rtn);
}
/*********************************
* file close routine for dirscan *
*********************************/
BOOLEAN close(fcbp, dirp, dirindx)
REG struct fcb *fcbp; /* pointer to fcb */
REG struct dirent *dirp; /* pointer to directory entry */
WORD dirindx; /* index into directory */
{
REG WORD i;
REG UBYTE *fp;
REG UBYTE *dp;
REG UWORD fcb_ext;
REG UWORD dir_ext;
BSETUP
if ( match(fcbp, dirp, TRUE) )
{ /* Note that FCB merging is done here as a final
confirmation that disks haven't been swapped */
LOCK
fp = &(fcbp->dskmap.small[0]);
dp = &(dirp->dskmap.small[0]);
if ((GBL.parmp)->dsm < 256)
{ /* Small disk map merge routine */
i = 16;
do
{
if (*dp)
{
if (*fp)
{
if (*dp != *fp) goto badmerge;
}
else *fp = *dp;
}
else *dp = *fp;
fp += 1;
dp += 1;
i -= 1;
} while (i);
}
else
{ /* Large disk map merge routine */
i = 8;
do
{
if (*(UWORD *)dp)
{
if (*(UWORD *)fp)
{
if (*(UWORD *)dp != *(UWORD *)fp) goto badmerge;
}
else *(UWORD *)fp = *(UWORD *)dp;
}
else *(UWORD *)dp = *(UWORD *)fp;
(UWORD *)fp += 1;
(UWORD *)dp += 1;
i -= 1;
} while (i);
}
/* Disk map merging complete */
fcb_ext = calcext(fcbp); /* calc max extent for fcb */
dir_ext = (UWORD)(dirp->extent) & 0x1f;
if ( (fcb_ext > dir_ext) ||
((fcb_ext == dir_ext) &&
(UBWORD(fcbp->rcdcnt) > UBWORD(dirp->rcdcnt))) )
/* if fcb points to larger file than dirp */
{
dirp->rcdcnt = fcbp->rcdcnt; /* set up rc, ext from fcb */
dirp->extent = (BYTE)fcb_ext;
}
dirp->s1 = fcbp->s1;
if ( (dirp->ftype[robit]) & 0x80) ro_err(fcbp,dirindx);
/* read-only file error */
dirp->ftype[arbit] &= 0x7f; /* clear archive bit */
dir_wr(dirindx >> 2);
UNLOCK
return(TRUE);
badmerge:
UNLOCK
ro_dsk |= (1 << GBL.curdsk);
return(FALSE);
}
else return(FALSE);
}
/************************
* close_fi entry point *
************************/
UWORD close_fi(fcbp)
struct fcb *fcbp; /* pointer to fcb for file to close */
{
flushit(); /* first, flush the buffers */
if ((fcbp->s2) & 0x80) return(0); /* if file write flag not on,
don't need to do physical close */
return( dirscan(close, fcbp, 0)); /* call dirscan with close function */
}
/************************
* search entry point *
************************/
/* First two functions for dirscan */
BOOLEAN alltrue(p1, p2, i)
UBYTE *p1;
UBYTE *p2;
WORD i;
{
return(TRUE);
}
BOOLEAN matchit(p1, p2, i)
UBYTE *p1;
UBYTE *p2;
WORD i;
{
return(match(p1, p2, TRUE));
}
/* search entry point */
UWORD search(fcbp, dsparm, p)
REG struct fcb *fcbp; /* pointer to fcb for file to search */
REG UWORD dsparm; /* parameter to pass through to dirscan */
UBYTE *p; /* pointer to pass through to tmp_sel */
{
REG UWORD rtn; /* return value */
BSETUP
if (fcbp->drvcode == '?')
{
seldsk(GBL.dfltdsk);
rtn = dirscan(alltrue, fcbp, dsparm);
}
else
{
tmp_sel(p); /* temporarily select disk */
if (fcbp->extent != '?') fcbp->extent = 0;
fcbp->s2 = 0;
rtn = dirscan(matchit, fcbp, dsparm);
}
move( GBL.dirbufp, GBL.dmaadr, SECLEN);
return(rtn);
}
/************************
* create entry point *
************************/
BOOLEAN create(fcbp, dirp, dirindx)
REG struct fcb *fcbp; /* pointer to fcb for file to create */
REG struct dirent *dirp; /* pointer to directory entry */
REG WORD dirindx; /* index into directory */
{
REG BYTE *p;
REG WORD i;
REG BOOLEAN rtn;
BSETUP
if ( rtn = ((dirp->entry) == 0xe5) )
{
p = &(fcbp->rcdcnt);
i = 17;
do
{ /* clear fcb rcdcnt and disk map */
*p++ = 0;
i -= 1;
} while (i);
move(fcbp, dirp, sizeof *dirp); /* move the fcb to the directory */
dir_wr(dirindx >> 2); /* write the directory sector */
if ( dirindx > (GBL.dphp)->hiwater )
(GBL.dphp)->hiwater = dirindx;
crit_dsk |= 1 << (GBL.curdsk);
}
return(rtn);
}
/************************
* delete entry point *
************************/
BOOLEAN delete(fcbp, dirp, dirindx)
REG struct fcb *fcbp; /* pointer to fcb for file to delete */
REG struct dirent *dirp; /* pointer to directory entry */
REG WORD dirindx; /* index into directory */
{
REG WORD i;
REG BOOLEAN rtn;
BSETUP
if ( rtn = match(fcbp, dirp, FALSE) )
{
if ( (dirp->ftype[robit]) & 0x80 ) ro_err(fcbp,dirindx);
/* check for read-only file */
dirp->entry = 0xe5;
LOCK
dir_wr(dirindx >> 2);
/* Now free up the space in the allocation vector */
if ((GBL.parmp)->dsm < 256)
{
i = 16;
do clraloc(UBWORD(dirp->dskmap.small[--i]));
while (i);
}
else
{
i = 8;
do clraloc(swap(dirp->dskmap.big[--i]));
while (i);
}
UNLOCK
}
return(rtn);
}
/************************
* rename entry point *
************************/
BOOLEAN rename(fcbp, dirp, dirindx)
REG struct fcb *fcbp; /* pointer to fcb for file to delete */
REG struct dirent *dirp; /* pointer to directory entry */
REG WORD dirindx; /* index into directory */
{
REG UWORD i;
REG BYTE *p; /* general purpose pointers */
REG BYTE *q;
REG BOOLEAN rtn;
BSETUP
if ( rtn = match(fcbp, dirp, FALSE) )
{
if ( (dirp->ftype[robit]) & 0x80 ) ro_err(fcbp,dirindx);
/* check for read-only file */
p = &(fcbp->dskmap.small[1]);
q = &(dirp->fname[0]);
i = 11;
do
{
*q++ = *p++ & 0x7f;
i -= 1;
} while (i);
dir_wr(dirindx >> 2);
}
return(rtn);
}
/************************
* set_attr entry point *
************************/
BOOLEAN set_attr(fcbp, dirp, dirindx)
REG struct fcb *fcbp; /* pointer to fcb for file to delete */
REG struct dirent *dirp; /* pointer to directory entry */
REG WORD dirindx; /* index into directory */
{
REG BOOLEAN rtn;
BSETUP
if ( rtn = match(fcbp, dirp, FALSE) )
{
move(&fcbp->fname[0], &dirp->fname[0], 11);
dir_wr(dirindx >> 2);
}
return(rtn);
}
/****************************
* utility routine used by *
* setran and getsize *
****************************/
LONG extsize(fcbp)
/* Return size of extent pointed to by fcbp */
REG struct fcb *fcbp;
{
return( ((LONG)(fcbp->extent & 0x1f) << 7)
| ((LONG)(fcbp->s2 & 0x3f) << 12) );
}
/************************
* setran entry point *
************************/
setran(fcbp)
REG struct fcb *fcbp; /* pointer to fcb for file to set ran rec */
{
struct
{
BYTE b3;
BYTE b2;
BYTE b1;
BYTE b0;
};
LONG random;
random = (LONG)UBWORD(fcbp->cur_rec) + extsize(fcbp);
/* compute random record field */
fcbp->ran0 = random.b2;
fcbp->ran1 = random.b1;
fcbp->ran2 = random.b0;
}
/**********************************/
/* fsize is a funtion for dirscan */
/* passed from getsize */
/**********************************/
BOOLEAN fsize(fcbp, dirp, dirindx)
REG struct fcb *fcbp; /* pointer to fcb for file to delete */
REG struct dirent *dirp; /* pointer to directory entry */
WORD dirindx; /* index into directory */
{
REG BOOLEAN rtn;
struct
{
BYTE b3;
BYTE b2;
BYTE b1;
BYTE b0;
};
LONG temp;
if ( rtn = match(fcbp, dirp, FALSE) )
{
temp = (LONG)UBWORD(dirp->rcdcnt) + extsize(dirp);
/* compute file size */
fcbp->ran0 = temp.b2;
fcbp->ran1 = temp.b1;
fcbp->ran2 = temp.b0;
}
return(rtn);
}
/************************
* getsize entry point *
************************/
getsize(fcbp)
/* get file size */
REG struct fcb *fcbp; /* pointer to fcb to get file size for */
{
LONG maxrcd;
LONG temp;
REG WORD dsparm;
struct
{
BYTE b3;
BYTE b2;
BYTE b1;
BYTE b0;
};
maxrcd = 0;
dsparm = 0;
temp = 0;
while ( dirscan(fsize, fcbp, dsparm) < 255 )
{ /* loop until no more matches */
temp.b2 = fcbp->ran0;
temp.b1 = fcbp->ran1;
temp.b0 = fcbp->ran2;
if (temp > maxrcd) maxrcd = temp;
dsparm = 1;
}
fcbp->ran0 = maxrcd.b2;
fcbp->ran1 = maxrcd.b1;
fcbp->ran2 = maxrcd.b0;
}
/************************
* free_sp entry point *
************************/
free_sp(dsknum)
UBYTE dsknum; /* disk number to get free space of */
{
REG LONG records;
REG UWORD *alvec;
REG UWORD bitmask;
REG UWORD alvword;
REG WORD i;
LONG temp; /*sw For DMA Odd problem */
BSETUP
seldsk(dsknum); /* select the disk */
records = (LONG)0; /* initialize the variables */
alvec = (GBL.dphp)->alv;
bitmask = 0;
for (i = 0; i <= (GBL.parmp)->dsm; i++) /* for loop to compute */
{
if ( ! bitmask)
{
bitmask = 0x8000;
alvword = ~(*alvec++);
}
if ( alvword & bitmask)
records += (LONG)( ((GBL.parmp)->blm) + 1 );
bitmask >>= 1;
}
temp = records; /*sw Put in memory */
move(&temp,GBL.dmaadr,sizeof(LONG)); /*sw Move to user's DMA */
}
ory */
move(&temp,GBL.dmaadr,sizeof(LONG)); /*sw Move to user's DMA */
}
ory */
move(&temp,GBL.dmaadr,sizeof(LONG)); /*sw Move to user's DMA */
}


Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More