home *** CD-ROM | disk | FTP | other *** search
- /*
- ** regextr.c - extract graphics modes and register information
- ** from C source file
- **
- ** This file is part of SVGALIB (C) 1993 by Tommy Frandsen and
- ** Harm Hanemaayer
- **
- ** Copyright (C) 1993 by Hartmut Schirmer
- **
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
- #include "vga.h"
- #include "libvga.h"
- #include "driver.h"
-
- #ifndef FALSE
- # define FALSE (1==0)
- #endif
- #ifndef TRUE
- # define TRUE (1==1)
- #endif
-
- #define WordLen 100
- typedef char WordStr[WordLen];
-
- typedef struct ML {
- WordStr x, y, c;
- int mnum;
- int equ;
- void *regs;
- struct ML *nxt;
- } ModeList;
-
- static void *Malloc(unsigned long bytes)
- {
- void *res;
-
- res = (void *) malloc(bytes);
- if (res == NULL) {
- fprintf(stderr, "regextr.c: Can't allocate memory\n");
- exit(1);
- }
- return res;
- }
-
- static void store_equ(ModeList **root, char *x1, char *y1, char *c1,
- int mnum, char *x2, char *y2, char *c2 )
- {
- ModeList *p;
-
- p = *root;
- while (p != NULL) {
- if ( strcmp(p->x, x1)==0
- && strcmp(p->y, y1)==0
- && strcmp(p->c, c1)==0 ) {
- fprintf(stderr, "regextr.c: Duplicate g%sx%sx%s_regs !\n",x1,y1,c1);
- exit(1);
- }
- p = p->nxt;
- }
- p = (ModeList *) Malloc(sizeof(ModeList));
- strcpy(p->x, x1);
- strcpy(p->y, y1);
- strcpy(p->c, c1);
- p->mnum= mnum;
- p->equ = TRUE;
- p->nxt = *root;
- *root = p;
- p = (ModeList *) Malloc(sizeof(ModeList));
- strcpy(p->x, x2);
- strcpy(p->y, y2);
- strcpy(p->c, c2);
- p->mnum= 0;
- p->equ = FALSE;
- p->regs= NULL;
- p->nxt = NULL;
- (*root)->regs = (void *)p;
- }
-
- static int check_new_mode(ModeList *p, char *x, char *y, char *c)
- {
- while (p != NULL) {
- if ( strcmp(p->x, x)==0
- && strcmp(p->y, y)==0
- && strcmp(p->c, c)==0 ) return FALSE;
- p = p->nxt;
- }
- return TRUE;
- }
-
- static void store_regs(ModeList **root, char *x, char *y, char *c, int mnum, char *r)
- {
- ModeList *p;
-
- if (!check_new_mode(*root, x, y, c)) {
- fprintf(stderr, "regextr.c: Duplicate g%sx%sx%s_regs !\n",x,y,c);
- exit(1);
- }
- p = (ModeList *) Malloc(sizeof(ModeList));
- strcpy(p->x, x);
- strcpy(p->y, y);
- strcpy(p->c, c);
- p->mnum = mnum;
- p->equ = FALSE;
- p->regs= (void *) r;
- p->nxt = *root;
- *root = p;
- }
-
-
- static void __store_regs(ModeList **root, int mnum, char *r)
- {
- WordStr x, y, c;
-
- sprintf( x, "%d", infotable[mnum].xdim);
- sprintf( y, "%d", infotable[mnum].ydim);
- switch (infotable[mnum].colors) {
- case 1<<15: strcpy( c, "32K"); break;
- case 1<<16: strcpy( c, "64K"); break;
- case 1<<24: strcpy( c, "16M"); break;
- default : sprintf( c, "%d", infotable[mnum].colors);
- }
- if (check_new_mode(*root, x, y, c))
- store_regs( root, x, y, c, mnum, r);
- }
-
-
- static char *mode2name(char *x, char *y, char *c)
- {
- static char mn[WordLen];
-
- sprintf(mn, "G%sx%sx%s", x, y, c);
- return mn;
- }
-
- /* -------------------------------------- Scanner --- */
- static int get_nextchar(FILE *inp)
- {
- int nch;
-
- nch = fgetc(inp);
- if (nch == '\\') {
- int nnch;
- nnch = fgetc(inp);
- if (nnch == '\n')
- return ' ';
- ungetc(nnch, inp);
- }
- if (isspace(nch)) return ' ';
- return nch;
- }
-
- static int next_ch = ' ';
-
- static int get_char(FILE *inp)
- {
- int ch;
-
- do {
- ch = next_ch;
- do
- next_ch = get_nextchar(inp);
- while (ch == ' ' && next_ch == ' ');
- if (ch != '/' || next_ch != '*')
- return ch;
- do {
- ch = next_ch;
- next_ch = get_nextchar(inp);
- } while (ch != EOF && !(ch == '*' && next_ch == '/'));
- next_ch = get_nextchar(inp);
- } while (1);
- }
-
- static char *get_word(FILE *inp)
- {
- int ch;
- static char buf[1000];
- char *p;
-
- do
- ch = get_char(inp);
- while (ch == ' ');
- p = buf;
- switch (ch) {
- case '[' :
- case ']' :
- case '{' :
- case '}' :
- case ',' :
- case ';' :
- case '=' :
- case '(' :
- case ')' : *(p++) = ch;
- *p = '\0';
- return buf;
- case EOF : buf[0] = '\0';
- return buf;
- }
- for (;;) {
- *(p++) = ch;
- switch (next_ch) {
- case EOF :
- case '[' :
- case ']' :
- case '{' :
- case '}' :
- case ',' :
- case ';' :
- case '=' :
- case '(' :
- case ')' :
- case ' ' : *p = '\0';
- return buf;
- }
- ch = get_char(inp);
- }
- }
-
- /* ----------------------------------------------- parser -- */
- static int is_res(char *rp, char *x, char *y, char *c, int *mnum)
- {
- char *p;
-
- if (*(rp++) != 'g') return FALSE;
- /* X resolution */
- p = x;
- if (!isdigit(*rp)) return FALSE;
- *(p++) = *(rp++);
- if (!isdigit(*rp)) return FALSE;
- *(p++) = *(rp++);
- if (!isdigit(*rp)) return FALSE;
- *(p++) = *(rp++);
- if (isdigit(*rp))
- *(p++) = *(rp++);
- if (*(rp++) != 'x') return FALSE;
- *p = '\0';
-
- /* Y resolution */
- p = y;
- if (!isdigit(*rp)) return FALSE;
- *(p++) = *(rp++);
- if (!isdigit(*rp)) return FALSE;
- *(p++) = *(rp++);
- if (!isdigit(*rp)) return FALSE;
- *(p++) = *(rp++);
- if (isdigit(*rp))
- *(p++) = *(rp++);
- if (*(rp++) != 'x') return FALSE;
- *p = '\0';
-
- /* colors */
- p = c;
- *(p++) = *rp;
- switch ( *(rp++) ) {
- case '1' : *(p++) = *rp;
- if (*(rp++) != '6') return FALSE;
- if (*rp == 'M')
- *(p++) = *(rp++);
- break;
- case '2' : if (*rp == '5' && *(rp+1) == '6') {
- *(p++) = *(rp++);
- *(p++) = *(rp++);
- }
- break;
- case '3' : if (*rp != '2') return FALSE;
- *(p++) = *(rp++);
- if (*rp != 'k' && *rp != 'K') return FALSE;
- *(p++) = 'K'; ++rp;
- break;
- case '6' : if (*rp != '4') return FALSE;
- *(p++) = *(rp++);
- if (*rp != 'k' && *rp != 'K') return FALSE;
- *(p++) = 'K'; ++rp;
- break;
- default : return FALSE;
- }
- *p = '\0';
- *mnum = __vga_name2number(mode2name(x,y,c));
- if (*mnum < 0) {
- int cols = 0;
- int xbytes = 0;
-
- if (strcmp("16M", c) == 0) { cols = 1<<24; xbytes = atoi(x)*3; } else
- if (strcmp("32K", c) == 0) { cols = 1<<15; xbytes = atoi(x)*2; } else
- if (strcmp("64K", c) == 0) { cols = 1<<16; xbytes = atoi(x)*2; } else
- if (strcmp("256", c) == 0) { cols = 256; xbytes = atoi(x); } else
- if (strcmp("16", c) == 0) { cols = 16; xbytes = atoi(x)/4; } else
- return FALSE;
- *mnum = __vga_addmode(atoi(x),atoi(y),cols, xbytes, xbytes / atoi(x));
- }
- return (*mnum > TEXT && *mnum != GPLANE16);
- }
-
- static int read_regs(FILE *inp, unsigned char **regs)
- {
- unsigned char r[MAX_REGS];
- char *w;
- int c;
- unsigned u;
-
- if (strcmp("[",get_word(inp)) != 0) return 0;
- if (strcmp("]",get_word(inp)) !=0)
- if (strcmp("]",get_word(inp)) != 0) return 0;
- if (strcmp("=",get_word(inp)) != 0) return 0;
- if (strcmp("{",get_word(inp)) != 0) return 0;
-
- c = 0;
- do {
- w = get_word(inp);
- if (strcmp(w,"}") == 0)
- continue;
- if (sscanf(w, "%x", &u) == EOF)
- if (sscanf(w, "%u", &u) == EOF) {
- fprintf(stderr, "regextr.c: Invalid register value %s\n", w);
- exit(1);
- }
- r[c++] = u;
- w = get_word(inp);
- } while (strcmp(",",w) == 0);
- *regs = (char *)Malloc(c);
- memcpy(*regs,r,c);
- return c;
- }
-
-
- void __vga_readmodes(FILE *inp, ModeTable **mt, int *dac, unsigned *clocks)
- {
- WordStr x1, y1, c1, x2, y2, c2;
- WordStr w1, w2;
- int mnum1, mnum2;
- ModeList *modes = NULL;
- ModeList *p, *q, *cmp;
- int regs_count = -1;
- int change;
- int mode_cnt, i;
-
- /* read the register information from file */
- while (!feof(inp)) {
- char *wp;
-
- wp = get_word(inp);
- if (strcmp(wp, "#define") == 0) {
- strcpy(w1, get_word(inp));
- strcpy(w2, get_word(inp));
- if (clocks != NULL && strcmp(w1,"CLOCK_VALUES") == 0) {
- unsigned freq;
-
- if (strcmp(w2, "{") == 0) {
- do {
- strcpy(w2, get_word(inp));
- if (sscanf(w2, "%u", &freq) == EOF)
- if (sscanf(w2, "%x", &freq) == EOF) {
- fprintf(stderr, "regextr.c: Invalid clock definition (%s)\n", w2);
- exit(1);
- }
- *(clocks++) = freq;
- strcpy(w1, get_word(inp));
- } while (strcmp(",", w1) == 0);
- clocks = NULL;
- }
- } else
- if (dac != NULL && strcmp(w1,"DAC_TYPE") == 0) {
- int new_dac;
-
- if (sscanf(w2, "%d", &new_dac) == EOF)
- if (sscanf(w2, "%x", &new_dac) == EOF) {
- fprintf(stderr, "regextr.c: Invalid dac definition (%s)\n", w2);
- exit(1);
- }
- *dac = new_dac;
- } else
- if ( is_res(w1,x1,y1,c1,&mnum1)) {
- if (is_res(w2,x2,y2,c2,&mnum2) )
- store_equ(&modes, x1,y1,c1,mnum1, x2,y2,c2);
- else
- if (strcmp(w2,"DISABLE_MODE") == 0)
- store_regs(&modes, x1,y1,c1,mnum1, DISABLE_MODE);
- }
- } else
- if (strcmp(wp, "char") == 0) {
- strcpy(w1, get_word(inp));
- if (is_res(w1,x1,y1,c1,&mnum1)) {
- unsigned char *regs;
- int rv;
-
- rv = read_regs(inp, ®s);
- if (rv == 0) continue;
- if (regs_count>0 && rv != regs_count) {
- fprintf(stderr, "regextr.c: Expected %d register values in %s, found %d\n",
- regs_count, w1, rv);
- exit(1);
- }
- regs_count = rv;
- store_regs(&modes,x1,y1,c1,mnum1,regs);
- }
- }
- }
- /* resolve all equates */
- do {
- change = FALSE;
- p = modes;
- while (p != NULL) {
- if (p->equ) {
- q = modes;
- cmp = (ModeList *)p->regs;
- while (q != NULL) {
- if (!q->equ &&
- !strcmp(q->x,cmp->x) &&
- !strcmp(q->y,cmp->y) &&
- !strcmp(q->c,cmp->c) ) {
- free(p->regs);
- p->regs = q->regs;
- p->equ = FALSE;
- change = TRUE;
- break;
- }
- q = q->nxt;
- }
- }
- p = p->nxt;
- }
- } while (change);
- /* Store modes from *mt */
- if (*mt != NULL)
- while ((*mt)->regs != NULL) {
- __store_regs(&modes, (*mt)->mode_number, (*mt)->regs);
- (*mt)++;
- }
- /* Check equates, count modes */
- mode_cnt = 0;
- p = modes;
- while (p!=NULL) {
- if (p->equ) {
- fprintf(stderr, "regextr.c: Unresolved equate (%sx%sx%s)\n",p->x,p->y,p->c);
- exit(1);
- }
- p = p->nxt;
- ++mode_cnt;
- }
- ++mode_cnt;
- /* Now generate the mode table */
- *mt = (ModeTable *) Malloc(mode_cnt*sizeof(ModeTable));
- i = 0;
- p = modes;
- while (p!=NULL) {
- #ifdef DEBUG
- printf("Found mode %2d: %s\n",p->mnum,mode2name(p->x,p->y,p->c));
- #endif
- (*mt)[i].mode_number = p->mnum;
- (*mt)[i].regs = p->regs;
- q = p;
- p = p->nxt;
- free( q);
- ++i;
- }
- (*mt)[i].mode_number = 0;
- (*mt)[i].regs = NULL;
- }
-