home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / falcon / utility / fs2 / fs.c next >
C/C++ Source or Header  |  1993-05-10  |  17KB  |  499 lines

  1. /************************************************************************/
  2. /*                                                                        */
  3. /* FalconScreen                                                            */
  4. /* ============                                                            */
  5. /*                                                                        */
  6. /* Copyright 1993 by Markus Gutschke.                                    */
  7. /* This program is postcardware. You are encouraged to distribute it    */
  8. /* freely as long as you do not charge anybody for it, but if you keep    */
  9. /* a copy, you have to send me a postcard:                                */
  10. /*        Markus Gutschke                                                    */
  11. /*        Papenbusch 31                                                    */
  12. /*        4400 M"unster                                                    */
  13. /*        W-Germany                                                        */
  14. /* Note! This program may not be distributed with so-called PD-            */
  15. /* collections or on cover-disks!                                        */
  16. /* If you encounter any bugs (there are probably a lot!), have comments    */
  17. /* or suggestions or just found some useful settings for the video        */
  18. /* registers, please send e-mail to:                                    */
  19. /*        srb242@math.uni-muenster.de                                        */
  20. /* or:    Markus.Gutschke@uni-muenster.de                                    */
  21. /*                                                                        */
  22. /* The current version of this program will only affect the 640x480x4bit*/
  23. /* mode on an SVGA monitor. It will replace this mode with a user        */
  24. /* selectable higher resolution. Currently 928x696 is the highest        */
  25. /* possible setting.                                                    */
  26. /*                                                                        */
  27. /* This program relies on several undocumented features of the            */
  28. /* Falcon030, thus I am unable to guarantee, that it will work on any    */
  29. /* computer other than my own. This program will most certainly damage    */
  30. /* any monitor, that does not support SVGA video modes! Even SVGA        */
  31. /* monitors might be damaged/destroyed, since this program is pushing    */
  32. /* the signal timing very hard. If you feel at all uncomfortable with    */
  33. /* the possibility of damaging your hardware, do not run this program!    */
  34. /*                                                                        */
  35. /* Since I am releasing this program free of charge, I am unable to        */
  36. /* give any support or guarantee for this program!                        */
  37. /*                                                                        */
  38. /* This program will compile with TurboC and PureC. You will probably    */
  39. /* have to make changes, if you want to compile it with any other        */
  40. /* system. If you added conditional preprocessor directives that allow    */
  41. /* you to compile this program both with TC/PC and with your system        */
  42. /* please let me know.                                                    */
  43. /* The assembler interface relies on the TC/PC parameter passing scheme.*/
  44. /* Scalar values will be passed in D0 through D2, addresses will be        */
  45. /* passed in A0 and A1; all parameters that cannot be passed by            */
  46. /* registers, will be passed on the stack. Return values will be either    */
  47. /* in D0 (scalar values) or in A0 (pointers). D3-D7/A2-A7 remain        */
  48. /* unaffected throughout a function call.                                */
  49. /*                                                                        */
  50. /************************************************************************/
  51.  
  52. #define        BETA                    /* This is a beta release of FS        */
  53. #define        PRGNAME        "FS.PRG"    /* Program name for patching params.*/
  54. #define        ID            '\344FSC'    /* XBRA Id                            */
  55. #define        PLANES        4            /* Number of planes                    */
  56.  
  57. #define        MINN        1            /* minimum legal value for N        */
  58. #define        MAXN        9            /* maximum legal value for N        */
  59.  
  60. /* Several negative LineA variables need patching                        */
  61.  
  62. #define        VGemX        (((int *)linea)[-0x015A])
  63. #define        VGemY        (((int *)linea)[-0x0159])
  64. #define        VCelHT        (((int *)linea)[-0x0017])
  65. #define        VCelMX        (((int *)linea)[-0x0016])
  66. #define        VCelMY        (((int *)linea)[-0x0015])
  67. #define        VCelWR        (((int *)linea)[-0x0014])
  68. #define        VXMax        (((int *)linea)[-0x0006])
  69. #define        VYMax        (((int *)linea)[-0x0002])
  70. #define        VBytesLin    (((int *)linea)[-0x0001])
  71. #define        VPlanes        (((int *)linea)[ 0x0000])
  72. #define        VWrap        (((int *)linea)[ 0x0001])
  73.  
  74. /* List of undocumented video registers (c.f. VIDEO.PRG)                */
  75.  
  76. #define        RShift        (*(int *)0xFFFF8260l)
  77. #define        RSpShift    (*(int *)0xFFFF8266l)
  78. #define        RWrap        (*(int *)0xFFFF8210l)
  79. #define        RCO            (*(int *)0xFFFF82C0l)
  80. #define        RMode        (*(int *)0xFFFF82C2l)
  81. #define        RHHT        (*(int *)0xFFFF8282l)
  82. #define        RHBB        (*(int *)0xFFFF8284l)
  83. #define        RHBE        (*(int *)0xFFFF8286l)
  84. #define        RHDB        (*(int *)0xFFFF8288l)
  85. #define        RHDE        (*(int *)0xFFFF828Al)
  86. #define        RHSS        (*(int *)0xFFFF828Cl)
  87. #define        RHFS        (*(int *)0xFFFF828El)
  88. #define        RHEE        (*(int *)0xFFFF8290l)
  89. #define        RVFT        (*(int *)0xFFFF82A2l)
  90. #define        RVBB        (*(int *)0xFFFF82A4l)
  91. #define        RVBE        (*(int *)0xFFFF82A6l)
  92. #define        RVDB        (*(int *)0xFFFF82A8l)
  93. #define        RVDE        (*(int *)0xFFFF82AAl)
  94. #define        RVSS        (*(int *)0xFFFF82ACl)
  95.  
  96. /* Bindings for system calls are provided by the assembler modul        */
  97.  
  98. void    *LineA0(void);
  99. int        Kbshift(int);
  100. void    *Physbase(void);
  101. void    Setscreen(void *,void *,int,int);
  102. int        Vsetmode(int);
  103. int        Montype(void);
  104. void    VsetRGB(int,int,long *);
  105. void    VgetRGB(int,int,long *);
  106. void    Pterm0(void);
  107. int        Cnecin(void);
  108. void    Cconws(char *);
  109. int        Cconis(void);
  110. void    *Srealloc(unsigned long);
  111. long    Super(void *);
  112. int        Fopen(char *,int);
  113. void    Fclose(int);
  114. long    Fread(int,long,void *);
  115. long    Fwrite(int,long,void *);
  116. long    Fseek(long,int,int);
  117. void    *Malloc(long amount);
  118. void    Mfree(void *addr);
  119.  
  120. /* Copyright message                                                    */
  121.  
  122. void showlogo(int x,int y,unsigned short *scr,
  123.               int width,int height,int planes);
  124. void hidelogo(void);
  125. static char copyright[] =
  126.     "\x1BpFalconScreen (c) 1993 by M. Gutschke\x1Bq\r\n"
  127.     "This program is postcardware!\r\n"
  128.     "If you like it, send a postcard to:\r\n"
  129.     "   Markus Gutschke\r\n"
  130.     "   Papenbusch 31\r\n"
  131.     "   4400 M\x81nster\r\n"
  132.     "   W-Germany\r\n"
  133. #ifdef    BETA
  134.     "Warning! This is a beta-Release!\r\n"
  135. #endif
  136.     "This program might damage your F030\r\n"
  137.     "and/or your monitor!\r\n";
  138.  
  139. /* Preset values                                                        */
  140.  
  141. struct settings {                    /* This preinitialized structure    */
  142.     long    magic;                    /* can be patched by the program!    */
  143.     int        size;
  144.     int        mask;                    /* It contains the user's prefered    */
  145.     int        value;                    /* resolution.                        */
  146.     int        planes;
  147.     int        n;
  148.     int        width,height;
  149. } settings = {ID,(int)sizeof(struct settings),
  150.               0x18F,0x00A,PLANES,MINN-1,640,400};
  151.  
  152. /* Precomputed parameter sets:                                            */
  153.  
  154. static struct {
  155.     int        width,height,frq,planes;
  156.     int        Shift,SpShift,Wrap,CO,Mode,HHT,HBB,HBE,HDB;
  157.     int        HDE,HSS,HFS,HEE,VFT,VBB,VBE,VDB,VDE,VSS;
  158. } table[MAXN-MINN+2] = {
  159.     640,480,62, 4,0,0,160,0x186,8,0x0c6,0x8d,0x15,0x2a3,0x7c,0x96,0,0,
  160.                                     0x3e7,0x3e3,0x23,0x23,0x3eb,0x3e4,
  161.     672,512,72, 4,0,0,168,0x182,8,0x0ce,0x8d,0x0d,0x2a3,0x7c,0x96,0,0,
  162.                                     0x427,0x423,0x23,0x23,0x42b,0x424,
  163.     704,528,67, 4,0,0,176,0x182,8,0x0d6,0x8d,0x05,0x2a3,0x7c,0x96,0,0,
  164.                                     0x447,0x443,0x23,0x23,0x44b,0x444,
  165. #ifdef    OLDVALUES
  166.     736,560,58, 4,0,0,184,0x182,8,0x0ea,0xa2,0x1e,0x2d0,0x91,0xb8,0,0,
  167.                                     0x487,0x483,0x23,0x23,0x48b,0x484,
  168.     768,576,55, 4,0,0,192,0x182,8,0x0f2,0xa2,0x16,0x2d0,0x91,0xb8,0,0,
  169.                                     0x4a7,0x4a3,0x23,0x23,0x4ab,0x4a4,
  170.     800,608,50, 4,0,0,200,0x182,8,0x0fa,0xa2,0x0e,0x2d0,0x91,0xb8,0,0,
  171.                                     0x4e7,0x4e3,0x23,0x23,0x4eb,0x4e4,
  172.     832,624,48, 4,0,0,208,0x182,8,0x102,0xa2,0x06,0x2d0,0x91,0xb8,0,0,
  173.                                     0x507,0x503,0x23,0x23,0x50b,0x504
  174. #else
  175.     /* Harald, thank you for finding these improved values!                */
  176.     736,560,61, 4,0,0,184,0x182,8,0x0df,0xb8,0x29,0x2d0,0xa8,0xb7,0,0,
  177.                                     0x487,0x483,0x23,0x23,0x48b,0x484,
  178.     768,576,57, 4,0,0,192,0x182,8,0x0e7,0xb8,0x21,0x2d0,0xa8,0xb7,0,0,
  179.                                     0x4a7,0x4a3,0x23,0x23,0x4ab,0x4a4,
  180.     800,608,52, 4,0,0,200,0x182,8,0x0ef,0xb8,0x19,0x2d0,0xa8,0xb7,0,0,
  181.                                     0x4e7,0x4e3,0x23,0x23,0x4eb,0x4e4,
  182.     832,624,50, 4,0,0,208,0x182,8,0x0f7,0xb8,0x11,0x2d0,0xa8,0xb7,0,0,
  183.                                     0x507,0x503,0x23,0x23,0x50b,0x504,
  184.     864,656,46, 4,0,0,216,0x182,8,0x0ff,0xb8,0x09,0x2d0,0xa8,0xb7,0,0,
  185.                                     0x547,0x543,0x23,0x23,0x54b,0x544,
  186.     896,672,45, 4,0,0,224,0x182,8,0x0ff,0xb8,0x01,0x2d0,0xa8,0xb7,0,0,
  187.                                     0x567,0x563,0x23,0x23,0x56b,0x564,
  188.     928,696,41, 4,0,0,232,0x182,8,0x10f,0xb8,0x01,0x2e0,0xa8,0xb7,0,0,
  189.                                     0x597,0x593,0x23,0x23,0x59b,0x594
  190. #endif
  191. };
  192.  
  193. /* Convert a number to a string without exceeding the string size        */
  194.  
  195. static char *tonum(int i,char *s,int *n)
  196. {
  197.     /* recursion is needed to output digits in the right order!            */
  198.     if (i > 10) s = tonum(i/10,s,n);
  199.     if (*n > 1) {
  200.         (*n)--;
  201.         *s++ = i%10+'0'; }
  202.     *s = '\000';
  203.     return(s);
  204. }
  205.  
  206. /* Create a string that describes a screen resolution                    */
  207.  
  208. static void makeresstr(int w,int h,int p,int f,char *s,int n)
  209. {
  210.     char    *ptr1 = "bit (";
  211.     char    *ptr2 = "Hz)           ";
  212.  
  213.     /* -> "NNNxNNNxNbit (NNHz)      "                                    */
  214.     s = tonum(w,s,&n);
  215.     if (n <= 1) goto eos; else { n--; *s++ = 'x'; }
  216.     s = tonum(h,s,&n);
  217.     if (n <= 1) goto eos; else { n--; *s++ = 'x'; }
  218.     s = tonum(p,s,&n);
  219.     while (*ptr1 && n-- > 1)
  220.         *s++ = *ptr1++;
  221.     if (n <= 1) goto eos;
  222.     s = tonum(f,s,&n);
  223.     while (*ptr2 && n-- > 1)
  224.         *s++ = *ptr2++;
  225. eos:
  226.     *s ='\000';
  227.     return;
  228. }
  229.  
  230. /* Initialize video registers                                            */
  231.  
  232. static void setvideo(void)
  233. {
  234.     RShift        = table[settings.n].Shift;
  235.     RSpShift    = table[settings.n].SpShift;
  236.     RWrap        = table[settings.n].Wrap;
  237.     RCO            = table[settings.n].CO;
  238.     RMode        = table[settings.n].Mode;
  239.     RHHT        = table[settings.n].HHT;
  240.     RHBB        = table[settings.n].HBB;
  241.     RHBE        = table[settings.n].HBE;
  242.     RHDB        = table[settings.n].HDB;
  243.     RHDE        = table[settings.n].HDE;
  244.     RHSS        = table[settings.n].HSS;
  245.     RHFS        = table[settings.n].HFS;
  246.     RHEE        = table[settings.n].HEE;
  247.     RVFT        = table[settings.n].VFT;
  248.     RVBB        = table[settings.n].VBB;
  249.     RVBE        = table[settings.n].VBE;
  250.     RVDB        = table[settings.n].VDB;
  251.     RVDE        = table[settings.n].VDE;
  252.     RVSS        = table[settings.n].VSS;
  253.     return;
  254. }
  255.  
  256. /* Patch (negative) line-A variables                                    */
  257.  
  258. static void patchos(void)
  259. {
  260.     void    *linea = LineA0();
  261.  
  262.     VPlanes     = settings.planes;    /* Patch a couple of LineA variables*/
  263.     VWrap        = (settings.width>>3)*settings.planes;
  264.     VGemX        = settings.width-1;    /* VGemX and VGemY are undocumented!*/
  265.     VGemY        = settings.height-1;
  266.     VCelMX        = (settings.width>>3)-1;
  267.     VCelMY        = settings.height/VCelHT-1;
  268.     VCelWR        = (settings.width>>3)*settings.planes*VCelHT;
  269.     VXMax        = settings.width;
  270.     VYMax        = settings.height;
  271.     VBytesLin    = (settings.width>>3)*settings.planes;
  272.     return;
  273. }
  274.  
  275. /* Reallocate new screen memory                                            */
  276.  
  277. static void realloc(void)
  278. {
  279.     long    scrsize,hz200;
  280.     void    *scraddr;
  281.  
  282.     scrsize = ((long)settings.width*(long)settings.height*
  283.               (long)settings.planes)>>3;
  284.     scraddr = Srealloc(scrsize);    /* Reallocate screen memory            */
  285.     Setscreen(scraddr,scraddr,-1,-1);/* Set new screen address            */
  286.     showlogo(48,48,scraddr,settings.width,settings.height,4);
  287.     for (hz200 = *(long *)0x4BA+130;/* wait 0.65 seconds                */
  288.          *(long *)0x4BA < hz200;);
  289.     hidelogo();
  290.     return;
  291. }
  292.  
  293. /* Initialize a new video mode                                            */
  294.  
  295. void init(int dorealloc)
  296. {
  297.     Cconws("\x1B""H");
  298.     patchos();
  299.     setvideo();
  300.     if (dorealloc)
  301.         realloc();
  302.     Cconws("\x1B""E");
  303.     return;
  304. }
  305.  
  306. /* Handle extended setscreen modes                                        */
  307.  
  308. long    setscreen(long rc,void *log,void *phys,int rez,int mode)
  309. {
  310.     if (rez == 3 && (mode & settings.mask) == settings.value)
  311.         init(!log && !phys);
  312.     return(rc);
  313. }
  314.  
  315. /* Replace 640x480x4bit with new video mode                                */
  316.  
  317. long    vsetmode(long rc,int mode)
  318. {
  319.     if ((mode & settings.mask) == settings.value)
  320.         init(0);
  321.     return(rc);
  322. }
  323.  
  324. /* Return new screen size                                                */
  325.  
  326. long    vgetsize(long rc,int mode)
  327. {
  328.     if ((mode & settings.mask) == settings.value)
  329.         return(((long)settings.width*(long)settings.height*
  330.                 (long)settings.planes)>>3);
  331.     return(rc);
  332. }
  333.  
  334. /* Get/set an entry from the system cookie jar                            */
  335.  
  336. static long    docookie(long cookie,long value)
  337. {
  338.     long    stack;
  339.     long    *cookiejar;
  340.  
  341.     stack = Super(0l);
  342.     cookiejar = *(long **)0x5a0;
  343.     if (cookiejar) {
  344.         while (*cookiejar && *cookiejar != cookie) cookiejar += 2;
  345.         if (*cookiejar == 0 && value != 0 &&
  346.             cookiejar - *(long **)0x5a0 < 2*cookiejar[1]) {
  347.             cookiejar[3] = cookiejar[1];
  348.             cookiejar[2] = 0;
  349.             cookiejar[1] = value;
  350.             cookiejar[0] = cookie; } }
  351.     Super((void *)stack);
  352.     return (cookiejar && *cookiejar == cookie ? cookiejar[1] : 0);
  353. }
  354.  
  355. /* Change preferences                                                    */
  356.  
  357. static void setup(void)
  358. {
  359.     char    s[22];
  360.     int        handle,oldn,mode,oldmode,frq;
  361.     long    scrsize,offset,stack;
  362.     unsigned long hz200,vbl;
  363.     void    *oldscr,*newscr;
  364.     struct {long magic;int size;} header;
  365.  
  366.     while (Cconis()) Cnecin();
  367.     if (settings.n < MINN || settings.n > MAXN)
  368.         settings.n = MINN-1;        /* FS is inactive                    */
  369.     Cconws("Press <SHIFT> for testing!\r\n");
  370.     oldn = settings.n;
  371.     for (;;) {
  372.         Cconws("\x1BY\x2C Current resolution: ");
  373.         settings.width = table[settings.n].width;
  374.         settings.height= table[settings.n].height;
  375.         makeresstr(settings.width,settings.height,
  376.                    settings.planes,table[settings.n].frq,s,21);
  377.         Cconws(s);
  378.         Cconws("(+/-)");
  379.         scrsize = ((long)settings.width*(long)settings.height*
  380.                    (long)settings.planes)>>3;
  381.         newscr = Malloc(scrsize);
  382.         oldscr = Physbase();
  383.         for (mode = oldmode = Vsetmode(-1);!Cconis() || !mode;)
  384.             if ((Kbshift(-1) & 3) && !Cconis()) {
  385.                 if (mode && newscr) {
  386.                     mode = 0;
  387.                     Setscreen(newscr,newscr,3,0x001A);
  388.                     stack = Super(0L);
  389.                     setvideo();
  390.                     showlogo(48,48,newscr,settings.width,
  391.                              settings.height,4);
  392.                                      /* measure refresh rate, while user */
  393.                                      /* views the screen                    */
  394.                     vbl = *(unsigned long *)0x462;
  395.                     hz200 = *(unsigned long *)0x4ba;
  396.                     Super((void *)stack); } }
  397.             else
  398.                 if (!mode) {
  399.                     stack = Super(0L);
  400.                     hz200 = *(unsigned long *)0x4ba - hz200;
  401.                     vbl = *(unsigned long *)0x462 - vbl;
  402.                     Super((void *)stack);
  403.                                     /* calculate "real" refresh rate    */
  404.                     frq = (int)((vbl*2000L+5)/hz200)/10;
  405.                     mode = oldmode;
  406.                     hidelogo();
  407.                     Setscreen(newscr,newscr,3,oldmode);
  408.                     Setscreen(oldscr,oldscr,-1,-1);
  409.                                     /* check for plausibility            */
  410.                     if ((frq - table[settings.n].frq) > -20 &&
  411.                         (frq - table[settings.n].frq) <  20 &&
  412.                         vbl > 20) {
  413.                         table[settings.n].frq = frq;
  414.                         makeresstr(settings.width,settings.height,
  415.                                    settings.planes,frq,s,21);
  416.                         Cconws("\x1BY\x2C Current resolution: ");
  417.                         Cconws(s);
  418.                         Cconws("(+/-)"); } }
  419.         Mfree(newscr);
  420.         switch ((char)Cnecin()) {    /* In/decrease resolution            */
  421.             case '+':
  422.                 if (settings.n < MAXN) settings.n++;
  423.                 break;
  424.             case '-':
  425.                 if (settings.n >= MINN) settings.n--;
  426.                 break;
  427.             default:
  428.                 goto eol; } }
  429. eol:                                /* Patch the executeable file        */
  430.     Cconws("\x1BY\x2C \x1BK");
  431.     if (oldn != settings.n) {
  432.         Cconws("S(ave settings, C(ontinue...\r\n");
  433.         if (((char)Cnecin() & 0xDF) == 'S') {
  434.             if ((handle = (int)Fopen(PRGNAME,2)) < 0 &&
  435.                 (handle = (int)Fopen("AUTO\\"PRGNAME,2)) < 0) {
  436.                 Cconws("Cannot open FS.PRG!\r\n");
  437.                 Cnecin();
  438.                 goto ferr; }
  439.             Fseek(0x1E,handle,0);    /* Find patch area and check for    */
  440.             Fread(handle,4,&offset);/* magic first!                        */
  441.             Fseek(0x1C+offset,handle,0);
  442.             Fread(handle,6,&header);
  443.             if (header.magic != ID || header.size != sizeof(settings)) {
  444.                 Cconws("Illegal file format!\r\n");
  445.                 Cnecin(); }
  446.             else if (Fwrite(handle,sizeof(settings)-6,
  447.                      ((char *)&settings)+6) != sizeof(settings)-6) {
  448.                 Cconws("Could not write to FS.PRG!\r\n");
  449.                 Cnecin(); }
  450.             Fclose(handle); } }
  451. ferr:
  452.     return;
  453. }
  454.  
  455. /* Main program: check video hardware and allow change of preferences    */
  456.  
  457. int main(void)
  458. {
  459.     int                rc = 0;
  460.     struct settings *ptr;
  461.  
  462.     if ((ptr = (struct settings *)docookie(ID,0)) != 0) {
  463.         Cconws("\x1B""E");
  464.         Cconws(copyright);
  465.         Cconws("FalconScreen is already installed...\r\n");
  466.         if (ptr->size == settings.size) {
  467.             settings = *ptr;
  468.             setup();
  469.             *ptr = settings; }
  470.         Pterm0(); }
  471.     if (docookie('_VDO',0) != 0x00030000L || Montype() != 2) {
  472.         Cconws(copyright);
  473.         Cconws("\x1BpYou need a Falcon030 & SVGA-monitor \x1Bq\x07"
  474.                "\r\n\r\n");
  475.         Pterm0(); }
  476.     settings.width = table[settings.n].width;
  477.     settings.height= table[settings.n].height;
  478.     if ((Cconis() && (Cnecin() & 0xDF) == 'S') ||
  479.         settings.n < MINN || settings.n > MAXN) {
  480.         Cconws("\x1B""E");
  481.         Cconws(copyright);
  482.         Cconws("Press 'S' for setup...\r\n");
  483.         setup(); }
  484.     else {
  485.         Cconws(copyright);
  486.         Cconws("Press 'S' for setup...\r\n"); }
  487.     Cconws("\r\n");
  488.     if (settings.n < MINN || settings.n > MAXN)
  489.         Pterm0();
  490.     if ((Vsetmode(-1) & settings.mask) == settings.value) {
  491.         if (docookie('MiNT',0)) {
  492.             Cconws("Your boot configuration has to be\r\n"
  493.                    "different from 640x480x4bit!\r\n");
  494.             Pterm0(); }
  495.         rc = 1; }
  496.     docookie(ID,(long)&settings);
  497.     return(rc);
  498. }
  499.