home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fujiology Archive
/
fujiology_archive_v1_0.iso
/
!FALCON
/
!BONUS
/
UTILITY
/
FS.ZIP
/
FALCSCR5
/
FS.C
next >
Wrap
C/C++ Source or Header
|
1997-06-16
|
19KB
|
533 lines
/************************************************************************/
/* */
/* FalconScreen */
/* ============ */
/* */
/* Copyright 1993 by Markus Gutschke. */
/* This program is postcardware. You are encouraged to distribute it */
/* freely as long as you do not charge anybody for it, but if you keep */
/* a copy, you have to send me a postcard: */
/* Markus Gutschke */
/* Papenbusch 31 */
/* 4400 M"unster */
/* W-Germany */
/* Note! This program may not be distributed with so-called PD- */
/* collections or on cover-disks! */
/* If you encounter any bugs (there are probably a lot!), have comments */
/* or suggestions or just found some useful settings for the video */
/* registers, please send e-mail to: */
/* srb242@math.uni-muenster.de */
/* or: Markus.Gutschke@uni-muenster.de */
/* */
/* The current version of this program will only affect the 640x480x1bit*/
/* mode (if "MONO" is defined) and the 640x480x4bit mode (TT-MEDIUM) on */
/* an SVGA monitor. It will replace one of these modes with a user */
/* selectable higher resolution. Currently 832x624 (for mono) and */
/* 928x704 (for 16 colors) are the highest possible settings. */
/* */
/* This program relies on several undocumented features of the */
/* Falcon030, thus I am unable to guarantee, that it will work on any */
/* computer other than my own. This program will most certainly damage */
/* any monitor, that does not support SVGA video modes! Even SVGA */
/* monitors might be damaged/destroyed, since this program is pushing */
/* the signal timing very hard. If you feel at all uncomfortable with */
/* the possibility of damaging your hardware, do not run this program! */
/* */
/* Since I am releasing this program free of charge, I am unable to */
/* give any support or guarantee for this program! */
/* */
/* This program will compile with TurboC and PureC. You will probably */
/* have to make changes, if you want to compile it with any other */
/* system. If you added conditional preprocessor directives that allow */
/* you to compile this program both with TC/PC and with your system */
/* please let me know. */
/* The assembler interface relies on the TC/PC parameter passing scheme.*/
/* Scalar values will be passed in D0 through D2, addresses will be */
/* passed in A0 and A1; all parameters that cannot be passed by */
/* registers, will be passed on the stack. Return values will be either */
/* in D0 (scalar values) or in A0 (pointers). D3-D7/A2-A7 remain */
/* unaffected throughout a function call. */
/* */
/************************************************************************/
#define BETA /* This is a beta release of FS */
#define MONO /* Add experimental code for mono- */
/* chrome mode! */
#undef OLDVALUES /* Use improved parameter sets! */
#define PRGNAME "FS.PRG" /* Program name for patching params.*/
#define ID '\344FSC' /* XBRA Id */
#define MINN 1 /* min-/maximum legal values for N */
#define MAXN ((int)(sizeof(table)/sizeof(struct TABLE)-1))
/* Several negative LineA variables need patching */
#define VGemX (((int *)linea)[-0x015A])
#define VGemY (((int *)linea)[-0x0159])
#define VCelHT (((int *)linea)[-0x0017])
#define VCelMX (((int *)linea)[-0x0016])
#define VCelMY (((int *)linea)[-0x0015])
#define VCelWR (((int *)linea)[-0x0014])
#define VXMax (((int *)linea)[-0x0006])
#define VYMax (((int *)linea)[-0x0002])
#define VBytesLin (((int *)linea)[-0x0001])
#define VPlanes (((int *)linea)[ 0x0000])
#define VWrap (((int *)linea)[ 0x0001])
/* List of undocumented video registers (c.f. VIDEO.PRG) */
#define RShift (*(int *)0xFFFF8260l)
#define RSpShift (*(int *)0xFFFF8266l)
#define RWrap (*(int *)0xFFFF8210l)
#define RCO (*(int *)0xFFFF82C0l)
#define RMode (*(int *)0xFFFF82C2l)
#define RHHT (*(int *)0xFFFF8282l)
#define RHBB (*(int *)0xFFFF8284l)
#define RHBE (*(int *)0xFFFF8286l)
#define RHDB (*(int *)0xFFFF8288l)
#define RHDE (*(int *)0xFFFF828Al)
#define RHSS (*(int *)0xFFFF828Cl)
#define RHFS (*(int *)0xFFFF828El)
#define RHEE (*(int *)0xFFFF8290l)
#define RVFT (*(int *)0xFFFF82A2l)
#define RVBB (*(int *)0xFFFF82A4l)
#define RVBE (*(int *)0xFFFF82A6l)
#define RVDB (*(int *)0xFFFF82A8l)
#define RVDE (*(int *)0xFFFF82AAl)
#define RVSS (*(int *)0xFFFF82ACl)
/* Bindings for system calls are provided by the assembler modul */
void *LineA0(void);
int Kbshift(int);
void *Physbase(void);
void Setscreen(void *,void *,int,int);
int Vsetmode(int);
int Montype(void);
void VsetRGB(int,int,long *);
void VgetRGB(int,int,long *);
void Pterm0(void);
int Cnecin(void);
void Cconws(char *);
int Cconis(void);
void *Srealloc(unsigned long);
long Super(void *);
int Fopen(char *,int);
void Fclose(int);
long Fread(int,long,void *);
long Fwrite(int,long,void *);
long Fseek(long,int,int);
void *Malloc(long amount);
void Mfree(void *addr);
/* Copyright message */
void showlogo(int x,int y,unsigned short *scr,
int width,int height,int planes);
void hidelogo(void);
static char copyright[] =
"\x1BpFalconScreen (c) 1993 by M. Gutschke\x1Bq\r\n"
"This program is postcardware!\r\n"
"If you like it, send a postcard to:\r\n"
" Markus Gutschke\r\n"
" Papenbusch 31\r\n"
" 4400 M\x81nster\r\n"
" W-Germany\r\n"
#ifdef BETA
"Warning! This is a beta-Release!\r\n"
#endif
"This program might damage your F030\r\n"
"and/or your monitor!\r\n";
/* Preset values */
struct settings { /* This preinitialized structure */
long magic; /* can be patched by the program! */
int size;
int mask; /* It contains the user's prefered */
int value; /* resolution. */
int planes;
int n;
int width,height;
} settings = {ID,(int)sizeof(struct settings),0,0,0,MINN-1,0,0};
/* Precomputed parameter sets: */
static struct TABLE {
int width,height,frq,planes;
int Shift,SpShift,Wrap,CO,Mode,HHT,HBB,HBE,HDB;
int HDE,HSS,HFS,HEE,VFT,VBB,VBE,VDB,VDE,VSS,mask,value;
} table[] = {
#ifdef MONO
640,480,80, 1,0,0x400, 40,0x182,8,0x0c6,0x8d,0x15,0x273,0x50,0x96,0,0,
0x3e7,0x3e3,0x23,0x23,0x3eb,0x3e4,0x18F,0x008,
672,512,72, 1,0,0x400, 42,0x182,8,0x0ce,0x8d,0x0d,0x273,0x50,0x96,0,0,
0x427,0x423,0x23,0x23,0x42b,0x424,0x18F,0x008,
704,528,67, 1,0,0x400, 44,0x182,8,0x0d6,0x8d,0x05,0x273,0x50,0x96,0,0,
0x447,0x443,0x23,0x23,0x44b,0x444,0x18F,0x008,
736,560,59, 1,0,0x400, 46,0x182,8,0x0e6,0x8d,0x05,0x283,0x50,0x96,0,0,
0x487,0x483,0x23,0x23,0x48b,0x484,0x18F,0x008,
768,576,54, 1,0,0x400, 48,0x182,8,0x0f6,0x8d,0x05,0x293,0x50,0x96,0,0,
0x4a7,0x4a3,0x23,0x23,0x4ab,0x4a4,0x18F,0x008,
800,608,48, 1,0,0x400, 50,0x182,8,0x106,0x8d,0x05,0x2a3,0x50,0x96,0,0,
0x4e7,0x4e3,0x23,0x23,0x4eb,0x4e4,0x18F,0x008,
832,624,44, 1,0,0x400, 52,0x182,8,0x116,0x8d,0x05,0x2b3,0x50,0x96,0,0,
0x507,0x503,0x23,0x23,0x50b,0x504,0x18F,0x008,
#endif
#if 0
640,480,78, 2,1,0x000, 80,0x182,8,0x017,0x12,0x01,0x20e,0x0d,0x11,0,0,
0x3e7,0x3e3,0x23,0x23,0x3eb,0x3e4,0x18F,0x009,
#endif
640,480,62, 4,0,0x000,160,0x186,8,0x0c6,0x8d,0x15,0x2a3,0x7c,0x96,0,0,
0x3e7,0x3e3,0x23,0x23,0x3eb,0x3e4,0x18F,0x00A,
672,512,72, 4,0,0x000,168,0x182,8,0x0ce,0x8d,0x0d,0x2a3,0x7c,0x96,0,0,
0x427,0x423,0x23,0x23,0x42b,0x424,0x18F,0x00A,
704,528,67, 4,0,0x000,176,0x182,8,0x0d6,0x8d,0x05,0x2a3,0x7c,0x96,0,0,
0x447,0x443,0x23,0x23,0x44b,0x444,0x18F,0x00A,
#ifdef OLDVALUES
736,560,58, 4,0,0x000,184,0x182,8,0x0ea,0xa2,0x1e,0x2d0,0x91,0xb8,0,0,
0x487,0x483,0x23,0x23,0x48b,0x484,0x18F,0x00A,
768,576,55, 4,0,0x000,192,0x182,8,0x0f2,0xa2,0x16,0x2d0,0x91,0xb8,0,0,
0x4a7,0x4a3,0x23,0x23,0x4ab,0x4a4,0x18F,0x00A,
800,608,50, 4,0,0x000,200,0x182,8,0x0fa,0xa2,0x0e,0x2d0,0x91,0xb8,0,0,
0x4e7,0x4e3,0x23,0x23,0x4eb,0x4e4,0x18F,0x00A,
832,624,48, 4,0,0x000,208,0x182,8,0x102,0xa2,0x06,0x2d0,0x91,0xb8,0,0,
0x507,0x503,0x23,0x23,0x50b,0x504,0x18F,0x00A
#else
/* Harald, thank you for finding these improved values! */
736,560,61, 4,0,0x000,184,0x182,8,0x0df,0xb8,0x29,0x2d0,0xa8,0xb7,0,0,
0x487,0x483,0x23,0x23,0x48b,0x484,0x18F,0x00A,
768,576,57, 4,0,0x000,192,0x182,8,0x0e7,0xb8,0x21,0x2d0,0xa8,0xb7,0,0,
0x4a7,0x4a3,0x23,0x23,0x4ab,0x4a4,0x18F,0x00A,
800,608,52, 4,0,0x000,200,0x182,8,0x0ef,0xb8,0x19,0x2d0,0xa8,0xb7,0,0,
0x4e7,0x4e3,0x23,0x23,0x4eb,0x4e4,0x18F,0x00A,
832,624,50, 4,0,0x000,208,0x182,8,0x0f7,0xb8,0x11,0x2d0,0xa8,0xb7,0,0,
0x507,0x503,0x23,0x23,0x50b,0x504,0x18F,0x00A,
864,656,46, 4,0,0x000,216,0x182,8,0x0ff,0xb8,0x09,0x2d0,0xa8,0xb7,0,0,
0x547,0x543,0x23,0x23,0x54b,0x544,0x18F,0x00A,
896,672,45, 4,0,0x000,224,0x182,8,0x0ff,0xb8,0x01,0x2d0,0xa8,0xb7,0,0,
0x567,0x563,0x23,0x23,0x56b,0x564,0x18F,0x00A,
928,704,40, 4,0,0x000,232,0x182,8,0x10f,0xb8,0x01,0x2e0,0xa8,0xb7,0,0,
0x5a7,0x5a3,0x23,0x23,0x5ab,0x5a4,0x18F,0x00A
#endif
};
/* Convert a number to a string without exceeding the string size */
static char *tonum(int i,char *s,int *n)
{
/* recursion is needed to output digits in the right order! */
if (i > 10) s = tonum(i/10,s,n);
if (*n > 1) {
(*n)--;
*s++ = i%10+'0'; }
*s = '\000';
return(s);
}
/* Create a string that describes a screen resolution */
static void makeresstr(int w,int h,int p,int f,char *s,int n)
{
char *ptr1 = "bit (";
char *ptr2 = "Hz) ";
/* -> "NNNxNNNxNbit (NNHz) " */
s = tonum(w,s,&n);
if (n <= 1) goto eos; else { n--; *s++ = 'x'; }
s = tonum(h,s,&n);
if (n <= 1) goto eos; else { n--; *s++ = 'x'; }
s = tonum(p,s,&n);
while (*ptr1 && n-- > 1)
*s++ = *ptr1++;
if (n <= 1) goto eos;
s = tonum(f,s,&n);
while (*ptr2 && n-- > 1)
*s++ = *ptr2++;
eos:
*s ='\000';
return;
}
/* Initialize video registers */
static void setvideo(void)
{
/* RShift = table[settings.n].Shift; */ /***/
/* RSpShift = table[settings.n].SpShift; */ /***/
RWrap = table[settings.n].Wrap;
RCO = table[settings.n].CO;
/* RMode = table[settings.n].Mode; */ /***/
RHHT = table[settings.n].HHT;
RHBB = table[settings.n].HBB;
RHBE = table[settings.n].HBE;
RHDB = table[settings.n].HDB;
RHDE = table[settings.n].HDE;
RHSS = table[settings.n].HSS;
RHFS = table[settings.n].HFS;
RHEE = table[settings.n].HEE;
RVFT = table[settings.n].VFT;
RVBB = table[settings.n].VBB;
RVBE = table[settings.n].VBE;
RVDB = table[settings.n].VDB;
RVDE = table[settings.n].VDE;
RVSS = table[settings.n].VSS;
return;
}
/* Patch (negative) line-A variables */
static void patchos(void)
{
void *linea = LineA0();
VPlanes = settings.planes; /* Patch a couple of LineA variables*/
VWrap = (settings.width>>3)*settings.planes;
VGemX = settings.width-1; /* VGemX and VGemY are undocumented!*/
VGemY = settings.height-1;
VCelMX = (settings.width>>3)-1;
VCelMY = settings.height/VCelHT-1;
VCelWR = (settings.width>>3)*settings.planes*VCelHT;
VXMax = settings.width;
VYMax = settings.height;
VBytesLin = (settings.width>>3)*settings.planes;
return;
}
/* Reallocate new screen memory */
static void realloc(void)
{
long scrsize,hz200;
void *scraddr;
scrsize = ((long)settings.width*(long)settings.height*
(long)settings.planes)>>3;
scraddr = Srealloc(scrsize); /* Reallocate screen memory */
Setscreen(scraddr,scraddr,-1,-1);/* Set new screen address */
showlogo(48,48,scraddr,settings.width,settings.height,settings.planes);
for (hz200 = *(long *)0x4BA+130;/* wait 0.65 seconds */
*(long *)0x4BA < hz200;);
hidelogo();
return;
}
/* Initialize a new video mode */
void init(int dorealloc)
{
Cconws("\x1B""H");
patchos();
setvideo();
if (dorealloc)
realloc();
Cconws("\x1B""E");
return;
}
/* Handle extended setscreen modes */
long setscreen(long rc,void *log,void *phys,int rez,int mode)
{
if (rez == 3 && (mode & settings.mask) == settings.value)
init(!log && !phys);
return(rc);
}
/* Replace 640x480x4bit with new video mode */
long vsetmode(long rc,int mode)
{
if ((mode & settings.mask) == settings.value)
init(0);
return(rc);
}
/* Return new screen size */
long vgetsize(long rc,int mode)
{
if ((mode & settings.mask) == settings.value)
return(((long)settings.width*(long)settings.height*
(long)settings.planes)>>3);
return(rc);
}
/* Get/set an entry from the system cookie jar */
static long docookie(long cookie,long value)
{
long stack;
long *cookiejar;
stack = Super(0l);
cookiejar = *(long **)0x5a0;
if (cookiejar) {
while (*cookiejar && *cookiejar != cookie) cookiejar += 2;
if (*cookiejar == 0 && value != 0 &&
cookiejar - *(long **)0x5a0 < 2*cookiejar[1]) {
cookiejar[3] = cookiejar[1];
cookiejar[2] = 0;
cookiejar[1] = value;
cookiejar[0] = cookie; } }
Super((void *)stack);
return (cookiejar && *cookiejar == cookie ? cookiejar[1] : 0);
}
/* Change preferences */
static void setup(void)
{
char s[22];
int handle,oldn,mode,oldmode,frq;
long scrsize,offset,stack;
unsigned long hz200,vbl;
void *oldscr,*newscr;
struct {long magic;int size;} header;
while (Cconis()) Cnecin();
if (settings.n < MINN || settings.n > MAXN)
settings.n = MINN-1; /* FS is inactive */
Cconws("Press <SHIFT> for testing!\r\n");
oldn = settings.n;
for (;;) {
Cconws("\x1BY\x2C Current resolution: ");
settings.width = table[settings.n].width;
settings.height= table[settings.n].height;
settings.mask = table[settings.n].mask;
settings.value = table[settings.n].value;
settings.planes= table[settings.n].planes;
makeresstr(settings.width,settings.height,
settings.planes,table[settings.n].frq,s,21);
Cconws(s);
Cconws("(+/-)");
scrsize = ((long)settings.width*(long)settings.height*
(long)settings.planes)>>3;
newscr = Malloc(scrsize);
oldscr = Physbase();
for (mode = oldmode = Vsetmode(-1);!Cconis() || !mode;)
if ((Kbshift(-1) & 3) && !Cconis()) {
if (mode && newscr) {
mode = 0;
Setscreen(newscr,newscr,3,0x0010|settings.value);
stack = Super(0L);
setvideo();
showlogo(48,48,newscr,settings.width,
settings.height,settings.planes);
/* measure refresh rate, while user */
/* views the screen */
vbl = *(unsigned long *)0x462;
hz200 = *(unsigned long *)0x4ba;
Super((void *)stack); } }
else
if (!mode) {
stack = Super(0L);
hz200 = *(unsigned long *)0x4ba - hz200;
vbl = *(unsigned long *)0x462 - vbl;
Super((void *)stack);
/* calculate "real" refresh rate */
frq = (int)((vbl*2000L+5)/hz200)/10;
mode = oldmode;
hidelogo();
Setscreen(newscr,newscr,3,oldmode);
Setscreen(oldscr,oldscr,-1,-1);
/* check for plausibility */
if ((frq - table[settings.n].frq) > -20 &&
(frq - table[settings.n].frq) < 20 &&
vbl > 20) {
table[settings.n].frq = frq;
makeresstr(settings.width,settings.height,
settings.planes,frq,s,21);
Cconws("\x1BY\x2C Current resolution: ");
Cconws(s);
Cconws("(+/-)"); } }
Mfree(newscr);
switch ((char)Cnecin()) { /* In/decrease resolution */
case '+':
if (settings.n < MAXN) settings.n++;
break;
case '-':
if (settings.n >= MINN) settings.n--;
break;
default:
goto eol; } }
eol: /* Patch the executeable file */
Cconws("\x1BY\x2C \x1BK");
if (oldn != settings.n) {
Cconws("S(ave settings, C(ontinue...\r\n");
if (((char)Cnecin() & 0xDF) == 'S') {
if ((handle = (int)Fopen(PRGNAME,2)) < 0 &&
(handle = (int)Fopen("AUTO\\"PRGNAME,2)) < 0) {
Cconws("Cannot open FS.PRG!\r\n");
Cnecin();
goto ferr; }
Fseek(0x1E,handle,0); /* Find patch area and check for */
Fread(handle,4,&offset);/* magic first! */
Fseek(0x1C+offset,handle,0);
Fread(handle,6,&header);
if (header.magic != ID || header.size != sizeof(settings)) {
Cconws("Illegal file format!\r\n");
Cnecin(); }
else if (Fwrite(handle,sizeof(settings)-6,
((char *)&settings)+6) != sizeof(settings)-6) {
Cconws("Could not write to FS.PRG!\r\n");
Cnecin(); }
Fclose(handle); } }
ferr:
return;
}
/* Main program: check video hardware and allow change of preferences */
int main(void)
{
int rc = 0;
struct settings *ptr;
if ((ptr = (struct settings *)docookie(ID,0)) != 0) {
Cconws("\x1B""E");
Cconws(copyright);
Cconws("FalconScreen is already installed...\r\n");
if (ptr->size == settings.size) {
settings = *ptr;
setup();
*ptr = settings; }
Pterm0(); }
if (docookie('_VDO',0) != 0x00030000L || Montype() != 2) {
Cconws(copyright);
Cconws("\x1BpYou need a Falcon030 & SVGA-monitor \x1Bq\x07"
"\r\n\r\n");
Pterm0(); }
settings.width = table[settings.n].width;
settings.height= table[settings.n].height;
settings.mask = table[settings.n].mask;
settings.value = table[settings.n].value;
settings.planes= table[settings.n].planes;
if ((Cconis() && (Cnecin() & 0xDF) == 'S') ||
settings.n < MINN || settings.n > MAXN) {
Cconws("\x1B""E");
Cconws(copyright);
Cconws("Press 'S' for setup...\r\n");
setup(); }
else {
Cconws(copyright);
Cconws("Press 'S' for setup...\r\n"); }
Cconws("\r\n");
if (settings.n < MINN || settings.n > MAXN ||
table[settings.n].planes != table[settings.n-1].planes)
Pterm0();
if ((Vsetmode(-1) & settings.mask) == settings.value) {
if (docookie('MiNT',0)) {
Cconws("You cannot replace your boot resolution\r\n"
"when running MiNT! Either choose a different\r\n"
"initial boot resolution (BOOTCONF.PRG) or\r\n"
"start FS before starting MiNT!\r\n");
Pterm0(); }
rc = 1; }
docookie(ID,(long)&settings);
return(rc);
}