home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / CPM3 / RSXMAP.LBR / RSXMAP.CZ / RSXMAP.C
Text File  |  2000-06-30  |  8KB  |  281 lines

  1. /*************************************************************************
  2. **    RSXMAP    RSXMAP    RSXMAP    RSXMAP    RSXMAP    RSXMAP    RSXMAP    RSXMAP    **
  3. **                                    **
  4. **    This little program is used to display the current dynamic    **
  5. **    memory map of a CP/M Plus (3.x) system.  It shows the amount    **
  6. **    of Transient Program Area (TPA) memory that is available.    **
  7. **    Next, each each installed RSX is shown by displaying its    **
  8. **    load address, name and size in pages.                **
  9. **                                    **
  10. **    There is currently a problem when using RSXMAP as a command    **
  11. **    in a multiple command line, i.e.:                **
  12. **        A>rsxmap ! dir                         **
  13. **    In this example the "dir" command is stored by the CCP as a    **
  14. **    quick & dirty RSX while the RSXMAP is being run.  The 1k size     **
  15. **    of the RSX is correct BUT the name is GARBAGE!!            **
  16. **    Jim Lopushinsky of the Meadowlark RCPM expects to have a fix    **
  17. **    for this in the next release of his CCP+.            **
  18. **                                    **
  19. **    This program was developed under Manx Aztec C version 1.06D    **
  20. **                                    **
  21. **    Developed by Sparrow Software        Version 1.00        **
  22. **    Released into the Public Domain        10 Feb 1986        **
  23. **                                    **
  24. **        Jim Dunn                        **
  25. **        Sparrow Software                    **
  26. **        30 Birch Lane                        **
  27. **        Fairport, NY  14450                    **
  28. **                                    **
  29. **        Sparrow RCPM:    (716) 377-1113 [300/1200/2400 bps]    **
  30. **        Voice:        (716) 377-7036                **
  31. **        CompuServe:    70245,170                **
  32. *************************************************************************/
  33.  
  34. #include <stdio.h>
  35.  
  36. #define    SML_STR        20    /* bytes in a small string        */
  37. #define MAX_RSX        20    /* maximum expected amount of RSXes    */
  38.  
  39. int
  40.     i,j,k,        /* my favorite 3 little worker ints        */
  41.     ver,        /* CP/M version variable            */
  42.     lhv,        /* last high value, used in RSX size calc    */
  43.     rsxct,        /* RSX counter variable                */
  44.     oc,        /* output counter (inverse of above)        */
  45.     *nextp,        /* pointer to next RSX header - initial        */
  46.     *nrsxp,        /* pointer to next RSX header - result        */
  47.     *biosp,        /* BIOS pointer                    */
  48.     *bdosp;        /* BDOS pointer                    */
  49.  
  50. long
  51.     li;        /* long integer needed for TPA size        */
  52.  
  53. char
  54.     gof[SML_STR],    /* gofer char array                */
  55.     str[SML_STR],    /* another char array                */
  56.     *cp;        /* general purpose char pointer            */
  57.  
  58.  
  59.             /* Let's make a new data type to hold RSX info    */
  60. typedef struct {
  61.     char
  62.         addr[4+1],    /* RSX address                */
  63.         name[8+1];    /* RSX name                */
  64. } RSXREC;
  65.  
  66.  
  67. RSXREC            /* array of pointers to RSX records        */
  68.     *rsxary[MAX_RSX];
  69.  
  70.  
  71. int
  72.     bdos(),        /* returns an int                */
  73.     isrsx();    /* returns an int                */
  74.  
  75. char
  76.     *strncpy(),    /* returns a pointer to a char            */
  77.     *malloc();    /* returns a pointer to a char            */
  78.  
  79. void
  80.     exit(),        /* returns nothing                */
  81.     storrsx();    /* returns absolutely nothing (like my dog)    */
  82.  
  83.  
  84. main()
  85. {
  86.     /****************************************************************/
  87.     /**********  Let's see what version of CP/M we are riding on    */
  88.  
  89.     /***** BDOS function 12                        */
  90.  
  91.     i = bdos(12, 0);
  92.  
  93.     /***** Quick and Dirty hex to decimal conversion        */
  94.  
  95.     sprintf(str, "%04x", i);
  96.     sscanf(str, "%d", &ver);
  97.  
  98.     /***** Split tens and ones to insert decimal point        */
  99.  
  100.     i = ver / 10;
  101.     j = ver - (i * 10);
  102.  
  103.     /***** Exit if not running under CP/M Plus            */
  104.  
  105.     if (i != 3) {
  106.         printf("This will only work under CP/M Plus\n");
  107.         exit(1);
  108.     }    
  109.  
  110.  
  111.  
  112.     /****************************************************************/
  113.     /********** Now let's display the TPA size            */
  114.     /********** This BDOS pointer will point to the begining of    */
  115.     /********** any and all installed RSXes, so it will show the    */
  116.     /********** current TPA, not the "ideal" TPA            */
  117.  
  118.     /***** Get value at 0006H, subtract 3 words (6 bytes)        */
  119.     /***** Assign to BDOS pointer                    */
  120.  
  121.     bdosp = (int *) (*(int *)6) - 3;
  122.  
  123.     /***** Subtract the CP/M base page from the TPA            */
  124.  
  125.     li = ((long)bdosp) - (long)256;
  126.  
  127.     /***** Now its time to display these values            */
  128.  
  129.     printf("CP/M Version %d.%d", i,j);
  130.     printf("                TPA is %ld bytes\n", li);
  131.     printf("==================================================\n");
  132.  
  133.  
  134.     /****************************************************************/
  135.     /**********     Where is the BIOS entry table            */
  136.  
  137.     /***** Get value at 0001H, assign to BIOS pointer        */
  138.  
  139.     biosp = (int *) (*(int *)1);
  140.  
  141.     /***** Subtract 3 bytes to get to page boundary            */
  142.  
  143.     biosp = (int *) (((char *) biosp) - 3);
  144.     
  145.     /***** Last high value (lvh) holds the current high map address    */
  146.     /***** it is used to calculate the difference between it and    */
  147.     /***** bottom (begining) of the next RSX.            */
  148.  
  149.     lhv = (int) biosp;
  150.  
  151.     /***** Convert to upper case hex value and display it        */
  152.  
  153.     sprintf(gof, "%04x", biosp);
  154.     for (cp = gof; *cp != '\0'; ++cp) {
  155.         *cp = (char)toupper(*cp);
  156.     }
  157.     printf("BIOS entry at %s\n", gof);
  158.  
  159.  
  160.     /****************************************************************/
  161.     /**********    Let's find the lowest (last) RSX        */
  162.  
  163.     /***** Get value at 0006H, subtract 3 words (6 bytes)        */
  164.     /***** Assign to BDOS pointer                    */
  165.  
  166.     bdosp = (int *) (*(int *)6) - 3;
  167.  
  168.     /***** Move from the serial entry point to the start entry     */
  169.     /***** point by adding 3 words (6 bytes)            */
  170.  
  171.     nextp = bdosp + 3;
  172.  
  173.     /***** cycle through the RSXes till we hit the BDOS        */
  174.     /***** each RSX has its information stored via storrsx()    */
  175.  
  176.     while ((nrsxp = (int *) isrsx(nextp)) != 0) {
  177.         storrsx(nextp, rsxct);
  178.         ++rsxct;
  179.         nextp = nrsxp;
  180.     }
  181.  
  182.  
  183.     /****************************************************************/
  184.     /***** This must now be the real BDOS entry            */
  185.     /***** Get some heap storage for the BDOS record        */
  186.     /***** Backup by 6 bytes for the top of the page (xx00H)    */
  187.     /***** Convert first 2 charcters to upper case            */
  188.  
  189.     if ((rsxary[rsxct] = malloc(sizeof(RSXREC))) == NULL) {
  190.         printf("malloc says:: out of memory!\n");
  191.         exit(1);
  192.     }
  193.     else {
  194.         sprintf(rsxary[rsxct]->addr, "%04x", ((int)nextp) - 6);
  195.  
  196.         rsxary[rsxct]->addr[0] = (char)toupper(rsxary[rsxct]->addr[0]);
  197.         rsxary[rsxct]->addr[1] = (char)toupper(rsxary[rsxct]->addr[1]);
  198.     }
  199.  
  200.  
  201.     /****************************************************************/
  202.     /***** time to display the upside down rsx table        */
  203.  
  204.     for (i = rsxct, oc = 0; i >= 0; --i, ++oc) {
  205.  
  206.         /* Convert hex addr string into integer    k        */
  207.  
  208.         sscanf(rsxary[i]->addr, "%4x", &k);
  209.  
  210.         /* Subtract this current RSX address from last         */
  211.         /* high value and covert into 256 byte pages        */
  212.  
  213.         j = (lhv - k) / 256;
  214.  
  215.         /*Iif (i == rsxct) then we are at BDOS entry        */
  216.  
  217.         if (i == rsxct)
  218.             printf("BDOS entry at %s and is %2d pages\n",
  219.             rsxary[i]->addr, j);
  220.         else {
  221.             printf("RSX %2d) is at %s and is %2d pages named %s\n",
  222.                 oc, rsxary[i]->addr, j, rsxary[i]->name);
  223.         }
  224.         /* Move current RSX address into last high value    */
  225.         /* for next cycle.                    */
  226.         
  227.         lhv = k;
  228.     }
  229.     printf("==================================================\n");
  230.     return(0);
  231. }
  232.  
  233.  
  234. int
  235. isrsx(upp)
  236. int
  237.   *upp;
  238. {
  239.     /***** We try to decide if this is an RSX by looking 9 bytes    */
  240.     /***** past the start entry point.  If in an RSX this is the    */
  241.     /***** non-bank flag which will either be 00H or FFH.  If we    */
  242.     /***** made it all the way to the BDOS, this byte will be a    */
  243.     /***** C3H jump command to whatever.                */
  244.  
  245.     if (((char *)upp)[9] == 0xc3)
  246.         return (0);
  247.     else
  248.  
  249.     /***** return with an integer value which is actually a pointer */
  250.     /***** to the next RSX.  This value is obtained by moving    */
  251.     /***** 4 bytes up from the start entry point.            */
  252.  
  253.         return (upp[2]);
  254. }
  255.  
  256. void
  257. storrsx(upp, ct)
  258. int
  259.     *upp,        /* pointer to next high RSX            */
  260.     ct;        /* RSX count                    */
  261. {
  262.     /***** get someheap storage and store RSX record        */
  263.     /***** Backup by 6 bytes for the top of the page (xx00H)    */
  264.     /***** Move address hex value into RSX record            */
  265.     /***** Move name into RSX record and delimit end of string    */
  266.     /***** Convert first 2 charcters to upper case            */
  267.  
  268.     if ((rsxary[ct] = malloc(sizeof(RSXREC))) == NULL) {
  269.         printf("malloc says:: out of memory!\n");
  270.         exit(1);
  271.     }
  272.     else {
  273.         sprintf(rsxary[ct]->addr, "%04x", (int)upp - 6);
  274.         strncpy(rsxary[ct]->name, (char *)upp + 10, 8);
  275.         rsxary[ct]->name[8] = '\0';
  276.  
  277.         rsxary[ct]->addr[0] = (char)toupper(rsxary[ct]->addr[0]);
  278.         rsxary[ct]->addr[1] = (char)toupper(rsxary[ct]->addr[1]);
  279.     }
  280. }
  281.