99
|
1 #define FILE char
|
|
2 #define FCBSIZE 320
|
|
3 #define NFILES 8
|
|
4
|
|
5 #define NULL 0
|
|
6 #define EOF (-1)
|
|
7
|
|
8 #define stdin _fcbtbl[0]
|
|
9 #define stdout _fcbtbl[1]
|
|
10 #define stderr _fcbtbl[2]
|
|
11
|
|
12 #define STDIN 0xffff
|
|
13 #define STDOUT 0xfffe
|
|
14 #define STDERR 0xfffd
|
|
15
|
|
16 FILE *_fcbtbl[NFILES];
|
|
17
|
|
18 _main(argc,argv)
|
|
19 int argc;
|
|
20 char **argv;
|
|
21 {int i;
|
|
22 stdin = STDIN;
|
|
23 stdout = STDOUT;
|
|
24 stderr = STDERR;
|
|
25 initheap();
|
|
26 for ( i = 3; i < NFILES; i++ ) _fcbtbl[i] = NULL;
|
|
27 main(argc,argv);
|
|
28 }
|
|
29
|
|
30 FILE *fopen(name,mode)
|
|
31 char *name,*mode;
|
|
32 {FILE *fcbp;
|
|
33 char *p;
|
|
34 int rd,wt,cm;
|
|
35 rd = wt = cm = 0;
|
|
36 for ( p = mode; *p; p++ ) {
|
|
37 switch ( *p ) {
|
|
38 case 'r':
|
|
39 rd = 1; break;
|
|
40 case 'w':
|
|
41 wt = 1; break;
|
|
42 case 'c':
|
|
43 cm = 1; break;
|
|
44 default:
|
|
45 return NULL;
|
|
46 }
|
|
47 }
|
|
48 if ( !(rd ^ wt) ) return NULL;
|
|
49 if ( rd ) return _open(name,cm);
|
|
50 else return _create(name,cm);
|
|
51 }
|
|
52
|
|
53 FILE *_open(name,cm)
|
|
54 char *name;
|
|
55 int cm;
|
|
56 {FILE *fcbp;
|
|
57 int i;
|
|
58 for ( i = 0; i < NFILES; i++)
|
|
59 if ( _fcbtbl[i] == NULL ) break;
|
|
60 if ( i >= NFILES) return NULL;
|
|
61 if ( (fcbp = malloc(FCBSIZE)) == NULL ) return NULL;
|
|
62 if ( _setname(name,fcbp) == 0 ) return NULL;
|
|
63 if ( FMS(fcbp,1) < 0 ) return NULL;
|
|
64 fcbp[59] = cm ? 0 : 0xff;
|
|
65 fcbp[60] = 0;
|
|
66 return (_fcbtbl[i] = fcbp);
|
|
67 }
|
|
68
|
|
69 FILE *_create(name,cm)
|
|
70 char *name;
|
|
71 int cm;
|
|
72 {FILE *fcbp;
|
|
73 int i;
|
|
74 for ( i = 0; i < NFILES; i++)
|
|
75 if ( _fcbtbl[i] == NULL ) break;
|
|
76 if ( i >= NFILES) return NULL;
|
|
77 if ( (fcbp = malloc(FCBSIZE)) == NULL ) return NULL;
|
|
78 if ( _setname(name,fcbp) == 0 ) return NULL;
|
|
79 if ( FMS(fcbp,2) < 0 )
|
|
80 { if ( (fcbp[1] != 3) || (FMS(fcbp,12) < 0) ) return NULL;
|
|
81 _setname(name,fcbp);
|
|
82 if (FMS(fcbp,2) < 0) return NULL;
|
|
83 }
|
|
84 fcbp[15] = 0;
|
|
85 fcbp[59] = cm ? 0 : 0xff;
|
|
86 fcbp[60] = 0;
|
|
87 return (_fcbtbl[i] = fcbp);
|
|
88 }
|
|
89
|
|
90 fclose(fcbp)
|
|
91 FILE *fcbp;
|
|
92 {int i;
|
|
93 for ( i = 0; i < NFILES; i++ )
|
|
94 if ( fcbp == _fcbtbl[i] ) break;
|
|
95 if ( i >= NFILES ) return EOF;
|
|
96 _fcbtbl[i] = NULL;
|
|
97 if ( (fcbp == STDIN) || (fcbp == STDOUT) || (fcbp == STDERR) ) return 0;
|
|
98 if ( FMS(fcbp,4) < 0 ) return EOF;
|
|
99 mfree(fcbp);
|
|
100 return 0;
|
|
101 }
|
|
102
|
|
103 _setname(name,fcbp)
|
|
104 char *name,*fcbp;
|
|
105 {int i;
|
|
106 while(isspace(*name)) ++name;
|
|
107 if (isdigit(*name))
|
|
108 { fcbp[3] = *name++ - '0';
|
|
109 if (*name++ != '.') return 0;
|
|
110 }
|
|
111 else fcbp[3] = 0xff;
|
|
112 for (i = 4; i < 15; ++i) fcbp[i] = 0;
|
|
113 if (!isalpha(*name)) return -1;
|
|
114 for (i = 4; i < 12; ++i)
|
|
115 { if (!*name || (*name == '.')) break;
|
|
116 fcbp[i] = *name++;
|
|
117 }
|
|
118 while (*name && (*name != '.')) ++name;
|
|
119 if (*name == '.')
|
|
120 { ++name;
|
|
121 for (i = 12; i < 15; ++i)
|
|
122 { if (!*name) break;
|
|
123 fcbp[i] = *name++;
|
|
124 }
|
|
125 }
|
|
126 return 1;
|
|
127 }
|
|
128
|
|
129
|
|
130 getc(fcbp)
|
|
131 char *fcbp;
|
|
132 {
|
|
133 switch (fcbp)
|
|
134 {case STDIN:
|
|
135 return GETCH();
|
|
136 case STDOUT:
|
|
137 case STDERR:
|
|
138 return EOF;
|
|
139 default:
|
|
140 if (fcbp[2] != 1) return EOF;
|
|
141 return FMS(fcbp,0);
|
|
142 }
|
|
143 }
|
|
144
|
|
145 putc(c,fcbp)
|
|
146 char c,*fcbp;
|
|
147 { if ( c == '\t' ) c = ' ';
|
|
148 switch (fcbp)
|
|
149 {case STDIN:
|
|
150 return EOF;
|
|
151 case STDOUT:
|
|
152 return PUTCH(c);
|
|
153 case STDERR:
|
|
154 return PUTCH2(c);
|
|
155 default:
|
|
156 if (fcbp[2] != 2) return EOF;
|
|
157 if (FMS(fcbp,0,c) < 0) return EOF;
|
|
158 return c;
|
|
159 }
|
|
160 }
|
|
161
|
|
162 getchar()
|
|
163 { return getc(stdin);
|
|
164 }
|
|
165
|
|
166 putchar(c)
|
|
167 char c;
|
|
168 { return putc(c,stdout);
|
|
169 }
|
|
170
|
|
171 printf(s)
|
|
172 char *s;
|
|
173 { _fprintf(stdout,s,(int *)&s+1);
|
|
174 }
|
|
175
|
|
176 fprintf(f,s)
|
|
177 char *f,*s;
|
|
178 { _fprintf(f,s,(int *)&s+1);
|
|
179 }
|
|
180
|
|
181 _fprintf(f,s,p)
|
|
182 char *f,*s;
|
|
183 int *p;
|
|
184 {int l,m,n;
|
|
185 char c,buf[8];
|
|
186 while(c = *s++)
|
|
187 if (c != '%') putc(c,f);
|
|
188 else
|
|
189 { if (l=(*s == '-')) ++s;
|
|
190 if (isdigit(*s)) s += _getint(&m,s);
|
|
191 else m = 0;
|
|
192 if (*s == '.') ++s;
|
|
193 if (isdigit(*s)) s += _getint(&n,s);
|
|
194 else n = 32767;
|
|
195 switch(*s++)
|
|
196 {case 'd':
|
|
197 itoa(*p++,buf);
|
|
198 break;
|
|
199 case 'o':
|
|
200 itooa(*p++,buf);
|
|
201 break;
|
|
202 case 'x':
|
|
203 itoxa(*p++,buf);
|
|
204 break;
|
|
205 case 'u':
|
|
206 itoua(*p++,buf);
|
|
207 break;
|
|
208 case 'c':
|
|
209 ctos(*p++,buf);
|
|
210 break;
|
|
211 case 's':
|
|
212 _putstr(f,*p++,l,m,n);
|
|
213 continue;
|
|
214 case '\0':
|
|
215 return;
|
|
216 default:
|
|
217 ctos(c,buf);
|
|
218 break;
|
|
219 }
|
|
220 _putstr(f,buf,l,m,n);
|
|
221 }
|
|
222 }
|
|
223
|
|
224 _getint(p,s)
|
|
225 int *p;
|
|
226 char *s;
|
|
227 {int i;
|
|
228 for(*p=i=0; isdigit(*s); ++i) *p = *p * 10 + *s++ - '0';
|
|
229 return i;
|
|
230 }
|
|
231
|
|
232 _putstr(f,s,l,m,n)
|
|
233 char *f,*s;
|
|
234 int l,m,n;
|
|
235 {int k;
|
|
236 k = (strlen(s) < n ? strlen(s) : n);
|
|
237 m = (k < m ? m-k : 0);
|
|
238 if (l)
|
|
239 { _putsn(f,s,n);
|
|
240 _putspc(f,m);
|
|
241 }
|
|
242 else
|
|
243 { _putspc(f,m);
|
|
244 _putsn(f,s,n);
|
|
245 }
|
|
246 }
|
|
247
|
|
248 _putsn(f,s,n)
|
|
249 char *f,*s;
|
|
250 int n;
|
|
251 { while(*s)
|
|
252 if (--n >= 0) putc(*s++,f);
|
|
253 else break;
|
|
254 }
|
|
255
|
|
256 _putspc(f,n)
|
|
257 char *f;
|
|
258 int n;
|
|
259 { while(--n >= 0) putc(' ',f);
|
|
260 }
|
|
261
|
|
262 puts(s)
|
|
263 char *s;
|
|
264 { while(*s) putchar(*s++);
|
|
265 }
|
|
266
|
|
267 itoa(n,s)
|
|
268 int n;
|
|
269 char *s;
|
|
270 { if (n < 0)
|
|
271 { *s++ = '-';
|
|
272 return (itoua(-n,s)+1);
|
|
273 }
|
|
274 return itoua(n,s);
|
|
275 }
|
|
276
|
|
277 itoua(n,s)
|
|
278 int n;
|
|
279 char *s;
|
|
280 { return _itoda(n,s,10);
|
|
281 }
|
|
282
|
|
283 itooa(n,s)
|
|
284 int n;
|
|
285 char *s;
|
|
286 { return _itoda(n,s,8);
|
|
287 }
|
|
288
|
|
289 itoxa(n,s)
|
|
290 int n;
|
|
291 char *s;
|
|
292 { return _itoda(n,s,16);
|
|
293 }
|
|
294
|
|
295 _itoac(n)
|
|
296 int n;
|
|
297 { return (n + ((n < 10) ? '0' : ('A'-10)));
|
|
298 }
|
|
299
|
|
300 _itoda(n,s,r)
|
|
301 unsigned n;
|
|
302 int r;
|
|
303 char *s;
|
|
304 {int i;
|
|
305 char t[8],*u;
|
|
306 u = t;
|
|
307 *u++ = '\0';
|
|
308 do *u++ = _itoac(n % r); while(n /= r);
|
|
309 for (i=0; *s++ = *--u; ++i);
|
|
310 return i;
|
|
311 }
|
|
312
|
|
313 char *ctos(c,s)
|
|
314 char c,*s;
|
|
315 { s[0] = c;
|
|
316 s[1] = '\0';
|
|
317 return s;
|
|
318 }
|
|
319
|
|
320 strlen(s)
|
|
321 char *s;
|
|
322 {int i;
|
|
323 for(i = 0; *s++; ++i);
|
|
324 return i;
|
|
325 }
|
|
326
|
|
327 isdigit(c)
|
|
328 char c;
|
|
329 { return '0' <= c && c <= '9';
|
|
330 }
|
|
331
|
|
332 isspace(c)
|
|
333 char c;
|
|
334 { return (c == ' ' || c == '\t' || c == '\n');
|
|
335 }
|
|
336
|
|
337 isalpha(c)
|
|
338 char c;
|
|
339 { return (isupper(c) || islower(c) || c == '_');
|
|
340 }
|
|
341
|
|
342 isupper(c)
|
|
343 char c;
|
|
344 { return ('A' <= c && c <= 'Z');
|
|
345 }
|
|
346
|
|
347 islower(c)
|
|
348 char c;
|
|
349 { return ('a' <= c && c <= 'z');
|
|
350 }
|
|
351
|
|
352 toupper(c)
|
|
353 char c;
|
|
354 { return (islower(c) ? c + ('A'-'a') : c);
|
|
355 }
|
|
356
|
|
357 tolower(c)
|
|
358 char c;
|
|
359 { return (isupper(c) ? c + ('a'-'A') : c);
|
|
360 }
|
|
361
|
|
362 atoi(s)
|
|
363 char *s;
|
|
364 {int i;
|
|
365 while (isspace(*s)) ++s;
|
|
366 for (i = 0; isdigit(*s);) i = i * 10 + *s++ - '0';
|
|
367 return i;
|
|
368 }
|
|
369
|
|
370 typedef struct header
|
|
371 { struct header *bptr;
|
|
372 unsigned bsize;
|
|
373 } HEADER;
|
|
374
|
|
375 HEADER base,*allocp,*heapp;
|
|
376
|
|
377 char *malloc(s)
|
|
378 unsigned s;
|
|
379 {HEADER *p,*q;
|
|
380 int nunits;
|
|
381 nunits = 1 + (s + sizeof(HEADER) - 1) / sizeof(HEADER);
|
|
382 if ((q = allocp) == NULL)
|
|
383 { base.bptr = allocp = q = &base;
|
|
384 base.bsize = 0;
|
|
385 }
|
|
386 for (p = q->bptr; ; q = p,p = p->bptr)
|
|
387 { if (p->bsize >= nunits)
|
|
388 { if (p->bsize == nunits)
|
|
389 q->bptr = p->bptr;
|
|
390 else
|
|
391 { p->bsize -= nunits;
|
|
392 p += p->bsize;
|
|
393 p->bsize = nunits;
|
|
394 }
|
|
395 allocp = q;
|
|
396 clearblock(p);
|
|
397 return ((char *)(p + 1));
|
|
398 }
|
|
399 if (p == allocp)
|
|
400 if ((p = morecore(nunits)) == NULL)
|
|
401 return(NULL);
|
|
402 }
|
|
403 }
|
|
404
|
|
405 clearblock(p)
|
|
406 HEADER *p;
|
|
407 {char *s,*t;
|
|
408 s = (char *)(p + 1);
|
|
409 t = (char *)(p + p->bsize);
|
|
410 while (s < t) *s++ = 0;
|
|
411 }
|
|
412
|
|
413 #define NALLOC 128
|
|
414
|
|
415 HEADER *morecore(nu)
|
|
416 unsigned nu;
|
|
417 {char *cp;
|
|
418 HEADER *up;
|
|
419 int rnu;
|
|
420 rnu = NALLOC * ((nu + NALLOC - 1) / NALLOC);
|
|
421 cp = sbrk(rnu * sizeof(HEADER));
|
|
422 if ((int)cp == -1) return NULL;
|
|
423 up = (HEADER *) cp;
|
|
424 up->bsize = rnu;
|
|
425 mfree((char *)(up+1));
|
|
426 return allocp;
|
|
427 }
|
|
428
|
|
429 #asm
|
|
430 sbrk PSHS U
|
|
431 LEAU ,S
|
|
432
|
|
433 LDD heapp,Y
|
|
434 BNE _mc0
|
|
435 BSR initheap
|
|
436 _mc0 PSHS D
|
|
437 TFR S,D
|
|
438 SUBD ,S++
|
|
439 CMPD 4,U
|
|
440 BCC _mc1
|
|
441 LDD #-1
|
|
442 LEAS ,U
|
|
443 PULS U,PC
|
|
444
|
|
445 _mc1 LDD 4,U
|
|
446 LDX heapp,Y
|
|
447 LEAX D,X
|
|
448 LDD heapp,Y
|
|
449 STX heapp,Y
|
|
450 LEAS ,U
|
|
451 PULS U,PC
|
|
452
|
|
453 initheap
|
|
454 PSHS U
|
|
455 LEAU ,S
|
|
456 TFR Y,D
|
|
457 ADDD #_GLOBALS
|
|
458 STD heapp,Y
|
|
459 LEAS ,U
|
|
460 PULS U,PC
|
|
461 #endasm
|
|
462
|
|
463 mfree(ap)
|
|
464 char *ap;
|
|
465 {HEADER *p,*q;
|
|
466 p = (HEADER *)ap - 1;
|
|
467 for (q = allocp; !(p > q && p < q->bptr); q = q->bptr)
|
|
468 if (q >= q->bptr && (p > q || p < q->bptr)) break;
|
|
469 if (p + p->bsize == q->bptr)
|
|
470 { p->bsize += q->bptr->bsize;
|
|
471 p->bptr = q->bptr->bptr;
|
|
472 }
|
|
473 else p->bptr = q->bptr;
|
|
474 if (q + q->bsize == p)
|
|
475 { q->bsize += p->bsize;
|
|
476 q->bptr = p->bptr;
|
|
477 }
|
|
478 else q->bptr = p;
|
|
479 allocp = q;
|
|
480 }
|
|
481
|
|
482 unsigned freesize()
|
|
483 {int i;
|
|
484 if (!heapp) initheap();
|
|
485 return ((char *)&i - (char *)heapp);
|
|
486 }
|