Files
Digital-Research-Source-Code/MPM OPERATING SYSTEMS/MPM-86/MISC DRI DISKS/04/CLIB.ARC
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

1738 lines
38 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

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

-ARCHIVE- $main.a86 2887
title 'c86 basic support package'
pagesize 51
; 7/28/81
;notes
; the first 4 words of usable ds space contain
;
; 100h The address of the first byte of uninitialised global storage
; 102h The address of the last+1 byte of uninitialized global stor
; 104h The minimum number of reserved bytes between top of heap and
; the bottom of the system stack
; 106h The address of the next available cell to add to the heap
; Note that this value is biased up by (104h) for
; efficient testing at run time.
DEFGBL equ 91h ;define a global
REFGBL equ 0a1h ;refer to a global
cseg
; $main entry point for c programs
dollar_main:
mov ax,ds
mov ss,ax ;set up the stack
mov es,ax ;just in case
mov sp,.6 ;get stack top value
mov bp,sp ;set the base pointer too
; set up the reverved bytes value
; and the heap top value
mov ax,128 ;default reserved bytes
mov .260,ax ;save for program use
add ax,.258 ;s-break value
mov .262,ax ;save for later
; clear the uninitialized global storage region
cld ;to go up
mov di,.256 ;get start of static uninitialised area
mov cx,.258 ;get end address +1 of static uninit
sub cx,di ;number of bytes in area
xor ax,ax ;zero ax
rep stos al ;clear the area
; call the routine _main to do other initialisation
umain equ $+1
call dollar_main ;enter c system at '_main'
; _exit abort exit point for c programs
under_exit:
mov cl,0
mov dl,cl
int 224 ;we are finished
; set up on entry to a function
dollar_entry0:
pop si ;get address we came from
push bp ;save frame pointer
mov bp,sp ;get new frame pointer
cmp sp,.262 ;how is heap space
jbe heap_error ;crash
jmp si ;go to program
dollar_entry1:
pop si ;get address we came from
push bp ;save frame pointer
mov bp,sp ;get new frame pointer
cld
db 2eh ;seg override prefix to cs:
lods al ;get offset
mov ah,0 ;as a word value
sub sp,ax ;adjust stack
cmp sp,.262 ;how is heap space
jbe heap_error ;crash
jmp si ;go to program
dollar_entry2:
pop si ;get address we came from
push bp ;save frame pointer
mov bp,sp ;get new frame pointer
cld
db 2eh ;seg override prefix to cs:
lods ax ;get the offset
sub sp,ax ;adjust stack
cmp sp,.262 ;how is heap space
jbe heap_error ;crash
jmp si ;go to program
; a heap error has occured
heap_error:
mov sp,bp ;reset the stack pointer
sub sp,2 ;save the base pointer
mov ax,8000h ;set error flag
push ax
jmps under_exit ;go to the exit mechanism
; define the addresses to relocate in the above code
eseg
dw dollar_main
db DEFGBL,'$main',0
dw under_exit
db DEFGBL,'_exit',0
dw dollar_entry0
db DEFGBL,'$entry0',0
dw dollar_entry1
db DEFGBL,'$entry1',0
dw dollar_entry2
db DEFGBL,'$entry2',0
dw umain
db REFGBL,'_main',0
dw 0,0
end
-ARCHIVE- \cpmread.c 2171
/* read characters from cp/m
*/
/* define the cp/m86 file control block
*/
struct cpmfcb
{
char dr; /* drive specification */
char fn[8]; /* the file name */
char fe[3]; /* the file extent */
char ex; /* the current extent number */
char s1; /* cp/m use */
char s2; /* cp/m use */
char rc; /* record count */
char dn[16]; /* cp/m use */
char cr; /* current record */
unsigned rr; /* random record number */
char ro; /* random record overflow */
};
struct bufstr
{
char *bfcb; /* really struct pointer to cp/m fcb block */
char basc; /* true if ascii data in file */
unsigned bsize; /* size of the buffer in bytes */
unsigned bsec; /* the first cp/m record in the buffer */
int bptr; /* next character to be read/written */
int bcnt; /* the number of characters in buffer */
char bmode; /* the open mode */
char bdirty; /* data in the buffer to write */
char blff; /* next character read will be a l/f */
char bdata[1]; /* the data itself */
};
#define SZBUFSTR 15
#define SECSIZE 128 /* size of cp/m sector */
#define NUMBSEC 8 /* number of sectors in buffer */
#define MAXFILES 8
extern char *_opentab[MAXFILES];
/* fill a buffer
*/
_cpmread(buf)
struct bufstr *buf;
{
int j;
unsigned status;
if(buf->bfcb<256){
buf->bptr=0;
buf->bcnt=1;
if(buf->blff){
buf->blff=0;
buf->bdata[0]='\n';
}
else {
buf->bdata[0]=bdos(buf->bfcb-1,0)&0x7f; /* strip parity */
if(buf->bdata[0]=='\r')buf->blff=1; /* next one out is a l/f */
if(buf->bdata[0]==26)buf->bptr=0; /* end of file */
}
return;
}
/* its a disk read */
buf->bsec+=((buf->bcnt+(SECSIZE-1))/SECSIZE); /* select sector to read */
for(j=0;j<NUMBSEC;++j){
bdos(0x1a,buf->bdata+(j*SECSIZE)); /* set transfer address */
buf->bfcb->rr=buf->bsec+j; /* set sector number */
status=bdos(0x21,buf->bfcb)&0xff; /* do the read */
if(status==3 || status>4)exit(0xff); /* terminal error */
if(status)break;
}
buf->bcnt=j*SECSIZE;
buf->bptr=0; /* no chars read yet */
}
-ARCHIVE- \cpmwrit.c 1885
/* write characters to a file
*/
/* define the cp/m86 file control block
*/
struct cpmfcb
{
char dr; /* drive specification */
char fn[8]; /* the file name */
char fe[3]; /* the file extent */
char ex; /* the current extent number */
char s1; /* cp/m use */
char s2; /* cp/m use */
char rc; /* record count */
char dn[16]; /* cp/m use */
char cr; /* current record */
unsigned rr; /* random record number */
char ro; /* random record overflow */
};
struct bufstr
{
char *bfcb; /* really struct pointer to cp/m fcb block */
char bfd; /* fd for this file */
unsigned bsize; /* size of the buffer in bytes */
unsigned bsec; /* the first cp/m record in the buffer */
int bptr; /* next character to be read/written */
int bcnt; /* the number of characters in buffer */
char bmode; /* the open mode */
char bdirty; /* data in the buffer to write */
char blff; /* next character read will be a l/f */
char bdata[1]; /* the data itself */
};
#define SZBUFSTR 15
#define SECSIZE 128 /* size of cp/m sector */
#define NUMBSEC 8 /* number of sectors in buffer */
#define MAXFILES 8
extern char *_opentab[MAXFILES];
/* empty a buffer
*/
_cpmwrite(buf)
struct bufstr *buf;
{
int j;
unsigned status;
if(buf->bdirty){
if(buf->bfcb>255){ /* disk file if not zero */
for(j=0;j*SECSIZE<buf->bcnt;++j){
bdos(0x1a,buf->bdata+(j*SECSIZE)); /* set transfer address */
buf->bfcb->rr=buf->bsec++; /* set sector number */
status=bdos(0x22,buf->bfcb)&0xff; /* do the write */
if(status)exit(0x80ff); /* terminal error */
}
}
else { /* character device */
bdos(buf->bfcb,buf->bdata[0]);
}
}
buf->bcnt=0;
buf->bptr=0;
buf->bdirty=0;
setmem(buf->bdata,buf->bsize,0x1a); /* force buffer to EOF */
}
-ARCHIVE- \main.c 1068
/* _main 7/20/81
*/
/* set up arguments from input command line
*/
#define MAXARG 20
#define STDIN 1
#define STDOUT 2
_main()
{
char *cp,*cp1,*cp2,j,k,argc,*argv[MAXARG];
cp=0x80; /* get address of cp/m input line */
j=*cp++; /* get number of characters in command line */
argv[0]=cp1=sbrk(j+2); /* a place to build arg list(s) */
open("con:",0); /* open STDIN */
open("con:",1); /* open STDOUT */
open("con:",1); /* open STDERR */
*cp1++='c';
*cp1++=0;
for(argc=1;argc<MAXARG;){
while(j && (*cp==' ' || *cp=='\t')){
--j;
++cp;
}
if(!j)break;
argv[argc]=cp2=cp1;
while(j && *cp!=' ' && *cp!='\t'){
--j;
k=*cp++;
if(k>='A' && k<='Z')k+=0x20;
*cp1++=k;
}
*cp1++=0;
if(*cp2=='<'){ /* redirect input */
close(STDIN);
open(cp2+1,0);
}
else if(*cp2=='>'){ /* redirect output */
close(STDOUT);
creat(cp2+1,1);
}
else ++argc; /* count the argument */
}
exit(main(argc,argv));
}
-ARCHIVE- \open.c 2706
/* common open routine
*/
/* define the cp/m86 file control block
*/
struct cpmfcb
{
char dr; /* drive specification */
char fn[8]; /* the file name */
char fe[3]; /* the file extent */
char ex; /* the current extent number */
char s1; /* cp/m use */
char s2; /* cp/m use */
char rc; /* record count */
char dn[16]; /* cp/m use */
char cr; /* current record */
unsigned rr; /* random record number */
char ro; /* random record overflow */
};
struct bufstr
{
char *bfcb; /* really struct pointer to cp/m fcb block */
char basc; /* flag non zero if ascii file */
unsigned bsize; /* size of the buffer in bytes */
unsigned bsec; /* the first cp/m record in the buffer */
int bptr; /* next character to be read/written */
int bcnt; /* the number of characters in buffer */
char bmode; /* the open mode */
char bdirty; /* data in the buffer to write */
char blff; /* next character read will be a l/f */
char bdata[1]; /* the data itself */
};
#define SZBUFSTR 15
#define SECSIZE 128 /* size of cp/m sector */
#define NUMBSEC 8 /* number of sectors in buffer */
#define MAXFILES 8
char *_opentab[MAXFILES];
_open(filename,mode,new)
char *filename;
unsigned mode,new;
{
int j;
unsigned status,size;
struct cpmfcb *fcb;
struct bufstr *buf;
if(mode>5)return -1; /* bad open mode */
if(mode>2)++mode;
for(j=1;j<MAXFILES;++j)if(!_opentab[j])break;
if(j==MAXFILES)return -1; /* all possable files open */
if(fcb=_opencdv(filename,++mode))size=1;
else {
if(!(fcb=makefcb(filename)))return -1;/* bad file name */
if(new){
bdos(0x13,fcb); /* delete the file if it exists */
new=7; /* set up for a create */
}
status=bdos(0x0f+new,fcb)&0xff; /* open/create the file */
if(status>3){
free(fcb);
return -1; /* file not found */
}
size=SECSIZE*NUMBSEC;
}
buf=alloc(SZBUFSTR-1+size); /* get the buffer */
if(!buf){
if(fcb>255)free(fcb);
return -1;
}
_opentab[j]=buf;
buf->basc=(mode<4);
buf->bfcb=fcb;
buf->bmode=mode&3;
buf->bsize=size;
setmem(buf->bdata,size,0x1a); /* fill with eof chars */
return j;
}
/* test for opening of a character device
*/
_opencdv(filename,mode)
char *filename;
unsigned mode;
{
char temp[5];
int j;
if(strlen(filename)!=4)return 0; /* not one of ours */
for(j=0;j<5;++j)temp[j]=toupper(*filename++); /* to upper case */
if(!strcmp(temp,"CON:"))return 2; /* its the console */
if(!strcmp(temp,"PRN:") && (mode&2))return 5; /* its a printer */
return 0; /* none of the above */
}
-ARCHIVE- \printf.c 1285
/* a service routine for fprintf et al
*/
_fprintf(fd,string,ip)
unsigned fd;
char *string;
int *ip;
{
char tbuff[17],*cp;
unsigned leftadj,padchar,width,precflg,precisn,longflg,length;
while(*string){
if(*string=='%'){
if(leftadj=(*++string=='-'))++string;
padchar=*string;
if(padchar!='0')padchar=' ';
for(width=0;isdigit(*string);)width=width*10+(*string++-'0');
if(precflg=(*string=='.'))
for(precisn=0;isdigit(*++string);)precisn=precisn*10+(*string-'0');
if(longflg=(toupper(*string)=='L'))++string;
switch(toupper(*string)){
case 'X':
itoh(*ip++,tbuff);
cp=tbuff;
length=strlen(cp);
break;
case 'D':
itoa(*ip++,tbuff);
cp=tbuff;
length=strlen(cp);
break;
case 'S':
cp=*ip++;
length=strlen(cp);
if(precflg && precisn<length)length=precisn;
break;
case 'C':
cp=ip++;
length=1;
break;
default:
cp=string;
length=1;
break;
}
if(!leftadj && width>length)
while(width-- >length)write(fd,&padchar,1);
if(width>length)width-=length; else width=0;
write(fd,cp,length);
if(leftadj && width)
while(width--)write(fd,&padchar,1);
++string;
}
else write(fd,string++,1);
}
}
-ARCHIVE- abort.c 215
/* print a message and abort
*/
#define STDERR 3
abort(string,arg1)
char *string,arg1;
{
_fprintf(STDERR,"\nABORT:- ");
_fprintf(STDERR,string,&arg1);
_fprintf(STDERR,"\n");
exit(0x7fff);
}
-ARCHIVE- alloc.c 728
/* alloc.c 7/16/81
*/
struct header
{
char *addr;
unsigned hsize;
};
#define HEADSIZE 4
struct header _allocb; /* base block for control purposes */
char _allocd; /* dummy so above wont be last entry */
alloc(size)
unsigned size;
{
char *pp,*cp,*np;
for(pp=&_allocb;cp=pp->addr;pp=cp){
if(cp->hsize>=size){
if(cp->hsize>=size+HEADSIZE){
np=cp+size+HEADSIZE;
np->addr=cp->addr;
np->hsize=cp->hsize-size-HEADSIZE;
cp->addr=np;
}
else size=cp->hsize;
pp->addr=cp->addr;
break;
}
}
if(!cp)if(!(cp=sbrk(size+HEADSIZE)))abort("alloc-heap full");
cp->hsize=size;
cp->addr=cp;
setmem(cp+HEADSIZE,size,0);
return cp+HEADSIZE;
}
-ARCHIVE- aseek.c 2126
/* do a short seek using an array
*/
/* define the cp/m86 file control block
*/
struct cpmfcb
{
char dr; /* drive specification */
char fn[8]; /* the file name */
char fe[3]; /* the file extent */
char ex; /* the current extent number */
char s1; /* cp/m use */
char s2; /* cp/m use */
char rc; /* record count */
char dn[16]; /* cp/m use */
char cr; /* current record */
unsigned rr; /* random record number */
char ro; /* random record overflow */
};
struct bufstr
{
char *bfcb; /* really struct pointer to cp/m fcb block */
char basc; /* non zero if ascii file */
unsigned bsize; /* size of the buffer in bytes */
unsigned bsec; /* the first cp/m record in the buffer */
int bptr; /* next character to be read/written */
int bcnt; /* the number of characters in buffer */
char bmode; /* the open mode */
char bdirty; /* data in the buffer to write */
char blff; /* next character read will be a l/f */
char bdata[1]; /* the data itself */
};
#define SZBUFSTR 15
#define SECSIZE 128 /* size of cp/m sector */
#define NUMBSEC 8 /* number of sectors in buffer */
#define MAXFILES 8
extern char *_opentab[MAXFILES];
aseek(fd,asposn,offset)
unsigned fd,asposn[2],offset;
{
unsigned reqdposn[2];
struct bufstr *buf;
if(fd>=MAXFILES)return -1; /* bad fd */
if(!(buf=_opentab[fd]))return -1; /* file not open */
if(buf->bfcb<256)return; /* no seek character device */
reqdposn[1]=asposn[1]+asposn[0]/SECSIZE; /* standardize */
reqdposn[0]=asposn[0]%SECSIZE; /* the reqd position */
if((reqdposn[1]<buf->bsec) || (reqdposn[1]>=buf->bsec+NUMBSEC)){
if(buf->bdirty)_cpmwrite(buf);
buf->bsec=(reqdposn[1]/NUMBSEC)*NUMBSEC; /* to correct base */
reqdposn[0]+=(reqdposn[1]%NUMBSEC)*SECSIZE; /* get correct offset */
buf->bcnt=0; /* say no data in buffer */
_cpmread(buf); /* read the buffer in */
}
else reqdposn[0]+=(reqdposn[1]-buf->bsec)*SECSIZE;
if(reqdposn[0]>buf->bcnt)buf->bcnt=reqdposn[0];
buf->bptr=reqdposn[0];
return 0;
}
-ARCHIVE- atell.c 1603
/* tell the current position using an array
*/
/* define the cp/m86 file control block
*/
struct cpmfcb
{
char dr; /* drive specification */
char fn[8]; /* the file name */
char fe[3]; /* the file extent */
char ex; /* the current extent number */
char s1; /* cp/m use */
char s2; /* cp/m use */
char rc; /* record count */
char dn[16]; /* cp/m use */
char cr; /* current record */
unsigned rr; /* random record number */
char ro; /* random record overflow */
};
struct bufstr
{
char *bfcb; /* really struct pointer to cp/m fcb block */
char basc; /* non zero if ascii file */
unsigned bsize; /* size of the buffer in bytes */
unsigned bsec; /* the first cp/m record in the buffer */
int bptr; /* next character to be read/written */
int bcnt; /* the number of characters in buffer */
char bmode; /* the open mode */
char bdirty; /* data in the buffer to write */
char blff; /* next character read will be a l/f */
char bdata[1]; /* the data itself */
};
#define SZBUFSTR 15
#define SECSIZE 128 /* size of cp/m sector */
#define NUMBSEC 8 /* number of sectors in buffer */
#define MAXFILES 8
extern char *_opentab[MAXFILES];
atell(fd,asposn)
unsigned fd,asposn[2];
{
struct bufstr *buf;
if(fd>=MAXFILES)return -1; /* bad fd */
if(!(buf=_opentab[fd]))return -1; /* file not open */
if(buf->bfcb<256)asposn[0]=asposn[1]=0; /* no seek character device */
else {
asposn[1]=buf->bsec+buf->bptr/SECSIZE;
asposn[0]=buf->bptr%SECSIZE;
}
return 0;
}
-ARCHIVE- bdos.a86 388
title 'c86 basic support package'
pagesize 51
; 5/18/81
DEFGBL equ 91h ;define a global
REFGBL equ 0a1h ;refer to a global
cseg
; bdos call bdos to execute a call
bdos:
push bp
mov bp,sp
mov cx,4[bp]
mov dx,6[bp]
int 224
pop bp
ret
; define the addresses to relocate in the above code
eseg
dw bdos
db DEFGBL,'bdos',0
dw 0,0
end
-ARCHIVE- close.c 1596
/* close a file
*/
/* define the cp/m86 file control block
*/
struct cpmfcb
{
char dr; /* drive specification */
char fn[8]; /* the file name */
char fe[3]; /* the file extent */
char ex; /* the current extent number */
char s1; /* cp/m use */
char s2; /* cp/m use */
char rc; /* record count */
char dn[16]; /* cp/m use */
char cr; /* current record */
unsigned rr; /* random record number */
char ro; /* random record overflow */
};
struct bufstr
{
char *bfcb; /* really struct pointer to cp/m fcb block */
char basc; /* ascii data flag */
unsigned bsize; /* size of the buffer in bytes */
unsigned bsec; /* the first cp/m record in the buffer */
int bptr; /* next character to be read/written */
int bcnt; /* the number of characters in buffer */
char bmode; /* the open mode */
char bdirty; /* data in the buffer to write */
char blff; /* next character read will be a l/f */
char bdata[1]; /* the data itself */
};
#define SZBUFSTR 15
#define SECSIZE 128 /* size of cp/m sector */
#define NUMBSEC 8 /* number of sectors in buffer */
#define MAXFILES 8
extern char *_opentab[MAXFILES];
close(fd)
unsigned fd;
{
struct bufstr *buf;
if(fd>=MAXFILES)return -1; /* bad fd */
if(!(buf=_opentab[fd]))return -1; /* file not open */
if(buf->bdirty)_cpmwrite(buf); /* empty the buffer */
if(buf->bfcb>255){
if((bdos(0x10,buf->bfcb)&0xff)>3)return -1;/* fatal close error */
free(buf->bfcb);
}
free(buf);
_opentab[fd]=0;
return 0;
}
-ARCHIVE- creat.c 189
/* create a new file, deleting any existing file
*/
creat(filename,mode)
char *filename;
unsigned mode;
{
return _open(filename,mode,7); /* do common open for a new file */
}
-ARCHIVE- exit.c 244
/* do exit processing for a c program
*/
#define MAXFILES 8
extern char *_opentab[MAXFILES];
exit(val)
int val;
{
int j;
for(j=0;j<MAXFILES;++j){
if(_opentab[j])close(j);
}
_exit(val); /* thats all folks */
}
-ARCHIVE- fclose.c 101
/* this is a convenience function only
*/
fclose(fd)
unsigned fd;
{
return close(fd);
}
-ARCHIVE- fgets.c 1974
/* get an input string from a file
*/
/* define the cp/m86 file control block
*/
struct cpmfcb
{
char dr; /* drive specification */
char fn[8]; /* the file name */
char fe[3]; /* the file extent */
char ex; /* the current extent number */
char s1; /* cp/m use */
char s2; /* cp/m use */
char rc; /* record count */
char dn[16]; /* cp/m use */
char cr; /* current record */
unsigned rr; /* random record number */
char ro; /* random record overflow */
};
struct bufstr
{
char *bfcb; /* really struct pointer to cp/m fcb block */
char basc; /* non vero if ascii */
unsigned bsize; /* size of the buffer in bytes */
unsigned bsec; /* the first cp/m record in the buffer */
int bptr; /* next character to be read/written */
int bcnt; /* the number of characters in buffer */
char bmode; /* the open mode */
char bdirty; /* data in the buffer to write */
char blff; /* next character read will be a l/f */
char bdata[1]; /* the data itself */
};
#define SZBUFSTR 15
#define SECSIZE 128 /* size of cp/m sector */
#define NUMBSEC 8 /* number of sectors in buffer */
#define MAXFILES 8
extern char *_opentab[MAXFILES];
fgets(line,maxline,fd)
char *line;
int maxline;
unsigned fd;
{
int j,cc,k;
struct bufstr *buf;
if(fd>=MAXFILES)return 0; /* bad fd */
if(!(buf=_opentab[fd]))return 0; /* file not open */
if(buf->bfcb==2 && (!buf->blff)){ /* do direct console input */
line[0]=maxline-2;
bdos(10,line); /* read the line */
bdos(2,'\n'); /* put out a l/f */
cc=line[1];
movmem(line+2,line,cc); /* position the data */
for(j=0;j<cc;++j)if(line[j]==26)break; /* check for cpm EOF */
line[j++]='\n';
}
else {
for(j=0;j<maxline-1;){
cc=read(fd,line+j,1);
if(cc<1)break;
if(line[j++]=='\n')break;
}
}
line[j]=0;
if(j)return line; else return 0;
}
-ARCHIVE- fopen.c 396
/* open a file
*/
#define AREAD 0
#define AWRITE 1
fopen(filename,fomode)
char *filename,*fomode;
{
int fd;
switch(tolower(*fomode)){
case 'r':
fd=open(filename,AREAD);
break;
case 'w':
fd=creat(filename,AWRITE);
break;
default:
abort("fopen-illegal mode %s opening %s",fomode,filename);
}
if(fd<1)fd=0;
return fd;
}
-ARCHIVE- fprintf.c 131
/* print a field to a file
*/
fprintf(fd,string,arg1)
unsigned fd;
char *string,arg1;
{
_fprintf(fd,string,&arg1);
}
-ARCHIVE- fputs.c 155
/* output a string expanding newlines
*/
fputs(line,fd)
char *line;
unsigned fd;
{
int leng;
leng=strlen(line);
write(fd,line,leng);
}
-ARCHIVE- free.c 639
/* return a free block to the heap
*/
struct header
{
char *addr;
unsigned hsize;
};
#define HEADSIZE 4
extern struct header _allocb; /* base block for control purposes */
free(fp)
char *fp;
{
char *pp,*cp,*np;
fp-=HEADSIZE;
if(fp!=fp->addr)abort("free-block address");
for(cp=&_allocb;cp->addr && cp->addr<fp;cp=cp->addr);
fp->addr=cp->addr;
cp->addr=fp;
if(fp==cp+cp->hsize+HEADSIZE){
cp->hsize+=(fp->hsize+HEADSIZE);
cp->addr=fp->addr;
}
else cp=fp;
fp=fp->addr;
if(fp==cp+cp->hsize+HEADSIZE){
cp->hsize+=(fp->hsize+HEADSIZE);
cp->addr=fp->addr;
}
}
-ARCHIVE- getc.c 192
/* get a character from the file
*/
getc(fd)
unsigned fd;
{
unsigned cc;
if(read(fd,&cc,1)!=1)return -1; /* read 1 character */
return cc&0xff; /* return character */
}
-ARCHIVE- getchar.c 211
/* get a character from the standard input
*/
#define STDIN 1
getchar()
{
unsigned cc;
if(read(STDIN,&cc,1)!=1)return -1; /* read 1 character */
return cc&0xff; /* return character */
}
-ARCHIVE- getw.c 275
/* get a word from a file
*/
getw(fd)
unsigned fd;
{
unsigned cc,count;
count=read(fd,&cc,2); /* read 2 characters */
switch(count){
case 2:
return cc;
case 1:
return cc&0xff;
}
return -1; /* EOF, not a good value */
}
-ARCHIVE- inportb.a86 361
; read an b bit value from a port
; input a port number
; returns the input byte, zero filled
cseg
inportb:
push bp
mov bp,sp ;set the frame pointer
mov dx,4[bp] ;get the port number
in al,dx ;get a byte value
mov ah,0 ;zero the top byte
pop bp
ret
eseg
DEFGBL equ 91h
dw inportb
db DEFGBL,'inportb',0
dw 0,0
end
-ARCHIVE- inportw.a86 317
; read an w bit value from a port
; input a port number
; returns the input word
cseg
inportw:
push bp
mov bp,sp ;set the frame pointer
mov dx,4[bp] ;get the port number
in ax,dx ;get a byte value
pop bp
ret
eseg
DEFGBL equ 91h
dw inportw
db DEFGBL,'inportw',0
dw 0,0
end
-ARCHIVE- isalpha.c 139
/* return true if input character is alphabetic
*/
isalpha(c)
char c;
{
return ((('A'<=c)&(c<='Z')) | (('a'<=c)&(c<='z')));
}
-ARCHIVE- isdigit.c 112
/* return true if input character is a digit
*/
isdigit(c)
char c;
{
return (('0'<=c)&(c<='9'));
}
-ARCHIVE- isspace.c 139
/* returns true if chararcter is a blank,tab or newline
*/
isspace(cc)
char cc;
{
return (cc==' ' || cc=='\t' || cc=='\n');
}
-ARCHIVE- itoa.c 202
/* integer to ascii
*/
itoa(n,cp)
int n;
char *cp;
{
int j;
if(n<0)*cp++='-';
else n=-n;
if(n<-9)j=itoa(n/-10,cp);
else j=0;
cp[j]='0'-(n%-10);
cp[++j]=0;
return j;
}
-ARCHIVE- itoh.c 198
/* integer to hex
*/
itoh(n,cp)
unsigned n;
char *cp;
{
int j,k;
cp[4]=0;
for(j=3;j>=0;--j){
k=(n&0xf)+'0';
n=n>>4;
if(k>'9')k=k+('A'-'9'-1);
cp[j]=k;
}
}
-ARCHIVE- makefcb.c 2031
/* make a cp/m file control block
*/
/* define the cp/m86 file control block
*/
struct cpmfcb
{
char dr; /* drive specification */
char fn[8]; /* the file name */
char fe[3]; /* the file extent */
char ex; /* the current extent number */
char s1; /* cp/m use */
char s2; /* cp/m use */
char rc; /* record count */
char dn[16]; /* cp/m use */
char cr; /* current record */
unsigned rr; /* random record number */
char ro; /* random record overflow */
};
struct bufstr
{
char *bfcb; /* really struct pointer to cp/m fcb block */
char basc; /* non zero if ascii */
unsigned bsize; /* size of the buffer in bytes */
unsigned bsec; /* the first cp/m record in the buffer */
int bptr; /* next character to be read/written */
int bcnt; /* the number of characters in buffer */
char bmode; /* the open mode */
char bdirty; /* data in the buffer to write */
char blff; /* next character read will be a l/f */
char bdata[1]; /* the data itself */
};
#define SZBUFSTR 15
#define SECSIZE 128 /* size of cp/m sector */
#define NUMBSEC 8 /* number of sectors in buffer */
#define MAXFILES 8
extern char *_opentab[MAXFILES];
#define SZCPMFCB 36
makefcb(filename)
char *filename;
{
char j,u;
struct cpmfcb *fcb;
if(!(fcb=alloc(SZCPMFCB)))return 0; /* heap full */
if(filename[1]==':'){
u=toupper(*filename);
if(u>='A' && u<='D')fcb->dr=u-('A'-1); /* set drive number */
else goto error;
filename+=2;
}
setmem(fcb->fn,11,' '); /* space fill fn and fe */
for(j=0;*filename;){ /* do file name */
u=toupper(*filename++)&0x7f;
if(u=='.')break; /* that part done */
if(u<0x21)goto error; /* some protection */
if(j<8)fcb->fn[j++]=u;
}
for(j=0;*filename;){ /* do fn extension */
u=toupper(*filename++)&0x7f;
if(u<0x21)goto error;
if(j<3)fcb->fe[j++]=u;
}
return fcb; /* all ok */
error:
free(fcb);
return 0;
}
-ARCHIVE- movmem.a86 826
title 'move a block of memory'
pagesize 51
; 7/28/81
DEFGBL equ 91h ;define a global
cseg
; movmem
; entry 1,the source address
; 2,the destination address
; 3,the number of bytes to move
movmem:
push bp
mov bp,sp
mov ax,ds ;ensure that extra seg is correct
mov es,ax
mov si,4[bp]; ;the source address
mov di,6[bp] ;the destination address
mov cx,8[bp] ;the number of bytes to move
cmp si,di ;which way to do the move ?
jb movmem01 ;do it in reverse order
cld
jmps movmem02 ;must be this
movmem01:
add si,cx ;point to other end of string
dec si
add di,cx
dec di
std ;backwards in memory
movmem02:
rep movs al,al ;do the move
pop bp
ret
; define the addresses to relocate in the above code
eseg
dw movmem
db DEFGBL,'movmem',0
dw 0,0
end
-ARCHIVE- open.c 167
/* open an existing file
*/
open(filename,mode)
char *filename;
unsigned mode;
{
return _open(filename,mode,0); /* do common open for existing file */
}
-ARCHIVE- outportb.a86 420
; write an 8 bit value to port
; input a port number
; the value to write
; returns the input byte, zero filled
cseg
outportb:
push bp
mov bp,sp ;set the frame pointer
mov dx,4[bp] ;get the port number
mov ax,6[bp] ;get the value to output
mov ah,0 ;zero the top byte
out dx,al ;put it out
pop bp
ret
eseg
DEFGBL equ 91h
dw outportb
db DEFGBL,'outportb',0
dw 0,0
end
-ARCHIVE- outportw.a86 377
; write an 16 bit value to port
; input a port number
; the value to write
; returns the input word
cseg
outportw:
push bp
mov bp,sp ;set the frame pointer
mov dx,4[bp] ;get the port number
mov ax,6[bp] ;get the value to output
out dx,ax ;put it out
pop bp
ret
eseg
DEFGBL equ 91h
dw outportw
db DEFGBL,'outportw',0
dw 0,0
end
-ARCHIVE- printf.c 150
/* print a field to the standard output
*/
#define STDOUT 2
printf(string,arg1)
char *string,arg1;
{
_fprintf(STDOUT,string,&arg1);
}
-ARCHIVE- putc.c 104
/* put a character to a file
*/
putc(c,fd)
unsigned c,fd;
{
write(fd,&c,1);
return 0;
}
-ARCHIVE- putchar.c 128
/* put a character to the standard output
*/
#define STDOUT 2
putchar(cc)
unsigned cc;
{
write(STDOUT,&cc,1);
}
-ARCHIVE- putw.c 86
/* put a word to a file
*/
putw(w,fd)
unsigned w,fd;
{
write(fd,&w,2);
}
-ARCHIVE- read.c 2286
/* read characters from the file
*/
/* define the cp/m86 file control block
*/
struct cpmfcb
{
char dr; /* drive specification */
char fn[8]; /* the file name */
char fe[3]; /* the file extent */
char ex; /* the current extent number */
char s1; /* cp/m use */
char s2; /* cp/m use */
char rc; /* record count */
char dn[16]; /* cp/m use */
char cr; /* current record */
unsigned rr; /* random record number */
char ro; /* random record overflow */
};
struct bufstr
{
char *bfcb; /* really struct pointer to cp/m fcb block */
char basc; /* true if ascii data in file */
unsigned bsize; /* size of the buffer in bytes */
unsigned bsec; /* the first cp/m record in the buffer */
int bptr; /* next character to be read/written */
int bcnt; /* the number of characters in buffer */
char bmode; /* the open mode */
char bdirty; /* data in the buffer to write */
char blff; /* next character read will be a l/f */
char bdata[1]; /* the data itself */
};
#define SZBUFSTR 15
#define SECSIZE 128 /* size of cp/m sector */
#define NUMBSEC 8 /* number of sectors in buffer */
#define MAXFILES 8
extern char *_opentab[MAXFILES];
read(fd,buffer,count)
unsigned fd;
char *buffer;
unsigned count;
{
int retval,retcc;
struct bufstr *buf;
if(fd>=MAXFILES)return -1; /* bad fd */
if(!(buf=_opentab[fd]))return -1; /* file not open */
if(!(buf->bmode&1))return -1; /* not open for reading */
for(retval=0;retval<count;++retval){
if((retcc=_read(buf))<0)break;
*buffer++=retcc;
if(buf->basc){
if(retcc==26){
--buf->bptr;
break;
}
if(retcc=='\r'){
retcc=_read(buf);
if(retcc=='\n') *(buffer-1)='\n';
else if(retcc!=-1)--buf->bptr;
}
}
}
return retval;
}
/* support routine for read
*/
_read(buf)
struct bufstr *buf;
{
char cc;
if(buf->bptr>=buf->bcnt){ /* no data in buffer */
if(buf->bdirty)_cpmwrite(buf); /* get out your dirty buff */
_cpmread(buf); /* fill the buffer */
}
if(!buf->bcnt)return -1; /* end of file */
return buf->bdata[buf->bptr++];
}
-ARCHIVE- rename.c 412
/* rename a file
*/
rename(filefrom,fileto)
char *filefrom,*fileto;
{
char *fcbfrom,*fcbto;
unsigned status;
if(!(fcbfrom=makefcb(filefrom)))return -1;
if(!(fcbto=makefcb(fileto))){
free(fcbfrom);
return -1;
}
movmem(fcbto,fcbfrom+16,16); /* build composite fcb */
status=bdos(0x17,fcbfrom)&0xff;
free(fcbfrom);
free(fcbto);
if(status)return -1;
return 0;
}
-ARCHIVE- sbrk.c 364
/* get some memory from the system
*/
sbrk(size)
unsigned size;
{
unsigned *up,uv;
up=0x106; /* get address of control field */
if(*up+size>=&size)return 0; /* no room left for this one */
uv=*up; /* get value to return to caller */
*up+=size; /* say its allocated */
uv-=*--up; /* subtract out the reserve */
return uv;
}
-ARCHIVE- setmem.a86 657
title 'set memory to a specified character'
pagesize 51
; 5/28/81
DEFGBL equ 91h ;define a global
cseg
; setmem
; entry 1,the address of first character to be set
; 2,the number of bytes to set (unsigned int)
; 3,the desired value
setmem:
push bp
mov bp,sp
mov ax,ds ;ensure that extra seg is correct
mov es,ax
cld ;and clear the direction flag
mov di,4[bp] ;the address to set
mov cx,6[bp] ;the number of bytes to set
mov al,8[bp] ;the value to set
rep stos al ;set the area
pop bp
ret
; define the addresses to relocate in the above code
eseg
dw setmem
db DEFGBL,'setmem',0
dw 0,0
end
-ARCHIVE- strcat.c 183
/* concatinate string t to string s
*/
strcat(s,t)
char *s,*t;
{
char *cp;
while(*s++); /* find end of string */
for(--s;*s++=*t++;); /* do the concatinate */
}
-ARCHIVE- strcmp.c 133
/* string compare
*/
strcmp(s,t)
char *s,*t;
{
for(;*s==*t;t++)if(!*s++)return 0;
if(*s<*t)return -1;
return 1;
}
-ARCHIVE- strcpy.c 89
/* string copy
*/
strcpy(to,from)
char *to,*from;
{
while(*to++=*from++);
}
-ARCHIVE- strlen.c 141
/* return the length of a string
*/
strlen(string)
char *string;
{
char *cp;
for(cp=string++;*cp++;);
return cp-string;
}
-ARCHIVE- tolower.c 133
/* convert character to lowercase if upper case */
tolower(c)
char c;
{
if('A'<=c && c<='Z')c+=('a'-'A');
return c;
}
-ARCHIVE- toupper.c 133
/* convert character to uppercase if lower case */
toupper(c)
char c;
{
if('a'<=c && c<='z')c+=('A'-'a');
return c;
}
-ARCHIVE- ungetc.c 1485
/* ungetc a char from an input file
*/
/* define the cp/m86 file control block
*/
struct cpmfcb
{
char dr; /* drive specification */
char fn[8]; /* the file name */
char fe[3]; /* the file extent */
char ex; /* the current extent number */
char s1; /* cp/m use */
char s2; /* cp/m use */
char rc; /* record count */
char dn[16]; /* cp/m use */
char cr; /* current record */
unsigned rr; /* random record number */
char ro; /* random record overflow */
};
struct bufstr
{
char *bfcb; /* really struct pointer to cp/m fcb block */
char basc; /* non zero if ascii data */
unsigned bsize; /* size of the buffer in bytes */
unsigned bsec; /* the first cp/m record in the buffer */
int bptr; /* next character to be read/written */
int bcnt; /* the number of characters in buffer */
char bmode; /* the open mode */
char bdirty; /* data in the buffer to write */
char blff; /* next character read will be a l/f */
char bdata[1]; /* the data itself */
};
#define SZBUFSTR 15
#define SECSIZE 128 /* size of cp/m sector */
#define NUMBSEC 8 /* number of sectors in buffer */
#define MAXFILES 8
extern char *_opentab[MAXFILES];
ungetc(cc,fd)
unsigned cc,fd;
{
struct bufstr *buf;
if(fd>=MAXFILES)return -1; /* bad fd */
if(!(buf=_opentab[fd]))return -1; /* file not open */
if(buf->bptr)buf->bdata[--buf->bptr]=cc;
else return -1;
return 0;
}
-ARCHIVE- unlink.c 255
/* unlink (delete) a disk file
*/
unlink(filename)
char *filename;
{
char *fcb;
unsigned status;
if(!(fcb=makefcb(filename)))return -1;
status=bdos(0x13,fcb)&0xff;
free(fcb);
if(status)return -1;
return 0; /* all ok */
}
-ARCHIVE- utoa.c 239
/* unsigned integer to ascii
*/
utoa(val,str)
unsigned val;
char *str;
{
char digit,offset;
digit=val%10+'0';
offset=0;
if(val>9)offset=utoa(val/10,str);
str[offset]=digit;
str[++offset]=0;
return offset;
}
-ARCHIVE- write.c 2026
/* write characters to a file
*/
/* define the cp/m86 file control block
*/
struct cpmfcb
{
char dr; /* drive specification */
char fn[8]; /* the file name */
char fe[3]; /* the file extent */
char ex; /* the current extent number */
char s1; /* cp/m use */
char s2; /* cp/m use */
char rc; /* record count */
char dn[16]; /* cp/m use */
char cr; /* current record */
unsigned rr; /* random record number */
char ro; /* random record overflow */
};
struct bufstr
{
char *bfcb; /* really struct pointer to cp/m fcb block */
char basc; /* non vero if ascii file */
unsigned bsize; /* size of the buffer in bytes */
unsigned bsec; /* the first cp/m record in the buffer */
int bptr; /* next character to be read/written */
int bcnt; /* the number of characters in buffer */
char bmode; /* the open mode */
char bdirty; /* data in the buffer to write */
char blff; /* next character read will be a l/f */
char bdata[1]; /* the data itself */
};
#define SZBUFSTR 15
#define SECSIZE 128 /* size of cp/m sector */
#define NUMBSEC 8 /* number of sectors in buffer */
#define MAXFILES 8
extern char *_opentab[MAXFILES];
write(fd,buffer,count)
unsigned fd,count;
char *buffer;
{
int retval;
struct bufstr *buf;
if(fd>=MAXFILES)return -1; /* bad fd */
if(!(buf=_opentab[fd]))return -1; /* file not open */
if(!(buf->bmode&2))return -1; /* not open for writing */
for(retval=0;retval<count;++retval){
if(*buffer=='\n' && buf->basc)_write('\r',buf);
_write(*buffer++,buf);
}
return retval;
}
/* service routine for write
*/
_write(cc,buf)
unsigned cc;
struct bufstr *buf;
{
if(!buf->bcnt && buf->bmode==3 && buf->bfcb>255)_cpmread(buf);
buf->bdata[buf->bptr++]=cc; /* put the character */
buf->bdirty=1; /* say data to write */
if(buf->bptr>buf->bcnt)buf->bcnt=buf->bptr;
if(buf->bptr>=buf->bsize)_cpmwrite(buf); /* empty the buffer */
}