setrows.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 392 行
C
392 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Routines to set number of text rows.
*
****************************************************************************/
#include <conio.h>
#include "gdefn.h"
#include "gbios.h"
#if defined( _DEFAULT_WINDOWS )
short _SetRows( short rows )
/*==========================
This function has no effect on Windows. It only re-initializes
the variable states. */
{
_ErrorStatus = _GROK;
_InitState(); // read the current machine state
rows = rows;
_clearscreen( _GCLEARSCREEN );
_Tx_Row_Min = 0; // text window is now
_Tx_Col_Min = 0; // the full screen
_Tx_Row_Max = _CurrState->vc.numtextrows - 1;
_Tx_Col_Max = _CurrState->vc.numtextcols - 1;
_TextPos.row = 0; // set mode function
_TextPos.col = 0; // sets position to 0,0
return( 0 );
}
#else
#define TX_CURS_8x8 0x0607
#define TX_CURS_8x14 0x0B0C
#define TX_CURS_EMU 0x0600
#define TX_FONT_8x8 0x1112
#define TX_FONT_8x14 0x1111
#define GR_FONT_8x8 0x1123
#define GR_FONT_8x14 0x1122
#define GR_FONT_8x16 0x1124
#define SCAN_200 0x1200
#define SCAN_350 0x1201
#define SCAN_400 0x1202
static void Load_25( void );
static void Load_VGA( short, short, short );
static void Load_EGA( short, short, short );
static void Load_MCGA( short, short, short );
extern void InitGener( void );
#if defined ( __386__ )
#pragma aux InitGener = \
0x06 /* push es */ \
0xb8 0x00 0xa0 0x00 0x00 /* mov ax,0a000H */ \
0x8e 0xc0 /* mov es,ax */ \
0x33 0xc0 /* xor eax,eax */ \
0x8b 0xf8 /* mov edi,eax */ \
0xb9 0x00 0x10 0x00 0x00 /* mov ecx,1000H */ \
0x66 0xab /* L1 stosw */ \
0xfe 0xc0 /* inc al */ \
0xe2 0xfa /* loop L1 */ \
0x07 /* pop es */ \
modify [eax ecx edi];
#else
#pragma aux InitGener = \
0xb8 0x00 0xa0 /* mov ax,0a000H */ \
0x8e 0xc0 /* mov es,ax */ \
0x33 0xc0 /* xor ax,ax */ \
0x8b 0xf8 /* mov di,ax */ \
0xb9 0x00 0x10 /* mov cx,1000H */ \
0xab /* L1 stosw */ \
0xfe 0xc0 /* inc al */ \
0xe2 0xfb /* loop L1 */ \
modify [ax cx es di];
#endif
static void TextModeRows( short rows )
//====================================
{
if( rows == _MAXTEXTROWS ) {
switch( _CurrState->vc.adapter ) {
case _MCGA:
case _VGA:
case _SVGA:
rows = 50;
break;
case _EGA:
if( _CurrState->vc.monitor == _COLOR ) {
rows = 25;
} else { // enhanced colour
rows = 43;
}
break;
default:
return; // can't be changed
}
}
if( rows == 25 ) {
Load_25();
return;
}
switch( _CurrState->vc.adapter ) { // find a text mode
case _VGA:
case _SVGA:
switch( rows ) {
case 28:
Load_VGA( SCAN_400, TX_FONT_8x14, TX_CURS_8x14 );
break;
case 43:
Load_VGA( SCAN_350, TX_FONT_8x8, TX_CURS_8x8 );
break;
case 50:
Load_VGA( SCAN_400, TX_FONT_8x8, TX_CURS_8x8 );
break;
default:
_ErrorStatus = _GRINVALIDPARAMETER;
}
break;
case _EGA:
if( _CurrState->vc.monitor == _COLOR ) {
switch( rows ) { // 200 scan lines
case 14:
Load_EGA( rows, TX_FONT_8x14, TX_CURS_8x14 );
break;
default:
_ErrorStatus = _GRINVALIDPARAMETER;
}
} else { // EGA Mono or Enhanced
switch( rows ) {
case 43: // 350 scan lines
Load_EGA( rows, TX_FONT_8x8, TX_CURS_EMU );
break;
default:
_ErrorStatus = _GRINVALIDPARAMETER;
}
}
break;
case _MCGA:
switch( rows ) {
case 40:
Load_MCGA( rows, TX_FONT_8x8, 0x0404 );
break;
case 50:
Load_MCGA( rows, TX_FONT_8x8, 0x0303 );
break;
default:
_ErrorStatus = _GRINVALIDPARAMETER;
}
break;
default:
_ErrorStatus = _GRERROR;
}
}
static void GrModeRows( short rows )
//==================================
{
short font;
switch( _CurrState->vc.mode ) {
case _ERESNOCOLOR:
case _ERESCOLOR:
switch( rows ) {
case 25:
font = GR_FONT_8x14; // 8x14
break;
case _MAXTEXTROWS:
rows = 43;
case 43:
font = GR_FONT_8x8; // 8x8
break;
default:
_ErrorStatus = _GRINVALIDPARAMETER;
return;
}
break;
case _VRES2COLOR:
case _VRES16COLOR:
switch( rows ) {
case 30:
font = GR_FONT_8x16; // 8x16
break;
case 34:
font = GR_FONT_8x14; // 8x14
break;
case _MAXTEXTROWS:
rows = 60;
case 60:
font = GR_FONT_8x8; // 8x8
break;
default:
_ErrorStatus = _GRINVALIDPARAMETER;
return;
}
break;
// 25 rows for all other graphics modes
default:
if (rows != 25) {
_ErrorStatus = _GRERROR;
}
return;
}
VideoInt( _BIOS_SET_MODE + GetVideoMode(), 0, 0, 0 );
// Load pointer to character set
if( _CurrState->vc.adapter == _EGA ) {
VideoInt( font, 0, 0, rows - 1 ); // do this only for the EGA
} else {
VideoInt( font, 0, 0, rows );
}
_GrCursor = 0; // cursor is off
}
short _SetRows( short rows )
/*==========================
This function sets the number of text rows in the current mode. It only
affects the _VGA, _EGA, and _MCGA adapters. */
{
_ErrorStatus = _GROK;
_InitState(); // read the current machine state
if( _GrMode ) {
GrModeRows( rows );
} else {
TextModeRows( rows );
}
if( _ErrorStatus != _GROK ) {
return( 0 );
} else {
rows = *(char far *)_BIOS_data( ROWS ) + 1; // 0 for Hercules
if( rows == 1 ) rows = 25;
_CurrState->vc.numtextrows = rows;
if( !_GrMode ) {
_CalcNumPages(); // update the video configuration
}
_Tx_Row_Min = 0; // text window is now
_Tx_Col_Min = 0; // the full screen
_Tx_Row_Max = _CurrState->vc.numtextrows - 1;
_Tx_Col_Max = _CurrState->vc.numtextcols - 1;
_TextPos.row = 0; // set mode function
_TextPos.col = 0; // sets position to 0,0
_CurrVisualPage = 0;
_CurrActivePage = 0;
VideoInt( _BIOS_VIDEO_PAGE, 0, 0, 0 ); // set to page 0
return( _CurrState->vc.numtextrows );
}
}
static void Load_25( void )
/*===================
When we want to go back to a 25-row display, just do a set mode
and update a few variables. */
{
VideoInt( _BIOS_SET_MODE + GetVideoMode(), 0, 0, 0 );
*(char far *)_BIOS_data( INFO ) &= 0xFE; // cursor emulation off
VideoInt( _BIOS_CURSOR_SIZE, 0, 0x0607, 0 ); // reset the cursor
_GrCursor = 1; // cursor is on
}
static void Load_VGA( short scan, short font, short cursor )
/*==========================================================
This routines loads an alphanumeric font for the VGA. */
{
VideoInt( scan, 0x0030, 0, 0 ); // becomes effective at next set mode
VideoInt( _BIOS_SET_MODE + GetVideoMode(), 0, 0, 0 );
VideoInt( _BIOS_VIDEO_PAGE, 0, 0, 0 ); // set active page to 0
VideoInt( font, 0, 0, 0 ); // load character set
VideoInt( _BIOS_CURSOR_SIZE, 0, cursor, 0 ); // reset the cursor
_GrCursor = 1; // cursor is on
}
static void Load_EGA( short rows, short font, short cursor )
/*==========================================================
This routines loads an alphanumeric font for the EGA. */
{
VideoInt( _BIOS_VIDEO_PAGE, 0, 0, 0 ); // set active page to 0
VideoInt( _BIOS_SET_MODE + GetVideoMode(), 0, 0, 0 );
VideoInt( font, 0, 0, 0 ); // load pointer to character set in block 0
if( rows == 43 ) { // cursor emulation
*(char far *)_BIOS_data( INFO ) |= 1; // 43 rows only
} else {
outpw( 0x03D4, 0x1414 ); // reset underline location to none
}
VideoInt( _BIOS_CURSOR_SIZE, 0, cursor, 0 ); // reset the cursor
_GrCursor = 1; // cursor is on
}
static void Load_MCGA( short rows, short font, short cursor )
/*===========================================================
This routines loads an alphanumeric font for the MCGA. */
{
VideoInt( _BIOS_VIDEO_PAGE, 0, 0, 0 ); // set active page to 0
VideoInt( _BIOS_SET_MODE + GetVideoMode(), 0, 0, 0 );
InitGener(); // must do for MCGA 40 rows
VideoInt( font & 0xFF0F, 0, 0, 0 ); // load character set
VideoInt( 0x1103, 0, 0, 0 );
VideoInt( _BIOS_CURSOR_SIZE, 0, cursor, 0 ); // reset the cursor
outpw( 0x03D4, ( cursor & 0xFF00 ) + 0x09 ); // # double scan lines
*(char far *)_BIOS_data( ROWS ) = rows - 1; // # of rows
// # of vertical points per character
*(short far *)_BIOS_data( POINTS ) = 2 * ( cursor & 0xFF + 1 );
_GrCursor = 1; // cursor is on
}
#endif
short _WCI86FAR _CGRAPH _settextrows( short rows )
/*===========================================
This function sets the number of text rows in the current mode. It only
affects the _VGA, _EGA, and _MCGA adapters. */
{
short set_rows;
set_rows = _SetRows( rows );
#if !defined( _DEFAULT_WINDOWS )
_PaletteInit(); // need to reset palette after changing mode
#endif
return( set_rows );
}
Entry( _SETTEXTROWS, _settextrows ) // alternate entry-point
short _WCI86FAR _CGRAPH _setvideomoderows( short mode, short rows )
/*============================================================
This routine sets the video mode if it is supported by the current
hardware configuration, then sets the number of text rows requested. It
returns the number of text rows if successful, otherwise it returns 0. */
{
if( _setvideomode( mode ) ) {
return( _settextrows( rows ) );
}
return( 0 );
}
Entry( _SETVIDEOMODEROWS, _setvideomoderows ) // alternate entry-point
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?