Mercurial > hg > Members > kono > os9 > sbc09
diff mc09/mclib.c @ 160:1a30cd6e5973
move mc09 to top
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 05 Feb 2019 09:03:07 +0900 |
parents | os9/mc09/mclib.c@92ed427b7f7d |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/mclib.c Tue Feb 05 09:03:07 2019 +0900 @@ -0,0 +1,486 @@ +#define FILE char +#define FCBSIZE 320 +#define NFILES 8 + +#define NULL 0 +#define EOF (-1) + +#define stdin _fcbtbl[0] +#define stdout _fcbtbl[1] +#define stderr _fcbtbl[2] + +#define STDIN 0xffff +#define STDOUT 0xfffe +#define STDERR 0xfffd + +FILE *_fcbtbl[NFILES]; + +_main(argc,argv) +int argc; +char **argv; +{int i; + stdin = STDIN; + stdout = STDOUT; + stderr = STDERR; + initheap(); + for ( i = 3; i < NFILES; i++ ) _fcbtbl[i] = NULL; + main(argc,argv); +} + +FILE *fopen(name,mode) +char *name,*mode; +{FILE *fcbp; + char *p; + int rd,wt,cm; + rd = wt = cm = 0; + for ( p = mode; *p; p++ ) { + switch ( *p ) { + case 'r': + rd = 1; break; + case 'w': + wt = 1; break; + case 'c': + cm = 1; break; + default: + return NULL; + } + } + if ( !(rd ^ wt) ) return NULL; + if ( rd ) return _open(name,cm); + else return _create(name,cm); +} + +FILE *_open(name,cm) +char *name; +int cm; +{FILE *fcbp; + int i; + for ( i = 0; i < NFILES; i++) + if ( _fcbtbl[i] == NULL ) break; + if ( i >= NFILES) return NULL; + if ( (fcbp = malloc(FCBSIZE)) == NULL ) return NULL; + if ( _setname(name,fcbp) == 0 ) return NULL; + if ( FMS(fcbp,1) < 0 ) return NULL; + fcbp[59] = cm ? 0 : 0xff; + fcbp[60] = 0; + return (_fcbtbl[i] = fcbp); +} + +FILE *_create(name,cm) +char *name; +int cm; +{FILE *fcbp; + int i; + for ( i = 0; i < NFILES; i++) + if ( _fcbtbl[i] == NULL ) break; + if ( i >= NFILES) return NULL; + if ( (fcbp = malloc(FCBSIZE)) == NULL ) return NULL; + if ( _setname(name,fcbp) == 0 ) return NULL; + if ( FMS(fcbp,2) < 0 ) + { if ( (fcbp[1] != 3) || (FMS(fcbp,12) < 0) ) return NULL; + _setname(name,fcbp); + if (FMS(fcbp,2) < 0) return NULL; + } + fcbp[15] = 0; + fcbp[59] = cm ? 0 : 0xff; + fcbp[60] = 0; + return (_fcbtbl[i] = fcbp); +} + +fclose(fcbp) +FILE *fcbp; +{int i; + for ( i = 0; i < NFILES; i++ ) + if ( fcbp == _fcbtbl[i] ) break; + if ( i >= NFILES ) return EOF; + _fcbtbl[i] = NULL; + if ( (fcbp == STDIN) || (fcbp == STDOUT) || (fcbp == STDERR) ) return 0; + if ( FMS(fcbp,4) < 0 ) return EOF; + mfree(fcbp); + return 0; +} + +_setname(name,fcbp) +char *name,*fcbp; +{int i; + while(isspace(*name)) ++name; + if (isdigit(*name)) + { fcbp[3] = *name++ - '0'; + if (*name++ != '.') return 0; + } + else fcbp[3] = 0xff; + for (i = 4; i < 15; ++i) fcbp[i] = 0; + if (!isalpha(*name)) return -1; + for (i = 4; i < 12; ++i) + { if (!*name || (*name == '.')) break; + fcbp[i] = *name++; + } + while (*name && (*name != '.')) ++name; + if (*name == '.') + { ++name; + for (i = 12; i < 15; ++i) + { if (!*name) break; + fcbp[i] = *name++; + } + } + return 1; +} + + +getc(fcbp) +char *fcbp; +{ + switch (fcbp) + {case STDIN: + return GETCH(); + case STDOUT: + case STDERR: + return EOF; + default: + if (fcbp[2] != 1) return EOF; + return FMS(fcbp,0); + } +} + +putc(c,fcbp) +char c,*fcbp; +{ if ( c == '\t' ) c = ' '; + switch (fcbp) + {case STDIN: + return EOF; + case STDOUT: + return PUTCH(c); + case STDERR: + return PUTCH2(c); + default: + if (fcbp[2] != 2) return EOF; + if (FMS(fcbp,0,c) < 0) return EOF; + return c; + } +} + +getchar() +{ return getc(stdin); +} + +putchar(c) +char c; +{ return putc(c,stdout); +} + +printf(s) +char *s; +{ _fprintf(stdout,s,(int *)&s+1); +} + +fprintf(f,s) +char *f,*s; +{ _fprintf(f,s,(int *)&s+1); +} + +_fprintf(f,s,p) +char *f,*s; +int *p; +{int l,m,n; + char c,buf[8]; + while(c = *s++) + if (c != '%') putc(c,f); + else + { if (l=(*s == '-')) ++s; + if (isdigit(*s)) s += _getint(&m,s); + else m = 0; + if (*s == '.') ++s; + if (isdigit(*s)) s += _getint(&n,s); + else n = 32767; + switch(*s++) + {case 'd': + itoa(*p++,buf); + break; + case 'o': + itooa(*p++,buf); + break; + case 'x': + itoxa(*p++,buf); + break; + case 'u': + itoua(*p++,buf); + break; + case 'c': + ctos(*p++,buf); + break; + case 's': + _putstr(f,*p++,l,m,n); + continue; + case '\0': + return; + default: + ctos(c,buf); + break; + } + _putstr(f,buf,l,m,n); + } +} + +_getint(p,s) +int *p; +char *s; +{int i; + for(*p=i=0; isdigit(*s); ++i) *p = *p * 10 + *s++ - '0'; + return i; +} + +_putstr(f,s,l,m,n) +char *f,*s; +int l,m,n; +{int k; + k = (strlen(s) < n ? strlen(s) : n); + m = (k < m ? m-k : 0); + if (l) + { _putsn(f,s,n); + _putspc(f,m); + } + else + { _putspc(f,m); + _putsn(f,s,n); + } +} + +_putsn(f,s,n) +char *f,*s; +int n; +{ while(*s) + if (--n >= 0) putc(*s++,f); + else break; +} + +_putspc(f,n) +char *f; +int n; +{ while(--n >= 0) putc(' ',f); +} + +puts(s) +char *s; +{ while(*s) putchar(*s++); +} + +itoa(n,s) +int n; +char *s; +{ if (n < 0) + { *s++ = '-'; + return (itoua(-n,s)+1); + } + return itoua(n,s); +} + +itoua(n,s) +int n; +char *s; +{ return _itoda(n,s,10); +} + +itooa(n,s) +int n; +char *s; +{ return _itoda(n,s,8); +} + +itoxa(n,s) +int n; +char *s; +{ return _itoda(n,s,16); +} + +_itoac(n) +int n; +{ return (n + ((n < 10) ? '0' : ('A'-10))); +} + +_itoda(n,s,r) +unsigned n; +int r; +char *s; +{int i; + char t[8],*u; + u = t; + *u++ = '\0'; + do *u++ = _itoac(n % r); while(n /= r); + for (i=0; *s++ = *--u; ++i); + return i; +} + +char *ctos(c,s) +char c,*s; +{ s[0] = c; + s[1] = '\0'; + return s; +} + +strlen(s) +char *s; +{int i; + for(i = 0; *s++; ++i); + return i; +} + +isdigit(c) +char c; +{ return '0' <= c && c <= '9'; +} + +isspace(c) +char c; +{ return (c == ' ' || c == '\t' || c == '\n'); +} + +isalpha(c) +char c; +{ return (isupper(c) || islower(c) || c == '_'); +} + +isupper(c) +char c; +{ return ('A' <= c && c <= 'Z'); +} + +islower(c) +char c; +{ return ('a' <= c && c <= 'z'); +} + +toupper(c) +char c; +{ return (islower(c) ? c + ('A'-'a') : c); +} + +tolower(c) +char c; +{ return (isupper(c) ? c + ('a'-'A') : c); +} + +atoi(s) +char *s; +{int i; + while (isspace(*s)) ++s; + for (i = 0; isdigit(*s);) i = i * 10 + *s++ - '0'; + return i; +} + +typedef struct header + { struct header *bptr; + unsigned bsize; + } HEADER; + +HEADER base,*allocp,*heapp; + +char *malloc(s) +unsigned s; +{HEADER *p,*q; + int nunits; + nunits = 1 + (s + sizeof(HEADER) - 1) / sizeof(HEADER); + if ((q = allocp) == NULL) + { base.bptr = allocp = q = &base; + base.bsize = 0; + } + for (p = q->bptr; ; q = p,p = p->bptr) + { if (p->bsize >= nunits) + { if (p->bsize == nunits) + q->bptr = p->bptr; + else + { p->bsize -= nunits; + p += p->bsize; + p->bsize = nunits; + } + allocp = q; + clearblock(p); + return ((char *)(p + 1)); + } + if (p == allocp) + if ((p = morecore(nunits)) == NULL) + return(NULL); + } +} + +clearblock(p) +HEADER *p; +{char *s,*t; + s = (char *)(p + 1); + t = (char *)(p + p->bsize); + while (s < t) *s++ = 0; +} + +#define NALLOC 128 + +HEADER *morecore(nu) +unsigned nu; +{char *cp; + HEADER *up; + int rnu; + rnu = NALLOC * ((nu + NALLOC - 1) / NALLOC); + cp = sbrk(rnu * sizeof(HEADER)); + if ((int)cp == -1) return NULL; + up = (HEADER *) cp; + up->bsize = rnu; + mfree((char *)(up+1)); + return allocp; +} + +#asm +sbrk PSHS U + LEAU ,S + + LDD heapp,Y + BNE _mc0 + BSR initheap +_mc0 PSHS D + TFR S,D + SUBD ,S++ + CMPD 4,U + BCC _mc1 + LDD #-1 + LEAS ,U + PULS U,PC + +_mc1 LDD 4,U + LDX heapp,Y + LEAX D,X + LDD heapp,Y + STX heapp,Y + LEAS ,U + PULS U,PC + +initheap + PSHS U + LEAU ,S + TFR Y,D + ADDD #_GLOBALS + STD heapp,Y + LEAS ,U + PULS U,PC +#endasm + +mfree(ap) +char *ap; +{HEADER *p,*q; + p = (HEADER *)ap - 1; + for (q = allocp; !(p > q && p < q->bptr); q = q->bptr) + if (q >= q->bptr && (p > q || p < q->bptr)) break; + if (p + p->bsize == q->bptr) + { p->bsize += q->bptr->bsize; + p->bptr = q->bptr->bptr; + } + else p->bptr = q->bptr; + if (q + q->bsize == p) + { q->bsize += p->bsize; + q->bptr = p->bptr; + } + else q->bptr = p; + allocp = q; +} + +unsigned freesize() +{int i; + if (!heapp) initheap(); + return ((char *)&i - (char *)heapp); +}