IMD 1.17: 30/09/2008 10:06:42 Aztec C Disk2    SCANF C D COMPIP COM:FSCANF C SSCANF C SCAN C #PRINTF BAK FPRINTF C  SPRINTF C  FORMAT C  FOPEN C FDOPEN C FREAD C FWRITE C FSEEK C GETS C MREXT ASM XOVLOADERC YOVBGN ASM ZBEGIN ASM[MBEGIN ASM\ROM ASM ]CSAVE ASM ^FMTCVT ASM _BLKIO ASM`BDOS ASMaBIOS ASMbFCBINIT ASMcSBRK ASMdLOADER ASM eUSER ASMfSETJMP ASM gQSORT C 3CTYPE C 4EXECL C 5EXEC C 6LIBC H 7ERRNO H 8FCNTL H 9IO H :MATH H ;SETJMP H <SGTTY H =STDIO H >CTYPE H ?SIN C @TAN C AASIN C B/* Copyright (C) 1982 by Manx Software Systems */ #include "stdio.h" static int scnlast; scanf(fmt, args) char *fmt; int *args; { int gchar(); scnlast = 0; return scanfmt(gchar, fmt, &args); } static gchar(what) { if (what == 0) { if (feof(stdin)) scnlast = EOF; else scnlast = agetc(stdin); } else scnlast = ungetc(scnlast, stdin); return scnlast; } FGETS C GETCHAR C AGETC C GETW C GETC C PUTS C FPUTS C PUTCHAR C PUTERR C APUTC C PUTW C PUTC C UNGETC C GETBUFF C  SETBUF C !CROOT C "STRCMP ASMhSTRCPY ASMiSTRNCPY ASMjSTRCAT ASMkINDEX ASMlRINDEX ASMmSTRLEN ASMnSETMEM ASMoMOVMEM ASMpSWAPMEM ASMqTOUPPER ASMrLSUBS ASMAstuDIVIDE ASM vSHIFTS ASMwBITOPR ASMxSUPPORT ASMyATAN C CSINH C DTANH C EPOW C FSQRT C GLOG C HRANDOM C IEXP C JFLOOR C KATOF ASMLFTOA ASM+MNFREXP ASM OFSUBS ASMPQRSTR C UCRBEGIN ASMVREXT ASM WOPEN C #CLOSE C $IOCTL C %READ C &WRITE C 'LSEEK C (POSIT C )CEOF C *FIND C +ISATTY C ,RENAME C -UNLINK C .ATOL C /ATOI C 0CALLOC C 1MALLOC C 2PORT ASMzSCANF ASM{SCANF O |PRINTF C } *( * " 3*1 #" " " *5 " > # R : B * +" ! +s#r( ! 6: " * ~2 * #" * +" > ʶ : 2 Ғ * +" : <2 O>ҳ ! 6* #" * ~2 p K* DMf = * *% DMf = * *% DMf = *( #"( K*# DMf = * *% DMf = : AOK :K . g S -A >>!  ~?l W >#^ : /!:' —  ʑ #‹  W ʢ #™ i`N#FogDM!>))덑o|g =¼ DM!>)) = ^#V) ^#V|g}o ABORTED$BAD PARAMETER$INVALID USER NUMBER$RECORD TOO LONG$INVALID DIGIT$END OF FILE, CTL-Z?$CHECKSUM ERROR$CORRECT ERROR, TYPE RETURN OR CTL-Z$INVALID FORMAT$HEX$$$$NO DIRECTORY SPACE$NO FILE$COM$START NOT FOUND$QUIT NOT FOUND$CANNOT CLOSE DESTINATION FILE$DESTINATION IS R/O, DELETE (Y/N)?$**NOT DELETED**$$$$$$$NOT FOUND$COPYING -$REQUIRES CP/M 2.0 OR NEWER FOR OPERATION.$UNRECOGNIZED DESTINATION$CANNOT WRITE$INVALID PIP FORMAT$CANNOT READ$INVALID SEPARATOR$1 :2L> ̈́M9 M "I *K  )*= ^#V"O I G  *G )*= N#F*O ? J*G #"G (*I )*= ^#V*O DM? m*I +"I JI G  *G )*= ^#V"Q *I )*= *G )*= N#Fq#p*I )*= *Q s#r*G #"G *I +"I K I  G M   !M G  :S <2S O!T *G s#r*S &l ) *M s#r*I "M ^I K  X:S <2S O!T *K s#r*S &l ) *I s#r*G "K û!" "    #* #" )*= * #" )*= N#Fq#p   * )*= * ) *= ^#VN#F? H * #" )*= ^#V";  *; ^#V" * )*= !p+q* !q*& *M *M !p+q*!!p+q*"!p+q*$!6  !kp+q*j> >ڪ Þ !qp+q/ *pDM9: :M2r:N!r !:r *r& N!r4 !6:͔: :ͳ.!ws+p+q+p+q:w=2wN *s*u w*s#"s*u#"u' !"*M^7 !x6:!xھ **DM͆ 2yʭ :yʗ ͯ *"*6:2x÷ *"!x4d !"/ !j}=2| !"*KM^'_ !z6:|!z1 * Hit SPACEName Ext Bytes UN At ! File(s), occupying K of K total capacity directory entries and K bytes remain on 1 !9" ! J> # ->! . *ͪe> # < * v K  K  K !B r+s+p+qA ?  p*A *? :]$Ž l]Q !]6 !E 6!C 6 :C *C &l ~2D U¼:E 2 :D S:E 2:D F:E 2:D V:E 2:D P:E 2 :D N2E ! _{ozgO{ozgi`N#Fogo&og_{_z#W OK = Y -S {-_ ! s+p+q*  ͼ 2 <2 : ! ڗ  K ! 4Á ! 6: =! ڻ * & NK ! 4œ >3  03} Z; { ) # 221@:2!o6+6+6!6#6!6#6:G*o .!N6:^*M^!K6!6!6+6' :$::=2K  :ʤ\:ҷ\x'Ͳ:!\͢  :͈'! Ͳ:$: $͈Ͳ!N6' :!Cwͯ !6:^͢c!6{:/>!/H{ͯ :<2Š ::=HҮͯ !6:Ҿ:2 !6::/H͈;!6:> !/>^#V"; *;  ͪ  *; q#pÝn* " ! p+q* )*= ^#V"; ! 6> ! i* &*; >OK : <2 E:/ *; ^#V*% DMf KK : *; Nf E*; ~ڻWK þE *; ~SK E = ! 6:! '= :/ = : = !: = : <2 * " !" >! .  * *&͵ "( * *&͵ > j*( #"( *DM*( V"( !" (   K!" }2 : <2 O:* * * "    >! = * DM** +" *( * " Ø* #" *&(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE) COPYRIGHT (C) 1979, DIGITAL RESEARCH, PIP VERS 1.5$$$ SUB =.:,<> _[]INPIRDPTRUR1UR2RDROUTLPTUL1PRNLSTPTPUP1UP2PUNTTYCRTUC1CONNULEOFDISK READ ERROR$DISK WRITE ERROR$VERIFY ERROR$NOT A CHARACTER SINK$READER STOPPING $NOT A CHARACTER SOURCE$ "}*}DM͆ ' ͯ *"!z4 :e !"͆ !z6:|!z '? 2*H#"H!{6:{ր!Ң *{& :{4 2!{4m *":ڹ ͯ !z4I '2!"!q: !4>!S :S! :2*M! ^#V͎ * :w*#" = = = = = ͯ  *M !6q  !6q  !6q  *& !6à  !6 à  !60à  *& !6  !6  !6  *& . 1 4 7 : = F P [ f q  C 4Ø:!4:!5(  ! I3= : [= t:\a:\=_: :] t ?]\ : ҃! 6?Î : 2   ]Q  ?\\ : DM, Q ! "= *3 ##)*= "; */ &# "! *3 #"#  !! "% >!1 . 2' \: 2 : ʩ: ƀo&"* ~ʛ*# +"# ** DMY қ** DM  *; q#p* " . ** #DM*; -e**  *; w* #" )*= *; s#r*; "; : 2 !S 6!"V * "n >!S d*S &T ) ^#V"K O!l ^#V"M :S =2S M K  a*K "G *HHͯ :^!w:<2:0}:@E}:!S!W6: z!]6:cm!c6:_z!_6l ::,: HHҰͯ : 2ó:E:1:2v!q!*8!*6: >ͦ>ͦ!q:_  !p+q.*   !q*&!p+q*2!p+q*2!p+q*22!p+q*!p+q*!p+q*!p+q*2!p+q*  :2!q: " *M n :c4 *M n :2!c:Q !c:2: !:cw>!n !5 Y : { !6!q:!lwҙ  â :0O !q:O| :O| !6:]2l:o'2o:n'2n:m'2m*mMͣ *nMͣ *oMͣ :]:   *}2D" * * *&"!q:UY: Y:ҩ: ʩ:_2ʘ:€!6<:<2!ژ!6 >!]Ҥ; !6:Q::H: !6*M : !6!q:a/>z!-:>>!p+q:,!6*DM9:<!6:z 2W!6D*&L :w:<2Ov*:>=20O> ڒ:0:AO>Ҥ::A }}Hͬ!wͻO`idͻV[2O>2:!X!6:!:=O!L NE!4 E E:/.*&L 6$L9k9.Xͯ *KM^020 :020:121'ͳ':²ͯ !G6!"!"7 *M^n/ :a/:H!6:ͯ !&6/* Copyright (C) 1982 by Manx Software Systems */ #include "stdio.h" static int scnlast; static FILE *scnfp; fscanf(fp, fmt, args) FILE *fp; char *fmt; int *args; { int gchar(); scnfp = fp; scnlast = 0; return scanfmt(gchar, fmt, &args); } static gchar(what) { if (what == 0) { if (feof(scnfp)) scnlast = EOF; else scnlast = agetc(scnfp); } else scnlast = ungetc(scnlast, scnfp); return scnlast; } *M8):[ͱ!N5!6ñ:5!6#6>!ڰ!6:<2O>/:!O!T *M͡H~K:¡!6[–ͱ!N5:2:2!4=:[¼ͱ4:!6:.2O8: :* ͇g:[ ͱ!N5!6:%:<2*6 * 6å!q!6> !d*&I :]>!4A>:<2O* :w:?†!6!q!6?!:ҠgÐ!q*&*~!6:22: :]Hں:A2O>: 2ͯ DM!  ::=H-\:N2O_og_{ozg^#V))) _{ozg^#V) d^#V|g}o n_{ozgO{ozgi`N#Fogo&og H ©=¨' !'6!36' :1/!aE*#">z?C9IͲÁ.!6> !ڇ*&' ~2 ʀ: y.*M!4Q>!қ:=2á:2:Ҭ\>!ҿ:=2K:2K!:!:K\: \!p+q͈*/H:_2:!q:A/>Z!/H8: 2::=O>m:W!Q} Hmd>9>!6:2*M!E ^#V͎ڗO **~2*#"m2m͖ 2m!6m!6m!6 m2mͯ m!62m!62m!62m!62m'2:2:TҒ:2!6*ME:2::Ҳ:<22ý: 2:} >ͯ :i:2:d*M:[ 2*">!b!ͯ >!`0ͯ !q:E:24J!46*}a!44EJ *KM^'́:‚ͯ !36'n::0:f9OY#9.3'ͳ.:020' 'ͳ'7 6'!j>A+!s!"@͓1!"<**"͓n "Dn"":!Q2҂:X!Wғä:ڤ*MEÓ:ұ@@:O2Mc;!6#6>!)*&P ~"::H:H÷:S:QHI:N<22: H@"2Í202O> c!6Í202O> ڍ*&O*& !sc*&P :w:·>!ұͯ :22:_!6=!6>'!E!4!p+q*0 !r+s+p+q*~$7*>*>H&>*#"*#"> 2:R͎:!6!6=2:ʙ!6:“H9Ž>!6-e!6ͻ2=2ʺ-é:>>"ͻ2:!!5ͻ2ͬ!\*M:>!(:=2%> >>!F!5+N! ~2!4<2T>>!b}*bMͭz:b2!b6:<2é>!`ҥ*`MͭҞ!`6!6> :é:(!q:!wO! ~2*& :w>!:!4!6>:N<2N!> *N& N2 !p+q!6!6+6 !6: S: M!6g8:N2M*M8p!6!6!6>!ڕ*&P 6!4z!6!6#6#6!6*M8:ھ:*͇g2ê::¿::,͡A<2O>:H:H"!6!4:_jYO jM*"S*" 3@bl*M1͓!""7 *M^͆ \͔!":͎H*#"ͧÝ/ :>͛9ͯ .*#":_!' !'6!36' :1/!aE*#">z?C9IͲÁ.!6> !ڇ*&' ~2 ʀ: y.*M!4Q>!қ:=2á:2:Ҭ\>!ҿ:=2K:2K!:!:K\: \!p+q͈* @@@/* Copyright (C) 1983 by Manx Software Systems */ static char *scnstr; static char quit; sscanf(string, fmt, arg) char *string, *fmt; int *arg; { int sgetc(); scnstr = string; quit = 0; return scanfmt(sgetc, fmt, &arg); } static sgetc(what) { if (what == 0) { if (*scnstr) return *scnstr++ & 255; quit = 1; } else { if (!quit) return *--scnstr & 255; } return -1; } @for compatibility) */ lflag = 0; goto decimal; case 'D': lflag = 1; case 'd': decimal: c = 12; base = 10; goto getval; case 'X': lflag = 1; case 'x': c = 0; base = 16; goto getval; case 'O': lflag = 1; case 'o': c = 14; base = 8; getval: if (skipblank()) goto stopscan; if (getnum(&list[c], &vals[c], base, &lv) == 0) goto stopscan; if (!suppress) { if (lflag) *(long *)(*arg@@/* Copyright (C) 1982, 1984 by Manx Software Systems */ #include #define EOF -1 static int maxwidth; static int (*gsub)(); char *index(); scanfmt(getsub, fmt, args) int (*getsub)(); register char *fmt; register int **args; { #ifdef FLOAT double atof(); #endif long lv; register int c, count, base; char suppress, lflag, widflg; char *cp; auto char tlist[130]; static char list[] = "ABCDEFabcdef9876543210"; static char vals[] = { 10,11,12,13,14,15,10,11,12,13,14,15,@@s++) = lv; else **args++ = lv; ++count; } break; #ifdef FLOAT case 'E': case 'F': lflag = 1; case 'e': case 'f': if (skipblank()) goto stopscan; if (getflt(tlist)) goto stopscan; if (!suppress) { if (lflag) *(double *)(*args++) = atof(tlist); else *(float *)(*args++) = atof(tlist); ++count; } break; #endif case '[': lflag = 0; if (*fmt == '^' || *fmt == '~') { ++fmt;@@9,8,7,6,5,4,3,2,1,0 }; count = 0; gsub = getsub; while (c = *fmt++) { if (c == '%') { widflg = lflag = suppress = 0; maxwidth = 127; if (*fmt == '*') { ++fmt; suppress = 1; } if (isdigit(*fmt)) { maxwidth = 0; do { maxwidth = maxwidth*10 + *fmt - '0'; } while (isdigit(*++fmt)); } if (*fmt == 'l') { lflag = 1; ++fmt; } switch (*fmt++) { case '%': c = '%'; goto matchit; case 'h': /* specify short (  lflag = 1; } for (cp = tlist ; (c = *fmt++) != ']' ; ) *cp++ = c; *cp = 0; goto string; case 's': lflag = 1; tlist[0] = ' '; tlist[1] = '\t'; tlist[2] = '\n'; tlist[3] = 0; string: if (skipblank()) goto stopscan; charstring: if (!suppress) cp = *args++; widflg = 0; while (maxwidth--) { if ((c = (*gsub)(0)) == EOF) break; if (lflag ? (index(tlist,c)!=0) : (index(tlist,c)==0)) { (*gsub)(@@ decpt = 1; else if (!exp && (c == 'e' || c == 'E')) { sign = 0; exp = decpt = 1; } else if (!isdigit(c)) { (*gsub)(1); break; } *cp++ = c; } *cp = 0; return cp==buffer; } #endif getnum(list, values, base, valp) char *list; char *values; long *valp; { register char *cp; register int c, cnt; long val; int sign; if (maxwidth <= 0) return 0L; val = cnt = sign = 0; if ((c = (*gsub)(0)) == '-') { sign = 1; ++cnt; } else if (c == '+') ++cnt; @@1); /* unget last character */ break; } if (!suppress) *cp++ = c; widflg = 1; } if (!widflg) goto stopscan; if (!suppress) { *cp = 0; ++count; } break; case 'c': if (!widflg) maxwidth = 1; tlist[0] = 0; lflag = 1; goto charstring; } } else if (isspace(c)) { if (skipblank()) goto stopscan; } else { matchit: if ((*gsub)(0) != c) { (*gsub)(1); goto stopscan; } } @@ else (*gsub)(1); for ( ; cnt < maxwidth ; ++cnt) { if ((cp = index(list, c = (*gsub)(0))) == 0) { if (base == 16 && val == 0 && (c=='x' || c=='X')) continue; (*gsub)(1); break; } val *= base; val += values[cp-list]; } if (sign) *valp = -val; else *valp = val; return cnt; }  return 0L; val = cnt = sign = 0; if ((c = (*gsub)(0)) == '-') { sign = 1; ++cnt; } else if (c == '+') ++cnt; @@} stopscan: if (count == 0) { if ((*gsub)(0) == EOF) return EOF; (*gsub)(1); } return count; } skipblank() { while (isspace((*gsub)(0))) ; if ((*gsub)(1) == EOF) return EOF; return 0; } #ifdef FLOAT getflt(buffer) char *buffer; { register char *cp; register int c; char decpt, sign, exp; cp = buffer; sign = exp = decpt = 0; while (maxwidth--) { c = (*gsub)(0); if (!sign && (c == '-' || c == '+')) sign = 1; else if (!decpt && c == '.') @/* Copyright (C) 1981,1982 by Manx Software Systems */ printf(fmt,args) char *fmt; unsigned args; { extern int putchar(); format(putchar,fmt,&args); }  @/* Copyright (C) 1981,1982 by Manx Software Systems */ #include "stdio.h" static FILE *Stream; fprintf(stream,fmt,args) FILE *stream; char *fmt; unsigned args; { int fpsub(); Stream = stream; return format(fpsub,fmt,&args); } static fpsub(c) { return aputc(c,Stream); } @@@/* Copyright (C) 1982 by Manx Software Systems */ static char *buff; sprintf(str,fmt,args) char *str, *fmt; unsigned args; { int spsub(); register int i; buff = str; i = format(spsub,fmt,&args); *buff = 0; return i; } static spsub(c) { return (*buff++ = c)&0xff; } @@@@@@@@@ @@cp && k < maxwidth ; ++k ) if ((*putsub)(*cp++) == -1) return -1; charcount += k; if ( !rj ) { for (; width-- > i ; ++charcount) if ((*putsub)(' ') == -1) return -1; } } else { if ((*putsub)(c) == -1) return -1; ++charcount; } } return charcount; } if ( rj ) { for (; width-- > i ; ++charcount) if ((*putsub)(fillc) == -1) return -1; } for ( k = 0 ; *@dth = maxwidth*10 + c - '0'; } } i = sizeof(int); if (c == 'l') { c = *fmt++; i = sizeof(long); } else if (c == 'h') c = *fmt++; switch ( c ) { case 'o': k = 8; goto do_conversion; case 'u': k = 10; goto do_conversion; case 'x': k = 16; goto do_conversion; case 'd': k = -10; do_conversion: cp = fmtcvt(args.cp, k, s+14, i); args.cp += i; break; case 's': i = strlen(cp = *args.cpp++); @@/* Copyright (C) 1981,1982,1983 by Manx Software Systems */ #include char *fmtcvt(); format(putsub, fmt, argp) register int (*putsub)(); register char *fmt; char *argp; { register int c; union { int *ip; char *cp; char **cpp; #ifdef FLOAT double *dp; #endif } args; int charcount; int rj, fillc; int maxwidth, width; int i, k; char *cp; auto char s[200]; charcount = 0; args.cp = argp; while ( c = *fmt++ ) { if ( c == '%' ) { s[14] = 0; rj @@ goto havelen; #ifdef FLOAT case 'e': case 'f': case 'g': ftoa(*args.dp++, s, maxwidth==10000?6:maxwidth, c-'e'); i = strlen(cp = s); maxwidth = 200; goto havelen; #endif case 'c': c = *args.ip++; default: *(cp = s+13) = c; break; } i = (s+14) - cp; havelen: if ( i > maxwidth ) i = maxwidth; if ( rj ) { for (; width-- > i ; ++charcount) if ((*putsub)(fillc) == -1) return -1; } for ( k = 0 ; */* Copyright (C) 1981,1982,1983,1984 by Manx Software Systems */ #include "stdio.h" #include "fcntl.h" #include "errno.h" extern int errno; static struct modes { char fmode[3]; int omode; } modes[] = { "r", O_RDONLY, "r+", O_RDWR, "w", (O_WRONLY|O_CREAT|O_TRUNC), "w+", (O_RDWR|O_CREAT|O_TRUNC), "a", (O_WRONLY|O_CREAT|O_APPEND), "a+", (O_RDWR|O_CREAT|O_APPEND), "x", (O_WRONLY|O_CREAT|O_EXCL), "x+", (O_RDWR|O_CREAT|O_EXCL), "", 0, }; FILE * fopen(name,mode) char *name,*m@= 1; fillc = ' '; maxwidth = 10000; if ((c = *fmt++) == '-') { rj = 0; c = *fmt++; } if (c == '0') { fillc = '0'; c = *fmt++; } if (c == '*') { width = *args.ip++; c = *fmt++; } else { for (width = 0 ; isdigit(c) ; c = *fmt++) width = width*10 + c - '0'; } if ( c == '.' ) { if ((c = *fmt++) == '*') { maxwidth = *args.ip++; c = *fmt++; } else { for (maxwidth = 0 ; isdigit(c) ; c = *fmt++) maxwi@  ode; { register FILE *fp; FILE *newstream(), *freopen(); if ((fp = newstream()) == NULL) return NULL; return freopen(name, mode, fp); } FILE * freopen(name, mode, fp) char *name,*mode; FILE *fp; { register struct modes *mp; register int fd; fclose(fp); for (mp = modes ; ; ++mp) { if (mp->fmode == 0) { errno = EINVAL; return NULL; } if (strcmp(mp->fmode, mode) == 0) break; } /* Don't try to optimize the next 3 lines. Since _unit is a char, assig@@@@@ning to it in the if statement will cause the -1 test to fail on unsigned char machines. */ if ((fd = open(name, mp->omode)) == -1) return (NULL); fp->_unit = fd; fp->_flags = _BUSY; return fp; } r int fd; fclose(fp); for (mp = modes ; ; ++mp) { if (mp->fmode == 0) { errno = EINVAL; return NULL; } if (strcmp(mp->fmode, mode) == 0) break; } /* Don't try to optimize the next 3 lines. Since _unit is a char, assig@@@@@@/* Copyright (C) 1984 by Manx Software Systems */ #include "stdio.h" FILE * fdopen(fd,mode) char *mode; { register FILE *fp; FILE *newstream(); if ((fp = newstream()) == NULL) return NULL; fp->_unit = fd; fp->_flags = _BUSY; return fp; } @  /* Copyright (C) 1981,1982 by Manx Software Systems */ #include "stdio.h" fread(buffer,size,number,stream) register char *buffer; unsigned size; int number; FILE *stream; { int total; register int c,i; for ( total = 0 ; total < number ; ++total ) { for ( i = size ; i ; --i ) { if ( (c = getc(stream)) == EOF ) return total; *buffer++ = c; } } return total; } @@@/* Copyright (C) 1981,1982 by Manx Software Systems */ #include "stdio.h" fwrite(buffer,size,number,stream) register char *buffer; unsigned size,number; FILE *stream; { register unsigned i,max; max = size * number; for ( i = 0 ; i < max ; ++i ) { if ( putc(*buffer++,stream) == EOF ) return 0; } return number; }  - fp->_buff; else if (fp->_bp) pos -= fp->_bend - fp->_bp; return pos; } gets.c /* Copyright (C) 1981,1982 by Manx Softwar@@@@@@@@@@  @@@@@@/* Copyright (c) 1981, 1982 by Manx Software Systems */ #include "stdio.h" fseek(fp,pos,mode) register FILE *fp; long pos; { register int i; long curpos, lseek(); fp->_flags &= ~_EOF; if (fp->_flags & _DIRTY) { if (flsh_(fp,-1)) return EOF; } else if (mode == 1 && fp->_bp) pos -= fp->_bend - fp->_bp; fp->_bp = fp->_bend = NULL; if (lseek(fp->_unit, pos, mode) < 0) return EOF; return 0; } long ftell(fp) register FILE *fp; { long pos, lseek(); pos = lseek(fp->@@@/* Copyright (C) 1981,1982 by Manx Software Systems */ #include "stdio.h" #undef getchar char *gets(line) char *line; { register char *cp; register int i; cp = line; while ((i = getchar()) != EOF && i != '\n') *cp++ = i; *cp = 0; if (i == EOF && cp == line) return NULL; return line; } ch (c &= 127) { case 0x1a: ptr->_flags |= _EOF; return EOF; case '\r': case 0: goto top; } } return c; } ge@_unit, 0L, 1); /* find out where we are */ if (fp->_flags & _DIRTY) pos += fp->_bp - fp->_buff; else if (fp->_bp) pos -= fp->_bend - fp->_bp; return pos; } urn EOF; } else if (mode == 1 && fp->_bp) pos -= fp->_bend - fp->_bp; fp->_bp = fp->_bend = NULL; if (lseek(fp->_unit, pos, mode) < 0) return EOF; return 0; } long ftell(fp) register FILE *fp; { long pos, lseek(); pos = lseek(fp->@@  @@/* Copyright (C) 1981,1982 by Manx Software Systems */ #include "stdio.h" #undef getchar getchar() { return agetc(stdin); } FOPEN C FDOPEN C  FREAD C  FWRITE C  FSEEK C GETS C FGETS C GETCHAR C @@@@@@@@@/* Copyright (C) 1981,1982 by Manx Software Systems */ #include "stdio.h" char *fgets(s, n, fp) char *s; FILE *fp; { register c; register char *cp; cp = s; while (--n > 0 && (c = agetc(fp)) != EOF) { *cp++ = c; if (c == '\n') break; } *cp = 0; if (c == EOF && cp == s) return NULL; return(s); } FSEEK C GETS C FGETS C @@  @@@/* Copyright (C) 1981,1982 by Manx Software Systems */ #include "stdio.h" agetc(ptr) register FILE *ptr; { register int c; top: if ((c = getc(ptr)) != EOF) { switch (c &= 127) { case 0x1a: ptr->_flags |= _EOF; return EOF; case '\r': case 0: goto top; } } return c; } @@@@/* Copyright (C) 1982 by Manx Software Systems */ #include "stdio.h" getw(stream) FILE *stream; { register int x1,x2; if ((x1 = getc(stream)) == EOF || (x2 = getc(stream)) == EOF) return EOF; return (x2<<8) | x1; } @@@@@@ @@@@@@@@@/* Copyright (C) 1982 by Manx Software Systems */ #include "stdio.h" getc(ptr) register FILE *ptr; { register int len; if (ptr->_bp >= ptr->_bend) { if (ptr->_flags&(_EOF|_IOERR)) return EOF; ptr->_flags &= ~_DIRTY; if (ptr->_buff == NULL) getbuff(ptr); if ((len = read(ptr->_unit,ptr->_buff,ptr->_buflen)) <= 0) { ptr->_flags |= len==0 ? _EOF : _IOERR; return EOF; } ptr->_bend = (ptr->_bp = ptr->_buff) + len; } return *ptr->_bp++ & 255; } @@@@/* Copyright (C) 1981,1982 by Manx Software Systems */ puts(str) register char *str; { while (*str) if (putchar(*str++) == -1) return -1; return putchar('\n'); }  @/* Copyright (C) 1981,1982 by Manx Software Systems */ #include "stdio.h" fputs(s,fp) register char *s; FILE *fp; { while ( *s ) if (aputc(*s++,fp) == EOF) return(EOF); return 0; } EOF; return w; } putc.c /* Copyright (C) 1981,1982,1983,1984 by Manx Software Systems */ #include "stdio.h" putc(c,ptr) int c; register FILE *ptr; { if (ptr->_bp >= ptr->_bend) return flsh_(ptr,c&0xff); return (*ptr->_bp++ = c) & 0xff; } static clo@@@/* Copyright (C) 1981,1982 by Manx Software Systems */ #include "stdio.h" #undef putchar putchar(c) { return aputc(c,stdout); } @@@@@@@@@ @@@@@@@/* Copyright (C) 1981,1982 by Manx Software Systems */ #include "stdio.h" puterr(c) { return aputc(c, stderr); } FPUTS C PUTCHAR C PUTERR C @@@/* Copyright (C) 1981,1982 by Manx Software Systems */ #include "stdio.h" aputc(c,ptr) register int c; register FILE *ptr; { if (c == '\n') if (putc('\r',ptr) == EOF) return EOF; return putc(c,ptr); } @@@ @@@@@@@@@@@@@/* Copyright (C) 1981,1982 by Manx Software Systems */ #include "stdio.h" putw(w,stream) register unsigned w; FILE *stream; { if ( putc(w,stream) < 0 ) return EOF; else if ( putc((w>>8),stream) < 0 ) return EOF; return w; } PUTW C @ /* Copyright (C) 1981,1982,1983,1984 by Manx Software Systems */ #include "stdio.h" putc(c,ptr) int c; register FILE *ptr; { if (ptr->_bp >= ptr->_bend) return flsh_(ptr,c&0xff); return (*ptr->_bp++ = c) & 0xff; } static closall() /* called by exit to close any open files */ { register FILE *fp; for ( fp = Cbuffs ; fp < Cbuffs+MAXSTREAM ; ) fclose(fp++); } fclose(ptr) register FILE *ptr; { register int err; err = 0; if ( ptr->_flags ) { if (ptr->_flags&_DIRTY) /*@@@/* Copyright (c) 1981, 1982 by Manx Software Systems */ #include "stdio.h" ungetc(c,ptr) int c; register FILE *ptr; { if (c == EOF || ptr->_bp <= ptr->_buff) return EOF; *--ptr->_bp = c; return c; } PUTW C PUTC C UNGETC C @ if modifed flush buffer */ err = flsh_(ptr,-1); err |= close(ptr->_unit); if (ptr->_flags&_ALLBUF) free(ptr->_buff); } ptr->_flags = 0; return err; } flsh_(ptr,data) register FILE *ptr; { register int size; extern int (*cls_)(); cls_ = closall; if (ptr->_flags & _IOERR) return EOF; if (ptr->_flags & _DIRTY) { size = ptr->_bp - ptr->_buff; if (write(ptr->_unit, ptr->_buff, size) != size) { ioerr: ptr->_flags |= _IOERR; ptr->_bend = ptr->_bp = NULL; @@@@@ return EOF; } } if (data == -1) { ptr->_flags &= ~_DIRTY; ptr->_bend = ptr->_bp = NULL; return 0; } if (ptr->_buff == NULL) getbuff(ptr); if (ptr->_buflen == 1) { /* unbuffered I/O */ if (write(ptr->_unit, &data, 1) != 1) goto ioerr; return data; } ptr->_bp = ptr->_buff; ptr->_bend = ptr->_buff + ptr->_buflen; ptr->_flags |= _DIRTY; return (*ptr->_bp++ = data) & 0xff; } @@ @@@@@@/* Copyright (C) 1983 by Manx Software Systems */ /* Copyright (C) 1981,1982 by Manx Software Systems */ #include "stdio.h" FILE Cbuffs[MAXSTREAM] = { { 0,0,0, _BUSY,0,0,1 }, { 0,0,0, _BUSY,1,0,1 }, { 0,0,0, _BUSY,2,0,1 }, }; FILE * newstream() { register FILE *fp; fp = Cbuffs; while (fp->_flags) if (++fp >= &Cbuffs[MAXSTREAM]) return NULL; fp->_buff = fp->_bend = /* nothing in buffer */ fp->_bp = 0; return fp; } getbuff(ptr) register FILE *ptr; { char *bu@@@/* Copyright (C) 1981,1982 by Manx Software Systems */ #include "stdio.h" setbuf(stream, buffer) register FILE *stream; char *buffer; { if (stream->_buff) return; if (buffer) { stream->_buff = buffer; stream->_buflen = BUFSIZ; } else { stream->_buff = &stream->_bytbuf; stream->_buflen = 1; } } SETBUF C @ffer; if (isatty(ptr->_unit)) { smlbuff: ptr->_buflen = 1; ptr->_buff = &ptr->_bytbuf; return; } if ((buffer = malloc(BUFSIZ)) == NULL) goto smlbuff; ptr->_buflen = BUFSIZ; ptr->_flags |= _ALLBUF; ptr->_buff = buffer; return; } buff = fp->_bend = /* nothing in buffer */ fp->_bp = 0; return fp; } getbuff(ptr) register FILE *ptr; { char *bu@@ @gc++] = 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; } /* 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_ }; statif_, 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@g&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; } close(fd) { register struct channel *chp; if (fd < 0 || fd@@c struct device filedev= { 1, 1, 0, 1, fileop }; /* * device table, contains names and pointers to device entries */ static struct devtabl devtabl[] = { { "con:", &condev, 2 }, { "CON:", &condev, 2 }, { "lst:", &bdosout, 5 }, { "LST:", &bdosout, 5 }, { "prn:", &bdosout, 5 }, { "PRN:", &bdosout, 5 }, { "pun:", &bdosout, 4 }, { "PUN:", &bdosout, 4 }, { "rdr:", &bdosin, 3 }, { "RDR:", &bdosin, 3 }, { 0, &filedev, 0 } /* this must be the last slot in the table! */ }; creat(n 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[Ar@ > 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; } 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 =/* 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_, 2 }, { 0, 2, 1, 0, ret_, 2 }, { 0, 2, 1, 0, ret_, 2 }, { 0, 0, 0, 0, bdf_, 0 }, { 0, 0, 0, 0, bdf_, 0 }, { 0, 0, 0, 0, bdf_, 0 }, { 0, 0, 0, 0, bdf_, 0 }, { 0, 0, 0, 0, bdf_, 0 }, { 0, 0, 0, 0, bdf_, 0 }, { 0, 0, 0, 0, bdf_, 0 }, { 0, 0, 0, 0, bd@ame, 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 = (fla  ENFILE; 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; rstusr(); return -1; } fp->offse@@/* 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; } @ _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-- t = fp->fcb.f_overfl = fp->fcb.f_record = 0; fp->user = user; chp->c_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; } @/* 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 = &@@; ) { if (*buff == '\n' && (Tty_ctl.sg_flags&CRMOD)) bdos(wrt_func,'\r'); bdos(wrt_func,*buff++); } return len; }  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-- @@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)  @ster 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 @@@,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) regist@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[@/* 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])(chp->c_arg, buff, len); } static filerd(afp,buffer,len) struct fcbtab *afp; char *buffer; unsigned len; { register unsigned l = 0; regi@er 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 ch@++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; } buffer[2] = 0; bdos(10,buffer); bdos(2,'\n'); if (buffer[2] == 0x1a) { buffer[1] = 0; return 0; } buffer[/* 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])(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 ar *buff; { register int count; for (count = len ; count-- ; ) bdos(kind,*buff++); return len; }  ((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 ch/* 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 = 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 */ @@@/* Copyright (C) 1982,1983 by Manx Software Systems */ #include "io.h" #include "errno.h" posit(fd, pos) unsigned pos; { register struct fcbtab *fp; if (chantab[fd].c_seek == 0) { errno = EBADF; return -1; } fp = chantab[fd].c_arg; fp->fcb.f_record = pos; fp->offset = fp->fcb.f_overfl = 0; return 0; } @ 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; } @@@@@@@ @@@@@@@/* 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 = cp-Wrkbuf) == 128) { ++fp->fcb.f_record; fp->offset = 0; } @@@/* 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@ return 0; }  { 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 = cp-Wrkbuf) == 128) { ++fp->fcb.f_record; fp->offset = 0; } @ ->fcb.f_record; } return 0; } ) /* 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@@@@@@@@@@@@/* Copyright (C) 1983 by Manx Software Systems */ #include "io.h" #include "errno.h" isatty(fd) { return chantab[fd].c_ioctl; } @ /* 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; } @@@/* 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; } @@@@@@@@@@ @@@@@@/* Copyright (C) 1982 by Manx Software Systems */ #include long atol(cp) register char *cp; { long n; register sign; while (*cp == ' ' || *cp == '\t') ++cp; sign = 0; if ( *cp == '-' ) { sign = 1; ++cp; } else if ( *cp == '+' ) ++cp; for ( n = 0 ; isdigit(*cp) ; ) n = n*10 + *cp++ - '0'; return sign ? -n : n; } ned size; { register char *cp; unsigned osize; char *malloc(); osize = (((FREE *)area-1)->f_size - 1) * sizeof(FREE); free@@@/* Copyright (C) 1981,1982 by Manx Software Systems */ #include atoi(cp) register char *cp; { register unsigned i; register sign; while (*cp == ' ' || *cp == '\t') ++cp; sign = 0; if ( *cp == '-' ) { sign = 1; ++cp; } else if ( *cp == '+' ) ++cp; for ( i = 0 ; isdigit(*cp) ; ) i = i*10 + *cp++ - '0'; return sign ? -i : i; } @@@@ @@/* Copyright (C) 1984 by Manx Software Systems */ typedef struct freelist { unsigned f_size; struct freelist *f_chain; } FREE; #define NULL (FREE *)0 #define GRAIN 1024 static FREE head, *last; char * realloc(area, size) register char *area; unsigned size; { register char *cp; unsigned osize; char *malloc(); osize = (((FREE *)area-1)->f_size - 1) * sizeof(FREE); free(area); if ((cp = malloc(size)) != 0 && cp != area) movmem(area, cp, size>osize ? osize : size); return@@ } } } free(area) char *area; { register FREE *tp, *hole; hole = (FREE *)area - 1; if (hole->f_chain != NULL) return -1; for (tp = last ; tp > hole || hole > tp->f_chain ; tp = tp->f_chain) if (tp >= tp->f_chain && (hole > tp || hole < tp->f_chain)) break; hole->f_chain = tp->f_chain; tp->f_chain = hole; last = tp; return 0; } FREE *)-1) return (char *)NULL; tp->f_size = GRAIN/sizeof(FREE); tp->f_chain = NULL; free(tp+1); tp = last;@@ cp; } char * malloc(size) unsigned size; { register FREE *tp, *prev; char *sbrk(); int units; units = (size+sizeof(FREE)-1)/sizeof(FREE) + 1; if ((prev = last) == NULL) last = head.f_chain = prev = &head; for (tp = prev->f_chain ; ; prev = tp, tp = tp->f_chain) { while (tp != tp->f_chain && tp+tp->f_size == tp->f_chain) { if (last == tp->f_chain) last = tp->f_chain->f_chain; tp->f_size += tp->f_chain->f_size; tp->f_chain = tp->f_chain->f_chain; } if (tp@@@/* Copyright (C) 1984 by Manx Software Systems */ char *calloc(nelem, size) unsigned nelem, size; { register unsigned i = nelem*size; register char *cp, *malloc(); if ((cp = malloc(i)) != (char *)0) setmem(cp, i, 0); return cp; } RENAME C *UNLINK C +ATOL C ,ATOI C -CALLOC C @->f_size >= units) { if (tp->f_size == units) prev->f_chain = tp->f_chain; else { last = tp + units; prev->f_chain = last; last->f_chain = tp->f_chain; last->f_size = tp->f_size - units; tp->f_size = units; } last = prev; tp->f_chain = NULL; return (char *)(tp+1); } if (tp == last) { if ((tp = (FREE *)sbrk(GRAIN)) == (FREE *)-1) return (char *)NULL; tp->f_size = GRAIN/sizeof(FREE); tp->f_chain = NULL; free(tp+1); tp = last; @ right partition */ } } while (base < r); if (sp <= stack) break; --sp; base = sp->l; r = sp->r; } }  i; sp->r = r; ++sp; } r = j; /* continue sorting left partition */ } else { if (base < j) { /* stack request for left partition */ sp->l = base; sp->r = j; ++sp; } base = i; /* continue sorting@/* Copyright (C) 1984 by Manx Software Systems */ qsort(base, nel, size, compar) char *base; unsigned nel, size; int (*compar)(); { register char *i,*j,*x,*r; auto struct stk { char *l, *r; } stack[16]; struct stk *sp; sp = stack; r = base + (nel-1)*size; for (;;) { do { x = base + (r-base)/size/2 * size; i = base; j = r; do { while ((*compar)(i,x) < 0) i += size; while ((*compar)(x,j) < 0) j -= size; if (i < j) { swapmem(i, j, size@/ 0x01, 0x01, 0x01, 0x40, /* X Y Z [ */ 0x40, 0x40, 0x40, 0x01, /* \ ] ^ _ */ 0x40, 0x0A, 0x0A, 0x0A, /* ` a b c */ 0x0A, 0x0A, 0x0A, 0x02, /* d e f g */ 0x02, 0x02, 0x02, 0x02, /* h i j k */ 0x02, 0x02, 0x02, 0x02, /* l m n o */ 0x02, 0x02, 0x02, 0x02, /* p q r s */ 0x02, 0x02, 0x02, 0x02, /* t u v w */ 0x02, 0x02, 0x02, 0x40, /* x y z { */ 0x40, 0x40, 0x40, 0x20, /* | } ~ del */ } ; @@/* Copyright (C) 1984 by Manx Software Systems */ char ctp_[129] = { 0, /* EOF */ 0x20, 0x20, 0x20, 0x20, /* nul soh stx etx */ 0x20, 0x20, 0x20, 0x20, /* eot enq ack bel */ 0x20, 0x30, 0x30, 0x30, /* bs ht nl vt */ 0x30, 0x30, 0x20, 0x20, /* ff cr so si */ 0x20, 0x20, 0x20, 0x20, /* dle dc1 dc2 dc3 */ 0x20, 0x20, 0x20, 0x20, /* dc4 nak syn etb */ 0x20, 0x20, 0x20, 0x20, /* can em sub esc */ 0x20, 0x20, 0x20, 0x20, /* fs gs rs us */ 0x90, 0x40, 0x40, 0x40, /* sp ! " # */ 0x40); if (i == x) x = j; else if (j == x) x = i; } if (i <= j) { i += size; j -= size; } } while (i <= j); if (j-base < r-i) { if (i < r) { /* stack request for right partition */ sp->l = i; sp->r = r; ++sp; } r = j; /* continue sorting left partition */ } else { if (base < j) { /* stack request for left partition */ sp->l = base; sp->r = j; ++sp; } base = i; /* continue sorting@@@@, 0x40, 0x40, 0x40, /* $ % & ' */ 0x40, 0x40, 0x40, 0x40, /* ( ) * + */ 0x40, 0x40, 0x40, 0x40, /* , - . / */ 0x0C, 0x0C, 0x0C, 0x0C, /* 0 1 2 3 */ 0x0C, 0x0C, 0x0C, 0x0C, /* 4 5 6 7 */ 0x0C, 0x0C, 0x40, 0x40, /* 8 9 : ; */ 0x40, 0x40, 0x40, 0x40, /* < = > ? */ 0x40, 0x09, 0x09, 0x09, /* @ A B C */ 0x09, 0x09, 0x09, 0x01, /* D E F G */ 0x01, 0x01, 0x01, 0x01, /* H I J K */ 0x01, 0x01, 0x01, 0x01, /* L M N O */ 0x01, 0x01, 0x01, 0x01, /* P Q R S */ 0x01, 0x01, 0x01, 0x01, /* T U V W * @@@@@SR, user); if (bdos(OPNFIL, &fcb) == 255) { errno = ENOENT; return -1; } fcb.f_cr = 0; fcbinit(0, 0x5c); fcbinit(0, 0x6c); cp = (char *)0x81; if (*argv) { ++argv; /* skip arg0, used for unix (tm) compatibility */ for (user = 0 ; (xp = *argv++) != 0 ; ++user) { if (user == 0) fcbinit(xp, 0x5c); else if (user == 1) fcbinit(xp, 0x6c); *cp++ = ' '; while (*xp) { if (cp > (char *)0xff) goto doload; *cp++ = *xp++; } } } doload: @@@/* 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); } patibility */ for (user = 0 ; (xp = *argv++) != 0 ; ++user) { if (user == 0) fcbinit(xp, 0x5c); else if (user == 1) fcbinit(xp, 0x6c); *cp++ = ' '; while (*xp) { if (cp > (char *)0xff) goto doload; *cp++ = *xp++; } }@*(char *)0x80 = cp - (char *)0x81; movmem(ldr_, loader, sizeof loader); (*(int (*)())loader)(&fcb, ouser); } it(0, 0x6c); cp = (char *)0x81; if (*argv) { ++argv; /* skip arg0, used for unix (tm) compatibility */ for (user = 0 ; (xp = *argv++) != 0 ; ++user) { if (user == 0) fcbinit(xp, 0x5c); else if (user == 1) fcbinit(xp, 0x6c); *cp++ = ' '; while (*xp) { if (cp > (char *)0xff) goto doload; *cp++ = *xp++; } } } doload: @@/* Copyright (C) 1983, 1984 by Manx Software Systems */ #include "io.h" #include "errno.h" execlp(path, args) char *path, *args; { return execvp(path, &args); } execvp(path, argv) char *path, **argv; { register char *cp, *xp; int user, ouser; auto struct fcb fcb; auto char loader[70]; extern char ldr_[]; if ((user = fcbinit(path, &fcb)) == -1) { errno = EINVAL; return -1; } if (fcb.f_type[0] == ' ') strcpy(fcb.f_type, "COM"); ouser = bdos(GETUSR, 255); bdos(GETU @/* Copyright (C) 1981, 1982 by Manx Software Systems */ extern int errno; #define FLT_FAULT 0 /* vector for floating-point faults */ extern int (*Sysvec[])(); #define NULL 0 #define EOF -1 #define BUFSIZ 1024 #define _BUSY 0x01 #define _ALLBUF 0x02 #define _DIRTY 0x04 #define _EOF 0x08 #define _IOERR 0x10 typedef struct { char *_bp; /* current position in buffer */ char *_bend; /* last character in buffer + 1 */ char *_buff; /* address of buffer */ char _flags; /* open mode@@@extern int errno; #define ENOENT -1 #define E2BIG -2 #define EBADF -3 #define ENOMEM -4 #define EEXIST -5 #define EINVAL -6 #define ENFILE -7 #define EMFILE -8 #define ENOTTY -9 #define EACCES -10 #define ERANGE -20 #define EDOM -21 @, etc. */ char _unit; /* token returned by open */ char _bytbuf; /* single byte buffer for unbuffer streams */ int _buflen; /* length of buffer */ } FILE; extern FILE Cbuffs[]; extern char *Stdbufs; /* free list of buffers */ long ftell(); #define stdin (&Cbuffs[0]) #define stdout (&Cbuffs[1]) #define stderr (&Cbuffs[2]) #define getchar() agetc(stdin) #define putchar(c) aputc(c, stdout) #define feof(fp) (((fp)->_flags&_EOF)!=0) #define ferror(fp) (((fp)->_flags&_IOERR)!=0) #defin@@@@@e clearerr(fp) ((fp)->_flags &= ~(_IOERR|_EOF)) #define fileno(fp) ((fp)->_unit) len; /* length of buffer */ } FILE; extern FILE Cbuffs[]; extern char *Stdbufs; /* free list of buffers */ long ftell(); #define stdin (&Cbuffs[0]) #define stdout (&Cbuffs[1]) #define stderr (&Cbuffs[2]) #define getchar() agetc(stdin) #define putchar(c) aputc(c, stdout) #define feof(fp) (((fp)->_flags&_EOF)!=0) #define ferror(fp) (((fp)->_flags&_IOERR)!=0) #defin@  @@@@@@@#define O_RDONLY 0 #define O_WRONLY 1 #define O_RDWR 2 #define O_CREAT 0x0100 #define O_TRUNC 0x0200 #define O_EXCL 0x0400 #define O_APPEND 0x0800 @@@/* Copyright (C) 1982 by Manx Software Systems */ /* * if MAXCHAN is changed then the initialization of chantab in croot.c * should be adjusted so that it initializes EXACTLY MAXCHAN elements of * the array. If this is not done, the I/O library may exhibit * strange behavior. */ #define MAXCHAN 11 /* maximum number of I/O channels */ /* * argument to device routines. * this is a typedef to allow future redeclaration to guarantee * enough space to store either a pointer or an intege@@@! r. */ typedef char *_arg; /* * device control structure */ struct device { char d_read; char d_write; char d_ioctl; /* used by character special devices (eg CON:) */ char d_seek; /* used by random I/O devices (eg: a file) */ int (*d_open)(); /* for special open handling */ }; /* * device table, contains names and pointers to device entries */ struct devtabl { char *d_name; struct device *d_dev; _arg d_arg; }; /* * channel table: relates fd's to devices */ struct @@@@@channel { char c_read; char c_write; char c_ioctl; char c_seek; int (*c_close)(); _arg c_arg; } ; extern struct channel chantab[MAXCHAN]; struct fcb { char f_driv; char f_name[8]; char f_type[3]; char f_ext; char f_resv[2]; char f_rc; char f_sydx[16]; char f_cr; unsigned f_record; char f_overfl; }; struct fcbtab { struct fcb fcb; char offset; char flags; char user; }; #define OPNFIL 15 #define CLSFIL 16 #define DELFIL 19 #define READSQ 20 #define WRITSQ@@@@@ 21 #define MAKFIL 22 #define SETDMA 26 #define GETUSR 32 #define READRN 33 #define WRITRN 34 #define FILSIZ 35 #define SETREC 36 #define Wrkbuf ((char *)0x80) r f_rc; char f_sydx[16]; char f_cr; unsigned f_record; char f_overfl; }; struct fcbtab { struct fcb fcb; char offset; char flags; char user; }; #define OPNFIL 15 #define CLSFIL 16 #define DELFIL 19 #define READSQ 20 #define WRITSQdouble sin(), cos(), tan(), cotan(); double asin(), acos(), atan(), atan2(); double ldexp(), frexp(), modf(); double floor(), ceil(); double log(), log10(), exp(), sqrt(), pow(); double sinh(), cosh(), tanh(), fabs(); #define HUGE 5.2e+151 #define LOGHUGE 349.3 #define TINY 7.5e-155 #define LOGTINY -354.8 @" /* Copyright (C) 1983 by Manx Software Systems */ #define JBUFSIZE (5*sizeof(int)) typedef char jmp_buf[JBUFSIZE]; FCNTL H 6IO H 7MATH H 8SETJMP H @@@/* Copyright (C) 1983 by Manx Software Systems */ #define TIOCGETP 0 /* read contents of tty control structure */ #define TIOCSETP 1 /* set contents of tty control structure */ #define TIOCSETN 1 /* ditto only don't wait for output to flush */ struct sgttyb { char sg_erase; /* ignored */ char sg_kill; /* ignored */ short sg_flags; /* control flags */ }; /* settings for flags */ #define _VALID 0x3a #define RAW 0x20 /* no echo or mapping of input/output BDOS(6) */ #define CRMOD 0x1@@@@@0 /* map input CR to NL, output NL to CR LF */ #define ECHO 0x08 /* ignored unless CBREAK is set */ #define CBREAK 0x02 /* input using BDOS(1), unless echo off then */ /* same as RAW */ truct sgttyb { char sg_erase; /* ignored */ char sg_kill; /* ignored */ short sg_flags; /* control flags */ }; /* settings for flags */ #define _VALID 0x3a #define RAW 0x20 /* no echo or mapping of input/output BDOS(6) */ #define CRMOD 0x1@@@@# @@e isascii(x) (((x)&0x80)==0) #define toascii(x) ((x)&127) #define _tolower(x) ((x)|0x20) #define _toupper(x) ((x)&0x5f) er(x) (ctp_[(x)+1]&0x01) #define islower(x) (ctp_[(x)+1]&0x02) #define isdigit(x) (ctp_[(x)+1]&0x04) #define isxdigit(x) (ctp_[(x)+1]&0x08) #define isalnum(x) (ctp_[(x)+1]&0x07) #define isspace(x) (ctp_[(x)+1]&0x10) #define ispunct(x) (ctp_[(x)+1]&0x40) #define iscntrl(x) (ctp_[(x)+1]&0x20) #define isprint(x) (ctp_[(x)+1]&0xc7) #define isgraph(x) (ctp_[(x)+1]&0x47) #defin) #define stderr (&Cbuffs[2]) #define getchar() agetc(stdin) #define putchar(c) aputc(c, stdout) #define feof(fp) (((fp)->_flags&_EOF)!=0) #define ferror(fp) (((fp)->_flags&_IOERR)!=0) #define clearerr(fp) ((fp)->_flags &= ~(_IOERR|_EOF)) #define fileno(fp) ((fp)->_unit) #define fflush(fp) flsh_(fp,-1) #endif er */ } FILE; extern FILE Cbuffs[]; FILE *fopen(); long ftell(); #define stdin (&Cbuffs[0]) #define stdout (&Cbuffs[1]@@/* Copyright (C) 1982, 1984 by Manx Software Systems */ #define fgetc getc #define fputc putc #define NULL 0 #define EOF -1 #ifdef TINY struct fcb { char f_driv; char f_name[8]; char f_type[3]; char f_ext; char f_resv[2]; char f_rc; char f_sydx[16]; char f_cr; unsigned f_record; char f_overfl; }; typedef struct { char *_bp; struct fcb _fcb; char user; } FILE; #else #define BUFSIZ 1024 #define MAXSTREAM 11 #define _BUSY 0x01 #define _ALLBUF 0x02 #define _DIRTY@@@/* Copyright (C) 1984 by Manx Software Systems */ extern char ctp_[]; #define isalpha(x) (ctp_[(x)+1]&0x03) #define isupper(x) (ctp_[(x)+1]&0x01) #define islower(x) (ctp_[(x)+1]&0x02) #define isdigit(x) (ctp_[(x)+1]&0x04) #define isxdigit(x) (ctp_[(x)+1]&0x08) #define isalnum(x) (ctp_[(x)+1]&0x07) #define isspace(x) (ctp_[(x)+1]&0x10) #define ispunct(x) (ctp_[(x)+1]&0x40) #define iscntrl(x) (ctp_[(x)+1]&0x20) #define isprint(x) (ctp_[(x)+1]&0xc7) #define isgraph(x) (ctp_[(x)+1]&0x47) #defin@ 0x04 #define _EOF 0x08 #define _IOERR 0x10 typedef struct { char *_bp; /* current position in buffer */ char *_bend; /* last character in buffer + 1 */ char *_buff; /* address of buffer */ char _flags; /* open mode, etc. */ char _unit; /* token returned by open */ char _bytbuf; /* single byte buffer for unbuffer streams */ int _buflen; /* length of buffer */ } FILE; extern FILE Cbuffs[]; FILE *fopen(); long ftell(); #define stdin (&Cbuffs[0]) #define stdout (&Cbuffs[1]@@$ @@#include "math.h" #include "errno.h" extern int errno; static double tansub(); double cotan(x) double x; { double y; y = fabs(x); if (y < 1.91e-152) { errno = ERANGE; if (x < 0.0) return -HUGE; else return HUGE; } return tansub(x,y,2); } double tan(x) double x; { return tansub(x, fabs(x), 0); } #define P1 -0.13338350006421960681e+0 #define P2 +0.34248878235890589960e-2 #define P3 -0.17861707342254426711e-4 #define Q0 +1.0 #define Q1 -0.466716833397559114e-09 #define R7 -0.76429178068910467734e-12 #define R8 +0.27204790957888846175e-14 #define YMAX 6.7465e09 static double sincos(x,y,sgn) double x,y; { double f, xn, r, g; extern int errno; if (y >= YMAX) { errno = ERANGE; return 0.0; } if (modf(y * 0.31830988618379067154, &xn) >= 0.5) ++xn; if ((int)xn & 1) sgn = !sgn; if (fabs(x) != y) xn -= 0.5; g = modf(fabs(x), &x); /* break into fraction and integer parts */ f = ((x - xn*3.1416015625) + g) + xn*8.9089102@@@@294240e+0 #define Q2 +0.25663832289440112864e-1 #define Q3 -0.31181531907010027307e-3 #define Q4 +0.49819433993786512270e-6 #define P(f,g) (((P3*g P2)*g P1)*g*f + f) #define Q(g) ((((Q4*g Q3)*g Q2)*g Q1)*g Q0) #define YMAX 6.74652e09 static double tansub(x, y, flag) double x,y; { double f, g, xn; double xnum, xden; if (y > YMAX) { errno = ERANGE; return 0.0; } if (modf(x*0.63661977236758134308, &xn) >= 0.5) xn += (x < 0.0) ? -1.0 : 1.0; f = (x - xn*1.57080078125) + xn*067615373566e-6; if (fabs(f) > 2.3283e-10) { g = f*f; r = (((((((R8*g R7)*g R6)*g R5)*g R4)*g R3)*g R2)*g R1)*g; f += f*r; } if (sgn) f = -f; return f; } 0.0; } if (modf(y * 0.31830988618379067154, &xn) >= 0.5) ++xn; if ((int)xn & 1) sgn = !sgn; if (fabs(x) != y) xn -= 0.5; g = modf(fabs(x), &x); /* break into fraction and integer parts */ f = ((x - xn*3.1416015625) + g) + xn*8.9089102@@#include "math.h" #include "errno.h" double cos(x) double x; { double sincos(); return sincos(x, fabs(x) + 1.57079632679489661923, 0); } double sin(x) double x; { double sincos(); if (x < 0.0) return sincos(x,-x,1); else return sincos(x,x,0); } #define R1 -0.16666666666666665052e+00 #define R2 +0.83333333333331650314e-02 #define R3 -0.19841269841201840457e-03 #define R4 +0.27557319210152756119e-05 #define R5 -0.25052106798274584544e-07 #define R6 +0.1605893649037158@4.454455103380768678308e-6; if (fabs(f) < 2.33e-10) { xnum = f; xden = 1.0; } else { g = f*f; xnum = P(f,g); xden = Q(g); } flag |= ((int)xn & 1); switch (flag) { case 1: /* A: tan, xn odd */ xnum = -xnum; case 2: /* B: cotan, xn even */ return xden/xnum; case 3: /* C: cotan, xn odd */ xnum = -xnum; case 0: /* D: tan, xn even */ return xnum/xden; } return 0.0; } % @ return 0.0; } g = (0.5-y)+0.5; g = ldexp(g,-1); y = sqrt(g); y = -(y+y); } else g = y*y; r = y + y* ((P(g)*g) /Q(g)); } if (flg) { if (x < 0.0) r = (b[i] + r) + b[i]; else r = (a[i] - r) + a[i]; } else { r = (a[i] + r) + a[i]; if (x < 0.0) r = -r; } return r; } bs(x); i = flg; if (y < 2.3e-10) r = y; else { if (y > 0.5) { i = 1-i; if (y > 1.0) { errno = EDOM; @#include "math.h" #include "errno.h" double arcsine(); double asin(x) double x; { return arcsine(x,0); } double acos(x) double x; { return arcsine(x,1); } #define P1 -0.27368494524164255994e+2 #define P2 +0.57208227877891731407e+2 #define P3 -0.39688862997504877339e+2 #define P4 +0.10152522233806463645e+2 #define P5 -0.69674573447350646411 #define Q0 -0.16421096714498560795e+3 #define Q1 +0.41714430248260412556e+3 #define Q2 -0.38186303361750149284e+3 #define Q3 +0.15095270841@((P3*g P2)*g P1)*g P0) #define Q(g) ((((g Q3)*g Q2)*g Q1)*g Q0) double atan(x) double x; { double f, r, g; int n; static double Avals[4] = { 0.0, 0.52359877559829887308, 1.57079632679489661923, 1.04719755119659774615 }; n = 0; f = fabs(x); if (f > 1.0) { f = 1.0/f; n = 2; } if (f > 0.26794919243112270647) { f = (((0.73205080756887729353*f - 0.5) - 0.5) + f) / (1.73205080756887729353 + f); ++n; } if (fabs(f) < 2.3e-10) r = f; else { g = f*f;@@#include "libc.h" #include "math.h" #include "errno.h" static int nopper() {;} #define PI 3.14159265358979323846 #define PIov2 1.57079632679489661923 double atan2(v,u) double u,v; { double f; int (*save)(); extern int flterr; extern int errno; if (u == 0.0) { if (v == 0.0) { errno = EDOM; return 0.0; } return PIov2; } save = Sysvec[FLT_FAULT]; Sysvec[FLT_FAULT] = nopper; flterr = 0; f = v/u; Sysvec[FLT_FAULT] = save; if (flterr == 2) /* overflow */030604719e+3 #define Q4 -0.23823859153670238830e+2 #define P(g) ((((P5*g P4)*g P3)*g P2)*g P1) #define Q(g) (((((g Q4)*g Q3)*g Q2)*g Q1)*g Q0) double arcsine(x,flg) double x; { double y, g, r; register int i; extern int errno; static double a[2] = { 0.0, 0.78539816339744830962 }; static double b[2] = { 1.57079632679489661923, 0.78539816339744830962 }; y = fabs(x); i = flg; if (y < 2.3e-10) r = y; else { if (y > 0.5) { i = 1-i; if (y > 1.0) { errno = EDOM; @ r = f + f * ((P(g)*g) /Q(g)); } if (n > 1) r = -r; r += Avals[n]; if (x < 0.0) r = -r; return r; } ; f = fabs(x); if (f > 1.0) { f = 1.0/f; n = 2; } if (f > 0.26794919243112270647) { f = (((0.73205080756887729353*f - 0.5) - 0.5) + f) / (1.73205080756887729353 + f); ++n; } if (fabs(f) < 2.3e-10) r = f; else { g = f*f;@@ f = PIov2; else { if (flterr == 1) /* underflow */ f = 0.0; else f = atan(fabs(f)); if (u < 0.0) f = PI - f; } if (v < 0.0) f = -f; return f; } #define P0 -0.13688768894191926929e+2 #define P1 -0.20505855195861651981e+2 #define P2 -0.84946240351320683534e+1 #define P3 -0.83758299368150059274e+0 #define Q0 +0.41066306682575781263e+2 #define Q1 +0.86157349597130242515e+2 #define Q2 +0.59578436142597344465e+2 #define Q3 +0.15024001160028576121e+2 #define P(g) (& @{ y = -x; sign = 1; } if (y > 1.0) { w = y - 0.6931610107421875000; if (w > 349.3) { errno = ERANGE; z = HUGE; } else { z = exp(w); if (w < 19.95) z -= 0.24999308500451499336 / z; z += 0.13830277879601902638e-4 * z; } if (sign) z = -z; } else if (y < 2.3e-10) z = x; else { z = x*x; z = x + x * (z*(PS(z) /QS(z))); } return z; } double cosh(x) double x; { double y, w, z; y = fabs(x); if (y > 1.0) { w = y - 0.693@@@se if (f < 2.3e-10) r = f; else { g = f*f; r = f + f* (gP(g) /Q(g)); } if (x < 0.0) r = -r; return r; }  #define gP(g) (((P2*g P1)*g P0)*g) #define Q(g) (((g Q2)*g Q1)*g Q0) double tanh(x) double x; { double f,g,r; f = fabs(x); if (f > 25.3) r = 1.0; else if (f > 0.54930614433405484570) { r = 0.5 - 1.0/(exp(f+f)+1.0); r += r; } el@1610107421875000; if (w > 349.3) { errno = ERANGE; return HUGE; } z = exp(w); if (w < 19.95) z += 0.24999308500451499336 / z; z += 0.13830277879601902638e-4 * z; } else { z = exp(y); z = z*0.5 + 0.5/z; } return z; } S(z))); } return z; } double cosh(x) double x; { double y, w, z; y = fabs(x); if (y > 1.0) { w = y - 0.693@#include "math.h" #include "errno.h" extern int errno; #define P0 -0.35181283430177117881e+6 #define P1 -0.11563521196851768270e+5 #define P2 -0.16375798202630751372e+3 #define P3 -0.78966127417357099479e+0 #define Q0 -0.21108770058106271242e+7 #define Q1 +0.36162723109421836460e+5 #define Q2 -0.27773523119650701667e+3 #define PS(x) (((P3*x P2)*x P1)*x P0) #define QS(x) (((x Q2)*x Q1)*x Q0) double sinh(x) double x; { double y, w, z; int sign; y = x; sign = 0; if (x < 0.0) @@@@#include "math.h" #define P0 -0.16134119023996228053e+4 #define P1 -0.99225929672236083313e+2 #define P2 -0.96437492777225469787e+0 #define Q0 +0.48402357071988688686e+4 #define Q1 +0.22337720718962312926e+4 #define Q2 +0.11274474380534949335e+3 #define gP(g) (((P2*g P1)*g P0)*g) #define Q(g) (((g Q2)*g Q1)*g Q0) double tanh(x) double x; { double f,g,r; f = fabs(x); if (f > 25.3) r = 1.0; else if (f > 0.54930614433405484570) { r = 0.5 - 1.0/(exp(f+f)+1.0); r += r; } el' @#include "math.h" #include "errno.h" double pow(a,b) double a,b; { double loga; extern int errno; if (a<=0.0) { if (a<0.0 || a==0.0 && b<=0.0) { errno = EDOM; return -HUGE; } else return 0.0; } loga = log(a); loga *= b; if (loga > LOGHUGE) { errno = ERANGE; return HUGE; } if (loga < LOGTINY) { errno = ERANGE; return 0.0; } return exp(loga); } @@@#include "math.h" #include "errno.h" double sqrt(x) double x; { double f, y; int n; extern int errno; if (x == 0.0) return x; if (x < 0.0) { errno = EDOM; return 0.0; } f = frexp(x, &n); y = 0.41731 + 0.59016 * f; y = (y + f/y); y = 0.25*y + f/y; /* fast calculation of y2 */ y = 0.5 * (y + f/y); y = y + 0.5 * (f/y - y); if (n&1) { y *= 0.70710678118654752440; ++n; } return ldexp(y,n/2); } @@@@@@@@@( @@@@@@@#include "math.h" #include "errno.h" double log10(x) double x; { return log(x)*0.43429448190325182765; } #define A0 -0.64124943423745581147e+2 #define A1 +0.16383943563021534222e+2 #define A2 -0.78956112887491257267e+0 #define A(w) ((A2*w A1)*w A0) #define B0 -0.76949932108494879777e+3 #define B1 +0.31203222091924532844e+3 #define B2 -0.35667977739034646171e+2 #define B(w) (((w B2)*w B1)*w B0) #define C0 0.70710678118654752440 #define C1 0.693359375 #define C2 -2.121944400546905827@@@/* * Random number generator - * adapted from the FORTRAN version * in "Software Manual for the Elementary Functions" * by W.J. Cody, Jr and William Waite. */ double ran() { static long int iy = 100001; iy *= 125; iy -= (iy/2796203) * 2796203; return (double) iy/ 2796203.0; } double randl(x) double x; { double exp(); return exp(x*ran()); }  - xn*0.693359375) + z) + xn*2.1219444005469058277e-4; z = g*g; r = P(z)*g; r = 0.5 + r/(Q(z)-r); return ldexp(r,n+1); } fl@679e-4 double log(x) double x; { double Rz, f, z, w, znum, zden, xn; int n; extern int errno; if (x <= 0.0) { errno = EDOM; return -HUGE; } f = frexp(x, &n); if (f > C0) { znum = (f-0.5)-0.5; zden = f*0.5 + 0.5; } else { --n; znum = f - 0.5; zden = znum*0.5 + 0.5; } z = znum/zden; w = z*z; /* the lines below are split up to allow expansion of A(w) and B(w) */ Rz = z + z * (w * A(w) /B(w)); xn = n; return (xn*C2 + Rz) + xn*C1; } @) @@@@LOGTINY) { errno = ERANGE; return 0.0; } if (fabs(x) < EPS) return 1.0; z = modf(x * 1.4426950408889634074, &xn); if (z >= 0.5) ++xn; n = xn; z = modf(x, &x); /* break x up into fraction and integer part */ g = ((x - xn*0.693359375) + z) + xn*2.1219444005469058277e-4; z = g*g; r = P(z)*g; r = 0.5 + r/(Q(z)-r); return ldexp(r,n+1); }  { int n; double xn, g, r, z; extern int errno; if (x > LOGHUGE) { errno = ERANGE; return HUGE; } if (x < @@@@@@@@#include "math.h" #include "errno.h" #define P0 0.249999999999999993e+0 #define P1 0.694360001511792852e-2 #define P2 0.165203300268279130e-4 #define Q0 0.500000000000000000e+0 #define Q1 0.555538666969001188e-1 #define Q2 0.495862884905441294e-3 #define P(z) ((P2*z + P1)*z + P0) #define Q(z) ((Q2*z + Q1)*z + Q0) #define EPS 2.710505e-20 double exp(x) double x; { int n; double xn, g, r, z; extern int errno; if (x > LOGHUGE) { errno = ERANGE; return HUGE; } if (x < @* #include "math.h" double floor(d) double d; { if (d < 0.0) return -ceil(-d); modf(d, &d); return d; } double ceil(d) double d; { if (d < 0.0) return -floor(-d); if (modf(d, &d) > 0.0) ++d; return d; } @exp dcx h shld dexp jmp skpsign notdigit: cpi '.' jnz nomore lxi h,dpflg mvi m,1 ;set dec. pt. seen jmp skpsign ; nomore: lxi h,0 ;clear exponent ori 20H ;force to lower case cpi 'e' jnz scaleit inx b ldax b cpi '-' jnz exppos sta esign ;set exponent negative jmp nxtchr exppos: cpi '+' jnz getexp nxtchr: inx b getexp: ldax b cpi '0' jc expdone cpi '9'+1 jnc expdone sui '0' dad h ; exp *= 2 mov d,h mov e,l dad h ;exp *= 4 dad h ;exp *=@; Copyright (C) 1983 by Manx Software Systems ; :ts=8 extrn .dml10, .utod, .dswap, .dad extrn .dlis, .ddv, .dng dseg msign: ds 1 esign: ds 1 dpflg: ds 1 dexp: ds 2 cseg public atof_ atof_: push b xra a sta msign ;clear mantissa sign sta esign ;clear exponent sign sta dpflg ;have not seen decimal point yet lxi h,0 shld dexp ;clear exponent to zero call .utod ;clear floating point accumulator ; lxi h,4 dad sp mov c,m ;get address of string to convert inx h mov le number up jnz rngerr mov a,l ;get loop count ora a jz dosign mov c,a sclp2: call .dml10 dcr c jnz sclp2 ; dosign: lda msign ;check sign of number ora a jz return call .dng ;negate accumulator return: pop b ret ; rngerr: pop b ret end clp1 call .dswap ;get everybody back in place call .ddv ;move into range jmp dosign ; movup: ;positive exponent sca@@ 8 dad d ;exp *= 10 mov e,a mvi d,0 dad d ;exp = exp*10 + char - '0' jmp nxtchr ; expdone: lda esign ;check sign of exponent ora a jz addexp mov a,h ;negate if sign was minus cma mov h,a mov a,l cma mov l,a inx h addexp: xchg lhld dexp ;get digit count dad d ;add in exponent value shld dexp ;save for scaling later ; scaleit: ;scale number to correct value lhld dexp mov a,h ora a jp movup ;negative exponent cpi 0ffH ;test if exponent too large @b,m skipbl: ldax b cpi ' ' jz blank cpi 9 jnz notblank blank: inx b jmp skipbl notblank: cpi '-' jnz notneg ;not minus sign sta msign ;set negative for later jmp skpsign notneg: cpi '+' ;check for plus sign jnz getnumb skpsign: inx b ;skip over sign character getnumb: ldax b cpi '0' jc notdigit cpi '9'+1 jnc notdigit push psw call .dml10 call .dswap pop psw sui '0' mov l,a mvi h,0 call .utod call .dad lda dpflg ora a jz skpsign lhld d@@@jnz rngerr mov a,l cma inr a mov c,a ;save for loop later cpi 166 jnc rngerr cpi 150 jc sizeok call .dlis ;divide by 1e16 since smallest will overflow db 47H,23H,86H,0f2H,6fH,0c1H,0,0 call .ddv mov a,c ;get exponent value back sui 16 mov c,a sizeok: call .dswap lxi h,1 call .utod sclp1: call .dml10 ;compute number to divide by dcr c jnz sclp1 call .dswap ;get everybody back in place call .ddv ;move into range jmp dosign ; movup: ;positive exponent sca+ @e lhld flprm inx h inx h inx h mov a,m cpi 10 jc numbok dcx b call .dml10 jmp numbok qcklp: lhld flprm inx h mov a,m cpi 1 jnz quick tentest: inx h inx h mov a,m cpi 10 jc numbok quick: call .ddv ;divide by ten till 1 <= number < 10 inx b ;count for exponent jmp qcklp sml.lp: lhld flprm inx h mov a,m cpi 1 jp numbok toosml: call .dml10 ;multiply by ten till 1 <= number < 10 dcx b ;count for exponent jmp sml.lp ; numbok: lda fft integer portion (virtual) zerodigit: lhld chrptr mov m,a inx h shld chrptr lxi h,ndig dcr m jz unpdone mov a,b cmp c jnz mul10 lhld chrptr mvi m,'.' inx h shld chrptr mul10: call .dml10 ;multiply by 10 and re-normalize inr b jmp unplp ; unpdone: lda fflag ora a jnz alldone ; lhld chrptr mvi m,'e' inx h mvi m,'+' lda exp+1 ora a lda exp jp posexp mvi m,'-' cma inr a posexp: inx h cpi 100 jc lt100 mvi m,'1' inx h sui 100 lt100 ; 0.00000000000005, DB 03BH,0EH,012H,0E1H,034H,024H,0BBH,043H ; 0.000000000000005, DB 03BH,01H,068H,049H,0B8H,06AH,012H,0BAH ; ; public ftoa_ ftoa_: push b lxi h,12 dad sp mov e,m inx h mov d,m xchg shld chrptr ;buffer for converted data lxi h,16 dad sp mov a,m sta fflag ;e/f/g format flag ; lxi h,4 dad sp call .dldp ;fetch number to convert lxi h,14 dad sp mov a,m ;fetch precision sta maxdig inr a mov l,a mvi h,0 shld ndig ; lhld flprm mov  mov h,b mov l,c shld exp lda fflag ora a jz unpack mov a,b ora a mov a,c ;move for unpack jp unpack ; F format and negative exponent ; put out leading zeros lhld chrptr mvi m,'0' inx h mvi m,'.' inx h lda ndig+1 ora a jm under mov a,c cma jmp L2 under: lda maxdig L2: ora a jz zdone zdiglp: mvi m,'0' inx h dcr a jnz zdiglp zdone: shld chrptr mvi a,0ffH ;mark decpt already output ; unpack: ;when we get here A has the position for the@; Copyright (C) 1982, 1983 by Manx Software Systems ; :ts=8 extrn .dldp, .dlds, .utod, .dlis, .dswap, .dtst extrn .dng, .dlt, .dge, .dad, .ddv, .dml10 extrn flprm dseg chrptr: ds 2 maxdig: ds 1 ndig: ds 2 exp: ds 2 count: ds 1 fflag: ds 1 cseg rounding: ; 0.5, DB 040H,080H,00H,00H,00H,00H,00H,00H ; 0.05, DB 040H,0CH,0CCH,0CCH,0CCH,0CCH,0CCH,0CDH ; 0.005, DB 040H,01H,047H,0AEH,014H,07AH,0E1H,048H ; 0.0005, DB 03FH,020H,0C4H,09BH,0A5H,0E3H,054H,00H ; 0.00005, DB 03FH,03H,046H,lag ;check conversion format ora a jz eformat cpi 1 jz fformat lda maxdig ;if %g then precision is # sig. digits mov l,a mvi h,0 shld ndig mov a,b ;select %f if maxdig > exp > -4, else use %e ora a jm chkm4 mov a,c cmp l jnc eformat mvi a,1 ;exp < maxdig, so use %f jmp setformat ; chkm4: mov a,c cpi -4 jc eformat ;exp < -4, so use %e fformat: lhld ndig dad b shld ndig mvi a,1 jmp setformat eformat: xra a setformat: sta fflag ; now round number : mvi b,0 tens: cpi 10 jc lt10 inr b sui 10 jmp tens lt10: adi '0' ;ascii of last digit mov e,a ;save last digit mvi a,'0' add b ;compute second digit mov m,a inx h mov m,e inx h shld chrptr ; alldone: lhld chrptr mvi m,0 pop b ret ; inverse: call .dswap lxi h,1 call .utod jmp .ddv ;implied return ; end ora a lda exp jp posexp mvi m,'-' cma inr a posexp: inx h cpi 100 jc lt100 mvi m,'1' inx h sui 100 lt100a,m ora a jp notneg call .dng lhld chrptr mvi m,'-' inx h shld chrptr notneg: lxi b,0 ;clear integer exponent call .dtst jz numbok call .dlis db 041H,0aH,0,0,0,0,0,0 adjust: lhld flprm inx h mov a,m cpi 1 jm toosml jz tentest cpi 2 jnz bignum inx h inx h mov a,m cpi 27H ;number < 10000, just do divides jc quick bignum: call inverse call .dlis db 40H,19H,99H,99H,99H,99H,99H,9aH bignlp: call .dml10 inx b call .dlt jnz bignlp call invers ;decimal point mov c,a ;save decimal point position lxi h,ndig+1 ;check if ndigits is <= zero mov a,m ora a jm unpdone ;if so just quit now dcx h ora m jz unpdone ;if so just quit now lhld flprm lxi d,10 dad d mvi m,0 ;zap guard bytes inx h mvi m,0 mvi b,0 unplp: mov a,b cpi 15 mvi a,'0' jnc zerodigit lhld flprm inx h ;skip sign byte mov a,m cpi 1 mvi a,'0' jnz zerodigit inx h ;skip exponent inx h ;skip overflow add m mvi m,0 ;subtrac@0DCH,05DH,063H,088H,066H ; 0.000005, DB 03EH,053H,0E2H,0D6H,023H,08DH,0A3H,0CDH ; 0.0000005, DB 03EH,08H,063H,07BH,0D0H,05AH,0F6H,0C8H ; 0.00000005, DB 03DH,0D6H,0BFH,094H,0D5H,0E5H,07AH,066H ; 0.000000005, DB 03DH,015H,079H,08EH,0E2H,030H,08CH,03DH ; 0.0000000005, DB 03DH,02H,025H,0C1H,07DH,04H,0DAH,0D3H ; 0.00000000005, DB 03CH,036H,0F9H,0BFH,0B3H,0AFH,07BH,080H ; 0.000000000005, DB 03CH,05H,07FH,05FH,0F8H,05EH,059H,026H ; 0.0000000000005, DB 03BH,08CH,0BCH,0CCH,09H,06FH,050H,09AH according to the number of digits lhld ndig dcx h mov a,h ora a jp L1 lxi h,0 jmp L5 L1: jnz toomany mov a,l cpi 14 jc L5 toomany: lxi h,14 L5: dad h ;*2 dad h ;*4 dad h ;*8 lxi d,rounding dad d call .dlds call .dad ;add in rounding counstant ; call .dlis db 041H,0aH,0,0,0,0,0,0 call .dge ;check for rounding overflow jz rndok lxi h,1 call .utod ;and repair if necessary inx b lda fflag ora a jz rndok lhld ndig inx h shld ndig rndok: @, @ ; rsexp: ora a mvi b,3 rselp: mov a,h rar mov h,a mov a,l rar mov l,a dcr b jnz rselp ret ; calcexp: call .dldp ;load into floating accumulator lhld flprm inx h mov a,m ;get exponent value cpi -64 rz mvi m,0 ;make exponent zero for return mov l,a ;get low byte of exponent rlc ;sign extend value sbb a mov h,a ;save high byte of exponent dad h dad h dad h ; exp*8 to make power of two mov b,h ; bc = exponent mov c,l lhld flprm inx h inx; Copyright (C) 1982, 1983, 1984 by Manx Software Systems ; :ts=8 extrn Sysvec_ extrn lnprm extrn puterr_ dseg public flprm,flsec flprm: dw acc1 flsec: dw acc2 public flterr_ flterr_: dw 0 retsave:ds 2 YU: ds 2 VEE: ds 2 expdiff:ds 1 acc1: ds 18 acc2: ds 18 ;work area for divide and multiply routines lcnt: ds 1 ;iterations left tmpa: ds 8 ;quotient tmpb: ds 8 ;remainder work area tmpc: ds 8 ;temp for divisor cseg public .flds ;load single float into secondary accum .flds:  b lxi h,4 dad sp call calcexp jz popret ;do nothing if number is zero or unnormalized lxi h,12 ;fetch number to add to exponent dad sp mov e,m inx h mov d,m xchg dad b ;add exponents mov a,h ora a ;check sign of exponent jp posexp cma ;make positive for div and modulo below mov h,a mov a,l cma mov l,a inx h mov a,l ani 7 mov c,a ;save amount to shift call rsexp ;make power of 256 mov a,l cma inr a ;fix sign back mov l,a jmp ldrs posexp: t move loop to 7 bytes mvi a,7 expok: mov e,a ;save count for loop cma adi 8 ; 7 - loop count mov d,a ;save # bytes in fraction intmov: ;copy integer part into given area mov a,m stax b inx h inx b dcr e jnz intmov ; fnorm: ;note: E is zero at start of this loop dcr d jm zfrac ;fraction is zero mov a,m ;look for non-zero byte inx h dcr e ;count for exponent of fraction ora a jz fnorm ; dcx h ;back up to good byte inr e ;fix exponent mov b,h ;save p pop d ;get return addr lxi h,8 ;size of double dad d push h ;put back correct return addr xchg ;fall through into .dlds ; public .dlds ;load double float into secondary accum .dlds: xchg lhld flsec jmp dload ; public .dlip ;load double immediate primary .dlip: pop d ;get return addr lxi h,8 ;size of double dad d push h ;put back correct return addr xchg ;fall through into .dldp ; public .dldp ;load double float into primary accum .dldp: xchg lhld f@ h inx h ;hl = first byte of mantissa mov a,m ora a rz ;unnormalized number? give up lshft: mov a,m ani 80H ;test high bit of mantissa rnz ;mantissa >= 0.5 ? yes return ;otherwise, shift number to the left one place dcx b ;and adjust exponent lxi d,7 dad d ;address of end of fraction lsloop: dcx h mov a,m ral mov m,a dcr e jnz lsloop jmp lshft ; modf_: ;split into integral and fraction parts push b lxi h,12 ;pick up address to store integral part  xchg lhld flsec jmp fload ; public .fldp ;load single float into primary accum .fldp: xchg lhld flprm fload: push b ldax d ;get first byte of number mov m,a ;save sign inx h ani 7fH ;isolate exponent sui 64 ;adjust from excess 64 notation mov m,a ;and save inx h mvi m,0 ;extra byte for carry mvi b,3 ;copy 3 byte fraction ldloop: inx h inx d ldax d mov m,a dcr b jnz ldloop mvi b,5 ;clear rest to zeros xra a clloop: inx h mov m,a dcr b jora l ;check if zero jz popret ;no adjustment needed mov c,l ;save to compute left shift call rsexp ;make power of 256 mov a,c ani 7 jz ldrsx inr l ;bump exponent to make right shift cma adi 9 ;compensate for +1 (c = -(x-8)) ldrsx: mov c,a ;save for loop below ldrs: xchg lhld flprm inx h mov m,e ;save exponent rsloop: dcr c jm popret lhld flprm inx h inx h mvi b,7 ora a ;clear carry rslp: inx h mov a,m rar mov m,a dcr b jnz rslp jmp rslooposition in accumulator mov c,l lhld flprm inx h mov m,e ;store exponent inx h ;skip overflow byte mvi e,7 ;count of # that must be cleared frcmov: inx h ldax b mov m,a inx b dcr e dcr d jp frcmov xra a frcclr: ;clear out rest of register inx h mov m,a dcr e jnz frcclr pop b ret zfrac: ;fraction is zero lxi h,0 call .utod pop b ret lprm dload: push b ldax d ;get first byte of number mov m,a ;save sign inx h ani 7fH ;isolate exponent sui 64 ;adjust from excess 64 notation mov m,a ;and save inx h mvi m,0 ;extra byte for carry mvi b,7 ;copy 7 byte fraction dloop: inx h inx d ldax d mov m,a dcr b jnz dloop inx h mvi m,0 ;clear guard byte pop b ret ; public .dst ;store double at addr in HL .dst: push b push h ;save address call dornd ;round fraction to 7 bytes pop d ;rest; Copyright (C) 1982, 1983, 1984 by Manx Software Systems ; :ts=8 extrn flprm extrn .dldp, .utod public frexp_, ldexp_, modf_ ; frexp_: ;return mantissa and exponent push b lxi h,4 dad sp call calcexp ;calculate power of two exponent jnz retexp lxi b,0 retexp: lxi h,12 ;address second argument dad sp mov e,m inx h mov d,m xchg mov m,c ;return base 2 exponent inx h mov m,b popret: pop b ret ; ldexp_: ;load new exponent value (actualy add to exponent) pushdad sp mov c,m inx h mov b,m mov l,c mov h,b mvi e,8 ;clear out integer xra a mdclr: mov m,a inx h dcr e jnz mdclr ; lxi h,4 dad sp call .dldp lhld flprm inx h mov a,m ora a jm popret jz popret adi 64 ani 7fH mov e,a dcx h mov a,m ;get sign of number ani 80H ;isolate ora e ;combine with exponent stax b ;store away inx b inx h mov a,m ;refetch exponent inx h ;skip over exponent inx h ;skip over overflow byte cpi 7 jc expok ;liminz clloop pop b ret ; public .fst ;store single at addr in HL .fst: push b xchg lhld flprm mov a,m ;get sign ani 80H ;and isolate mov b,a ;save inx h mov a,m ;get exponent adi 64 ;put into excess 64 notation ani 7fH ;clear sign bit ora b ;merge exponent and sign stax d inx h ;skip overflow byte mvi b,3 ;copy 3 bytes of fraction fstlp: inx d inx h mov a,m stax d dcr b jnz fstlp pop b ret ; public .dlis ;load double immediate secondary .dlis:- ore address lhld flprm mov a,m ;get sign ani 80H ;and isolate mov b,a ;save inx h mov a,m ;get exponent adi 64 ;put into excess 64 notation ani 7fH ;clear sign bit ora b ;merge exponent and sign stax d inx h ;skip overflow byte mvi b,7 ;copy 7 bytes of fraction dstlp: inx d inx h mov a,m stax d dcr b jnz dstlp pop b ret ; public .dpsh ;push double float onto the stack .dpsh: ;from the primary accumulator pop h ;get return address shld retsave ;ffer the p < s xchg ;both negative reverse sense of test docomp: inx h inx d ldax d cmp m ;compare exponents jm p.lt.s ;sign test ok since -64 < exp < 64 jnz p.gt.s mvi b,9 ;test overflow byte + 8 bytes of fraction cmploop: inx h inx d ldax d cmp m jc p.lt.s jnz p.gt.s dcr b jnz cmploop ;return 0 if p == s xra a pop b ret ; public .dsb ;subtract secondary from primary .dsb: lhld flsec mov a,m xri 80H ;flip sign of secondary mov m,a ;fall thr YU xchg lhld VEE addlp: ;carry is already cleared ldax d adc m stax d dcx d dcx h dcr b jnz addlp crylp: ldax d aci 0 stax d dcx d dcr c jp crylp jmp normalize ; public .ddv .ddv: ;double floating divide (primary = primary/secondary) push b lhld flprm xchg lhld flsec ldax d xra m ;compute sign of result stax d ;and store inx h inx d ldax d ;primary exponent sub m ;eu-ev mov c,a ;save exponent push d push h mov a,m cpi -64 jnz dh pop d ;bytes 6 and 7 of fraction mov m,e inx h mov m,d inx h mvi m,0 ;clear guard byte lhld retsave pchl ; public .dswap ;exchange primary and secondary .dswap: lhld flsec xchg lhld flprm shld flsec xchg shld flprm ret ; public .dng ;negate primary .dng: lhld flprm mov a,m xri 80H ;flip sign mov m,a ret ; public .dtst ;test if primary is zero .dtst: lhld flprm ; mov a,m ; ora a ; jnz true inx h mov a,m cpi -64 jnz true ; inx h ; inx ;check if signs same jp doadd ldax d ora a ;test which one is negative jm UfromV ;jump if primary is negative ;subtract V from U mvi b,7 lhld YU xchg lhld VEE sublpa: ;carry is already cleared ldax d sbb m stax d dcx d dcx h dcr b jnz sublpa brlpa: ldax d sbi 0 stax d dcx d dcr c jp brlpa xchg ;get destination into HL jmp subchk ;check for negative result ; UfromV: ;subtract U from V mvi b,7 lhld VEE xchg lhld YU sublpb: ;carry isinto work area divsav: mov a,m stax d dcx h inx d dcr b jnz divsav mvi b,8 lxi h,tmpa ;clear quotient buffer xra a quinit: mov m,a inx h dcr b jnz quinit mvi a,64 sta lcnt ;initialize loop counter divloop: lxi h,tmpa mvi b,16 ora a ;clear carry shlp: mov a,m adc a ;shift one bit to the left mov m,a inx h dcr b jnz shlp sbb a ani 1 mov c,a mvi b,8 lxi d,tmpb lxi h,tmpc ora a ;clear carry sublp: ldax d sbb m stax d inx d inxand save for later call dornd lhld flprm lxi d,9 dad d mov d,m ;bytes 6 and 7 dcx h mov e,m dcx h push d mov d,m ;bytes 4 and 5 dcx h mov e,m dcx h push d mov d,m ;bytes 2 and 3 dcx h mov e,m dcx h push d mov d,m ;byte 1 dcx h dcx h ;skip over carry byte mov a,m ;get exponent adi 64 ;and restore to excess 64 notation ani 7fH mov e,a dcx h mov a,m ani 80H ;isolate sign bit ora e ;combine exponent and sign mov e,a push d lhld retsave u into add routine ; public .dad ;add secondary to primary .dad: ;DE is used as primary address ;and HL is used as secondary address push b ;clear extra bytes at end of accumulators lhld flprm lxi d,11 ;leave guard byte alone dad d mvi b,7 xra a clp1: mov m,a inx h dcr b jnz clp1 lhld flsec lxi d,11 ;leave guard byte alone dad d mvi b,7 clp2: mov m,a inx h dcr b jnz clp2 lhld flprm xchg lhld flsec inx h inx d ldax d ;primary exponent .ok pop h pop h ;throw away mvi a,3 ;flag divide by zero error sta flterr_ jmp setbig ;set to biggest possible number d.ok: inx d inx h mvi b,8 cmloop: inx d inx h ldax d cmp m jnz differ dcr b jnz cmloop ;numbers are the same give 1 as the answer pop h ;throw away pop h ;get destination addr inr c ;adjust exponent mov m,c ;save exponent inx h mvi m,0 ;clear extra byte inx h mvi m,1 ;set result mvi b,8 xra a sta flterr_ jmp zclr ; differ: h ; mov a,m ; ora a ; jnz true jmp false ; public .dcmp ;compare primary and secondary ; ;return 0 if p == s p.lt.s: ;return < 0 if p < s xra a dcr a pop b ret ; p.gt.s: ; > 0 if p > s xra a inr a pop b ret ; .dcmp: push b lhld flprm xchg lhld flsec ldax d ora a jm dcneg ; primary is positive xra m ;check if signs the same jm p.gt.s ;differ then p > s jmp docomp dcneg: ;primary is negative xra m ;check if signs the same jm p.lt.s ;di already cleared ldax d sbb m mov m,a dcx d dcx h dcr b jnz sublpb brlpb: mvi a,0 sbb m mov m,a dcx h dcr c jp brlpb subchk: ;check for negative result inx h mov a,m ;check carry byte ora a ;test sign mvi a,1 jp makpos lxi d,15 dad d ;point to end of number neglp: mvi a,0 sbb m mov m,a dcx h dcr e jp neglp mvi a,81H ;make number negative makpos: lhld flprm mov m,a ;set sign of number jmp normalize ; doadd: ;add V to U mvi b,7 lhld h dcr b jnz sublp mov a,c sbi 0 jnz zerobit onebit: lxi h,tmpa inr m lxi h,lcnt dcr m jnz divloop jmp divdone ; zerobit: lxi h,lcnt dcr m jz divdone lxi h,tmpa mvi b,16 ora a ;clear carry zshlp: mov a,m adc a ;shift one bit to the left mov m,a inx h dcr b jnz zshlp sbb a mov c,a mvi b,8 lxi d,tmpb lxi h,tmpc ora a ;clear carry daddlp: ldax d adc m stax d inx d inx h dcr b jnz daddlp mov a,c aci 0 jnz zerobit jmp onebi pchl ; public .dpop ;pop double float into secondary accum .dpop: pop h ;get return address shld retsave ;and save lhld flsec pop d ;exponent/sign and first fraction mov m,e ;save sign inx h mov a,e ani 7fH ;isolate exponent sui 64 ;adjust for excess 64 notation mov m,a inx h mvi m,0 ;extra byte for carry inx h mov m,d inx h pop d ;bytes 2 and 3 of fraction mov m,e inx h mov m,d inx h pop d ;bytes 4 and 5 of fraction mov m,e inx h mov m,d inx  sub m ;compute difference jp ordok xchg ;swap so primary is larger cma inr a ordok: dcx d dcx h shld flsec ;fix primary and secondary xchg shld flprm cpi 9 ;check for exp diff too large jnc normalize mov c,a ;save exponent difference push h push d adi 9 ;adjust for offset mov e,a mvi d,0 dad d ;adjust address for exponent difference shld YU pop d lxi h,9 dad d shld VEE pop h xchg ;get prm in DE and scnd in HL ldax d ;sign of primary xra m ;check carry to find out smaller number pop d ;restore divisor address pop h ;restore dividend address mov m,c ;store exponent jc uok inr c ;bump exponent mov m,c dcx h ;and shift dividend right (logically) uok: push d ;save for later lxi d,9 dad d ;compute end address mvi b,8 lxi d,tmpb ;copy dividend into work area remsav: mov a,m stax d dcx h inx d dcr b jnz remsav pop h ;restore divisor addr lxi d,9 dad d ;move backwards mvi b,8 lxi d,tmpc ;copy divisor . t ; divdone: lhld flprm lxi d,12 dad d mvi m,0 dcx h mvi m,0 lxi d,tmpa mvi b,8 qusav: dcx h ldax d mov m,a inx d dcr b jnz qusav jmp normalize ; public .dml .dml: ;double floating multiply (primary = primary * secondary) push b lhld flprm xchg lhld flsec ldax d xra m ;compute sign of result stax d ;and store inx h inx d ldax d ;primary exponent cpi -64 jz zresult add m ;eu+ev stax d ;save exponent mov a,m ;check for mult by zero cp2 ;setup exponent inx h mvi m,0 ;clear extra byte inx h mov m,d ;move number into accumulator inx h mov m,e mvi b,6 xra a cnvlp: inx h mov m,a dcr b jnz cnvlp jmp goodexit ; dornd: ; round the number in the primary accumulator lhld flprm lxi d,10 ;offset of guard byte dad d mov a,m cpi 128 rc ; < 128 do nothing jnz rndit dcx h ; == 128 make number odd mov a,m ori 1 mov m,a ret ; rndit: ; > 128 add one to fraction push b lxi b,0800H ;b = r ;clear rest to zero ; overflow: mvi a,2 sta flterr_ setbig: call userrtn ;check for user routine to handle errors lhld flprm inx h ;leave sign alone mvi m,63 ;set exponent at max inx h mvi m,0 ;clear overflow byte mvi a,0ffH ;and set fraction to max mvi b,7 oclr: inx h mov m,a dcr b jnz oclr inx h mvi m,0 pop b ret ; userrtn: ;handle messages lhld Sysvec_ ;any routine supplied? mov a,h ora l jz myway xchg lxi h,4 dad sp mov c,m inx h moav: ldax d mov m,a inx d dcx h dcr b jnz msav jmp normalize ; ; public .deq .deq: call .dcmp jz true false: lxi h,0 xra a ret ; public .dne .dne: call .dcmp jz false true: lxi h,1 xra a inr a ret ; public .dlt .dlt: call .dcmp jm true jmp false ; public .dle .dle: call .dcmp jm true jz true jmp false ; public .dge .dge: call .dcmp jm false jmp true ; public .dgt .dgt: call .dcmp jm false jz false jmp true ; public s to move mov c,a ;save for loop lmovlp: mov a,m stax d inx d inx h dcr c jnz lmovlp xra a lclrlp: stax d ;pad with zeros inx d dcr b jnz lclrlp pop d ;restore accum address ; chkexp: ;check for over/under flow ldax d ;get exponent ora a jm chkunder cpi 64 jc goodexit jmp overflow ; chkunder: cpi -63 jc underflow goodexit: mvi a,0 sta flterr_ pop b ret ; movrgt: ;fraction overflow inr c ;bump exponent mov a,c stax d ;save in accum rm mvi m,0 ;clear sign inx h mvi m,3 ;set up exponent lxi d,4 dad d mov e,l mov d,h mvi b,5 xra a xtodclr: inx h mov m,a dcr b jnz xtodclr ; mvi b,4 lxi h,lnprm lda lnprm+3 ora a jp lngok ; lngloop: mvi a,0 sbb m stax d inx h dcx d dcr b jnz lngloop dcx d ;back up to sign field mvi a,080H ;mark as negative stax d jmp normalize ; lngok: mov a,m stax d inx h dcx d dcr b jnz lngok jmp normalize ; public .dtox .dtox: push b i -64 jz zresult push d ;save for later lxi d,9 dad d ;compute end address mvi b,8 lxi d,tmpc ;copy muliplicand into work area msav1: mov a,m stax d dcx h inx d dcr b jnz msav1 pop h ;restore multiplier addr lxi d,9 dad d ;move backwards mvi b,8 lxi d,tmpb ;copy multiplier into work area msav2: mov a,m stax d dcx h inx d dcr b jnz msav2 mvi b,8 lxi h,tmpa ;clear buffer xra a clrmul: mov m,a inx h dcr b jnz clrmul mvi a,64 sta lcnt ;8, and c = 0 stc ; make loop add 1 rndlp: dcx h mov a,m adc c mov m,a dcr b jnz rndlp ora a ;check for fraction overflow jnz normalize ;re-normalize number if so. pop b ret ;return if none ; normalize: lhld flprm ;get address of accum inx h mov a,m ;fetch exponent mov d,h ;save address for later mov e,l inx h mov c,a xra a cmp m ;check extra byte jnz movrgt ;non-zero move number right mvi b,8 ;search up to 8 bytes nloop: inx h cmp m jnz mov b,m push b lhld flterr_ push h xchg call apchl pop h pop h ;clean up arguments ret apchl: pchl ; myway: call pmsg db 'Floating point ',0 lda flterr_ cpi 1 jnz notund call pmsg db 'underflow',0 jmp mycontinue notund: cpi 2 jnz notovr call pmsg db 'overflow',0 jmp mycontinue notovr: call pmsg db 'divide by zero',0 mycontinue: call pmsg db ' at location 0x',0 lxi h,5 dad sp mov a,m push h push psw call phex2 pop psw call phex pop h dcx.utod .utod: push b mov a,h ora l jz zresult xchg mvi b,0 jmp posconv ; public .itod .itod: push b mov a,h ora l jz zresult xchg mvi b,0 mov a,d ora a jp posconv cma mov d,a mov a,e cma mov e,a inx d mvi b,80H posconv: lhld flprm mov m,b ;store sign inx h mov a,d ora a jnz longcvt mvi m,1 ;set up exponent inx h mvi m,0 ;clear extra byte inx h mov m,e ;move number into accumulator mvi b,7 xra a jmp cnvlp ; longcvt: mvi m,mvi b,15 push d ;save for check at end lxi h,16 dad d ;end address for backwards move mov d,h mov e,l rmovlp: dcx d ldax d mov m,a dcx h dcr b jnz rmovlp mvi m,0 ;zap overflow byte back to zero pop d ;restore exponent addr jmp chkexp ; underflow: mvi a,1 sta flterr_ call userrtn ;check for user routine to handle errors xra a lhld flprm inx h ;leave sign alone mvi m,-63 ;set to smallest non-zero value inx h mov m,a inx h mvi m,1 mvi b,8 jmp zcl lxi h,0 shld lnprm shld lnprm+2 lxi d,lnprm ; lhld flprm mov c,m ;get sign inx h mov a,m ;get exponent ora a jz goodexit ; |x| < 1.0 so return zero jm goodexit ; cpi 5 ;check for too big jnc ltoobig ; mov b,a ;save byte count inx h ;skip overflow byte add l mov l,a jnc lxx inr h lxx: mov a,m stax d inx d dcx h dcr b jnz lxx ; mov a,c ;now check sign ora a jp goodexit mvi b,4 lxi h,lnprm d2xneg: mvi a,0 sbb m mov m,a inx h dcr initialize loop counter muloop: lxi h,tmpa mvi b,16 ora a ;clear carry mshlp: mov a,m adc a ;shift one bit to the left mov m,a inx h dcr b jnz mshlp jnc mnext mvi b,8 lxi d,tmpa lxi h,tmpc ora a ;clear carry maddlp: ldax d adc m stax d inx d inx h dcr b jnz maddlp ; mvi b,8 madclp: ldax d aci 0 stax d jnc mnext inx d dcr b jnz madclp ; mnext: lxi h,lcnt dcr m jnz muloop lhld flprm lxi d,12 dad d lxi d,tmpb-2 mvi b,10 msvleft dcr c ;adjust exponent dcr b ;count times thru jnz nloop ;zero answer zresult: xra a sta flterr_ under0: lhld flprm mvi b,10 mov m,a inx h mvi m,-64 ;so exponent will be zero after store zclr: inx h mov m,a dcr b jnz zclr pop b ret ; movleft: mvi a,8 sub b mov b,a jz chkexp ;no change in counter, no move needed dcx h ;back up to zero mov a,c stax d ;save new exponent push d ;save for rounding inx d mvi a,15 sub b ;compute # of byte h mov a,m push psw call phex2 pop psw call phex lxi h,10 ;newline push h call puterr_ pop h ret ; phex2: rar rar rar rar phex: ani 15 adi '0' cpi '9'+1 jc hexok adi 'A'-'0'-10 hexok: mov l,a mvi h,0 push h call puterr_ pop h ret ; pmsg: pop b ;get address of message pmloop: ldax b inx b ora a jz pmsgdone mov l,a mvi h,0 push h call puterr_ pop h jmp pmloop pmsgdone: push b ret ; public .xtod .xtod: push b lhld flp/ b jnz d2xneg jmp goodexit ; ltoobig: xchg mov a,c ora a jm bigneg mvi m,07fH inx h mvi m,0ffH inx h mvi m,0ffH inx h mvi m,0ffH jmp oflow bigneg: mvi m,080H inx h mvi m,0 inx h mvi m,0 inx h mvi m,0 jmp oflow ; ; public .dtou .dtou: push b mvi c,0 ;flag as dtou jmp ifix ; public .dtoi .dtoi: push b mvi c,1 ;flag as dtoi ifix: lhld flprm mov b,m ;get sign inx h mov a,m ;get exponent ora a jz zeroint jp nonzero zeroint: lx/* Copyright (C) 1984 by Manx Software Systems */ #include main(argc, argv) char **argv; { register int (*func)(); int (*prgload())(); if (argc < 2) { fprintf(stderr, "usage: r progname args ...\n"); exit(4); } ++argv; if ((func = prgload(*argv)) == 0) { fprintf(stderr, "Cannot load program\n"); exit(4); } (*func)(argc-1, argv); } #define OVMAGIC 0xf1 struct header { int magic; unsigned ovaddr; unsigned ovsize; unsigned ovbss; int (*ovbgn)(); }@mov a,d aci 0 dcx h dcx h pop b dcr b jnz ml10lp inx h mov m,a ;save last byte of result ora a jz normalize dcx h dcx h ;back up to exponent mov a,m ;check to be sure no overflow ora a jm m10ok cpi 64 jnc overflow m10ok: pop b ret end  dad h ;num*2 mov b,h mov c,l ;save dad h ;num*4 dad h ;num*8 dad b ;num*10 xchg add e inx h mov m,a @; Copyright (C) 1983 by Manx Software Systems ; :ts=8 public .ovbgn extrn main_ extrn _Uorg_, _Uend_ bss saveret,2 .ovbgn: lxi h,_Uorg_ lxi b,_Uend_-_Uorg_ mvi e,0 clrbss: mov m,e inx h dcx b mov a,c ora b jnz clrbss ; pop h shld saveret call main_ lhld saveret ;get return addr pchl ;return to caller end .ovbgn CRBEGIN ASMi h,0 ; |x| < 1.0 so return zero jmp goodexit ; nonzero: cpi 3 ;check for too big jnc toobig ; inx h ;skip overflow byte add l mov l,a jnc xx inr h xx: mov e,m dcx h mov d,m xchg mov a,c ora a jz goodexit mov a,b ora a jp goodexit mov a,h cma mov h,a mov a,l cma mov l,a inx h jmp goodexit ; toobig: mov a,c ora a jnz bigsigned lxi h,0ffffH ;return largest unsigned # jmp oflow ; bigsigned: mov a,b ora a jm negover lxi h,7fffH ;r; static int (*prgload(argv0))() char *argv0; { int fd; char *topmem, *ovend, *sbrk(); unsigned size; struct header header; char name[20]; strcpy(name, argv0); strcat(name, ".ovr"); if ((fd = open(name, 0)) < 0) return 0; if (read(fd, &header, sizeof header) < 0) return 0; /* check magic number on overlay file */ if (header.magic != OVMAGIC || header.ovsize == 0) return 0; topmem = sbrk(0); ovend = header.ovaddr + header.ovsize + header.ovbss; if (topmem < oven@@@@eturn largest positive # jmp oflow ; negover: lxi h,8000H ;return largest negative # oflow: mvi a,2 sta flterr_ pop b ret ; public fabs_ fabs_: lhld flprm mvi m,0 ;force to positive sign ret ; public .dml10 .dml10: push b lhld flprm inx h inr m ;adjust exponent lxi d,9 dad d xra a mvi b,8 ml10lp: push b mov e,m xchg mvi h,0 dad h ;num*2 mov b,h mov c,l ;save dad h ;num*4 dad h ;num*8 dad b ;num*10 xchg add e inx h mov m,a d) { if (sbrk(ovend - topmem) == (char *)-1) return 0; } if (read(fd, header.ovaddr, header.ovsize) < header.ovsize) return 0; close(fd); return header.ovbgn; } ead(fd, &header, sizeof header) < 0) return 0; /* check magic number on overlay file */ if (header.magic != OVMAGIC || header.ovsize == 0) return 0; topmem = sbrk(0); ovend = header.ovaddr + header.ovsize + header.ovbss; if (topmem < oven@0 @@@@r_ extrn tolower_ extrn getusr_ extrn setusr_ extrn rstusr_ extrn .dv,.ud extrn .ml _ extrn scanfmt_ extrn scanf_ extrn setbuf_ extrn sprintf_ extrn sscanf_ extrn ungetc_ extrn unlink_ extrn bios_ extrn index_ extrn movmem_ extrn rindex_ extrn sbrk_ extrn rsvstk_ extrn setjmp_ extrn setmem_ extrn strcat_ extrn strncat_ extrn strcmp_ extrn strncmp_ extrn strcpy_ extrn strlen_ extrn strncpy_ extrn swapmem_ extrn touppe@@ extrn .begin extrn execv_ extrn execl_ extrn agetc_ extrn aputc_ extrn atoi_ extrn atol_ extrn calloc_ extrn Croot_ extrn fdopen_ extrn fgets_ extrn fopen_ extrn freopen_ extrn format_ extrn fprintf_ extrn fputs_ extrn fread_ extrn fscanf_ extrn fseek_ extrn ftell_ extrn fwrite_ extrn getchar_ extrn gets_ extrn getw_ extrn ioctl_ extrn isatty_ extrn lseek_ extrn realloc_ extrn malloc_ extrn free_ extrn creat_ extrn open_ extrn close_ extrn p@@@ extrn .begin extrn atof_ extrn frexp_, ldexp_, modf_ extrn ftoa_ extrn asin_ extrn acos_ extrn arcsine_ extrn atan2_ extrn atan_ extrn exp_ extrn floor_ extrn ceil_ extrn log10_ extrn log_ extrn pow_ extrn ran_ extrn randl_ extrn cos_ extrn sin_ extrn sinh_ extrn cosh_ extrn sqrt_ extrn cotan_ extrn tan_ extrn tanh_ extrn execv_ extrn execl_ extrn agetc_ extrn aputc_ extrn atoi_ extrn atol_ extrn calloc_ extrn Croot_ extrn fdopen_ extrn @osit_ extrn printf_ extrn fclose_ extrn putchar_ extrn puterr_ extrn puts_ extrn putw_ extrn qsort_ extrn rename_ extrn scanfmt_ extrn scanf_ extrn setbuf_ extrn sprintf_ extrn sscanf_ extrn ungetc_ extrn unlink_ extrn bios_ extrn index_ extrn movmem_ extrn rindex_ extrn sbrk_ extrn rsvstk_ extrn setjmp_ extrn setmem_ extrn strcat_ extrn strncat_ extrn strcmp_ extrn strncmp_ extrn strcpy_ extrn strlen_ extrn strncpy_ extrn swapmem_ extrn touppe@1 fgets_ extrn fopen_ extrn freopen_ extrn format_ extrn fprintf_ extrn fputs_ extrn fread_ extrn fscanf_ extrn fseek_ extrn ftell_ extrn fwrite_ extrn getchar_ extrn gets_ extrn getw_ extrn ioctl_ extrn isatty_ extrn lseek_ extrn realloc_ extrn malloc_ extrn free_ extrn creat_ extrn open_ extrn close_ extrn posit_ extrn printf_ extrn fclose_ extrn putchar_ extrn puts_ extrn putw_ extrn qsort_ extrn rename_ extrn scanfmt_ extrn scanf_ extrn set@@@r (;;) { strcat(filename, ".ovr"); if ((fd = open(filename, 0)) >= 0) break; if (flag++) loadabort(10); strcpy(filename, "a:"); strcat(filename, ovname); } if (read(fd, &hdr, sizeof hdr) != sizeof hdr) loadabort(20); /* check magic number on overlay file */ if (hdr.magic != OVMAGIC) loadabort(30); if (_mbot < hdr.ovaddr+hdr.ovsize+hdr.ovbss) loadabort(40); if (read(fd, hdr.ovaddr, hdr.ovsize) < hdr.ovsize) loadabort(50); close(fd); return hdr.ovbgn;@buf_ extrn sprintf_ extrn sscanf_ extrn ungetc_ extrn unlink_ extrn bios_ extrn index_ extrn movmem_ extrn rindex_ extrn sbrk_ extrn rsvstk_ extrn setjmp_ extrn setmem_ extrn strcat_ extrn strncat_ extrn strcmp_ extrn strncmp_ extrn strcpy_ extrn strlen_ extrn strncpy_ extrn swapmem_ extrn toupper_ extrn tolower_ extrn getusr_ extrn setusr_ extrn rstusr_ extrn .dv,.ud extrn .ml @@@ } static loadabort(code) { char buffer[80]; sprintf(buffer, "Error %d loading overlay: %s$", code, ovname); bdos(9, buffer); exit(10); } check magic number on overlay file */ if (hdr.magic != OVMAGIC) loadabort(30); if (_mbot < hdr.ovaddr+hdr.ovsize+hdr.ovbss) loadabort(40); if (read(fd, hdr.ovaddr, hdr.ovsize) < hdr.ovsize) loadabort(50); close(fd); return hdr.ovbgn;@@/* Copyright (C) 1983, 1984 by Manx Software Systems */ #define OVMAGIC 0xf1 struct header { int magic; unsigned ovaddr; unsigned ovsize; unsigned ovbss; int (*ovbgn)(); }; static char *ovname; #asm public ovloader ovloader: lxi h,2 dad sp mov e,m inx h mov d,m xchg shld ovname_ ; call _ovld_ pchl #endasm static _ovld() { int fd, flag; auto struct header hdr; extern char *_mbot; auto char filename[64]; flag = 0; strcpy(filename, ovname); fo@2 ; Copyright (C) 1983, 1984 by Manx Software Systems ; :ts=8 public .ovbgn, ovexit_ extrn ovmain_ extrn _Uorg_, _Uend_ bss ovstkpt,2 bss saveret,2 bss bcsave,2 bss ixsave,2 bss iysave,2 ; .ovbgn: lxi h,_Uorg_ lxi b,_Uend_-_Uorg_ mvi e,0 clrbss: mov m,e inx h dcx b mov a,c ora b jnz clrbss ; mov h,b mov l,c shld bcsave xra a adi 3 jpe savedone db 221 shld ixsave db 253 shld iysave savedone: pop h shld saveret pop d lxi h,0 dad sp shld ovs@@@;Copyright (C) 1981,1982,1983 by Manx Software Systems ; :ts=8 BDOS equ 5 extrn Croot_ extrn _Uorg_, _Uend_ ; public lnprm, lntmp, lnsec ; ; The 3 "bss" statements below must remain in EXACTLY the same order, ; with no intervening statements! ; bss lnprm,4 bss lntmp,4 bss lnsec,4 ; global sbot,2 global errno_,2 global _mbot_,2 dseg public Sysvec_ Sysvec_: dw 0 dw 0 dw 0 dw 0 public $MEMRY $MEMRY: dw 0ffffh ; fcb: db 0,'???????????',0,0,0,0 ds 16 cseg public .@tkpt ;save stack pointer for ovexit call ovmain_ xchg ;save return value ovret: lhld saveret ;get return addr push h ;place dummy overlay name ptr on stack push h ;place return addr on stack xchg ;restore return value to hl ret ;return to caller ; ovexit_: lhld bcsave mov b,h mov c,l xra a adi 3 jpe restdone db 221 lhld ixsave db 253 lhld iysave restdone: lxi h,2 ;get return value dad sp mov e,m inx h mov d,m lhld ovstkpt ;restore original stack @@@begin public _exit_ .begin: lxi h,_Uorg_ lxi b,_Uend_-_Uorg_ mvi e,0 clrbss: mov m,e inx h dcx b mov a,c ora b jnz clrbss ; LHLD BDOS+1 SPHL lxi d,-2048 dad d ;set heap limit at 2K below stack shld sbot lhld $MEMRY shld _mbot_ CALL Croot_ _exit_: mvi c,17 ;search for first (used to flush deblock buffer) lxi d,fcb call BDOS lxi b,0 call BDOS JMP _exit_ ; end .begin @pointer sphl jmp ovret end .ovbgn h ;place dummy overlay name ptr on stack push h ;place return addr on stack xchg ;restore return value to hl ret ;return to caller ; ovexit_: lhld bcsave mov b,h mov c,l xra a adi 3 jpe restdone db 221 lhld ixsave db 253 lhld iysave restdone: lxi h,2 ;get return value dad sp mov e,m inx h mov d,m lhld ovstkpt ;restore original stack @@3 @@lic $MEMRY $MEMRY: dw 0ffffh cseg public .begin .begin: di lxi sp,stack+stksize ; ; The loop below moves the initialized data from ROM to RAM. ; If your program has no initialized data, or the initialized ; data isn't modified, then delete this loop. ; lxi h,_Cend_ lxi d,_Dorg_ lxi b,_Dend_-_Dorg_ mov a,h cmp d jnz movedata mov a,l cmp e jz movedone movedata: ; If your processor is a Z80, then remove the comment from the ; next line and comment out the next 8 lines. ; db@@@;Copyright (C) 1981,1982,1983 by Manx Software Systems ; :ts=8 BDOS equ 5 extrn Croot_ dseg ; ; The 3 "ds 4" statements below must remain in EXACTLY the same order, ; with no intervening statements! ; public lnprm, lntmp, lnsec lnprm: ds 4 lntmp: ds 4 lnsec: ds 4 ; public Sysvec_ Sysvec_: dw 0 dw 0 dw 0 dw 0 public $MEMRY $MEMRY: dw -1 public sbot sbot: dw 0 public errno_ errno_: dw 0 ; fcb: db 0,'???????????',0,0,0,0 ds 16 cseg public .begin public _exit_ .begi@ 237,176 ;ldir mov a,m stax d inx h inx d dcx b mov a,c ora b jnz movedata movedone: ; lxi h,_Uorg_ lxi b,_Uend_-_Uorg_ mvi e,0 clrbss: mov m,e inx h dcx b mov a,c ora b jnz clrbss ; ei ;no argc,argv in ROM system jmp main_ ;main shouldn't return in ROM based system end .begin  movedata: ; If your processor is a Z80, then remove the comment from the ; next line and comment out the next 8 lines. ; db@;Copyright (C) 1983 by Manx Software Systems ; :ts=8 ; ; stksize should be set according to your program's needs ; stksize equ 1024 bss stack,stksize extrn main_ extrn _Corg_, _Cend_ extrn _Dorg_, _Dend_ extrn _Uorg_, _Uend_ ; ; The 3 "bss" statements below must remain in EXACTLY the same order, ; with no intervening statements! ; public lnprm, lntmp, lnsec bss lnprm,4 bss lntmp,4 bss lnsec,4 ; global errno_,2 dseg public Sysvec_ Sysvec_: dw 0 dw 0 dw 0 dw 0 pub@n: LHLD BDOS+1 SPHL lxi d,-2048 dad d ;set heap limit at 2K below stack shld sbot CALL Croot_ _exit_: mvi c,17 ;search for first (used to flush deblock buffer) lxi d,fcb call BDOS lxi b,0 call BDOS JMP _exit_ end .begin ntmp: ds 4 lnsec: ds 4 ; public Sysvec_ Sysvec_: dw 0 dw 0 dw 0 dw 0 public $MEMRY $MEMRY: dw -1 public sbot sbot: dw 0 public errno_ errno_: dw 0 ; fcb: db 0,'???????????',0,0,0,0 ds 16 cseg public .begin public _exit_ .begi@@4 @@; Copyright (C) 1983 by Manx Software Systems ; :ts=8 dseg string: ds 2 size: dw 0 number: ds 4 cseg public fmtcvt_ fmtcvt_: ;char *fmtcvt(ptr, base, buffer, size) push b lxi h,0 shld number shld number+2 lxi h,10 dad sp mov a,m sta size mov b,a ;save size for later dcx h mov d,m dcx h mov e,m dcx h xchg mvi m,0 ;null terminate string shld string xchg dcx h mov c,m ;C = base dcx h mov d,m dcx h mov e,m lxi h,number cpnum: ldax d mov m,a  SPHL PUSH D lxi h,cret push h mov h,b mov l,c pchl ; ; move - move BC bytes from (HL) to (DE), used for struct assignment ; public .move .move: mov a,m stax d inx h inx d dcx b mov a,b ora c jnz .move ret ; public .ARG1,.ARG2,.ARG3,.asave ; .asave: ;support for assembly routines which must save IX and IY pop d ;save return address lxi h,2 ;compute address of arguments dad sp xra a adi 3 jpe nopush DB 221,229,253,229 ;push ix ; push iy nopush: PU@@@@ inx d inx h dcr b jnz cpnum mov a,c ora a jp unsigned ; base < 0, means do signed conversion cma inr a mov c,a ;C = base lhld size lxi d,number-1 dad d mov a,m ora a push psw jp top ;number is negative, so make it positive ;note: carry is already cleared by 'ora' above lda size mov b,a lxi h,number ngloop: mvi a,0 sbb m mov m,a inx h dcr b jnz ngloop jmp top unsigned: push psw top: lxi h,number+3 mvi d,0 mvi a,4 outer: push psw SH B push d ;put return addr back lxi d,.ARG1 mvi b,6 cpyloop: ;copy args to known place mov a,m stax d inx h inx d dcr b jnz cpyloop lxi h,asmret xthl pchl ; asmret: POP B xra a adi 3 jpe nopop DB 253,225,221,225 ; pop iy ; pop ix nopop: mov a,h ora l RET ; dseg .ARG1: ds 2 .ARG2: ds 2 .ARG3: ds 2 end i h,2 ;compute address of arguments dad sp xra a adi 3 jpe nopush DB 221,229,253,229 ;push ix ; push iy nopush: PU@@;Copyright (C) 1981,1982,1984 by Manx Software Systems ; :ts=8 extrn .begin public .chl .chl: PCHL ; public zsave,zret zsave: POP H PUSH B MOV B,H MOV C,L LXI H,0 DAD SP XCHG DAD SP SPHL PUSH D DB 221,229,253,229 ;push ix ; push iy mov h,b mov l,c call .chl ; zret: DB 253,225,221,225 ; pop iy ; pop ix cret: XCHG POP H SPHL POP B XCHG MOV A,H ORA L RET ; public csave,cret csave: POP H PUSH B MOV B,H MOV C,L LXI H,0 DAD SP XCHG DAD SP @ mov e,m xchg mvi b,8 inner: dad h mov a,h sub c jc zero mov h,a inr l zero: dcr b jnz inner xchg mov m,e dcx h pop psw dcr a jnz outer ; mov e,d mvi d,0 lxi h,digits dad d mov a,m lhld string dcx h shld string mov m,a ; lxi h,number mvi b,4 xra a zcheck: cmp m jnz top inx h dcr b jnz zcheck lhld string pop psw jp notneg dcx h mvi m,'-' notneg: pop b ret ; digits: db '0123456789abcdef' end 5 @@@; Copyright (C) 1982, 1983 by Manx Software Systems ; :ts=8 BDOS equ 5 extrn errno_ extrn .asave,.ARG1,.ARG2,.ARG3 public blkrd_ blkrd_: call .asave mvi c,33 ;set function to read sequential jmp rdwrt ; public blkwr_ blkwr_: call .asave mvi c,34 ;set function to write sequential rdwrt: push b ioloop: lhld .ARG2 xchg lxi h,128 dad d ;bump address to next sector shld .ARG2 mvi c,26 ;set DMA address call BDOS pop b push b lhld .ARG1 xchg call BDOS ;read o@@@@;Copyright (C) 1981,1982 by Manx Software Systems ; :ts=8 BASE equ 0 BDOS equ 5 extrn .ARG1,.ARG2,.ARG3,.asave ; public bdoshl_ bdoshl_: call .asave call combdos xchg ;get back original hl value ret ; public bdos_,CPM_ bdos_: CPM_: call .asave combdos: lhld .ARG1 mov b,h mov c,l lhld .ARG2 xchg CALL BDOS xchg ;save for bdoshl call mov l,a xra a ;set zero flag mov h,a RET end r write sector ora a jnz ioerr lhld .ARG1 lxi d,33 dad d inr m jnz nocarry inx h inr m nocarry: lhld .ARG3 dcx h shld .ARG3 mov a,l ora h jnz ioloop pop b ;pull function code from stack ret ;all done, return number remaining ; ioerr: cpi 1 jz dontset cpi 4 jz dontset mov l,a mvi h,0 shld errno_ dontset: pop b ;pull function code from stack lhld .ARG3 ret ;return number remaining end @@@@@6 @@@@@dr ; mov a,c ora b jz badname skipbl: ldax b cpi ' ' jz skip cpi 9 jnz skipdone skip: inx b jmp skipbl skipdone: ; push b ;save address of name mvi d,0 ;init user # userloop: ldax b call isdig jc userdone sui '0' mov e,a mov a,d add a ;*2 add a ;*4 add a ;*8 add d ;*9 add d ;*10 add e ;add in digit mov d,a inx b jmp userloop userdone: cpi '/' jnz nouser inx b pop psw ;throw away saved address jmp setuser nouser: pop b ;restore@@@;Copyright (C) 1981,1982 by Manx Software Systems BASE equ 0 BDOS equ 5 extrn .ARG1,.ARG2,.ARG3,.asave ; public bios_ bios_: call .asave call combios mov l,a mvi h,0 ret ; public bioshl_ bioshl_: call .asave combios: lhld .ARG1 xchg lhld BASE+1 dcx h dcx h dcx h dad d dad d dad d xchg ;bios jump addr in DE lhld .ARG2 mov b,h mov c,l lhld .ARG3 xchg ;now arg3 in DE, and bios jump in HL pchl end @ original address mvi d,255 ;set user # to default setuser: inx b ldax b cpi ':' dcx b mvi a,0 jnz nodrive ; ldax b ani 127 cpi 'A' jc badname cpi 'Z'+1 jnc lowerc sui 'A'-1 jmp setdrive ; lowerc: cpi 'a' jc badname cpi 'z'+1 jnc badname sui 'a'-1 setdrive: mov m,a inx b inx b nodrive: inx h ; move name in mapping to upper case mvi e,8 nameskp: inr e namelp: ldax b inx b cpi '.' jz namedn ora a jz alldone dcr e jz nameskp cal@@;Copyright (C) 1981,1982 by Manx Software Systems ; :ts=8 public fcbinit_ fcbinit_: push b lxi h,4 dad sp mov c,m ; BC contains name inx h mov b,m inx h mov e,m ; DE contains fcb address inx h mov d,m ; clear name to blanks mov l,e ;copy fcb address into HL mov h,d mvi m,0 ;clear drive # inx h mvi a,11 ;clear name and ext to blanks clrlp: mvi m,' ' inx h dcr a jnz clrlp mvi a,4 zrlp: mvi m,0 inx h dcr a jnz zrlp xchg ; now HL contains fcb ad7 l toupper mov m,a inx h jmp namelp ; namedn: dcr e mov a,e add l mov l,a mov a,h aci 0 mov h,a ; move extension mapping to upper case mvi e,3 extlp: ldax b inx b ora a jz alldone call toupper mov m,a inx h dcr e jnz extlp ; alldone: mvi h,0 mov l,d ;return user # prefix mov a,d ora a pop b ret ; badname: lxi h,-1 mov a,h ora a pop b ret ; toupper: cpi '*' jnz nostar dcx b ;back up so we see star again mvi a,'?' ;and map i;Copyright (C) 1981,1982 by Manx Software Systems ;Copyright (C) 1983,1984 by Manx Software Systems ; :ts=8 extrn $MEMRY, sbot ; ; sbrk(size): return address of current top & bump by size bytes ; public sbrk_ sbrk_: lxi h,2 dad sp mov e,m ; get size to allocate inx h mov d,m lhld $MEMRY dad d jc sbrk.ov xchg ;save for compare lhld sbot mov a,l ;check for stack/heap overflow sub e mov a,h sbb d jc sbrk.ov lhld $MEMRY ;get old value xchg shld $MEMRY ;new value @@@; Copyright (C) 1984 by Manx Software Systems ; :ts=8 ; The C routine execl() in exec.c knows that this function is ; less than 70 bytes long. If this code is changed, then execl ; must be changed also. ; ; This routine is copied into an automatic array and invoked ; there by execl(). The code is self relocating and must ; remain so. ; bdos equ 5 defdma equ 80h tpa equ 100h public ldr__ ; ldr_(&fcb, ouser) ldr__: pop d ;throw away return pop b ;set up fcb address lxi d,9 dad d ;nto question ret nostar: cpi 'a' rc cpi 'z'+1 rnc sui 'a'-'A' ret ; isdig: cpi '0' rc cpi '9'+1 jnc notdig ora a ret notdig: stc ret ; end e jnz extlp ; alldone: mvi h,0 mov l,d ;return user # prefix mov a,d ora a pop b ret ; badname: lxi h,-1 mov a,h ora a pop b ret ; toupper: cpi '*' jnz nostar dcx b ;back up so we see star again mvi a,'?' ;and map iis good so save it away xchg ;return original value mov a,h ora l ret ; no space left!! sbrk.ov: lxi h,-1 xra a dcr a ret ; ; ; rsvstk(size): reserve size bytes of stack space ; public rsvstk_ rsvstk_: lxi h,2 dad sp mov a,l sub m mov e,a mov a,h inx h sbb m mov d,a xchg shld sbot ret end eck for stack/heap overflow sub e mov a,h sbb d jc sbrk.ov lhld $MEMRY ;get old value xchg shld $MEMRY ;new value @@@fix hl to point to head of loop lxi d,tpa ; ; bc = fcb address ; de = tpa address ; hl = address of this routine ; old user # pushed onto stack ; push h ;save loop address push d push b mvi c,26 call bdos pop d push d mvi c,20 call bdos pop b ;restore fcb address pop d ;and loading addr. lxi h,80h dad d ;bump loading addr xchg pop h push h ;restore loop address ora a ;check if eof rz ;if not, return to top of loop pop h ;throw away return addr pop d @@@8 ;get old user # mvi c,32 call bdos ;restore user # lxi d,defdma mvi c,26 call bdos lhld bdos+1 sphl lxi h,0 push h ;set for proper return from program jmp tpa end ll bdos pop b ;restore fcb address pop d ;and loading addr. lxi h,80h dad d ;bump loading addr xchg pop h push h ;restore loop address ora a ;check if eof rz ;if not, return to top of loop pop h ;throw away return addr pop d @@@@@@; Copyright (C) 1983 by Manx Software Systems ; :ts=8 BDOS equ 5 extrn .asave,.ARG1,.ARG2,.ARG3 dseg oldusr: db 0 cseg public getusr_ getusr_: call .asave mvi c,32 mvi e,255 call BDOS ;get current user # mov l,a mvi h,0 ora a ret ; public setusr_ setusr_: call .asave mvi c,32 mvi e,255 call BDOS sta oldusr lda .ARG1 cpi 255 rz mvi c,32 mov e,a jmp BDOS ;set new user number ; public rstusr_ rstusr_: call .asave mvi c,32 lda oldusr mov e,a j@@@; Copyright (C) 1983 by Manx Software Systems ; :ts=8 public setjmp_ setjmp_: lxi h,2 dad sp mov e,m ;get address of jump buffer inx h mov d,m dcx h ;get SP value back xchg mov m,e ;save SP value inx h mov m,d inx h pop d push d mov m,e ;save PC value inx h mov m,d inx h mov m,c ;save BC value inx h mov m,b xra a adi 3 jpe setdone inx h db 221,229 ;push ix pop d mov m,e ;save IX value inx h mov m,d inx h db 253,229 ;push iy pop d @mp BDOS ;restore old user number end  public getusr_ getusr_: call .asave mvi c,32 mvi e,255 call BDOS ;get current user # mov l,a mvi h,0 ora a ret ; public setusr_ setusr_: call .asave mvi c,32 mvi e,255 call BDOS sta oldusr lda .ARG1 cpi 255 rz mvi c,32 mov e,a jmp BDOS ;set new user number ; public rstusr_ rstusr_: call .asave mvi c,32 lda oldusr mov e,a j@9 mov m,e ;save IY value inx h mov m,d setdone: lxi h,0 xra a ;set zero flag ret ; public longjmp_ longjmp_: lxi h,2 dad sp mov e,m ;get address of jump buffer inx h mov d,m inx h mov c,m ;get return value inx h mov b,m xchg mov e,m ;get SP value inx h mov d,m inx h xchg sphl ;switch to original stack xchg mov e,m ;get PC value inx h mov d,m inx h push d ;save for return push b ;save return value mov c,m ;get BC value inx h mov b,m @@@ ora a jz done inx d ;++s1 inx h ;++s2 dcx b ;--len jmp cmploop ;} done: pop b mov l,a sbb a mov h,a ora l ret end : mov d,m dcx h mov e,m ;DE = s2 dcx h mov a,m dcx h mov l,m mov h,a ;HL = s1 xchg ;now DE=s1, HL=s2 cmploop: mov a,b ;while (len) { ora c jz done ldax d ;if (*s1-*s2) break sub m jnz done ldax d ;if (*s1 == 0) break @ xra a adi 3 jpe longdone inx h mov e,m ;get IX value inx h mov d,m inx h push d db 221,225 ;pop ix mov e,m ;get IY value inx h mov d,m push d db 253,225 ;pop iy longdone: pop h mov a,l ora h rnz inx h ;force non-zero return inr a ;set non-zero flag ret end ue inx h mov d,m inx h push d ;save for return push b ;save return value mov c,m ;get BC value inx h mov b,m @@@@@@;Copyright (C) 1981,1982,1983 by Manx Software Systems ; :ts=8 public strcmp_ strcmp_: lxi h,5 dad sp push b lxi b,32767 jmp same ; public strncmp_ strncmp_: lxi h,7 dad sp push b mov b,m dcx h mov c,m ;BC = len dcx h same: mov d,m dcx h mov e,m ;DE = s2 dcx h mov a,m dcx h mov l,m mov h,a ;HL = s1 xchg ;now DE=s1, HL=s2 cmploop: mov a,b ;while (len) { ora c jz done ldax d ;if (*s1-*s2) break sub m jnz done ldax d ;if (*s1 == 0) break @: ;Copyright (C) 1981,1982,1983 by Manx Software Systems ; :ts=8 public strcpy_ strcpy_: lxi h,5 dad sp mov d,m dcx h mov e,m ;DE = s2 dcx h mov a,m dcx h mov l,m mov h,a ;HL = s1 push h ;save target for return cpyloop: ldax d ;while (*s1++ = *s2++) ; mov m,a ora a jz done inx d inx h ;++s2 jmp cpyloop ;} done: pop h ;return target address mov a,h ora l ret end @@@;Copyright (C) 1981,1982,1983 by Manx Software Systems ; :ts=8 public strncpy_ strncpy_: lxi h,7 dad sp push b mov b,m dcx h mov c,m ;BC = len dcx h mov d,m dcx h mov e,m ;DE = s2 dcx h mov a,m dcx h mov l,m mov h,a ;HL = s1 push h ;save target for return cpyloop: mov a,b ;while (len) { ora c jz done ldax d ;if (*s1 = *s2) ++s1 mov m,a ora a jz padding inx d padding: inx h ;++s2 dcx b ;--len jmp cpyloop ;} done: pop h ;return target addr@@@@@ess pop b mov a,h ora l ret end ,m dcx h mov c,m ;BC = len dcx h mov d,m dcx h mov e,m ;DE = s2 dcx h mov a,m dcx h mov l,m mov h,a ;HL = s1 push h ;save target for return cpyloop: mov a,b ;while (len) { ora c jz done ldax d ;if (*s1 = *s2) ++s1 mov m,a ora a jz padding inx d padding: inx h ;++s2 dcx b ;--len jmp cpyloop ;} done: pop h ;return target addr@@@@; @@@@@@;Copyright (C) 1981,1982,1983 by Manx Software Systems ; :ts=8 public strcat_ ;strcat(s1,s2) strcat_: lxi h,5 dad sp push b lxi b,32767 jmp same ; public strncat_ ;strncat(s1,s2,len) strncat_: lxi h,7 dad sp push b mov b,m dcx h mov c,m ;BC = len dcx h same: mov d,m dcx h mov e,m ;DE = s2 dcx h mov a,m dcx h mov l,m mov h,a ;HL = s1 push h ;save destination for return value xra a eloop: cmp m ;while (*s1) ++s1; jz cpyloop inx h jmp eloop ;@@@;Copyright (C) 1981,1982,1983 by Manx Software Systems ; :ts=8 public index_ index_: lxi h,2 dad sp mov e,m ;DE = destination inx h mov d,m inx h mov l,m xchg ;e has char to look for scan: mov a,m cmp e jz foundit ora a jz noluck inx h jmp scan ; noluck: lxi h,0 xra a ret ; foundit: mov a,h ora l ret end @} cpyloop: ;while (len) { mov a,b ora c jz done ldax d ;if ((*s1 = *s2) == 0) break mov m,a ora a jz done inx d ;++s1 inx h ;++s2 dcx b ;--len jmp cpyloop ;} done: mov m,a ;guarantee null termination pop h pop b mov a,h ora l ret end = s1 push h ;save destination for return value xra a eloop: cmp m ;while (*s1) ++s1; jz cpyloop inx h jmp eloop ;@@< @@;Copyright (C) 1981,1982,1983 by Manx Software Systems ; :ts=8 public strlen_ strlen_: LXI H,2 DAD SP MOV A,M INX H MOV H,M MOV L,A LXI D,0 XRA A .stl: CMP M JZ .stlx INX D INX H JMP .stl .stlx: XCHG mov a,l ora h RET end ploop: ;HL=dst, DE=src dcx d dcx h ldax d mov m,a dcx b mov a,b ora c jnz uploop pop b ret ; movedown: ;src < dst @@@@@@@@@;Copyright (C) 1981,1982,1983 by Manx Software Systems ; :ts=8 public rindex_ rindex_: push b lxi h,4 dad sp mov e,m ;DE = destination inx h mov d,m inx h mov l,m xchg ;e has char to look for lxi b,0 xra a toend: cmp m ;scan for end of string jz scan inx h inx b jmp toend scan: mov a,b ora c jz noluck dcx b dcx h mov a,m cmp e jnz scan mov a,h ora l pop b ret noluck: lxi h,0 xra a pop b ret ; end @@= @@@;Copyright (C) 1983 by Manx Software Systems public setmem_ setmem_: push b lxi h,4 dad sp mov e,m inx h mov d,m inx h mov c,m inx h mov b,m inx h mov l,m xchg setloop: mov a,b ora c jz done mov m,e inx h dcx b jmp setloop done: pop b ret end @@@@;Copyright (C) 1983 by Manx Software Systems ; :ts=8 public movmem_ ;movmem(src,dst,len) movmem_: push b lxi h,9 dad sp mov b,m ;BC=len dcx h mov c,m dcx h mov d,m ;DE=dst dcx h mov e,m dcx h mov a,m dcx h mov l,m ;HL=src mov h,a cmp d jc movedown jnz moveup mov a,l cmp e jc movedown jz done moveup: ;src > dst dad b xchg dad b xra a adi 3 ;test if z80 jpe uploop ;not z80 use loop to move data xchg dcx d dcx h db 237,184 ;lddr @@@@@ pop b ret ; uploop: ;HL=dst, DE=src dcx d dcx h ldax d mov m,a dcx b mov a,b ora c jnz uploop pop b ret ; movedown: ;src < dst xra a adi 3 ;test if z80 jpe downloop ;not z80 use loop to move data db 237,176 ;ldir pop b ret ; downloop: mov a,m stax d inx d inx h dcx b mov a,b ora c jnz downloop done: pop b ret end > @ h b mov b,m dcx h mov c,m ;BC = len dcx h mov d,m dcx h mov e,m ;DE = s2 dcx h mov a,m dcx h mov l,m mov h,a ;HL = s1 mov a,c ora a jnz bok dcr b bok: push b swaploop: mov b,m ldax d mov m,a mov a,b stax d inx h inx d dcr c jnz swaploop pop psw ora a jz done dcr a push psw jmp swaploop done: pop b ret end@@@@@@@; Copyright (C) 1983 by Manx Software Systems ; :ts=8 public swapmem_ ;swapmem(s1,s2,len) swapmem_: lxi h,7 dad sp push b mov b,m dcx h mov c,m ;BC = len dcx h mov d,m dcx h mov e,m ;DE = s2 dcx h mov a,m dcx h mov l,m mov h,a ;HL = s1 mov a,c ora a jnz bok dcr b bok: push b swaploop: mov b,m ldax d mov m,a mov a,b stax d inx h inx d dcr c jnz swaploop pop psw ora a jz done dcr a push psw jmp swaploop done: pop b ret end@@@@;Copyright (C) 1981,1982 by Manx Software Systems ; :ts=8 public toupper_ toupper_: lxi h,2 dad sp mov a,m cpi 'a' jc skip cpi 'z'+1 jnc skip sui 'a'-'A' skip: mov l,a mvi h,0 ora a ret ; ; public tolower_ ; tolower_: lxi h,2 dad sp mov a,m cpi 'A' jc skip2 cpi 'Z'+1 jnc skip2 adi 'a'-'A' skip2: mov l,a mvi h,0 ora a ret end ? @; Copyright (C) 1982, 1983, 1984 by Manx Software Systems ; :ts=8 extrn lnprm,lntmp,lnsec ; public .llis ;load long immediate secondary .llis: pop d ;get return addr lxi h,4 ;size of long dad d push h ;put back correct return addr xchg ;fall through into .llds ; public .llds ;load long into secondary accum .llds: lxi d,lnsec jmp lload ; public .llip ;load long immediate primary .llip: pop d ;get return addr lxi h,4 ;size of long dad d push h ;put back correcear carry mvi b,4 adloop: ldax d adc m stax d inx h inx d dcr b jnz adloop pop b ret ; public .lsb ;subtract secondary from primary .lsb: push b lxi d,lnprm lxi h,lnsec xra a ;clear carry mvi b,4 sbloop: ldax d sbb m stax d inx h inx d dcr b jnz sbloop pop b ret ; public .lan ;and primary with secondary .lan: push b lxi d,lnprm lxi h,lnsec mvi b,4 ndloop: ldax d ana m stax d inx h inx d dcr b jnz ndloop pop b ret ; pub@ .lng ;negate primary .lng: lxi h,lnprm negate: xra a mvi d,4 ngloop: mvi a,0 sbb m mov m,a inx h dcr d jnz ngloop ret ; public .ltst ;test if primary is zero .ltst: lxi h,lnprm mvi d,4 tstlp: mov a,m ora a jnz true inx h dcr d jnz tstlp jmp false ; public .lcmp ;compare primary and secondary ; ;return 0 if p == s p.lt.s: ;return < 0 if p < s xra a dcr a pop b ret ; p.gt.s: ; > 0 if p > s xra a inr a pop b ret ; .lcmp: push  ;right shift primary by secondary bits .lrs: lda lnprm+3 ral ;set carry to MSB rs_sub: push psw lda lnsec ani 03fH ;limit to 63 places jz rsdone mov d,a rslp1: lxi h,lnprm+3 mvi e,4 pop psw ;get correct carry setting push psw rslp2: mov a,m rar mov m,a dcx h dcr e jnz rslp2 dcr d jnz rslp1 rsdone: pop psw ret ; ; setup: lxi h,3 dad d mov c,m mov a,c ora a rp xchg jmp negate ;force positive ; public .ldv .ldv: ;long divide (primary =@t return addr xchg ;fall through into .lldp ; public .lldp ;load long into primary accum .lldp: lxi d,lnprm lload: mov a,m stax d inx d inx h mov a,m stax d inx d inx h mov a,m stax d inx d inx h mov a,m stax d ret ; public .lst ;store long at addr in HL .lst: lxi d,lnprm ldax d mov m,a inx h inx d ldax d mov m,a inx h inx d ldax d mov m,a inx h inx d ldax d mov m,a ret ; public .lpsh ;push long onto the stack .lpsh: ;flic .lor ;or primary with secondary .lor: push b lxi d,lnprm lxi h,lnsec mvi b,4 orloop: ldax d ora m stax d inx h inx d dcr b jnz orloop pop b ret ; public .lxr ;exclusive or primary with secondary .lxr: push b lxi d,lnprm lxi h,lnsec mvi b,4 xrloop: ldax d xra m stax d inx h inx d dcr b jnz xrloop pop b ret ; public .lcm ;complement primary .lcm: lxi h,lnprm mvi d,4 cmloop: mov a,m cma mov m,a inx h dcr d jnz cmloop ret @b lxi d,lnprm+3 lxi h,lnsec+3 mov a,m xri 80h mov c,a ldax d xri 80h cmp c mvi b,4 jmp pswchk public .ulcmp .ulcmp: push b lxi d,lnprm+3 lxi h,lnsec+3 mvi b,4 cmploop: ldax d cmp m pswchk: jc p.lt.s jnz p.gt.s dcx h dcx d dcr b jnz cmploop ;return 0 if p == s xra a pop b ret ; public .lad ;add secondary to primary .lad: ;DE is used as primary address ;and HL is used as secondary address push b lxi d,lnprm lxi h,lnsec xra a ;cl primary/secondary) push b lxi d,lnprm call setup push b lxi d,lnsec call setup mov a,c pop b ;get primary sign xra c ;merge signs push psw ;save for return call dodivide pop psw pop b jm .lng ret ; public .lrm .lrm: ;long remainder (primary = primary%secondary) push b lxi d,lnprm call setup mov a,c ora a push psw lxi d,lnsec call setup call dodivide lxi d,lntmp lxi h,lnprm mvi b,4 remsave: ldax d mov m,a inx d inx h dcr b jnz remsav@rom the primary accumulator pop d ;get return address lxi h,lnprm+3 lhld lnprm+2 push h lhld lnprm push h xchg pchl ; public .lpop ;pop long into secondary accum .lpop: pop d ;get return address pop h ;bytes 0 and 1 shld lnsec pop h shld lnsec+2 xchg pchl ; public .lswap ;exchange primary and secondary .lswap: lhld lnsec xchg lhld lnprm shld lnsec xchg shld lnprm lhld lnsec+2 xchg lhld lnprm+2 shld lnsec+2 xchg shld lnprm+2 ret ; public; public .lls ;shift primary left by secondary .lls: lda lnsec ani 03fH ;restrict to 63 bits rz lhld lnprm xchg lhld lnprm+2 ;DE has low word, HL has high word lsloop: dad h ;shift high word xchg dad h ;shift low word xchg jnc lsnc inr l ;carry into high word lsnc: dcr a jnz lsloop shld lnprm+2 ;put back high word xchg shld lnprm ret ; public .lur ;unsigned right shift primary by secondary bits .lur: clc ;propogate 0 bit jmp rs_sub ; public .lrs @ e pop psw pop b jm .lng ret ; public .lud .lud: ;unsigned long divide (primary = primary/secondary) push b call dodivide pop b ret ; public .lum .lum: ;long remainder (primary = primary%secondary) push b call dodivide lxi d,lntmp lxi h,lnprm mvi b,4 uremsave: ldax d mov m,a inx d inx h dcr b jnz uremsave pop b ret ; ; dodivide: mvi b,4 lxi h,lntmp ;clear quotient buffer xra a quinit: mov m,a inx h dcr b jnz quinit mvi a,32 ;initial jz false jmp true ; public .lul .lul: call .ulcmp jm true jmp false ; public .lue .lue: call .ulcmp jm true jz true jmp false ; public .luf .luf: call .ulcmp jm false jmp true ; public .lug .lug: call .ulcmp jm false jz false jmp true ; public .utox .utox: shld lnprm posconv: lxi h,0 shld lnprm+2 ret ; public .itox .itox: shld lnprm mov a,h ora a jp posconv lxi h,-1 shld lnprm+2 ret ; public .xtoi .xtoi: lhld lnprm ret e@blic .lml .lml: ;long multiply (primary = primary * secondary) push b ; lxi h,lnprm mvi b,4 lxi d,lntmp ;copy multiplier into work area msav: mov a,m stax d mvi m,0 inx h inx d dcr b jnz msav ; mvi a,32 ;initialize loop counter muloop: push psw lxi h,lnprm mvi b,8 ora a ;clear carry mshlp: mov a,m adc a ;shift one bit to the left mov m,a inx h dcr b jnz mshlp jnc mnext mvi b,4 lxi d,lnprm lxi h,lnsec ora a ;clear carry maddlp: ldax d a@@ize loop counter divloop: push psw lxi h,lnprm mvi b,8 ora a ;clear carry shlp: mov a,m adc a ;shift one bit to the left mov m,a inx h dcr b jnz shlp sbb a ani 1 mov c,a mvi b,4 lxi d,lntmp lxi h,lnsec ora a ;clear carry sublp: ldax d sbb m stax d inx d inx h dcr b jnz sublp mov a,c sbi 0 jnz zerobit onebit: lxi h,lnprm inr m pop psw dcr a jnz divloop ret ; zerobit: pop psw dcr a jz restore push psw lxi h,lnprm mvi b,8 nd  jz true jmp false ; public .luf .luf: call .ulcmp jm false jmp true ; public .lug .lug: call .ulcmp jm false jz false jmp true ; public .utox .utox: shld lnprm posconv: lxi h,0 shld lnprm+2 ret ; public .itox .itox: shld lnprm mov a,h ora a jp posconv lxi h,-1 shld lnprm+2 ret ; public .xtoi .xtoi: lhld lnprm ret e@dc m stax d inx d inx h dcr b jnz maddlp ; mnext: pop psw dcr a jnz muloop pop b ret ; ; public .leq .leq: call .lcmp jz true false: lxi h,0 xra a ret ; public .lne .lne: call .lcmp jz false true: lxi h,1 xra a inr a ret ; public .llt .llt: call .lcmp jm true jmp false ; public .lle .lle: call .lcmp jm true jz true jmp false ; public .lge .lge: call .lcmp jm false jmp true ; public .lgt .lgt: call .lcmp jm false @;Copyright (C) 1981,1982,1983 by Manx Software Systems ; :ts=8 extrn .ng public .dv,.ud .dv: ; DE has dividend, HL has divisor mov a,d xra h ;check if signs differ push psw ;and remember call divsub ;use same routine as modulo xchg ;and swap results pop psw jm .ng ;negate result if signs of operands differ mov a,l ora h RET ; .ud: CALL .um ;use same routine as modulo XCHG ;and swap results mov a,l ora h RET ; public .rm,.um .rm: mov a,d push psw call di ora a ;clear carry zshlp: mov a,m adc a ;shift one bit to the left mov m,a inx h dcr b jnz zshlp sbb a mov c,a mvi b,4 lxi d,lntmp lxi h,lnsec ora a ;clear carry daddlp: ldax d adc m stax d inx d inx h dcr b jnz daddlp mov a,c aci 0 jnz zerobit jmp onebit ; restore: ;fix up remainder if still negative mvi b,4 lxi d,lntmp lxi h,lnsec ora a ;clear carry resloop: ldax d adc m stax d inx d inx h dcr b jnz resloop ret ; ; pu@@A vsub pop psw ora a jm .ng ;negate result if dividend was signed mov a,h ora l ret ; divsub: mov a,h ora a jp hlpos cma mov h,a mov a,l cma mov l,a inx h hlpos: mov a,d ora a jp .um cma mov d,a mov a,e cma mov e,a inx d ; fall through into .um ; .um: push b ;save for C mov c,l mov b,h lxi h,0 call div16 pop b mov a,l ;set flags for C ora h ret ; ; div16: divides (hl,de) by bc ; returns remainder in hl, quotient in de public div@@@ .sign ora h ret ; public .ls .ls: XCHG mov a,e ani 31 mov e,a jz setcc lslp: DAD H DCR E JNZ lslp setcc: mov a,l ora h ret ; public .ur .ur: XCHG mov a,e ani 31 mov e,a jz setcc .arloop: MOV A,H ORA A RAR MOV H,A MOV A,L RAR MOV L,A DCR E JNZ .arloop ora h ret ; end v e,a jz setcc MOV A,H ORA H JP .arloop ; .sign: MOV A,H STC RAR MOV H,A MOV A,L RAR MOV L,A DCR E JNZ@16 div16: mov a,c cma mov c,a mov a,b cma mov b,a inx b MVI A,16 ;iteration count divloop: DAD H ;shift hl left XCHG DAD H ;shift de left XCHG JNC nocy INR L ;carry into high part nocy: dad b ;subtract divisor jc setbit push psw mov a,l sub c mov l,a mov a,h sbb b mov h,a pop psw DCR A ;count times thru JNZ divloop ret setbit: INR E ;set quotient bit DCR A ;count times thru JNZ divloop ret end @@@@@@;Copyright (C) 1981,1982 by Manx Software Systems ; public .ml .ml: PUSH B MOV B,H MOV C,L LXI H,0 ;CLEAR RESULT MVI A,16 ;ITERATION COUNT .mlp: DAD H ;SHIFT LEFT XCHG ; NOW SHIFT DE LEFT DAD H XCHG JNC .msk DAD B .msk: DCR A ;COUNT TIMES THRU JNZ .mlp ;go thru 16 times POP B mov a,l ora h RET ; public .rs .rs: XCHG mov a,e ani 31 mov e,a jz setcc MOV A,H ORA H JP .arloop ; .sign: MOV A,H STC RAR MOV H,A MOV A,L RAR MOV L,A DCR E JNZ@B ;Copyright (C) 1981,1982 by Manx Software Systems public .an .an: MOV A,H ANA D MOV H,A MOV A,L ANA E MOV L,A ora h RET ; public .cm .cm: MOV A,H CMA MOV H,A MOV A,L CMA MOV L,A ora h RET ; public .or .or: MOV A,H ORA D MOV H,A MOV A,L ORA E MOV L,A ora h RET ; public .xr .xr: MOV A,H XRA D MOV H,A MOV A,L XRA E MOV L,A ora h RET end @ l,a mov a,h sbb d mov h,a ora l ret ; public .swt .swt: xchg pop h PUSH B MOV B,D MOV C,E MOV E,M INX H MOV D,M swt.1: DCX D MOV A,D ORA A JM swt.def INX H MOV A,C CMP M JZ swt.3 INX H swt.2: INX H INX H JMP swt.1 swt.3: INX H MOV A,B CMP M JNZ swt.2 swt.def: INX H MOV A,M INX H MOV H,M MOV L,A POP B PCHL ; public .ue,.uf .uf: ; uge XCHG .ue: mov a,l ; ule sub e mov a,h sbb d mvi a,0 cmc aci 0 mov l,a mvi h,0 re@;Copyright (C) 1981,1982 by Manx Software Systems ; Copyright (C) 1981 Thomas Fenwick ; :ts=8 public .nt .nt: MOV A,H ORA L jz .true jmp .false ; public .eq,.ne .eq: mov a,l sub e jnz .false mov a,h sub d jz .true .false: lxi h,0 xra a ret ; .ne: mov a,l sub e jnz .true mov a,h sub d jz .false .true: lxi h,1 mov a,l ora h RET ; public .le,.ge .ge: ; ge XCHG .le: mov a,h xra d jm .lediff ; signs differ ; signs alike mov a,l sub e mov a,@@@t ; public .ug,.ul .ul: ; ult XCHG .ug: mov a,l sub e mov a,h sbb d mvi a,0 aci 0 mov l,a mvi h,0 ret ; end MP swt.1 swt.3: INX H MOV A,B CMP M JNZ swt.2 swt.def: INX H MOV A,M INX H MOV H,M MOV L,A POP B PCHL ; public .ue,.uf .uf: ; uge XCHG .ue: mov a,l ; ule sub e mov a,h sbb d mvi a,0 cmc aci 0 mov l,a mvi h,0 re@h sbb d cmc mvi a,0 aci 0 mov l,a mvi h,0 ret .lediff: mov a,d rlc ani 1 mov l,a mvi h,0 ret ; public .lt,.gt .lt: XCHG .gt: mov a,h xra d jm .gtdiff ; signs differ ; signs alike mov a,l sub e mov a,h sbb d mvi a,0 aci 0 mov l,a mvi h,0 ret .gtdiff: mov a,h rlc ani 1 mov l,a mvi h,0 ret ; public .ng .ng: MOV A,L CMA MOV L,A MOV A,H CMA MOV H,A INX H mov a,l ora h RET ; public .sb .sb: XCHG mov a,l sub e mov@@@@C @@,Cbuffs_ PUSH H CALL agetc_ POP D SHLD scnlast_ .6: JMP .7 .4: LXI H,Cbuffs_ PUSH H LHLD scnlast_ PUSH H CALL ungetc_ POP D POP D SHLD scnlast_ .7: LHLD scnlast_ RET .3 EQU 0 extrn ungetc_ extrn agetc_ extrn scanfmt_ extrn Cbuffs_ extrn .an END ora m JNZ .4 LDA Cbuffs_+6 MOV L,A MVI H,0 LXI D,8 CALL .an JZ .5 LXI H,-1 SHLD scnlast_ JMP .6 .5: LXI H stack. DAD SP MOV H, M MVI L, 0dbh ;Form input instruction of temporary SHLD TMP ; subroutine and set it up in core. LXI H, TMP + 2 ;Add return instruction to temporary MVI M, 0c9h ; subroutine in core. CALL TMP ;Call temporary subroutine. MOV L, A ;Return result. MVI H, 0 ORA H RET ;***************************************************************************** out_: LXI H, 4 ;Get data and port number from stack. DAD SP MOV A, M DCX H DCX H@@; ; Direct Port I/O Functions for AZTEC C II ; ; Copyright (c) 1982 William C. Colley III ; ; I grant Manx Software Systems permission to incorporate these functions ; into the AZTEC C library subject only to the condition that my copyright ; notice remain in the source code. WCC3. ; ; These functions allow AZTEC C II to get to the machine I/O ports. They ; are more complicated than might be expected as they can't use the Z-80's ; "IN A,(C)" and "OUT (C),A" instructions and still remain 8080-co@@ MOV H, M MVI L, 0d3h ;Form output instruction of temporary SHLD TMP ; subroutine and set it up in core. LXI H, TMP + 2 ;Add return instruction to temporary MVI M, 0c9h ; subroutine in core. JMP TMP ;Call temporary subroutine and return. ;***************************************************************************** DSEG TMP: DS 3 ;Space for temporary subroutine. ;***************************************************************************** END  extrn .begin,.chl,.swt extrn csave,cret,.move bss scnlast_,2 PUBLIC scanf_ scanf_: lxi d,.2 call csave LXI H,0 SHLD scnlast_ LXI H,10-.2 DAD SP PUSH H LXI H,10-.2 DAD SP MOV E,M INX H MOV D,M PUSH D LXI H,gchar_ PUSH H CALL scanfmt_ POP D POP D POP D RET .2 EQU 0 gchar_: lxi d,.3 call csave LXI H,8-.3 DAD SP mov a,m inx h ora m JNZ .4 LDA Cbuffs_+6 MOV L,A MVI H,0 LXI D,8 CALL .an JZ .5 LXI H,-1 SHLD scnlast_ JMP .6 .5: LXI H@mpatible. ; Self-modifying code is also out of the question as that kills ROMability. ; I therefore go through the hassle of setting up temporary subroutines in ; RAM and calling them. ; ; The functions in the package are: ; ; char in(p) Returns contents of input port p. ; char p; ; ; out(p,c) Sends character c to output port p. ; char p, c; ; CSEG PUBLIC in_, out_ ;***************************************************************************** in_: LXI H, 2 ;Get port number from@@D @@/* Copyright (C) 1981,1982 by Manx Software Systems */ printf(fmt,args) char *fmt; unsigned args; { extern int putchar(); format(putchar,fmt,&args); } @@@@@@@@@nm`s!"v!":`9!":`9^#V!xyas!"8a9~#b:!z6o&{c!"vd!z|"ve!z*v}"v*v.begin.chl.swtcsavecret.move scnlast_scanf_$gchar_scanfmt_Cbuffs_.anagetc_ungetc_@@ZLWj@@E @@@@@@@@@@@@@@@F @@@@@@@@@@@@@@@G @@@@@@@@@@@@@@@H @@@@@@@@@@@@@@@I @@@@@@@@@@@@@@@J @@@@@@@@@@@@@@@K @@@@@@@@@@@@@@@L @@@@@@@@@@@@@@@