home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 328_01 / w50line.c < prev    next >
C/C++ Source or Header  |  1991-03-17  |  6KB  |  218 lines

  1. /* w50line.c - control EGA/VGA display in text modes to 43/50 line 
  2.  *
  3.  *    USAGE:  w50line ( ON_OFF );
  4.  *            PARAMETER:    ON_OFF = if 0, restore to 25 line mode
  5.  *                                    non-0, set to 50/43 line
  6.  *    RETURNS:  int is50  = 0 if in 25 line mode,
  7.  *                          non-0 if in 50/43 line mode
  8.  *    ALSO:    changes winymax to 42,49, or 24 as needed.
  9.  *            changes the size of wfullscreen, the initial fullscreen window.
  10.  *            moves the cursor to within a 25-line window if needed.
  11.  *            changes parameters governing multiple video pages.
  12.  *            allows for 2 top protected lines if pulldown menus are installed.
  13.  *
  14.  *    WARNINGS:    When switching back to 25-line mode, this function 
  15.  *                does not check any currently open windows
  16.  *                to make sure they are inside the 25-line screen.
  17.  *
  18.  *  This function has no effect in graphics modes or on HERCULES cards. 
  19.  *
  20.  *    ACKNOWLEDGEMENT: The logic for switching to 43/50 line mode comes
  21.  *        from DOS POWER TOOLS by Somerson. 
  22.  *
  23.  */
  24. #include "wsys.h"
  25.  
  26.  
  27. static void clear50(void);    /* prototype for atexit func */
  28. static char exit_installed     =0; 
  29.  
  30. static char is50            =0;
  31.  
  32. #define  BIOS_CURSOR_EMULATION   *( (unsigned char far *) 0x0487L )
  33.  
  34. #define BIOS_PAGE_SIZE  *( (int far *) 0x044CL )
  35.  
  36. int w50line ( int want50 )
  37.     {
  38.     int  nlines;
  39.     unsigned char save_BIOS_CURSOR;
  40.     
  41.     PSEUDOREGS
  42.     
  43.     
  44.     if ( 
  45.         ( wmonitor == 'E'  || wmonitor == 'V' )
  46.     #ifndef TEXTONLY
  47.         /* do nothing if in a graphics mode */
  48.         &&   ( wmode == 'T' )
  49.     #endif  /* TEXTONLY */
  50.         )
  51.             {
  52.             if ( want50 )
  53.                 {
  54.                 if ( !exit_installed )
  55.                     {
  56.                     /* install exit function only once per program
  57.                      */
  58.                     exit_installed = ON;                    
  59.                     atexit (clear50);
  60.                     }
  61.                     
  62.                 /*set 8-byte font
  63.                  */
  64.                 _BX = 0;            /* load font */
  65.                 _AX = 0x1112;
  66.                 INTERRUPT ( 0x10 );
  67.                 
  68.                                             
  69.                 wcurscanln = 0x0607;
  70.  
  71.                 /* force EGA cursor to correct size
  72.                  *    A fairly complex situation here.
  73.                  *        with 'cursor emulation' ON, 
  74.                  *            EGA card converts row 6 to row 12 (for CGA compat.)
  75.                  *        so have to turn OFF cursor emulation, then set cur. row
  76.                  *
  77.                  */
  78.                 save_BIOS_CURSOR = BIOS_CURSOR_EMULATION;
  79.                 BIOS_CURSOR_EMULATION |= 0x01;    /* turn OFF emulation*/
  80.                 _CX = 0x0600;                    /* cursor size request */
  81.                 _AH = 1;
  82.                 INTERRUPT ( 0x10 );
  83.                 BIOS_CURSOR_EMULATION = save_BIOS_CURSOR;    /* restore emul. */
  84.                 outport ( 0x03B4, 0x0714 );
  85.                 
  86.                 
  87.                 /* set number of screen lines
  88.                  * dividing BIOS_PAGE_SIZE by 80 (=#columns) doesn't work
  89.                  *    for some reason in VGA BIOS page size is 64 bytes too big.
  90.                  */
  91.                 nlines = ( wmonitor == 'V' ) ? 50 : 43;
  92.                 
  93.                 /* setup windows globals
  94.                  */                    
  95.                 wyabsmax = nlines -1;    
  96.                 
  97.                 /* adjust size of wfullscreen to allow for top menu
  98.                  */
  99.                 wfullscreen->winymax = nlines-1 - (wfullscreen->wintop);
  100.                 
  101.                 /* clear lower half of screen to fullscreen color
  102.                  */
  103.                 wdefine ( 0, 25, wxabsmax+1, nlines-25, 0, 0, 0);
  104.                 wsetattr ( wfullscreen-> winattr );
  105.                 wclear ();
  106.                 wabandon();
  107.                  
  108.                 /* setup multiple pages if this is a 'paging' program
  109.                  */
  110.                 if ( wlastpage )
  111.                     {
  112.                     /* have to change the PAGE size to reflect smaller chars.
  113.                      * also, for reasons totally unclear to me,
  114.                      * the pages in 50-line mode are 32 chars =64 bytes longer.
  115.                      * ie, 64 bytes are unused in VGA RAM at end of each page.
  116.                      * and the pages in 43-line mode are something else.
  117.                      *
  118.                      * Therefore, get the page size form the BIOS storage area.
  119.                      */
  120.                     wlastpage = 3;        /* pages 0, 1, 2, 3 = 4 total */
  121.                     wpage_size = BIOS_PAGE_SIZE;
  122.                     }
  123.                 is50 = ON;
  124.                 }
  125.             else
  126.                 {
  127.                 /* don't want50 */
  128. #if 0                    
  129.             /* OLD-FASHIONED WAY TO SET 25 LINE MODE
  130.              */
  131.                 /*set BIOS to 25 line mode
  132.                  */
  133.                 _BX = 0;
  134.                 _AX = 0x1111;
  135.                 INTERRUPT (0x10);
  136.                 
  137.                 wcurscanln = 0x0C0D;        /* cursor scan lines */
  138.         
  139.                 /* force EGA/VGA cursor to correct size
  140.                  */
  141.                 _CX = 0x0C0D;            /* cursor size request */
  142.                 _AX = 1;
  143.                 INTERRUPT ( 0x10 );
  144.                 outport ( 0x03B4, 0x0D14 );
  145. #endif /* 0 */
  146.             /* NEW, easier way to restore 25-line mode
  147.              */
  148.                 /* revert video using BIOS mode select
  149.                  * MODE=3, bit 7 of AL =1 means save video contents
  150.                  */
  151.                 _AX = 0x0083;    
  152.                 INTERRUPT ( 0x10 );
  153.                 
  154.                 nlines   = 25; 
  155.                 wyabsmax = 24;
  156.                 
  157.                 /* wfullscreen may have been shrunk by 2 lines by wpulldown() 
  158.                  */
  159.                 wfullscreen->winymax = 24 - (wfullscreen-> wintop);
  160.                 if ( w0 -> winy > 24 )
  161.                     {
  162.                     /* make sure cursor is inside 24-line boundary
  163.                      */
  164.                     wgoto ( -1, 24 );
  165.                     }
  166.                 if ( w0 != wfullscreen )
  167.                     {
  168.                     /* make sure wfullscreen is also inside 24-line boundary
  169.                      */
  170.                     if (wfullscreen-> winy > (wfullscreen->winymax) )
  171.                         {
  172.                         wfullscreen-> winy = (wfullscreen->winymax);
  173.                         }
  174.                     }
  175.                 
  176.                 /* reset multiple pages if this is a 'paging' program
  177.                  */
  178.                 if ( wlastpage )
  179.                     {
  180.                     wlastpage = 7;        /* pages 0..7  = 8 total */
  181.                     wpage_size = 4096;
  182.                     }
  183.                 is50 = OFF;
  184.                 }
  185.                         
  186.             /* the cursor was turned 'ON' during the above manipulation.
  187.              * if the cursor was 'OFF' prior to calling this routine, 
  188.              * it should be turned 'OFF' again.
  189.              */
  190.             if ( (w0-> winflag & WFL_CURSOR) == 0 )
  191.                 {
  192.                 wcursor (OFF);
  193.                 }
  194.                         
  195.             /* change mouse mvt limits to match nlines.
  196.              */
  197.             if ( wmouse.wms_present )
  198.                 {
  199.                 _DX = (nlines*8)-1;
  200.                 _CX = 0;
  201.                 _AX = 0x08;
  202.                 INTERRUPT ( 0x33 );
  203.                 }
  204.                                         
  205.             }        /* end if wmonitor== 'E' or 'V' and wmode=='T' */
  206.             
  207.     return (is50);        /* w50line() */
  208.     }
  209.     
  210. static void clear50 (void)
  211.     {
  212.     if ( is50 )
  213.         {
  214.         w50line ( OFF );
  215.         }
  216.     return;        /* clear50() - called only atexit */
  217.     }
  218.