|
|
1.1 root 1: /*
2:
3: Copyright 1990,1991 Eric R. Smith. All rights reserved.
4:
5: */
6:
7:
8:
9: /*
10:
11: * misc. utility routines
12:
13: */
14:
15:
16:
17: #include "mint.h"
18:
19:
20:
21: /*
22:
23: * given an address, find the corresponding memory region in this program's
24:
25: * memory map
26:
27: */
28:
29:
30:
31: MEMREGION *
32:
33: addr2mem(a)
34:
35: virtaddr a;
36:
37: {
38:
39: int i;
40:
41:
42:
43: for (i = 0; i < curproc->num_reg; i++) {
44:
45: if (a == curproc->addr[i])
46:
47: return curproc->mem[i];
48:
49: }
50:
51: return 0;
52:
53: }
54:
55:
56:
57: /*
58:
59: * given a pid, return the corresponding process
60:
61: */
62:
63:
64:
65: PROC *
66:
67: pid2proc(pid)
68:
69: int pid;
70:
71: {
72:
73: PROC *p;
74:
75:
76:
77: for (p = proclist; p; p = p->gl_next) {
78:
79: if (p->pid == pid)
80:
81: return p;
82:
83: }
84:
85: return 0;
86:
87: }
88:
89:
90:
91: /*
92:
93: * return a new pid
94:
95: */
96:
97:
98:
99: int
100:
101: newpid()
102:
103: {
104:
105: static int _maxpid = 1;
106:
107: int i;
108:
109: #ifndef NDEBUG
110:
111: int j = 0;
112:
113: #endif
114:
115:
116:
117: do {
118:
119: i = _maxpid++;
120:
121: if (_maxpid >= 1000) _maxpid = 1;
122:
123: assert(j++ < 1000);
124:
125: } while (pid2proc(i));
126:
127:
128:
129: return i;
130:
131: }
132:
133:
134:
135: /*
136:
137: * zero out a block of memory, quickly; the block must be word-aligned,
138:
139: * and should be long-aligned for speed reasons
140:
141: */
142:
143:
144:
145: void
146:
147: zero(place, size)
148:
149: char *place;
150:
151: long size;
152:
153: {
154:
155: long cruft, *lp;
156:
157:
158:
159: cruft = size % 256; /* quickzero does 256 byte blocks */
160:
161: size = size / 256;
162:
163: while (cruft > 0) {
164:
165: *place++ = 0;
166:
167: cruft--;
168:
169: }
170:
171: lp = (long *)place;
172:
173: if (size > 0) {
174:
175: quickzero(place, size);
176:
177: }
178:
179: }
180:
181:
182:
183: #ifdef JUNK_MEM
184:
185: void
186:
187: fillwjunk(place, size)
188:
189: long *place;
190:
191: long size;
192:
193: {
194:
195: while (size > 0) {
196:
197: *place++ = size;
198:
199: size -= 4;
200:
201: }
202:
203: }
204:
205: #endif
206:
207:
208:
209: /*
210:
211: * kernel memory allocation routines
212:
213: */
214:
215:
216:
217: #define KMAGIC ((MEMREGION *)0x87654321)
218:
219: #define KERMEM_THRESHOLD 264
220:
221:
222:
223: void *
224:
225: kmalloc(size)
226:
227: long size;
228:
229: {
230:
231: MEMREGION *m = 0;
232:
233: MEMREGION **p;
234:
235:
236:
237: size += sizeof(m) + sizeof (m);
238:
239: /*
240:
241: * for small requests, we try kernel memory first, to cut down on fragmentation
242:
243: */
244:
245: if (size <= KERMEM_THRESHOLD)
246:
247: m = get_region(ker, size);
248:
249: else
250:
251: m = get_region(alt, size);
252:
253:
254:
255: if (!m) m = get_region(core, size);
256:
257: if (!m) {
258:
259: if (size <= KERMEM_THRESHOLD)
260:
261: m = get_region(alt, size);
262:
263: else
264:
265: m = get_region(ker, size);
266:
267: }
268:
269: if (m) {
270:
271: p = (MEMREGION **)m->loc;
272:
273: *p++ = KMAGIC;
274:
275: *p++ = m;
276:
277: return (void *)p;
278:
279: }
280:
281: else {
282:
283: return 0;
284:
285: }
286:
287: }
288:
289:
290:
291: /* allocate from ST memory only */
292:
293:
294:
295: void *
296:
297: kcore(size)
298:
299: long size;
300:
301: {
302:
303: MEMREGION *m = 0;
304:
305: MEMREGION **p;
306:
307:
308:
309: size += sizeof(m) + sizeof (m);
310:
311: m = get_region(core, size);
312:
313:
314:
315: if (m) {
316:
317: p = (MEMREGION **)m->loc;
318:
319: *p++ = KMAGIC;
320:
321: *p++ = m;
322:
323: return (void *)p;
324:
325: }
326:
327: else {
328:
329: return 0;
330:
331: }
332:
333: }
334:
335:
336:
337: void
338:
339: kfree(place)
340:
341: void *place;
342:
343: {
344:
345: MEMREGION **p;
346:
347: MEMREGION *m;
348:
349:
350:
351: if (!place) return;
352:
353: p = place;
354:
355: p -= 2;
356:
357: if (*p++ != KMAGIC) {
358:
359: FATAL("kfree: memory not allocated by kmalloc");
360:
361: }
362:
363: m = *p++;
364:
365: if (--m->links != 0) {
366:
367: FATAL("kfree: block has %d links", m->links);
368:
369: }
370:
371: free_region(m);
372:
373: }
374:
375:
376:
377: /*
378:
379: * "user" memory allocation routines; the kernel can use these to
380:
381: * allocate/free memory that will be attached in some way to a process
382:
383: * (and freed automatically when the process exits)
384:
385: */
386:
387: void *
388:
389: umalloc(size)
390:
391: long size;
392:
393: {
394:
395: return (void *)m_xalloc(size, 3);
396:
397: }
398:
399:
400:
401: void
402:
403: ufree(block)
404:
405: void *block;
406:
407: {
408:
409: (void)m_free((virtaddr)block);
410:
411: }
412:
413:
414:
415: /*
416:
417: * convert a time in milliseconds to a GEMDOS style date/time
418:
419: * timeptr[0] gets the time, timeptr[1] the date.
420:
421: * BUG/FEATURE: in the conversion, it is assumed that all months have
422:
423: * 30 days and all years have 360 days.
424:
425: */
426:
427:
428:
429: void
430:
431: ms_time(ms, timeptr)
432:
433: ulong ms;
434:
435: short *timeptr;
436:
437: {
438:
439: ulong secs;
440:
441: short tsec, tmin, thour;
442:
443: short tday, tmonth, tyear;
444:
445:
446:
447: secs = ms / 1000;
448:
449: tsec = secs % 60;
450:
451: secs /= 60; /* secs now contains # of minutes */
452:
453: tmin = secs % 60;
454:
455: secs /= 60; /* secs now contains # of hours */
456:
457: thour = secs % 24;
458:
459: secs /= 24; /* secs now contains # of days */
460:
461: tday = secs % 30;
462:
463: secs /= 30;
464:
465: tmonth = secs % 12;
466:
467: tyear = secs / 12;
468:
469: *timeptr++ = (thour << 11) | (tmin << 5) | (tsec >> 1);
470:
471: *timeptr = (tyear << 9) | ((tmonth + 1) << 5) | (tday+1);
472:
473: }
474:
475:
476:
477: /*
478:
479: * unixtim(time, date): convert a Dos style (time, date) pair into
480:
481: * a Unix time (seconds from midnight Jan 1., 1970)
482:
483: */
484:
485:
486:
487: static int
488:
489: mth_start[13] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
490:
491:
492:
493: long
494:
495: unixtim(time, date)
496:
497: unsigned time, date;
498:
499: {
500:
501: int sec, min, hour;
502:
503: int mday, mon, year;
504:
505: long y, s;
506:
507:
508:
509: sec = (time & 31) << 1;
510:
511: min = (time >> 5) & 63;
512:
513: hour = (time >> 11) & 31;
514:
515: mday = date & 31;
516:
517: mon = ((date >> 5) & 15) - 1;
518:
519: year = 80 + ((date >> 9) & 255);
520:
521:
522:
523: /* calculate tm_yday here */
524:
525: y = (mday - 1) + mth_start[mon] + /* leap year correction */
526:
527: ( ( (year % 4) != 0 ) ? 0 : (mon > 1) );
528:
529:
530:
531: s = (sec) + (min * 60L) + (hour * 3600L) +
532:
533: (y * 86400L) + ((year - 70) * 31536000L) +
534:
535: ((year - 69)/4) * 86400L;
536:
537:
538:
539: return s;
540:
541: }
542:
543:
544:
545: /* convert a Unix time into a DOS time. The longword returned contains
546:
547: the time word first, then the date word.
548:
549: BUG: we completely ignore any time zone information.
550:
551: */
552:
553: #define SECS_PER_MIN (60L)
554:
555: #define SECS_PER_HOUR (3600L)
556:
557: #define SECS_PER_DAY (86400L)
558:
559: #define SECS_PER_YEAR (31536000L)
560:
561: #define SECS_PER_LEAPYEAR (SECS_PER_DAY + SECS_PER_YEAR)
562:
563:
564:
565: static int
566:
567: days_per_mth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
568:
569:
570:
571: long
572:
573: dostim(t)
574:
575: long t;
576:
577: {
578:
579: unsigned long time, date;
580:
581: int tm_hour, tm_min, tm_sec;
582:
583: int tm_year, tm_mon, tm_mday;
584:
585: int i;
586:
587:
588:
589: if (t <= 0) return 0;
590:
591:
592:
593: tm_year = 70;
594:
595: while (t >= SECS_PER_YEAR) {
596:
597: if ((tm_year & 0x3) == 0) {
598:
599: if (t < SECS_PER_LEAPYEAR)
600:
601: break;
602:
603: t -= SECS_PER_LEAPYEAR;
604:
605: } else {
606:
607: t -= SECS_PER_YEAR;
608:
609: }
610:
611: tm_year++;
612:
613: }
614:
615: tm_mday = t/SECS_PER_DAY;
616:
617: days_per_mth[1] = (tm_year & 0x3) ? 28 : 29;
618:
619: for (i = 0; tm_mday >= days_per_mth[i]; i++)
620:
621: tm_mday -= days_per_mth[i];
622:
623: tm_mon = i+1;
624:
625: tm_mday++;
626:
627: t = t % SECS_PER_DAY;
628:
629: tm_hour = t/SECS_PER_HOUR;
630:
631: t = t % SECS_PER_HOUR;
632:
633: tm_min = t/SECS_PER_MIN;
634:
635: tm_sec = t % SECS_PER_MIN;
636:
637:
638:
639: if (tm_year < 80) {
640:
641: tm_year = 80;
642:
643: tm_mon = tm_mday = 1;
644:
645: tm_hour = tm_min = tm_sec = 0;
646:
647: }
648:
649:
650:
651: time = (tm_hour << 11) | (tm_min << 5) | (tm_sec >> 1);
652:
653: date = ((tm_year - 80) & 0x7f) << 9;
654:
655: date |= ((tm_mon) << 5) | (tm_mday);
656:
657: return (time << 16) | date;
658:
659: }
660:
661:
662:
663: /*
664:
665: * Case insensitive string comparison. note that this only returns
666:
667: * 0 (match) or nonzero (no match), and that the returned value
668:
669: * is not a reliable indicator of any "order".
670:
671: */
672:
673:
674:
675: int
676:
677: strnicmp(str1, str2, len)
678:
679: register const char *str1, *str2;
680:
681: register int len;
682:
683: {
684:
685: register char c1, c2;
686:
687:
688:
689: do {
690:
691: c1 = *str1++; if (isupper(c1)) c1 = tolower(c1);
692:
693: c2 = *str2++; if (isupper(c2)) c2 = tolower(c2);
694:
695: } while (--len >= 0 && c1 && c1 == c2);
696:
697:
698:
699: if (len < 0 || c1 == c2)
700:
701: return 0;
702:
703: return c1 - c2;
704:
705: }
706:
707:
708:
709: int
710:
711: stricmp(str1, str2)
712:
713: const char *str1, *str2;
714:
715: {
716:
717: return strnicmp(str1, str2, 0x7fff);
718:
719: }
720:
721:
722:
723:
724:
725: /*
726:
727: * string utilities: strlwr() converts a string to lower case, strupr()
728:
729: * converts it to upper case
730:
731: */
732:
733:
734:
735: char *
736:
737: strlwr(s)
738:
739: char *s;
740:
741: {
742:
743: char c;
744:
745: char *old = s;
746:
747:
748:
749: while ((c = *s) != 0) {
750:
751: if (isupper(c)) {
752:
753: *s = _tolower(c);
754:
755: }
756:
757: s++;
758:
759: }
760:
761: return old;
762:
763: }
764:
765:
766:
767: char *
768:
769: strupr(s)
770:
771: char *s;
772:
773: {
774:
775: char c;
776:
777: char *old = s;
778:
779:
780:
781: while ((c = *s) != 0) {
782:
783: if (islower(c)) {
784:
785: *s = _toupper(c);
786:
787: }
788:
789: s++;
790:
791: }
792:
793: return old;
794:
795: }
796:
797:
798:
799: #ifdef OWN_LIB
800:
801:
802:
803: /*
804:
805: * Case sensitive comparison functions.
806:
807: */
808:
809:
810:
811: int
812:
813: strncmp(str1, str2, len)
814:
815: register const char *str1, *str2;
816:
817: register int len;
818:
819: {
820:
821: register char c1, c2;
822:
823:
824:
825: do {
826:
827: c1 = *str1++;
828:
829: c2 = *str2++;
830:
831: } while (--len >= 0 && c1 && c1 == c2);
832:
833:
834:
835: if (len < 0) return 0;
836:
837:
838:
839: return c1 - c2;
840:
841: }
842:
843:
844:
845: int
846:
847: strcmp(str1, str2)
848:
849: const char *str1, *str2;
850:
851: {
852:
853: register char c1, c2;
854:
855:
856:
857: do {
858:
859: c1 = *str1++;
860:
861: c2 = *str2++;
862:
863: } while (c1 && c1 == c2);
864:
865:
866:
867: return c1 - c2;
868:
869: }
870:
871:
872:
873:
874:
875: /*
876:
877: * some standard string functions
878:
879: */
880:
881:
882:
883: char *
884:
885: strcat(dst, src)
886:
887: char *dst;
888:
889: const char *src;
890:
891: {
892:
893: register char *_dscan;
894:
895:
896:
897: for (_dscan = dst; *_dscan; _dscan++) ;
898:
899: while (*_dscan++ = *src++) ;
900:
901: return dst;
902:
903: }
904:
905:
906:
907: char *
908:
909: strcpy(dst, src)
910:
911: char *dst;
912:
913: const char *src;
914:
915: {
916:
917: register char *_dscan = dst;
918:
919: while (*_dscan++ = *src++) ;
920:
921: return dst;
922:
923: }
924:
925:
926:
927: char *
928:
929: strncpy(dst, src, len)
930:
931: char *dst;
932:
933: const char *src;
934:
935: int len;
936:
937: {
938:
939: register char *_dscan = dst;
940:
941: while (--len >= 0 && (*_dscan++ = *src++))
942:
943: continue;
944:
945: while (--len >= 0)
946:
947: *_dscan++ = 0;
948:
949: return dst;
950:
951: }
952:
953:
954:
955: int
956:
957: strlen(scan)
958:
959: const char *scan;
960:
961: {
962:
963: register const char *_start = scan+1;
964:
965: while (*scan++) ;
966:
967: return (int)((long)scan - (long)_start);
968:
969: }
970:
971:
972:
973: /*
974:
975: * strrchr: find the last occurence of a character in a string
976:
977: */
978:
979: char *
980:
981: strrchr(str, which)
982:
983: const char *str;
984:
985: register int which;
986:
987: {
988:
989: register unsigned char c, *s;
990:
991: register char *place;
992:
993:
994:
995: s = (unsigned char *)str;
996:
997: place = 0;
998:
999: do {
1000:
1001: c = *s++;
1002:
1003: if (c == which)
1004:
1005: place = (char *)s-1;
1006:
1007: } while (c);
1008:
1009: return place;
1010:
1011: }
1012:
1013:
1014:
1015: unsigned char _ctype[256] =
1016:
1017: {
1018:
1019: _CTc, _CTc, _CTc, _CTc, /* 0x00..0x03 */
1020:
1021: _CTc, _CTc, _CTc, _CTc, /* 0x04..0x07 */
1022:
1023: _CTc, _CTc|_CTs, _CTc|_CTs, _CTc|_CTs, /* 0x08..0x0B */
1024:
1025: _CTc|_CTs, _CTc|_CTs, _CTc, _CTc, /* 0x0C..0x0F */
1026:
1027:
1028:
1029: _CTc, _CTc, _CTc, _CTc, /* 0x10..0x13 */
1030:
1031: _CTc, _CTc, _CTc, _CTc, /* 0x14..0x17 */
1032:
1033: _CTc, _CTc, _CTc, _CTc, /* 0x18..0x1B */
1034:
1035: _CTc, _CTc, _CTc, _CTc, /* 0x1C..0x1F */
1036:
1037:
1038:
1039: _CTs, _CTp, _CTp, _CTp, /* 0x20..0x23 */
1040:
1041: _CTp, _CTp, _CTp, _CTp, /* 0x24..0x27 */
1042:
1043: _CTp, _CTp, _CTp, _CTp, /* 0x28..0x2B */
1044:
1045: _CTp, _CTp, _CTp, _CTp, /* 0x2C..0x2F */
1046:
1047:
1048:
1049: _CTd|_CTx, _CTd|_CTx, _CTd|_CTx, _CTd|_CTx, /* 0x30..0x33 */
1050:
1051: _CTd|_CTx, _CTd|_CTx, _CTd|_CTx, _CTd|_CTx, /* 0x34..0x37 */
1052:
1053: _CTd|_CTx, _CTd|_CTx, _CTp, _CTp, /* 0x38..0x3B */
1054:
1055: _CTp, _CTp, _CTp, _CTp, /* 0x3C..0x3F */
1056:
1057:
1058:
1059: _CTp, _CTu|_CTx, _CTu|_CTx, _CTu|_CTx, /* 0x40..0x43 */
1060:
1061: _CTu|_CTx, _CTu|_CTx, _CTu|_CTx, _CTu, /* 0x44..0x47 */
1062:
1063: _CTu, _CTu, _CTu, _CTu, /* 0x48..0x4B */
1064:
1065: _CTu, _CTu, _CTu, _CTu, /* 0x4C..0x4F */
1066:
1067:
1068:
1069: _CTu, _CTu, _CTu, _CTu, /* 0x50..0x53 */
1070:
1071: _CTu, _CTu, _CTu, _CTu, /* 0x54..0x57 */
1072:
1073: _CTu, _CTu, _CTu, _CTp, /* 0x58..0x5B */
1074:
1075: _CTp, _CTp, _CTp, _CTp, /* 0x5C..0x5F */
1076:
1077:
1078:
1079: _CTp, _CTl|_CTx, _CTl|_CTx, _CTl|_CTx, /* 0x60..0x63 */
1080:
1081: _CTl|_CTx, _CTl|_CTx, _CTl|_CTx, _CTl, /* 0x64..0x67 */
1082:
1083: _CTl, _CTl, _CTl, _CTl, /* 0x68..0x6B */
1084:
1085: _CTl, _CTl, _CTl, _CTl, /* 0x6C..0x6F */
1086:
1087:
1088:
1089: _CTl, _CTl, _CTl, _CTl, /* 0x70..0x73 */
1090:
1091: _CTl, _CTl, _CTl, _CTl, /* 0x74..0x77 */
1092:
1093: _CTl, _CTl, _CTl, _CTp, /* 0x78..0x7B */
1094:
1095: _CTp, _CTp, _CTp, _CTc, /* 0x7C..0x7F */
1096:
1097:
1098:
1099: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80..0x8F */
1100:
1101: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90..0x9F */
1102:
1103: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0..0xAF */
1104:
1105: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0..0xBF */
1106:
1107: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0..0xCF */
1108:
1109: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0..0xDF */
1110:
1111: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0..0xEF */
1112:
1113: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0..0xFF */
1114:
1115: };
1116:
1117:
1118:
1119: int toupper(c)
1120:
1121: int c;
1122:
1123: {
1124:
1125: return(islower(c) ? (c ^ 0x20) : (c));
1126:
1127: }
1128:
1129:
1130:
1131: int tolower(c)
1132:
1133: int c;
1134:
1135: {
1136:
1137: return(isupper(c) ? (c ^ 0x20) : (c));
1138:
1139: }
1140:
1141:
1142:
1143: /*
1144:
1145: * converts a decimal string to an integer
1146:
1147: */
1148:
1149:
1150:
1151: int
1152:
1153: atoi(s)
1154:
1155: const char *s;
1156:
1157: {
1158:
1159: int d = 0;
1160:
1161: int negflag = 0;
1162:
1163: int c;
1164:
1165:
1166:
1167: while (*s && isspace(*s)) s++;
1168:
1169: while (*s == '-' || *s == '+') {
1170:
1171: if (*s == '-')
1172:
1173: negflag ^= 1;
1174:
1175: s++;
1176:
1177: }
1178:
1179: while ((c = *s++) && isdigit(c)) {
1180:
1181: d = 10 * d + (c - '0');
1182:
1183: }
1184:
1185: if (negflag) d = -d;
1186:
1187: return d;
1188:
1189: }
1190:
1191:
1192:
1193: #endif /* OWN_LIB */
1194:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.