home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / SVGALIB / SVGALIB1.TAR / svgalib / src / regextr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-01  |  10.1 KB  |  464 lines

  1. /*
  2. ** regextr.c  -  extract graphics modes and register information
  3. **               from C source file
  4. **
  5. ** This file is part of SVGALIB (C) 1993 by Tommy Frandsen and
  6. **                        Harm Hanemaayer
  7. **
  8. ** Copyright (C) 1993 by Hartmut Schirmer
  9. **
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16.  
  17. #include "vga.h"
  18. #include "libvga.h"
  19. #include "driver.h"
  20.  
  21. #ifndef FALSE
  22. #  define FALSE (1==0)
  23. #endif
  24. #ifndef TRUE
  25. #  define TRUE (1==1)
  26. #endif
  27.  
  28. #define WordLen 100
  29. typedef char WordStr[WordLen];
  30.  
  31. typedef struct ML {
  32.   WordStr x, y, c;
  33.   int     mnum;
  34.   int     equ;
  35.   void    *regs;
  36.   struct  ML *nxt;
  37. } ModeList;
  38.  
  39. static void *Malloc(unsigned long bytes)
  40. {
  41.   void *res;
  42.  
  43.   res = (void *) malloc(bytes);
  44.   if (res == NULL) {
  45.     fprintf(stderr, "regextr.c: Can't allocate memory\n");
  46.     exit(1);
  47.   }
  48.   return res;
  49. }
  50.  
  51. static void store_equ(ModeList **root, char *x1, char *y1, char *c1, 
  52.                       int mnum,        char *x2, char *y2, char *c2 )
  53. {
  54.   ModeList *p;
  55.  
  56.   p = *root;
  57.   while (p != NULL) {
  58.     if (   strcmp(p->x, x1)==0
  59.     && strcmp(p->y, y1)==0
  60.     && strcmp(p->c, c1)==0 ) {
  61.       fprintf(stderr, "regextr.c: Duplicate g%sx%sx%s_regs !\n",x1,y1,c1);
  62.       exit(1);
  63.     }
  64.     p = p->nxt;
  65.   }
  66.   p = (ModeList *) Malloc(sizeof(ModeList));
  67.   strcpy(p->x, x1); 
  68.   strcpy(p->y, y1);
  69.   strcpy(p->c, c1);
  70.   p->mnum= mnum;
  71.   p->equ = TRUE;
  72.   p->nxt = *root;
  73.   *root  = p;
  74.   p = (ModeList *) Malloc(sizeof(ModeList));
  75.   strcpy(p->x, x2); 
  76.   strcpy(p->y, y2);
  77.   strcpy(p->c, c2);
  78.   p->mnum= 0;
  79.   p->equ = FALSE;
  80.   p->regs= NULL;
  81.   p->nxt = NULL;
  82.   (*root)->regs = (void *)p;
  83. }
  84.  
  85. static int check_new_mode(ModeList *p, char *x, char *y, char *c)
  86. {
  87.   while (p != NULL) {
  88.     if (   strcmp(p->x, x)==0
  89.     && strcmp(p->y, y)==0
  90.     && strcmp(p->c, c)==0 ) return FALSE;
  91.     p = p->nxt;
  92.   }
  93.   return TRUE;
  94. }
  95.  
  96. static void store_regs(ModeList **root, char *x, char *y, char *c, int mnum, char *r)
  97. {
  98.   ModeList *p;
  99.  
  100.   if (!check_new_mode(*root, x, y, c)) {
  101.       fprintf(stderr, "regextr.c: Duplicate g%sx%sx%s_regs !\n",x,y,c);
  102.       exit(1);
  103.   }
  104.   p = (ModeList *) Malloc(sizeof(ModeList));
  105.   strcpy(p->x, x); 
  106.   strcpy(p->y, y);
  107.   strcpy(p->c, c);
  108.   p->mnum = mnum;
  109.   p->equ = FALSE;
  110.   p->regs= (void *) r;
  111.   p->nxt = *root;
  112.   *root  = p;
  113. }
  114.  
  115.  
  116. static void __store_regs(ModeList **root, int mnum, char *r)
  117. {
  118.   WordStr x, y, c;
  119.  
  120.   sprintf( x, "%d", infotable[mnum].xdim);
  121.   sprintf( y, "%d", infotable[mnum].ydim);
  122.   switch (infotable[mnum].colors) {
  123.     case 1<<15: strcpy( c, "32K"); break;
  124.     case 1<<16: strcpy( c, "64K"); break;
  125.     case 1<<24: strcpy( c, "16M"); break;
  126.     default   : sprintf( c, "%d", infotable[mnum].colors);
  127.   }
  128.   if (check_new_mode(*root, x, y, c)) 
  129.     store_regs( root, x, y, c, mnum, r);
  130. }
  131.  
  132.  
  133. static char *mode2name(char *x, char *y, char *c)
  134. {
  135.   static char mn[WordLen];
  136.  
  137.   sprintf(mn, "G%sx%sx%s", x, y, c);
  138.   return mn;
  139. }
  140.  
  141. /* -------------------------------------- Scanner --- */
  142. static int get_nextchar(FILE *inp)
  143. {
  144.   int nch;
  145.  
  146.   nch = fgetc(inp);
  147.   if (nch == '\\') {
  148.     int nnch;
  149.     nnch = fgetc(inp);
  150.     if (nnch == '\n') 
  151.       return ' ';
  152.     ungetc(nnch, inp);
  153.   }
  154.   if (isspace(nch)) return ' ';
  155.   return nch;
  156. }
  157.  
  158. static int next_ch = ' ';
  159.  
  160. static int get_char(FILE *inp)
  161. {
  162.   int ch;
  163.  
  164.   do {
  165.     ch = next_ch;
  166.     do
  167.       next_ch = get_nextchar(inp);
  168.     while (ch == ' ' && next_ch == ' ');
  169.     if (ch != '/' || next_ch != '*')
  170.       return ch;
  171.     do {
  172.       ch = next_ch;
  173.       next_ch = get_nextchar(inp);
  174.     } while (ch != EOF && !(ch == '*' && next_ch == '/'));
  175.     next_ch = get_nextchar(inp);
  176.   } while (1);
  177. }
  178.  
  179. static char *get_word(FILE *inp)
  180. {
  181.   int ch;
  182.   static char buf[1000];
  183.   char *p;
  184.  
  185.   do
  186.     ch = get_char(inp);
  187.   while (ch == ' ');
  188.   p = buf;
  189.   switch (ch) {
  190.     case '[' :
  191.     case ']' :
  192.     case '{' :
  193.     case '}' :
  194.     case ',' :
  195.     case ';' :
  196.     case '=' :
  197.     case '(' :
  198.     case ')' : *(p++) = ch;
  199.            *p = '\0';
  200.            return buf;
  201.     case EOF : buf[0] = '\0';
  202.            return buf;
  203.   }
  204.   for (;;) {
  205.     *(p++) = ch;
  206.     switch (next_ch) {
  207.       case EOF :
  208.       case '[' :
  209.       case ']' :
  210.       case '{' :
  211.       case '}' :
  212.       case ',' :
  213.       case ';' :
  214.       case '=' :
  215.       case '(' :
  216.       case ')' :
  217.       case ' ' : *p = '\0';
  218.          return buf;
  219.     }
  220.     ch = get_char(inp);
  221.   }
  222. }
  223.  
  224. /* ----------------------------------------------- parser -- */
  225. static int is_res(char *rp, char *x, char *y, char *c, int *mnum)
  226. {
  227.   char *p;
  228.  
  229.   if (*(rp++) != 'g') return FALSE;
  230.   /* X resolution */
  231.   p = x;
  232.   if (!isdigit(*rp))  return FALSE;
  233.   *(p++) = *(rp++);
  234.   if (!isdigit(*rp))  return FALSE;
  235.   *(p++) = *(rp++);
  236.   if (!isdigit(*rp))  return FALSE;
  237.   *(p++) = *(rp++);
  238.   if (isdigit(*rp))
  239.     *(p++) = *(rp++);
  240.   if (*(rp++) != 'x') return FALSE;
  241.   *p = '\0';
  242.  
  243.   /* Y resolution */
  244.   p = y;
  245.   if (!isdigit(*rp))  return FALSE;
  246.   *(p++) = *(rp++);
  247.   if (!isdigit(*rp))  return FALSE;
  248.   *(p++) = *(rp++);
  249.   if (!isdigit(*rp))  return FALSE;
  250.   *(p++) = *(rp++);
  251.   if (isdigit(*rp))
  252.     *(p++) = *(rp++);
  253.   if (*(rp++) != 'x') return FALSE;
  254.   *p = '\0';
  255.  
  256.   /* colors */
  257.   p = c;
  258.   *(p++) = *rp;
  259.   switch ( *(rp++) ) {
  260.     case '1' :    *(p++) = *rp;
  261.            if (*(rp++) != '6') return FALSE;
  262.            if (*rp == 'M') 
  263.          *(p++) = *(rp++);
  264.            break;
  265.     case '2' : if (*rp == '5' && *(rp+1) == '6') {
  266.           *(p++) = *(rp++);
  267.           *(p++) = *(rp++);
  268.            }
  269.            break;
  270.     case '3' : if (*rp != '2') return FALSE;
  271.            *(p++) = *(rp++);
  272.            if (*rp != 'k' && *rp != 'K') return FALSE;
  273.            *(p++) = 'K'; ++rp;
  274.            break;
  275.     case '6' : if (*rp != '4') return FALSE;
  276.            *(p++) = *(rp++);
  277.            if (*rp != 'k' && *rp != 'K') return FALSE;
  278.            *(p++) = 'K'; ++rp;
  279.            break;
  280.     default  : return FALSE;
  281.   }
  282.   *p = '\0';
  283.   *mnum = __vga_name2number(mode2name(x,y,c));
  284.   if (*mnum < 0) {
  285.     int cols = 0;
  286.     int xbytes = 0;
  287.  
  288.     if (strcmp("16M", c) == 0) { cols = 1<<24; xbytes = atoi(x)*3; } else
  289.     if (strcmp("32K", c) == 0) { cols = 1<<15; xbytes = atoi(x)*2; } else
  290.     if (strcmp("64K", c) == 0) { cols = 1<<16; xbytes = atoi(x)*2; } else
  291.     if (strcmp("256", c) == 0) { cols = 256;   xbytes = atoi(x);   } else
  292.     if (strcmp("16",  c) == 0) { cols = 16;    xbytes = atoi(x)/4; } else
  293.         return FALSE;
  294.     *mnum = __vga_addmode(atoi(x),atoi(y),cols, xbytes, xbytes / atoi(x));
  295.   }
  296.   return (*mnum > TEXT && *mnum != GPLANE16);
  297. }
  298.  
  299. static int read_regs(FILE *inp, unsigned char **regs)
  300. {
  301.   unsigned char  r[MAX_REGS];
  302.   char          *w;
  303.   int            c;
  304.   unsigned       u;
  305.  
  306.   if (strcmp("[",get_word(inp)) != 0) return 0;
  307.   if (strcmp("]",get_word(inp)) !=0)
  308.     if (strcmp("]",get_word(inp)) != 0) return 0;
  309.   if (strcmp("=",get_word(inp)) != 0) return 0;
  310.   if (strcmp("{",get_word(inp)) != 0) return 0;
  311.  
  312.   c = 0;
  313.   do {
  314.     w = get_word(inp);
  315.     if (strcmp(w,"}") == 0)
  316.       continue;
  317.     if (sscanf(w, "%x", &u) == EOF)
  318.     if (sscanf(w, "%u", &u) == EOF) {
  319.     fprintf(stderr, "regextr.c: Invalid register value %s\n", w);
  320.     exit(1);
  321.     }
  322.     r[c++] = u;
  323.     w = get_word(inp);
  324.   } while (strcmp(",",w) == 0);
  325.   *regs = (char *)Malloc(c);
  326.   memcpy(*regs,r,c);
  327.   return c;
  328. }
  329.  
  330.  
  331. void __vga_readmodes(FILE *inp, ModeTable **mt, int *dac, unsigned *clocks)
  332. {
  333.   WordStr    x1, y1, c1, x2, y2, c2;
  334.   WordStr    w1, w2;
  335.   int        mnum1, mnum2;
  336.   ModeList  *modes = NULL;
  337.   ModeList  *p, *q, *cmp;
  338.   int        regs_count = -1;
  339.   int         change;
  340.   int         mode_cnt, i;
  341.  
  342.   /* read the register information from file */
  343.   while (!feof(inp)) {
  344.     char *wp;
  345.  
  346.     wp = get_word(inp);
  347.     if (strcmp(wp, "#define") == 0) {
  348.       strcpy(w1, get_word(inp));
  349.       strcpy(w2, get_word(inp));
  350.       if (clocks != NULL && strcmp(w1,"CLOCK_VALUES") == 0) {
  351.         unsigned freq;
  352.  
  353.     if (strcmp(w2, "{") == 0) {
  354.       do {
  355.         strcpy(w2, get_word(inp));
  356.         if (sscanf(w2, "%u", &freq) == EOF)
  357.         if (sscanf(w2, "%x", &freq) == EOF) {
  358.           fprintf(stderr, "regextr.c: Invalid clock definition (%s)\n", w2);
  359.           exit(1);
  360.         }
  361.         *(clocks++) = freq;
  362.         strcpy(w1, get_word(inp));
  363.       } while (strcmp(",", w1) == 0);
  364.       clocks = NULL;
  365.     }
  366.       } else
  367.       if (dac != NULL && strcmp(w1,"DAC_TYPE") == 0) {
  368.         int new_dac;
  369.  
  370.     if (sscanf(w2, "%d", &new_dac) == EOF)
  371.     if (sscanf(w2, "%x", &new_dac) == EOF) {
  372.       fprintf(stderr, "regextr.c: Invalid dac definition (%s)\n", w2);
  373.       exit(1);
  374.     }
  375.     *dac = new_dac;
  376.       } else
  377.       if ( is_res(w1,x1,y1,c1,&mnum1)) {
  378.         if (is_res(w2,x2,y2,c2,&mnum2) ) 
  379.       store_equ(&modes, x1,y1,c1,mnum1, x2,y2,c2);
  380.     else
  381.     if (strcmp(w2,"DISABLE_MODE") == 0) 
  382.       store_regs(&modes, x1,y1,c1,mnum1, DISABLE_MODE);
  383.       }
  384.     } else
  385.     if (strcmp(wp, "char") == 0) {
  386.       strcpy(w1, get_word(inp));
  387.       if (is_res(w1,x1,y1,c1,&mnum1)) {
  388.     unsigned char *regs;
  389.     int rv;
  390.  
  391.     rv = read_regs(inp, ®s);
  392.     if (rv == 0) continue;
  393.     if (regs_count>0 && rv != regs_count) {
  394.       fprintf(stderr, "regextr.c: Expected %d register values in %s, found %d\n",
  395.               regs_count, w1, rv);
  396.       exit(1);
  397.     }
  398.     regs_count = rv;
  399.     store_regs(&modes,x1,y1,c1,mnum1,regs);
  400.       }
  401.     }
  402.   }
  403.   /* resolve all equates */
  404.   do {
  405.     change = FALSE;
  406.     p = modes;
  407.     while (p != NULL) {
  408.       if (p->equ) {
  409.     q = modes;
  410.     cmp = (ModeList *)p->regs;
  411.     while (q != NULL) {
  412.       if (!q->equ              && 
  413.           !strcmp(q->x,cmp->x) &&
  414.           !strcmp(q->y,cmp->y) &&
  415.           !strcmp(q->c,cmp->c)    ) {
  416.         free(p->regs);
  417.         p->regs = q->regs;
  418.         p->equ  = FALSE;
  419.         change  = TRUE;
  420.         break;
  421.           }
  422.       q = q->nxt;
  423.     }
  424.       }
  425.       p = p->nxt;
  426.     }
  427.   } while (change);
  428.   /* Store modes from *mt */
  429.   if (*mt != NULL)
  430.     while ((*mt)->regs != NULL) {
  431.       __store_regs(&modes, (*mt)->mode_number, (*mt)->regs);
  432.       (*mt)++;
  433.     }
  434.   /* Check equates, count modes */
  435.   mode_cnt = 0;
  436.   p = modes;
  437.   while (p!=NULL) {
  438.     if (p->equ) {
  439.     fprintf(stderr, "regextr.c: Unresolved equate (%sx%sx%s)\n",p->x,p->y,p->c);
  440.     exit(1);
  441.     }
  442.     p = p->nxt;
  443.     ++mode_cnt;
  444.   }
  445.   ++mode_cnt;
  446.   /* Now generate the mode table */
  447.   *mt = (ModeTable *) Malloc(mode_cnt*sizeof(ModeTable));
  448.   i = 0;
  449.   p = modes;
  450.   while (p!=NULL) {
  451. #ifdef DEBUG
  452.     printf("Found mode %2d: %s\n",p->mnum,mode2name(p->x,p->y,p->c));
  453. #endif
  454.     (*mt)[i].mode_number = p->mnum;
  455.     (*mt)[i].regs        = p->regs;
  456.     q = p;
  457.     p = p->nxt;
  458.     free( q);
  459.     ++i;
  460.   }
  461.   (*mt)[i].mode_number = 0;
  462.   (*mt)[i].regs = NULL;
  463. }
  464.