home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / SVGALIB / SVGALIB1.TAR / svgalib / utils / fix132x43.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-10  |  6.3 KB  |  211 lines

  1. /*
  2.   This file assumes 132 column textmode :-).
  3.  
  4.   This program tries to fix problems with extended textmodes on some cards. The problem is that for 132x43 textmode, some
  5.   BIOSes set the vertical display end register to 349 (350), instead of 343 (344 = 3 * 8 scanlines). Because in Linux textmode
  6.   video memory is usually filled with old text that has already scrolled away (this includes the area below the 43rd textmode
  7.   line, which changes when the console scrolls), the top half of a constantly changing irrelevant text line is visible
  8.   at the bottom of the screen, which is very annoying.
  9.  
  10.   This program sets the VGA Vertical Display End register to the proper value.
  11.  
  12.   The problem is at least present in the BIOS of most Cirrus Logic 542x based cards, and some WD90C03x based cards.
  13.  
  14.  
  15.   You can also change the number scanlines and number of lines per character of 132x43 textmode to improve readability.
  16.  
  17.   
  18. VGA CRTC 0x12    bits 0-7    Vertical Display End Register bits 0-7
  19. VGA CRTC 0x07    bit 1        Vertical Display End Register bit 8
  20.  
  21. Cirrus 542x BIOS v1.10 132x43:    0x15d (349)    (this is the wrong value that the BIOS sets)
  22. Correct value for 132x43:    0x157 (343)
  23. Correct value for 132x44:    0x15f (351)
  24.  
  25.  
  26. VGA CRTC 0x09    bits 0-4    Number of scanlines in a textmode font character.
  27. VGA MiscOut    bits 6-7    Indicates number of scanlines: 1 = 400, 2 = 350, 3 = 480.
  28. VGA CRTC 0x06   bits 0-7    Vertical Total register bits 0-7 (should be #scanlines - 2)
  29.                 Bit 8 is in VGA CRTC 0x07, bit 0
  30.                 Bit 9 is in VGA CRTC 0x07, bit 5
  31. VGA CRTC 0x10    bits 0-7    Vertical Retrace Start
  32.                 Bit 8 is in VGA CRTC 0x07, bit 2
  33.                 Bit 9 is in VGA CRTC 0x07, bit 7
  34. VGA CRTC 0x11    bits 0-3    Vertical Retrace End (last 4 bits)
  35. VGA CRTC 0x15    bits 0-7    Vertical Blank Start
  36.                 Bit 8 is in VGA CRTC 0x07 bit 3
  37.  
  38. */
  39.  
  40.  
  41. /* Comment this out if setting graphics modes is undesirable. You can load proper fonts with restorefont. */
  42. #define FIX_FONT
  43.  
  44.  
  45. #include <stdlib.h>
  46. #include <stdio.h>
  47. #include <string.h>
  48. #include <unistd.h>
  49. #include <vga.h>
  50. #include "../src/libvga.h"    /* For port I/O macros. */
  51.  
  52.  
  53.  
  54. static void fixfont( int );
  55.  
  56.  
  57. void main( int argc, char *argv[] ) {
  58.     int vgaIOBase;
  59.     unsigned char val;
  60.     int lines;
  61.  
  62.     vga_disabledriverreport();
  63.     vga_setchipset(VGA);
  64.     vga_init();
  65.  
  66.     if (argc == 1) {
  67.         printf("Fiddle with 132x43 textmode VGA registers.\n");
  68.         printf("Syntax: fix132x43 option (one at a time).\n");
  69.         printf("    -f    Fix problem of annoying changing line of text at bottom of screen.\n");
  70.         printf("    -v    Switch to 9 line characters (400 line frame, 70 Hz).\n");
  71. #ifdef INCLUDE_480LINEMODE
  72.         printf("    -w    Switch to 11 line characters (480 line frame, 60 Hz).\n");
  73. #endif
  74.         printf("    -r    Switch to 8 line characters again (350 line frame, 70 Hz).\n");
  75.         printf("LINES environment variable is used to detect 43 or 44 line console.\n");
  76.         exit(0);
  77.     }
  78.  
  79.     if (argv[1][0] != '-') {
  80.         printf("Must specify -f, -v or -r.\n");
  81.         exit(1);
  82.     }
  83.     
  84.     if (argv[1][1] != 'f' && argv[1][1] != 'v' && argv[1][1] != 'w' && argv[1][1] != 'r') {
  85.         printf("Must specify -f, -v, or -r.\n");
  86.         exit(1);
  87.     }
  88.  
  89.     lines = atoi(getenv("LINES"));
  90.     printf("Lines: %d\n", lines);
  91.  
  92.     /* Deprotect CRT registers 0-7. */
  93.     vgaIOBase = (inb(0x3cc) & 0x01) ? 0x3D0 : 0x3B0;
  94.         outb(vgaIOBase + 4, 0x11);
  95.         val = inb(vgaIOBase + 5);
  96.         outb(vgaIOBase + 5, val & 0x7f);
  97.  
  98.     if (argv[1][1] == 'f') {
  99.         /* Fix stupid bottom line. */
  100.         outb(vgaIOBase + 4, 0x12);
  101.         outb(vgaIOBase + 5, 0x57);        /* Value for 43 lines (343). */
  102.     }
  103.  
  104.     if (argv[1][1] == 'r') {
  105.         /* Set 8 line characters, 350 line frame (344 used). */
  106.  
  107.         outb(vgaIOBase + 4, 0x09);
  108.         val = inb(vgaIOBase + 5);
  109.         outb(vgaIOBase + 5, (val & 0xe0) | 7);    /* Set 8-line characters. */
  110.  
  111.         val = inb(0x3cc);
  112.         outb(0x3c2, (val & 0x3f) | (2 << 6));    /* 350 scanlines. */
  113.  
  114.         outb(vgaIOBase + 4, 0x12);        /* Vertical Display End */
  115.         if (lines == 44)
  116.             outb(vgaIOBase + 5, 0x60);    /* Value for 44 lines (352). */
  117.         else
  118.             outb(vgaIOBase + 5, 0x57);    /* Value for 43 lines (343). */
  119.  
  120.         outb(vgaIOBase + 4, 0x10);        /* Retrace Start */
  121.         outb(vgaIOBase + 5, 0x83);        /* Value for 350 line frame. */
  122.         
  123.         outb(vgaIOBase + 4, 0x11);        /* Retrace End */
  124.         val = inb(vgaIOBase + 5);
  125.         outb(vgaIOBase + 5, (val & 0xf0) | 0x05);
  126.  
  127.         outb(vgaIOBase + 4, 0x15);        /* Vertical Blank Start */
  128.         outb(vgaIOBase + 5, 0x63);        /* Value for 350 line frame. */
  129.     }
  130.  
  131.     if (argv[1][1] == 'v') {
  132.         /* Set 9 line characters, 400 line frame (387 used). */
  133.  
  134.         outb(vgaIOBase + 4, 0x09);
  135.         val = inb(vgaIOBase + 5);
  136.         outb(vgaIOBase + 5, (val & 0xe0) | 8);    /* Set 9-line characters. */
  137.  
  138.         val = inb(0x3cc);
  139.         outb(0x3c2, (val & 0x3f) | (1 << 6));    /* 400 scanlines. */
  140.  
  141.         outb(vgaIOBase + 4, 0x12);
  142.         if (lines == 44)
  143.             outb(vgaIOBase + 5, 0x8b);    /* End scanline is 44 * 9 - 1 = 395 */
  144.         else
  145.             outb(vgaIOBase + 5, 0x82);    /* End scanline is 43 * 9 - 1 = 386 */
  146.  
  147.         outb(vgaIOBase + 4, 0x10);        /* Retrace Start */
  148.         outb(vgaIOBase + 5, 0x9c);        /* Value for 400 line frame. */
  149.  
  150.         outb(vgaIOBase + 4, 0x11);        /* Retrace End */
  151.         val = inb(vgaIOBase + 5);
  152.         outb(vgaIOBase + 5, (val & 0xf0) | 0x0e);
  153.  
  154.         outb(vgaIOBase + 4, 0x15);        /* Vertical Blank Start */
  155.         outb(vgaIOBase + 5, 0x95);        /* Value for 400 line frame. */
  156.  
  157.         #ifdef FIX_FONT        
  158.         fixfont(9);
  159.         #endif
  160.     }
  161.  
  162. #ifdef INCLUDE_480LINEMODE
  163.     if (argv[1][1] == 'w') {
  164.         /* Set 11 line characters, 480 line frame (473 used). */
  165.  
  166.         outb(vgaIOBase + 4, 0x09);
  167.         val = inb(vgaIOBase + 5);
  168.         outb(vgaIOBase + 5, (val & 0xe0) | 10);    /* Set 11-line characters. */
  169.  
  170.         outb(0x3c2, 0xeb);
  171.  
  172.         outb(vgaIOBase + 4, 0x12);
  173.         outb(vgaIOBase + 5, 0xd8);        /* End scanline is 43 * 11 - 1 = 472 */
  174.  
  175.         outb(vgaIOBase + 4, 0x10);        /* Retrace Start */
  176.         outb(vgaIOBase + 5, 0xf4 /*0xea*/);    /* Value for 480 line frame. ?? */
  177.  
  178.         outb(vgaIOBase + 4, 0x11);        /* Retrace End */
  179.         val = inb(vgaIOBase + 5);
  180.         outb(vgaIOBase + 5, (val & 0xf0) | 0x0c);
  181.  
  182.         outb(vgaIOBase + 4, 0x15);        /* Vertical Blank Start */
  183.         outb(vgaIOBase + 5, 0xf4 /*0xe7*/);    /* Value for 480 line frame. */
  184.         
  185.         #ifdef FIX_FONT
  186.         fixfont(11);
  187.         #endif
  188.     }
  189. #endif
  190.  
  191.     exit(0);
  192. }
  193.  
  194.  
  195.  
  196. /* Clear offsets 8-31 of each character bitmap (the BIOS usually leaves some trash here from the 16 line font that was loaded */
  197. /* prior to setting 132x43 (8 line font) textmode). */
  198.  
  199. static void fixfont( int lines ) {
  200.     unsigned char font[8192];
  201.     int i;
  202.     vga_setmode(G640x480x16);
  203.     vga_gettextfont(font);
  204.  
  205.     for (i = 0; i < 256; i++)
  206.         memset(font + i * 32 + 8, 0, 32 - 8);        /* Clear remaining part of character bitmap buffer. */
  207.  
  208.     vga_puttextfont(font);
  209.     vga_setmode(TEXT);
  210. }
  211.