254 lines
5 KiB
C
254 lines
5 KiB
C
|
|
||
|
/*
|
||
|
* This is a quickly hacked program to convert an SVPMI (Super VGA Protected
|
||
|
* Mode Interface) data file to an svgalib driver. Feedback is
|
||
|
* very welcome.
|
||
|
*
|
||
|
* Initial version (Mar 94 HH). Doesn't do much yet.
|
||
|
* Assumes textmode is last defined mode.
|
||
|
* End with ctrl-c. Correct resulting files by hand.
|
||
|
* (add "}" to modetable.svpmi)
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
|
||
|
void parse ();
|
||
|
|
||
|
|
||
|
void
|
||
|
main ()
|
||
|
{
|
||
|
parse ();
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Return pointer to line red from stdin, end marked by CR or CR/LF.
|
||
|
* Initial spaces are removed. */
|
||
|
|
||
|
char *
|
||
|
getline ()
|
||
|
{
|
||
|
static char linebuf[128];
|
||
|
int i, length, spaces;
|
||
|
i = 0;
|
||
|
for (;;)
|
||
|
{
|
||
|
int c;
|
||
|
c = fgetc (stdin);
|
||
|
if (feof (stdin))
|
||
|
return NULL;
|
||
|
if (c == 13)
|
||
|
continue; /* Skip. */
|
||
|
if (c == 10)
|
||
|
break;
|
||
|
linebuf[i] = c;
|
||
|
i++;
|
||
|
}
|
||
|
length = i;
|
||
|
linebuf[i] = 0;
|
||
|
/* Remove initial spaces. */
|
||
|
spaces = 0;
|
||
|
i = 0;
|
||
|
while (i < length)
|
||
|
{
|
||
|
if (linebuf[i] != ' ')
|
||
|
break;
|
||
|
i++;
|
||
|
spaces++;
|
||
|
}
|
||
|
return linebuf + spaces;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Skip lines until left side of line matches string s. */
|
||
|
|
||
|
char *
|
||
|
getthisline (char *s)
|
||
|
{
|
||
|
char buf[128];
|
||
|
int n;
|
||
|
n = strlen (s);
|
||
|
for (;;)
|
||
|
{
|
||
|
char *line;
|
||
|
line = getline ();
|
||
|
if (strncmp (line, s, n) == 0)
|
||
|
return line;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Get the (n + 1)th word delimited by ' ' and ';' in string s. */
|
||
|
|
||
|
char *
|
||
|
getword (char *s, int n)
|
||
|
{
|
||
|
int i;
|
||
|
char *word;
|
||
|
int mode, wcount;
|
||
|
word = s;
|
||
|
mode = 0; /* Whitespace. */
|
||
|
wcount = 0;
|
||
|
i = 0;
|
||
|
for (i = 0; s[i] != 0; i++)
|
||
|
{
|
||
|
if (s[i] == ' ' || s[i] == ';')
|
||
|
if (mode == 0)
|
||
|
continue;
|
||
|
else
|
||
|
{
|
||
|
s[i] = 0;
|
||
|
if (wcount == n)
|
||
|
return word;
|
||
|
wcount++;
|
||
|
mode = 0;
|
||
|
}
|
||
|
else if (mode == 1)
|
||
|
continue;
|
||
|
else
|
||
|
{
|
||
|
word = &s[i];
|
||
|
mode = 1;
|
||
|
}
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Write lines to file until left part matches string s. */
|
||
|
|
||
|
void
|
||
|
writetofileuntilthisline (char *s, FILE * f)
|
||
|
{
|
||
|
int n;
|
||
|
n = strlen (s);
|
||
|
for (;;)
|
||
|
{
|
||
|
char *line;
|
||
|
line = getline ();
|
||
|
if (strncmp (line, s, n) == 0)
|
||
|
break;
|
||
|
fprintf (f, "%s\n", line);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
writetofileuntilend (FILE * f)
|
||
|
{
|
||
|
for (;;)
|
||
|
{
|
||
|
char *line;
|
||
|
line = getline ();
|
||
|
if (line == NULL)
|
||
|
return;
|
||
|
fprintf (f, "%s\n", line);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
parse ()
|
||
|
{
|
||
|
char *line;
|
||
|
char s[128];
|
||
|
char modename[40];
|
||
|
int modenumber;
|
||
|
FILE *f, *g;
|
||
|
printf ("SVPMI to svgalib driver converter.\n\n");
|
||
|
|
||
|
/* Read header. */
|
||
|
getthisline ("[ADAPTER]");
|
||
|
line = getline ();
|
||
|
printf ("Graphics Adapter string: %s\n", line);
|
||
|
|
||
|
/* Read modes. */
|
||
|
modenumber = 0;
|
||
|
g = fopen ("modetable.svpmi", "wb");
|
||
|
f = fopen ("modes.svpmi", "wb");
|
||
|
fprintf (g, "/* svgalib SVPMI mode table. */\n\n");
|
||
|
fprintf (g, "static svpmi_modeentry svpmi_modes[] = {\n");
|
||
|
|
||
|
for (;;)
|
||
|
{
|
||
|
int XResolution; /* SVPMI modeinfo fields. */
|
||
|
int YResolution;
|
||
|
int BitsPerPixel;
|
||
|
int BytesPerScanline;
|
||
|
int WinAGranularity;
|
||
|
int WinASize;
|
||
|
int WinABase;
|
||
|
int ModeAttributes;
|
||
|
getthisline ("[MODEINFO]");
|
||
|
line = getthisline ("ModeAttributes");
|
||
|
ModeAttributes = atoi (getword (line, 2));
|
||
|
line = getthisline ("WinAGranularity");
|
||
|
WinAGranularity = atoi (getword (line, 2));
|
||
|
line = getthisline ("WinASize");
|
||
|
WinASize = atoi (getword (line, 2));
|
||
|
line = getthisline ("WinABase");
|
||
|
WinABase = atoi (getword (line, 2));
|
||
|
#if 0
|
||
|
if (WinABase != 0xa0000)
|
||
|
{
|
||
|
printf ("Window is not at 0xa0000.\n");
|
||
|
exit (-1);
|
||
|
}
|
||
|
#endif
|
||
|
line = getthisline ("BytesPerScanline");
|
||
|
BytesPerScanline = atoi (getword (line, 2));
|
||
|
line = getthisline ("XResolution");
|
||
|
XResolution = atoi (getword (line, 2));
|
||
|
line = getthisline ("YResolution");
|
||
|
YResolution = atoi (getword (line, 2));
|
||
|
line = getthisline ("BitsPerPixel");
|
||
|
BitsPerPixel = atoi (getword (line, 2));
|
||
|
|
||
|
if (ModeAttributes == 0x07)
|
||
|
{
|
||
|
/* Text mode. */
|
||
|
printf ("Textmode found.\n");
|
||
|
getthisline ("[SETMODE]");
|
||
|
fprintf (f, "static void svpmi_setmode_text() {\n");
|
||
|
writetofileuntilend (f);
|
||
|
fprintf (f, "}\n\n\n");
|
||
|
fprintf (g, "}\n");
|
||
|
fclose (f);
|
||
|
fclose (g);
|
||
|
exit (0);
|
||
|
}
|
||
|
|
||
|
printf ("Mode found: %d x %d, %dbpp %d bpl gran A %d\n",
|
||
|
XResolution, YResolution, BitsPerPixel,
|
||
|
BytesPerScanline, WinAGranularity);
|
||
|
|
||
|
sprintf (modename, "%dx%dx%d", XResolution, YResolution,
|
||
|
1 << BitsPerPixel);
|
||
|
|
||
|
getthisline ("[SETMODE]");
|
||
|
fprintf (f, "static void svpmi_setmode_%s() {\n", modename);
|
||
|
writetofileuntilthisline ("[SETCOLOR]", f);
|
||
|
fprintf (f, "}\n\n\n");
|
||
|
getthisline ("[SETWINDOW]");
|
||
|
fprintf (f, "static void svpmi_setwindow_%s( int r0 ) {\n", modename);
|
||
|
writetofileuntilthisline ("[MODE]", f);
|
||
|
fprintf (f, "}\n\n\n");
|
||
|
|
||
|
fprintf (g, "{ %d, %d, %d, %d, %d, svpmi_setmode_%s, svpmi_setwindow_%s },\n",
|
||
|
XResolution, YResolution, BitsPerPixel,
|
||
|
BytesPerScanline, WinAGranularity, modename, modename);
|
||
|
|
||
|
fflush (f);
|
||
|
fflush (g);
|
||
|
|
||
|
modenumber++;
|
||
|
}
|
||
|
fprintf (g, "}\n");
|
||
|
fclose (f);
|
||
|
fclose (g);
|
||
|
}
|