home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mint104s.zoo / mint.src / util.c < prev    next >
C/C++ Source or Header  |  1993-03-08  |  13KB  |  641 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith.
  3. Copyright 1992 Atari Corporation.
  4. All rights reserved.
  5. */
  6.  
  7. /*
  8.  * misc. utility routines
  9.  */
  10.  
  11. #include "mint.h"
  12.  
  13. /*
  14.  * given an address, find the corresponding memory region in this program's
  15.  * memory map
  16.  */
  17.  
  18. MEMREGION *
  19. addr2mem(a)
  20.     virtaddr a;
  21. {
  22.     int i;
  23.  
  24.     for (i = 0; i < curproc->num_reg; i++) {
  25.         if (a == curproc->addr[i])
  26.             return curproc->mem[i];
  27.     }
  28.     return 0;
  29. }
  30.  
  31. /*
  32.  * given a pid, return the corresponding process
  33.  */
  34.  
  35. PROC *
  36. pid2proc(pid)
  37.     int pid;
  38. {
  39.     PROC *p;
  40.  
  41.     for (p = proclist; p; p = p->gl_next) {
  42.         if (p->pid == pid)
  43.             return p;
  44.     }
  45.     return 0;
  46. }
  47.  
  48. /*
  49.  * return a new pid
  50.  */
  51.  
  52. int
  53. newpid()
  54. {
  55.     static int _maxpid = 1;
  56.     int i;
  57. #ifndef NDEBUG
  58.     int j = 0;
  59. #endif
  60.  
  61.     do {
  62.         i = _maxpid++;
  63.         if (_maxpid >= 1000) _maxpid = 1;
  64.         assert(j++ < 1000);
  65.     } while (pid2proc(i));
  66.  
  67.     return i;
  68. }
  69.  
  70. /*
  71.  * zero out a block of memory, quickly; the block must be word-aligned,
  72.  * and should be long-aligned for speed reasons
  73.  */
  74.  
  75. void
  76. zero(place, size)
  77.     char *place;
  78.     long size;
  79. {
  80.     long cruft;
  81.  
  82.     cruft = size % 256;    /* quickzero does 256 byte blocks */
  83.     size = size / 256;
  84.     while (cruft > 0) {
  85.         *place++ = 0;
  86.         cruft--;
  87.     }
  88.     if (size > 0) {
  89.         quickzero(place, size);
  90.     }
  91. }
  92.  
  93. #ifdef JUNK_MEM
  94. void
  95. fillwjunk(place, size)
  96.     long *place;
  97.     long size;
  98. {
  99.     while (size > 0) {
  100.         *place++ = size;
  101.         size -= 4;
  102.     }
  103. }
  104. #endif
  105.  
  106. /*
  107.  * kernel memory allocation routines
  108.  */
  109.  
  110. #define KERMEM_THRESHOLD QUANTUM-8
  111. #define KMAGIC ((MEMREGION *)0x87654321L)
  112. #define NKMAGIC 0x19870425L
  113.  
  114. void * ARGS_ON_STACK 
  115. kmalloc(size)
  116.     long size;
  117. {
  118.     MEMREGION *m = 0;
  119.     MEMREGION **p;
  120.     long *lp;
  121.  
  122.     /*
  123.      * increase size by two pointers' worth: the first contains
  124.      * a pointer to the region descriptor for this block, and the
  125.      * second contains KMAGIC.  If the block came from nalloc,
  126.      * then they both contain NKMAGIC.
  127.      */
  128.     size += sizeof(m) + sizeof(m);
  129. /*
  130.  * for small requests, we use nalloc first
  131.  */
  132. tryagain:
  133.     if (size < KERMEM_THRESHOLD) {
  134.         lp = nalloc(size);
  135.         if (lp) {
  136.         *lp++ = NKMAGIC;
  137.         *lp++ = NKMAGIC;
  138.         TRACELOW(("kmalloc(%lx) -> (nalloc) %lx",size,lp));
  139.         return lp;
  140.         }
  141.         else {
  142.         DEBUG(("kmalloc(%lx): nalloc is out of memory",size));
  143.  
  144.     /* If this is commented out, then we fall through to try_getregion */
  145.         if (0 == (m = get_region(alt, QUANTUM, PROT_S))) {
  146.             if (0 == (m = get_region(core, QUANTUM, PROT_S))) {
  147.             DEBUG(("No memory for another arena"));
  148.             goto try_getregion;
  149.             }
  150.         }
  151.         nalloc_arena_add((void *)m->loc,QUANTUM);
  152.         m = 0;
  153.         goto tryagain;
  154.         }
  155.     }
  156.  
  157. try_getregion:
  158.     m = get_region(alt, size, PROT_S);
  159.  
  160.     if (!m) m = get_region(core, size, PROT_S);
  161.  
  162.     if (m) {
  163.         p = (MEMREGION **)m->loc;
  164.         *p++ = KMAGIC;
  165.         *p++ = m;
  166.         TRACELOW(("kmalloc(%lx) -> (get_region) %lx",size,p));
  167.         return (void *)p;
  168.     }
  169.     else {
  170.         TRACELOW(("kmalloc(%lx) -> (fail)",size));
  171. #if 0
  172.         /* this is a serious offense; I want to hear about it */
  173.         /* maybe Allan wanted to hear about it, but ordinary users
  174.          * won't! -- ERS
  175.          */
  176.         NALLOC_DUMP();
  177.         BIG_MEM_DUMP(0,0);
  178. #endif
  179.         return 0;
  180.     }
  181. }
  182.  
  183. /* allocate from ST memory only */
  184.  
  185. void *
  186. kcore(size)
  187.     long size;
  188. {
  189.     MEMREGION *m;
  190.     MEMREGION **p;
  191.  
  192.     size += sizeof(m) + sizeof (m);
  193.     m = get_region(core, size, PROT_S);
  194.  
  195.     if (m) {
  196.         p = (MEMREGION **)m->loc;
  197.         *p++ = KMAGIC;
  198.         *p++ = m;
  199.         return (void *)p;
  200.     }
  201.     else {
  202.         return 0;
  203.     }
  204. }
  205.  
  206. void ARGS_ON_STACK 
  207. kfree(place)
  208.     void *place;
  209. {
  210.     MEMREGION **p;
  211.     MEMREGION *m;
  212.  
  213.     TRACELOW(("kfree(%lx)",place));
  214.  
  215.     if (!place) return;
  216.     p = place;
  217.     p -= 2;
  218.     if (*p == (MEMREGION *)NKMAGIC) {
  219.         nfree(p);
  220.         return;
  221.     }
  222.     else if (*p++ != KMAGIC) {
  223.         FATAL("kfree: memory not allocated by kmalloc");
  224.     }
  225.     m = *p;
  226.     if (--m->links != 0) {
  227.         FATAL("kfree: block has %d links", m->links);
  228.     }
  229.     free_region(m);
  230. }
  231.  
  232. /*
  233.  * "user" memory allocation routines; the kernel can use these to
  234.  * allocate/free memory that will be attached in some way to a process
  235.  * (and freed automatically when the process exits)
  236.  */
  237. void * ARGS_ON_STACK 
  238. umalloc(size)
  239.     long size;
  240. {
  241.     return (void *)m_xalloc(size, 3);
  242. }
  243.  
  244. void ARGS_ON_STACK 
  245. ufree(block)
  246.     void *block;
  247. {
  248.     (void)m_free((virtaddr)block);
  249. }
  250.  
  251. /*
  252.  * convert a time in milliseconds to a GEMDOS style date/time
  253.  * timeptr[0] gets the time, timeptr[1] the date.
  254.  * BUG/FEATURE: in the conversion, it is assumed that all months have
  255.  * 30 days and all years have 360 days.
  256.  */
  257.  
  258. void ARGS_ON_STACK 
  259. ms_time(ms, timeptr)
  260.     ulong ms;
  261.     short *timeptr;
  262. {
  263.     ulong secs;
  264.     short tsec, tmin, thour;
  265.     short tday, tmonth, tyear;
  266.  
  267.     secs = ms / 1000;
  268.     tsec = secs % 60;
  269.     secs /= 60;        /* secs now contains # of minutes */
  270.     tmin = secs % 60;
  271.     secs /= 60;        /* secs now contains # of hours */
  272.     thour = secs % 24;
  273.     secs /= 24;        /* secs now contains # of days */
  274.     tday = secs % 30;
  275.     secs /= 30;
  276.     tmonth = secs % 12;
  277.     tyear = secs / 12;
  278.     *timeptr++ = (thour << 11) | (tmin << 5) | (tsec >> 1);
  279.     *timeptr = (tyear << 9) | ((tmonth + 1) << 5) | (tday+1);
  280. }
  281.  
  282. /*
  283.  * unixtim(time, date): convert a Dos style (time, date) pair into
  284.  * a Unix time (seconds from midnight Jan 1., 1970)
  285.  */
  286.  
  287. static int
  288. mth_start[13] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
  289.  
  290. long ARGS_ON_STACK 
  291. unixtim(time, date)
  292.     unsigned time, date;
  293. {
  294.     int sec, min, hour;
  295.     int mday, mon, year;
  296.     long y, s;
  297.  
  298.     sec = (time & 31) << 1;
  299.     min = (time >> 5) & 63;
  300.     hour = (time >> 11) & 31;
  301.     mday = date & 31;
  302.     mon = ((date >> 5) & 15) - 1;
  303.     year = 80 + ((date >> 9) & 255);
  304.  
  305. /* calculate tm_yday here */
  306.     y = (mday - 1) + mth_start[mon] + /* leap year correction */
  307.         ( ( (year % 4) != 0 ) ? 0 : (mon > 1) );
  308.  
  309.     s = (sec) + (min * 60L) + (hour * 3600L) +
  310.         (y * 86400L) + ((year - 70) * 31536000L) +
  311.         ((year - 69)/4) * 86400L;
  312.  
  313.     return s;
  314. }
  315.  
  316. /* convert a Unix time into a DOS time. The longword returned contains
  317.    the time word first, then the date word.
  318.    BUG: we completely ignore any time zone information.
  319. */
  320. #define SECS_PER_MIN    (60L)
  321. #define SECS_PER_HOUR   (3600L)
  322. #define SECS_PER_DAY    (86400L)
  323. #define SECS_PER_YEAR   (31536000L)
  324. #define SECS_PER_LEAPYEAR (SECS_PER_DAY + SECS_PER_YEAR)
  325.  
  326. static int
  327. days_per_mth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  328.  
  329. long ARGS_ON_STACK 
  330. dostim(t)
  331.     long t;
  332. {
  333.         unsigned long time, date;
  334.     int tm_hour, tm_min, tm_sec;
  335.     int tm_year, tm_mon, tm_mday;
  336.     int i;
  337.  
  338.     if (t <= 0) return 0;
  339.  
  340.     tm_year = 70;
  341.     while (t >= SECS_PER_YEAR) {
  342.         if ((tm_year & 0x3) == 0) {
  343.             if (t < SECS_PER_LEAPYEAR)
  344.                 break;
  345.             t -= SECS_PER_LEAPYEAR;
  346.         } else {
  347.             t -= SECS_PER_YEAR;
  348.         }
  349.         tm_year++;
  350.     }
  351.     tm_mday = (int)(t/SECS_PER_DAY);
  352.         days_per_mth[1] = (tm_year & 0x3) ? 28 : 29;
  353.         for (i = 0; tm_mday >= days_per_mth[i]; i++)
  354.                 tm_mday -= days_per_mth[i];
  355.         tm_mon = i+1;
  356.     tm_mday++;
  357.         t = t % SECS_PER_DAY;
  358.         tm_hour = (int)(t/SECS_PER_HOUR);
  359.         t = t % SECS_PER_HOUR;
  360.         tm_min = (int)(t/SECS_PER_MIN);
  361.         tm_sec = (int)(t % SECS_PER_MIN);
  362.  
  363.     if (tm_year < 80) {
  364.         tm_year = 80;
  365.         tm_mon = tm_mday = 1;
  366.         tm_hour = tm_min = tm_sec = 0;
  367.     }
  368.  
  369.     time = (tm_hour << 11) | (tm_min << 5) | (tm_sec >> 1);
  370.     date = ((tm_year - 80) & 0x7f) << 9;
  371.     date |= ((tm_mon) << 5) | (tm_mday);
  372.     return (time << 16) | date;
  373. }
  374.  
  375. /*
  376.  * Case insensitive string comparison. note that this only returns
  377.  * 0 (match) or nonzero (no match), and that the returned value
  378.  * is not a reliable indicator of any "order".
  379.  */
  380.  
  381. int ARGS_ON_STACK 
  382. strnicmp(str1, str2, len)
  383.     register const char *str1, *str2;
  384.     register int len;
  385. {
  386.     register char c1, c2;
  387.  
  388.     do {
  389.         c1 = *str1++; if (isupper(c1)) c1 = tolower(c1);
  390.         c2 = *str2++; if (isupper(c2)) c2 = tolower(c2);
  391.     } while (--len >= 0 && c1 && c1 == c2);
  392.  
  393.     if (len < 0 || c1 == c2)
  394.         return 0;
  395.     return c1 - c2;
  396. }
  397.  
  398. int ARGS_ON_STACK 
  399. stricmp(str1, str2)
  400.     const char *str1, *str2;
  401. {
  402.     return strnicmp(str1, str2, 0x7fff);
  403. }
  404.  
  405.  
  406. /*
  407.  * string utilities: strlwr() converts a string to lower case, strupr()
  408.  * converts it to upper case
  409.  */
  410.  
  411. char * ARGS_ON_STACK 
  412. strlwr(s)
  413.     char *s;
  414. {
  415.     char c;
  416.     char *old = s;
  417.  
  418.     while ((c = *s) != 0) {
  419.         if (isupper(c)) {
  420.             *s = _tolower(c);
  421.         }
  422.         s++;
  423.     }
  424.     return old;
  425. }
  426.  
  427. char * ARGS_ON_STACK 
  428. strupr(s)
  429.     char *s;
  430. {
  431.     char c;
  432.     char *old = s;
  433.  
  434.     while ((c = *s) != 0) {
  435.         if (islower(c)) {
  436.             *s = _toupper(c);
  437.         }
  438.         s++;
  439.     }
  440.     return old;
  441. }
  442.  
  443. #ifdef OWN_LIB
  444.  
  445. /*
  446.  * Case sensitive comparison functions.
  447.  */
  448.  
  449. int
  450. strncmp(str1, str2, len)
  451.     register const char *str1, *str2;
  452.     register int len;
  453. {
  454.     register char c1, c2;
  455.  
  456.     do {
  457.         c1 = *str1++;
  458.         c2 = *str2++;
  459.     } while (--len >= 0 && c1 && c1 == c2);
  460.  
  461.     if (len < 0) return 0;
  462.  
  463.     return c1 - c2;
  464. }
  465.  
  466. int
  467. strcmp(str1, str2)
  468.     const char *str1, *str2;
  469. {
  470.     register char c1, c2;
  471.  
  472.     do {
  473.         c1 = *str1++;
  474.         c2 = *str2++;
  475.     } while (c1 && c1 == c2);
  476.  
  477.     return c1 - c2;
  478. }
  479.  
  480.  
  481. /*
  482.  * some standard string functions
  483.  */
  484.  
  485. char *
  486. strcat(dst, src)
  487.     char *dst;
  488.     const char *src;
  489. {
  490.     register char *_dscan;
  491.  
  492.     for (_dscan = dst; *_dscan; _dscan++) ;
  493.     while ((*_dscan++ = *src++) != 0) ;
  494.     return dst;
  495. }
  496.  
  497. char *
  498. strcpy(dst, src)
  499.     char *dst;
  500.     const char *src;
  501. {
  502.     register char *_dscan = dst;
  503.     while ((*_dscan++ = *src++) != 0) ;
  504.     return dst;
  505. }
  506.  
  507. char *
  508. strncpy(dst, src, len)
  509.     char *dst;
  510.     const char *src;
  511.     int len;
  512. {
  513.     register char *_dscan = dst;
  514.     while (--len >= 0 && (*_dscan++ = *src++) != 0)
  515.         continue;
  516.     while (--len >= 0)
  517.         *_dscan++ = 0;
  518.     return dst;
  519. }
  520.  
  521. int
  522. strlen(scan)
  523.     const char *scan;
  524. {
  525.     register const char *_start = scan+1;
  526.     while (*scan++) ;
  527.     return (int)((long)scan - (long)_start);
  528. }
  529.  
  530. /*
  531.  * strrchr: find the last occurence of a character in a string
  532.  */
  533. char *
  534. strrchr(str, which)
  535.     const char *str;
  536.     register int which;
  537. {
  538.     register unsigned char c, *s;
  539.     register char *place;
  540.  
  541.     s = (unsigned char *)str;
  542.     place = 0;
  543.     do {
  544.         c = *s++;
  545.         if (c == which)
  546.             place = (char *)s-1;
  547.     } while (c);
  548.     return place;
  549. }
  550.  
  551. unsigned char _ctype[256] =
  552. {
  553.     _CTc, _CTc, _CTc, _CTc,                /* 0x00..0x03 */
  554.     _CTc, _CTc, _CTc, _CTc,                /* 0x04..0x07 */
  555.     _CTc, _CTc|_CTs, _CTc|_CTs, _CTc|_CTs,        /* 0x08..0x0B */
  556.     _CTc|_CTs, _CTc|_CTs, _CTc, _CTc,        /* 0x0C..0x0F */
  557.  
  558.     _CTc, _CTc, _CTc, _CTc,                /* 0x10..0x13 */
  559.     _CTc, _CTc, _CTc, _CTc,                /* 0x14..0x17 */
  560.     _CTc, _CTc, _CTc, _CTc,                /* 0x18..0x1B */
  561.     _CTc, _CTc, _CTc, _CTc,                /* 0x1C..0x1F */
  562.  
  563.     _CTs, _CTp, _CTp, _CTp,                /* 0x20..0x23 */
  564.     _CTp, _CTp, _CTp, _CTp,                /* 0x24..0x27 */
  565.     _CTp, _CTp, _CTp, _CTp,                /* 0x28..0x2B */
  566.     _CTp, _CTp, _CTp, _CTp,                /* 0x2C..0x2F */
  567.  
  568.     _CTd|_CTx, _CTd|_CTx, _CTd|_CTx, _CTd|_CTx,    /* 0x30..0x33 */
  569.     _CTd|_CTx, _CTd|_CTx, _CTd|_CTx, _CTd|_CTx,    /* 0x34..0x37 */
  570.     _CTd|_CTx, _CTd|_CTx, _CTp, _CTp,        /* 0x38..0x3B */
  571.     _CTp, _CTp, _CTp, _CTp,                /* 0x3C..0x3F */
  572.  
  573.     _CTp, _CTu|_CTx, _CTu|_CTx, _CTu|_CTx,        /* 0x40..0x43 */
  574.     _CTu|_CTx, _CTu|_CTx, _CTu|_CTx, _CTu,        /* 0x44..0x47 */
  575.     _CTu, _CTu, _CTu, _CTu,                /* 0x48..0x4B */
  576.     _CTu, _CTu, _CTu, _CTu,                /* 0x4C..0x4F */
  577.  
  578.     _CTu, _CTu, _CTu, _CTu,                /* 0x50..0x53 */
  579.     _CTu, _CTu, _CTu, _CTu,                /* 0x54..0x57 */
  580.     _CTu, _CTu, _CTu, _CTp,                /* 0x58..0x5B */
  581.     _CTp, _CTp, _CTp, _CTp,                /* 0x5C..0x5F */
  582.  
  583.     _CTp, _CTl|_CTx, _CTl|_CTx, _CTl|_CTx,        /* 0x60..0x63 */
  584.     _CTl|_CTx, _CTl|_CTx, _CTl|_CTx, _CTl,        /* 0x64..0x67 */
  585.     _CTl, _CTl, _CTl, _CTl,                /* 0x68..0x6B */
  586.     _CTl, _CTl, _CTl, _CTl,                /* 0x6C..0x6F */
  587.  
  588.     _CTl, _CTl, _CTl, _CTl,                /* 0x70..0x73 */
  589.     _CTl, _CTl, _CTl, _CTl,                /* 0x74..0x77 */
  590.     _CTl, _CTl, _CTl, _CTp,                /* 0x78..0x7B */
  591.     _CTp, _CTp, _CTp, _CTc,                /* 0x7C..0x7F */
  592.  
  593.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80..0x8F */
  594.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90..0x9F */
  595.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0..0xAF */
  596.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0..0xBF */
  597.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0..0xCF */
  598.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0..0xDF */
  599.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0..0xEF */
  600.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  /* 0xF0..0xFF */
  601. };
  602.  
  603. int toupper(c)
  604.     int c;
  605. {
  606.     return(islower(c) ? (c ^ 0x20) : (c));
  607. }
  608.  
  609. int tolower(c)
  610.     int c;
  611. {
  612.     return(isupper(c) ? (c ^ 0x20) : (c));
  613. }
  614.  
  615. /*
  616.  * converts a decimal string to an integer
  617.  */
  618.  
  619. long
  620. atol(s)
  621.     const char *s;
  622. {
  623.     long d = 0;
  624.     int negflag = 0;
  625.     int c;
  626.  
  627.     while (*s && isspace(*s)) s++;
  628.     while (*s == '-' || *s == '+') {
  629.         if (*s == '-')
  630.             negflag ^= 1;
  631.         s++;
  632.     }
  633.     while ((c = *s++) != 0 && isdigit(c)) {
  634.         d = 10 * d + (c - '0');
  635.     }
  636.     if (negflag) d = -d;
  637.     return d;
  638. }
  639.  
  640. #endif /* OWN_LIB */
  641.