makefile OBJ=access.o bdos.o begin.o blkio.o ceof.o close.o croot.o csread.o exec.o\ execl.o fcbinit.o find.o ioctl.o isatty.o lseek.o open.o read.o rename.o\ sbrk.o stkover.o unlink.o user.o write.o CC=cc AS=as MODEL= AMODEL=0 .c.o: $(CC) +$(MODEL) -n $*.c -o $@ sqz $@ .asm.o: $(AS) -dMODEL=$(AMODEL) $*.asm -o $@ sqz $@ bld: $(OBJ) @echo cpm86 done access.c /* Copyright (C) 1982 by Manx Software Systems */ #include "errno.h" #include "fcntl.h" #include "io.h" access(path, amode) char *path; { register int fd; if ((fd = open(path, amode&2 ? 1 : 0)) != -1) { close(fd); fd = 0; } return fd; } bdos.asm ; :ts=8 ; Copyright (C) 1983 by Manx Software Systems codeseg segment para public 'code' assume cs:codeseg ; public bdos_ bdos_ proc near push bp mov bp,sp push di push si mov cx,word ptr 4[bp] mov dx,word ptr 6[bp] int 224 pop si pop di pop bp and ax,255 ret ; bdos_ endp codeseg ends end begin.asm ; Copyright (C) 1983, 1984 by Manx Software Systems ; :ts=8 codeseg segment word public 'code' public $MEMRY public _mbot_, _sbot_ dataseg segment word public 'data' $MEMRY dw -1 public errno_ errno_ dw 0 public _dsval_,_csval_ _dsval_ dw 0 _csval_ dw 0 _mbot_ dw 0 _sbot_ dw 0 exitad dw 0 exitcs dw 0 bad8087 db "8087/80287 is required!",13,10,'$' extrn _Uorg_:byte,_Uend_:byte dataseg ends assume cs:codeseg,ds:dataseg,es:dataseg,ss:dataseg extrn Croot_:near extrn $fltinit:near public $begin public _exit_ $begin proc far pop exitad pop exitcs cli mov ax,ds mov es,ax mov ss,ax mov sp,word ptr ds:[6] and sp,-2 sti cld ; clear uninitialized data mov di,offset _Uorg_ mov cx,offset _Uend_ sub cx,di inc cx shr cx,1 jcxz noclear sub ax,ax rep stosw noclear: mov ax,$MEMRY ;save memory allocation info for sbrk() mov _mbot_,ax add ax,512 mov _sbot_,ax mov _dsval_,ds mov _csval_,cs call $fltinit jc no_8087 call Croot_ _exit_: sub cx,cx sub dx,dx jmp dword ptr exitad ; no_8087: mov cx,9 ;cp/m print message mov dx,offset bad8087 int 254 ;tell the user about it jmp short _exit_ $begin endp public _sig_setup_ _sig_setup_ proc near ret _sig_setup_ endp codeseg ends end $begin blkio.asm ; :ts=8 ; Copyright (C) 1983 by Manx Software Systems codeseg segment para public 'code' dataseg segment para public 'data' extrn errno_:word dataseg ends assume cs:codeseg,ds:dataseg,es:dataseg,ss:dataseg public blkrd_ blkrd_ proc near mov cl,33 ;set function to read sequential jmp short rdwrt ; public blkwr_ blkwr_: mov cl,34 ;set function to write sequential rdwrt: push bp mov bp,sp push di push si push cx ;save function code on stack ioloop: mov dx,6[bp] add word ptr 6[bp],128 ;bump to next 128 byte position push bp mov cl,26 ;set DMA address int 224 pop bp pop cx push cx push bp mov dx,4[bp] int 224 ;read or write sector pop bp and ax,0ffH jnz ioerr mov bx,4[bp] ;get fcb address add word ptr 33[bx],1 ;increment random record # adc byte ptr 35[bx],0 dec word ptr 8[bp] jnz ioloop blkexit: pop cx ;pull function code from stack mov ax,word ptr 8[bp] ;get number of sectors remaining pop si pop di pop bp test ax,ax ret ;all done, return number remaining ; ioerr: cmp al,1 je blkexit cmp al,4 je blkexit mov errno_,ax jmp blkexit blkrd_ endp codeseg ends end c86.bld stdio/tmpfile.o stdio/perror.o stdio/fdopen.o stdio/fgets.o stdio/fopen.o stdio/assert.o stdio/fprintf.o stdio/fputs.o stdio/fread.o stdio/fscanf.o stdio/fseek.o stdio/fwrite.o stdio/gets.o stdio/getchar.o stdio/getw.o stdio/printf.o stdio/puterr.o stdio/puts.o stdio/putchar.o stdio/aputc.o stdio/putw.o stdio/putc.o stdio/scanf.o stdio/agetc.o stdio/getc.o stdio/getbuff.o stdio/setbuf.o stdio/ungetc.o stdio/tmpnam.o stdio/mktemp.o misc/atoi.o misc/atol.o misc/calloc.o misc/qsort.o misc/sscanf.o misc/scan.o misc/rand.o misc/abort.o misc/raise.o misc/signal.o misc/malloc.o misc/sprintf.o misc/format.o misc/ctype.o mch86/cswt.o mch86/cswit.o mch86/clswit.o mch86/farcall.o mch86/fcall.o mch86/index.o mch86/lsubs.o mch86/olsubs.o mch86/peek.o mch86/port.o mch86/rindex.o mch86/segread.o mch86/setjmp.o mch86/strlen.o mch86/strncpy.o mch86/swapmem.o mch86/sysint.o mch86/toupper.o cpm86/sbrk.o mch86/memccpy.o mch86/memchr.o mch86/memcmp.o mch86/memcpy.o mch86/memset.o cpm86/access.o cpm86/csread.o mch86/movblock.o cpm86/execl.o cpm86/exec.o cpm86/ioctl.o cpm86/isatty.o cpm86/lseek.o cpm86/read.o cpm86/rename.o cpm86/write.o cpm86/blkio.o mch86/csav.o mch86/pointers.o mch86/fptrs.o mch86/ptrdiff.o mch86/ptradd.o mch86/strchr.o mch86/strrchr.o cpm86/stkover.o cpm86/begin.o cpm86/croot.o cpm86/close.o cpm86/open.o mch86/strcmp.o cpm86/ceof.o cpm86/find.o mch86/setmem.o mch86/strcat.o mch86/strcpy.o mch86/movmem.o cpm86/unlink.o mch86/fltstub.o cpm86/bdos.o cpm86/fcbinit.o cpm86/user.o ceof.c /* Copyright (C) 1984 by Manx Software Systems */ #include "io.h" #include "errno.h" _Ceof(fp) register struct fcbtab *fp; { register char *cp; bdos(FILSIZ, &fp->fcb); if (fp->fcb.f_record == 0) { fp->offset = 0; return 0; } --fp->fcb.f_record; /* backup to last record */ if (_find(fp)) return -1; for (cp = Wrkbuf+128 ; cp > Wrkbuf ; ) if (*--cp != 0x1a) { ++cp; break; } if ((fp->offset = (char)((int)(cp-Wrkbuf))) == 128) { ++fp->fcb.f_record; fp->offset = 0; } return 0; } close.c /* Copyright (C) 1982 by Manx Software Systems */ #include "errno.h" #include "io.h" close(fd) { register struct channel *chp; extern int bdf_(); if (fd < 0 || fd > MAXCHAN) { errno = EBADF; return -1; } chp = &chantab[fd]; fd = (*chp->c_close)(chp->c_arg); chp->c_read = chp->c_write = chp->c_ioctl = chp->c_seek = 0; chp->c_close = bdf_; return fd; } croot.c /* Copyright (C) 1981,1982,1984 by Manx Software Systems */ #include "errno.h" #include "fcntl.h" #include "io.h" int bdf_(), ret_(); /* * channel table: relates fd's to devices */ struct channel chantab[] = { { 2, 0, 1, 0, ret_, (_arg)2 }, { 0, 2, 1, 0, ret_, (_arg)2 }, { 0, 2, 1, 0, ret_, (_arg)2 }, { 0, 0, 0, 0, bdf_, (_arg)0 }, { 0, 0, 0, 0, bdf_, (_arg)0 }, { 0, 0, 0, 0, bdf_, (_arg)0 }, { 0, 0, 0, 0, bdf_, (_arg)0 }, { 0, 0, 0, 0, bdf_, (_arg)0 }, { 0, 0, 0, 0, bdf_, (_arg)0 }, { 0, 0, 0, 0, bdf_, (_arg)0 }, { 0, 0, 0, 0, bdf_, (_arg)0 }, }; #define MAXARGS 30 static char *Argv[MAXARGS]; static char Argbuf[128]; static int Argc; int (*cls_)() = ret_; Croot() { register char *cp, *fname; register int k; movmem((char *)0x81, Argbuf, 127); Argbuf[*(char *)0x80 & 0x7f] = 0; Argv[0] = ""; cp = Argbuf; Argc = 1; while (Argc < MAXARGS) { while (*cp == ' ' || *cp == '\t') ++cp; if (*cp == 0) break; #ifndef NOREDIR if (*cp == '>') { /* redirect output */ k = 1; goto redirect; } else if (*cp == '<') { /* redirect input */ k = 0; redirect: while (*++cp == ' ' || *cp == '\t') ; fname = cp; while (*++cp) if (*cp == ' ' || *cp == '\t') { *cp++ = 0; break; } close(k); if (k) k = creat(fname, 0666); else k = open(fname, O_RDONLY); if (k == -1) { strcpy(0x80, "Can't open file for redirection: "); strcat(0x80, fname); strcat(0x80, "$"); bdos(9,0x80); exit(10); } } else #endif { Argv[Argc++] = cp; while (*++cp) if (*cp == ' ' || *cp == '\t') { *cp++ = 0; break; } } } main(Argc,Argv); exit(0); } exit(code) { register int fd; (*cls_)(); for (fd = 0 ; fd < MAXCHAN ; ) close(fd++); if (code && (bdos(24)&1) != 0) unlink("A:$$$.SUB"); _exit(); } bdf_() { errno = EBADF; return -1; } ret_() { return 0; } csread.c /* Copyright (C) 1983, 1984 by Manx Software Systems */ #include "io.h" #include "errno.h" extern int errno; extern unsigned _dsval, _csval; _csread(fd, buffer, len) char *buffer; { register unsigned l = 0; register struct fcbtab *fp; register struct channel *chp; unsigned k,j; chp = &chantab[fd]; if (chp->c_read != 1) { /* only valid for disk files */ errno = EINVAL; return -1; } fp = (struct fcbtab *)chp->c_arg; setusr(fp->user); if (fp->offset) { if ((l = 128 - fp->offset) > len) l = len; if (getsect(fp, buffer, l)) { l = 0; goto done; } } if (k = (len-l)/128) { bdos(51, _csval); /* set dma segment to CS */ j = blkrd(&fp->fcb, buffer+l, k); bdos(51, _dsval); /* set dma segment back to DS */ if (j != 0) { l += (k-j)*128; goto done; } } l += k*128; if (l < len) if (getsect(fp, buffer+l, len-l)) goto done; l = len; done: rstusr(); return l; } static getsect(fp, buf, len) register struct fcbtab *fp; char *buf; unsigned len; { if (_find(fp)) return -1; movblock(Wrkbuf+fp->offset,_dsval, buf,_csval, len); if ((fp->offset = (fp->offset + len) & 127) == 0) ++fp->fcb.f_record; return 0; } exec.c /* Copyright (C) 1983, 1984 by Manx Software Systems */ execlp(path, args) char *path, *args; { return execvp(path, &args); } execvp(path, argv) char *path, **argv; { char buffer[130]; register char *cp, *xp; cp = buffer; for (xp = path ; *xp && cp < buffer+128 ; ) *cp++ = *xp++; if (*argv) { ++argv; /* skip arg0, used for unix (tm) compatibility */ while (*argv) { *cp++ = ' '; for (xp = *argv++ ; *xp && cp < buffer+128 ; ) *cp++ = *xp++; } } *cp = 0; bdos(26, buffer); bdos(47, 0); } execl.c /* Copyright (C) 1983, 1984 by Manx Software Systems */ execl(path, args) char *path, *args; { return execvp(path, &args); } execv(path, argv) char *path, **argv; { return execvp(path, argv); } fcbinit.asm ; :ts=8 ; Copyright (C) 1983, 1984 by Manx Software Systems codeseg segment para public 'code' ; include lmacros.h public fcbinit_ fcbinit_ proc near mov bx,sp push di push si cld ifndef LONGPTR mov di,ds mov es,di endif mov si,word ptr 2[bx] ;si contains name mov di,word ptr 4[bx] ;di contains fcb address ; clear name to blanks mov dx,di ;save fcb address in dx inc di mov cx,11 ;clear name and ext to blanks mov al,' ' rep stosb mov cx,4 sub al,al rep stosb mov di,dx ;restore fcb address ; sub dx,dx ;init user # mov cl,10 ;multiplier inside loop userloop: ;loop packing leading digits into DL lodsb cmp al,'0' jb userdone cmp al,'9' ja userdone sub al,'0' xchg ax,dx ;get accumlated value into AL for multiply mul cl ;value *= 10 add al,dl ;add in new digit xchg ax,dx ;put result back into DL jmp userloop ; userdone: cmp al,'/' ;check if user # prefix je haveuser mov dl,255 ;set user # to default indicator mov si,word ptr 2[bx] ;reset filename pointer haveuser: ; sub al,al ;default drive # cmp byte ptr 1[si],':' jnz setdrive ; lodsb inc si ;skip over colon and al,127 cmp al,'A' jl badname cmp al,'Z' jg lowerc sub al,'A'-1 jmp short setdrive ; lowerc: cmp al,'a' jl badname cmp al,'z' jg badname sub al,'a'-1 setdrive: stosb ; move name in mapping to upper case mov cx,8 nameskp: inc cx namelp: lodsb cmp al,'.' jz namedn test al,al jz alldone loop store jmp short nameskp store: call toupper stosb jmp short namelp ; namedn: dec cx add di,cx ; move extension mapping to upper case mov cx,3 extlp: lodsb test al,al jz alldone call toupper stosb loop extlp ; alldone: xchg ax,dx and ax,255 retn: pop si pop di ret ; badname: sub ax,ax dec ax jmp short retn ; toupper: cmp al,'*' jne nostar dec si ;backup so we see star again mov al,'?' ;and map into question mark ret nostar: cmp al,'a' jl notrans cmp al,'z' jg notrans sub al,'a'-'A' notrans: ret fcbinit_ endp codeseg ends end find.c /* Copyright (C) 1984 by Manx Software Systems */ #include "io.h" static struct fcbtab *Wfp; static unsigned Wsct; _zap() /* invalidate work buffer */ { Wfp = 0; } _find(fp) register struct fcbtab *fp; { extern int errno; bdos(SETDMA, Wrkbuf); if (Wfp != fp || fp->fcb.f_record != Wsct) { if ((errno = bdos(READRN, &fp->fcb)) == 1 || errno == 4) { errno = 0; setmem(Wrkbuf, 128, 0x1a); Wfp = 0; return 1; } else if (errno) return -1; Wfp = fp; Wsct = fp->fcb.f_record; } return 0; } ioctl.c /* Copyright (C) 1984 by Manx Software Systems */ #include "io.h" #include "errno.h" #include "sgtty.h" #define TIME 10 /* number of iterations of raw_rd loop */ #define MIN 1 /* minimum number of chars returned from read */ extern int (*Rd_tab[])(); extern int (*Wrt_tab[])(); struct sgttyb Tty_ctl; extern char _Eol; extern int tty_rd(); static int raw_rd(), raw_wr(); static int rd_func, wrt_func; ioctl(fd, cmd, arg) struct sgttyb *arg; { register struct channel *chp; chp = &chantab[fd]; if (chp->c_ioctl == 0) { errno = ENOTTY; return -1; } switch (cmd) { case TIOCGETP: *arg = Tty_ctl; break; case TIOCSETP: Tty_ctl = *arg; Wrt_tab[2] = raw_wr; Rd_tab[2] = raw_rd; if (Tty_ctl.sg_flags&RAW) { rd_func = wrt_func = 6; _Eol = '\r'; break; } else if (Tty_ctl.sg_flags&CBREAK) { rd_func = (Tty_ctl.sg_flags&ECHO) ? 1 : 6; wrt_func = 2; } else { Rd_tab[2] = tty_rd; wrt_func = 2; } if (Tty_ctl.sg_flags&CRMOD) _Eol = '\n'; else _Eol = '\r'; } return 0; } raw_rd(x, buff, len) register char *buff; { int c, i; register int count; for (count = 0 ; count < len ; ) { for (i = TIME ; i-- ; ) if ((c = bdos(rd_func,0xff)) != 0) goto have_char; if (count < MIN) continue; break; have_char: if (c == '\r') c = _Eol; *buff++ = c; ++count; } return count; } raw_wr(kind, buff, len) register char *buff; { register int count; for (count = len ; count-- ; ) { if (*buff == '\n' && (Tty_ctl.sg_flags&CRMOD)) bdos(wrt_func,'\r'); bdos(wrt_func,*buff++); } return len; } isatty.c /* Copyright (C) 1983 by Manx Software Systems */ #include "io.h" #include "errno.h" isatty(fd) { return chantab[fd].c_ioctl; } lseek.c /* Copyright (C) 1982, 1984 by Manx Software Systems */ #include "io.h" #include "errno.h" long lseek(fd, pos, how) long pos; { register struct fcbtab *fp; if (chantab[fd].c_seek == 0) { Badf: errno = EBADF; return -1L; } fp = (struct fcbtab *)chantab[fd].c_arg; switch (how) { case 2: /* * Close the file because CP/M doesn't know how big an open file is. * However, the fcb is still valid. */ setusr(fp->user); fp->fcb.f_name[4] |= 0x80; /* set parital close flag for MP/M */ bdos(CLSFIL, &fp->fcb); fp->fcb.f_name[4] &= 0x7f; /* clear parital close flag */ _Ceof(fp); rstusr(); case 1: pos += fp->offset + ((long)fp->fcb.f_record << 7); case 0: break; default: errno = EINVAL; return -1L; } fp->fcb.f_overfl = 0; if (pos < 0) { fp->offset = fp->fcb.f_record = 0; errno = EINVAL; return -1L; } fp->offset = (unsigned)pos & 127; fp->fcb.f_record = pos >> 7; return pos; } open.c /* Copyright (C) 1982 by Manx Software Systems */ #include "errno.h" #include "fcntl.h" #include "io.h" #define MAXFILE 8 /* maximum number of open DISK files */ int bdf_(), ret_(), fileop(); /* * note: The ioctl function knows that the condev read/write numbers are * 2. It uses this information to patch the read/write tables. */ static struct device condev = { 2, 2, 1, 0, ret_ }; static struct device bdosout= { 0, 3, 0, 0, ret_ }; static struct device bdosin = { 3, 0, 0, 0, ret_ }; static struct device filedev= { 1, 1, 0, 1, fileop }; /* * device table, contains names and pointers to device entries */ static struct devtabl devtabl[] = { { "con:", &condev, (_arg)2 }, { "CON:", &condev, (_arg)2 }, { "lst:", &bdosout,(_arg)5 }, { "LST:", &bdosout,(_arg)5 }, { "prn:", &bdosout,(_arg)5 }, { "PRN:", &bdosout,(_arg)5 }, { "pun:", &bdosout,(_arg)4 }, { "PUN:", &bdosout,(_arg)4 }, { "rdr:", &bdosin, (_arg)3 }, { "RDR:", &bdosin, (_arg)3 }, { 0, &filedev, (_arg)0 } /* this must be the last slot in the table! */ }; creat(name, mode) char *name; { return open(name, O_WRONLY|O_TRUNC|O_CREAT, mode); } open(name, flag, mode) char *name; { register struct devtabl *dp; register struct channel *chp; register struct device *dev; int fd, mdmask; for (chp = chantab, fd = 0 ; fd < MAXCHAN ; ++chp, ++fd) if (chp->c_close == bdf_) goto fndchan; errno = EMFILE; return -1; fndchan: for (dp = devtabl ; dp->d_name ; ++dp) if (strcmp(dp->d_name, name) == 0) break; dev = dp->d_dev; mdmask = (flag&3) + 1; if (mdmask&1) { if ((chp->c_read = dev->d_read) == 0) { errno = EACCES; return -1; } } if (mdmask&2) { if ((chp->c_write = dev->d_write) == 0) { errno = EACCES; return -1; } } chp->c_arg = dp->d_arg; chp->c_ioctl = dev->d_ioctl; chp->c_seek = dev->d_seek; chp->c_close = ret_; if ((*dev->d_open)(name, flag, mode, chp, dp) < 0) { chp->c_close = bdf_; return -1; } return fd; } static struct fcbtab fcbtab[MAXFILE]; static fileop(name,flag,mode,chp,dp) char *name; struct channel *chp; struct devtabl *dp; { register struct fcbtab *fp; int filecl(); int user; for ( fp = fcbtab ; fp < fcbtab+MAXFILE ; ++fp ) if ( fp->flags == 0 ) goto havefcb; errno = EMFILE; return -1; havefcb: if ((user = fcbinit(name,&fp->fcb)) == -1) { errno = EINVAL; return -1; } if (user == 255) user = getusr(); setusr(user); if (flag & O_TRUNC) bdos(DELFIL, &fp->fcb); if (bdos(OPNFIL,&fp->fcb) == 0xff) { if ((flag&(O_TRUNC|O_CREAT)) == 0 || bdos(MAKFIL,&fp->fcb) == 0xff) { errno = ENOENT; rstusr(); return -1; } } else if ((flag&(O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) { errno = EEXIST; goto punt; } else if ((flag&3) > 0 && fp->fcb.f_type[0]&0x80) { errno = EACCES; punt: bdos(CLSFIL, &fp->fcb); rstusr(); return -1; } fp->offset = fp->fcb.f_overfl = fp->fcb.f_record = 0; fp->user = user; chp->c_arg = (_arg)fp; fp->flags = (flag&3)+1; chp->c_close = filecl; if (flag&O_APPEND) _Ceof(fp); rstusr(); return 0; } static filecl(fp) register struct fcbtab *fp; { _zap(); /* zap work buffer, so data is not reused */ setusr(fp->user); bdos(CLSFIL,&fp->fcb); rstusr(); fp->flags = 0; return 0; } read.c /* Copyright (C) 1983, 1984 by Manx Software Systems */ #include "io.h" #include "errno.h" #include "fcntl.h" int bdf_(), filerd(), tty_rd(), bdosrd(); int (*Rd_tab[])() = { bdf_, filerd, tty_rd, bdosrd, }; extern int errno; read(fd, buff, len) char *buff; { register struct channel *chp; chp = &chantab[fd]; return (*Rd_tab[chp->c_read])((struct fcbtab *)chp->c_arg, buff, len); } static filerd(afp,buffer,len) struct fcbtab *afp; char *buffer; unsigned len; { register unsigned l = 0; register struct fcbtab *fp; unsigned k,j; fp = afp; setusr(fp->user); if (fp->offset) { if ((l = 128 - fp->offset) > len) l = len; if (getsect(fp, buffer, l)) { rstusr(); return 0; } } if (k = (len-l)/128) if ((j = blkrd(&fp->fcb, buffer+l, k)) != 0) { rstusr(); return (k-j)*128 + l; } l += k*128; if (l < len) if (getsect(fp, buffer+l, len-l)) { rstusr(); return l; } rstusr(); return len; } static getsect(fp, buf, len) register struct fcbtab *fp; char *buf; unsigned len; { if (_find(fp)) return -1; movmem(Wrkbuf+fp->offset, buf, len); if ((fp->offset = (fp->offset + len) & 127) == 0) ++fp->fcb.f_record; return 0; } char _Eol = '\n'; tty_rd(x,buff,len) char *buff; { static char buffer[258]; static int used; register int l; if (buffer[1] == 0) { buffer[0] = 255; buffer[1] = buffer[2] = 0; bdos(10,buffer); bdos(2,'\n'); if (buffer[2] == 0x1a) { buffer[1] = 0; return 0; } buffer[++buffer[1] + 1] = _Eol; used = 2; } if ((l = buffer[1]) > len) l = len; movmem(buffer+used, buff, l); used += l; buffer[1] -= l; return l; } static bdosrd(kind, buff, len) register char *buff; { register int count; for (count = 0 ; count < len ; ++count) { if ((*buff++ = bdos(kind)) == 0x1a) break; } return count; } rename.c /* Copyright (C) 1983, 1984 by Manx Software Systems */ #include "errno.h" rename(old, new) char *old, *new; { auto char buff[60]; register int user; user = fcbinit(old,buff); fcbinit(new,buff+16); setusr(user); user = 0; if (bdos(15,buff+16) != 0xff) { bdos(16,buff+16); errno = EEXIST; user = -1; } else if (bdos(23,buff) == 0xff) { errno = ENOENT; user = -1; } rstusr(); return user; } sbrk.asm ; :ts=8 ;Copyright (C) 1983 by Manx Software Systems include lmacros.h dataseg segment word public 'data' extrn $MEMRY:word extrn _mbot_:word, _sbot_:word extrn errno_:word stkred dw 512 dataseg ends assume ds:dataseg ; ; sbrk(size): return address of current top & bump by size bytes ; procdef sbrk,<> push di mov ax,siz mov di,$MEMRY add ax,di push ax call brk_ pop cx jnz brk_error mov ax,di ;return original value of the break ifdef LONGPTR mov dx,ds pop di pret endif brk_error: pop di ifdef LONGPTR mov dx,ax endif test ax,ax ;set flags for C pret pend sbrk ; ; brk(addr): set current top address to addr ; returns 0 if ok, -1 if error ; procdef brk,<> mov ax,addr inc ax and al,-2 mov bx,sp sub bx,stkred cmp ax,bx ;double check with sp for saftey jae brk_ov cmp ax,_mbot_ jb brk_ov mov $MEMRY,ax ;new value is good so save it away add ax,stkred mov _sbot_,ax sub ax,ax pret ; invalid request brk_ov: mov errno_,-4 mov ax,-1 test ax,ax pret pend brk ; ; rsvstk(size): set saftey margin for stack ; this will make sure that at least size ; bytes of stack below the current level remain. ; procdef rsvstk,<> mov ax,stksize mov stkred,ax add ax,$MEMRY mov _sbot_,ax pret pend rsvstk finish end stkover.c _stkover() { bdos(9, "STACK OVERFLOW, INCREASE STACK SIZE\r\n$"); _exit(200); } unlink.c /* Copyright (C) 1983, 1984 by Manx Software Systems */ #include "errno.h" unlink(name) char *name; { auto char delfcb[40]; register int user; user = fcbinit(name,delfcb); setusr(user); user = bdos(19,delfcb); rstusr(); if (user == 0xff) { errno = ENOENT; return -1; } return 0; } user.asm ; Copyright (C) 1984 by Manx Software Systems ; :ts=8 codeseg segment para public 'code' dataseg segment para public 'data' olduser db 0 dataseg ends assume cs:codeseg,ds:dataseg public getusr_ getusr_ proc near push bp push si push di mov cl,32 mov dl,255 int 224 and ax,255 pop di pop si pop bp ret getusr_ endp ; public setusr_ setusr_ proc near push bp mov bp,sp push si push di mov cl,32 mov dl,255 int 224 mov olduser,al ; mov dl,4[bp] cmp dl,255 je skipset mov cl,32 int 224 skipset: pop di pop si pop bp ret setusr_ endp ; public rstusr_ rstusr_ proc near push bp push si push di mov cl,32 mov dl,olduser int 224 pop di pop si pop bp ret rstusr_ endp codeseg ends end write.c /* Copyright (C) 1983, 1984 by Manx Software Systems */ #include "io.h" #include "errno.h" int tty_wr(), bdoswr(), filewr(), bdf_(); int (*Wrt_tab[])() = { bdf_, filewr, bdoswr, bdoswr }; write(fd, buff, len) char *buff; { register struct channel *chp; chp = &chantab[fd]; return (*Wrt_tab[chp->c_write])((struct fcbtab *)chp->c_arg, buff, len); } static filewr(afp,buffer,len) struct fcbtab *afp; char *buffer; unsigned len; { register unsigned l = 0; register struct fcbtab *fp; unsigned k,j; fp = afp; setusr(fp->user); if (fp->offset) { if ((l = 128 - fp->offset) > len) l = len; if (putsect(fp, buffer, l)) { rstusr(); return -1; } } if (k = (len-l)/128) if ((j = blkwr(&fp->fcb, buffer+l, k)) != 0) { rstusr(); if ((l += (k-j)*128) == 0) return -1; else return l; } l += k*128; if (l < len) if (putsect(fp, buffer+l, len-l)) { rstusr(); return l; } rstusr(); return len; } static putsect(fp, buf, len) register struct fcbtab *fp; char *buf; unsigned len; { if (_find(fp) < 0) return -1; movmem(buf, Wrkbuf+fp->offset, len); if ((errno = bdos(WRITRN, &fp->fcb)) != 0) return -1; if ((fp->offset = (fp->offset + len) & 127) == 0) ++fp->fcb.f_record; return 0; } tty_wr(kind, buff, len) register char *buff; { register int count; for (count = len ; count-- ; ) { if (*buff == '\n') bdos(2,'\r'); bdos(2,*buff++); } return len; } static bdoswr(kind, buff, len) register char *buff; { register int count; for (count = len ; count-- ; ) bdos(kind,*buff++); return len; }