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