dsxscrn.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,333 行 · 第 1/3 页

C
1,333
字号
{
    hw_display_type     temp;

    temp = HWDisplay.active;
    HWDisplay.active = HWDisplay.alt;
    HWDisplay.alt = temp;
    OnAlt = TRUE;
}

static bool ChkColour( void )
{
    if( ChkForColour( HWDisplay.active ) ) {
        return( TRUE );
    }
    if( ChkForColour( HWDisplay.alt ) ) {
        SwapActAlt();
        return( TRUE );
    }
    return( FALSE );
}

static bool ChkForMono( hw_display_type display )
{
    if( ColourAdapters[ display ] >= 0 ) {
        return( FALSE );
    }
    ScrnMode = MD_MONO;
    return( TRUE );
}

static bool ChkMono( void )
{
    if( ChkForMono( HWDisplay.active ) ) {
        return( TRUE );
    }
    if( ChkForMono( HWDisplay.alt ) ) {
        SwapActAlt();
        return( TRUE );
    }
    return( FALSE );
}

static bool ChkForEGA( hw_display_type display )
{
    switch( display ) {
    case DISP_EGA_COLOUR:
    case DISP_VGA_COLOUR:
    case DISP_EGA_MONO:
    case DISP_VGA_MONO:
        ScrnMode = MD_EGA;
        return( TRUE );
    default:
        return( FALSE );
    }
}

static bool ChkEGA( void )
{
    if( ChkForEGA( HWDisplay.active ) ) {
        return( TRUE );
    }
    if( ChkForEGA( HWDisplay.alt ) ) {
        SwapActAlt();
        return( TRUE );
    }
    return( FALSE );
}

static void GetDefault( void )
{
    if( StartScrn.mode == 0x07 || StartScrn.mode == 0x0f ) {
        if( FlipMech == FLIP_TWO ) {
            if( ChkColour() == FALSE ) {
                FlipMech = FLIP_SWAP;
                ChkMono();
            }
        } else {
            ChkMono();
        }
    } else {
        if( FlipMech == FLIP_TWO ) {
            if( ChkMono() == FALSE ) {
                FlipMech = FLIP_PAGE;
                ChkColour();
            }
        } else {
            ChkColour();
        }
    }
}

static void ChkPage( void )
{
    switch( ScrnMode ) {
    case MD_MONO:
        FlipMech = FLIP_SWAP;
        break;
    case MD_EGA:
    case MD_COLOUR:
        break;
    default:
        FlipMech = FLIP_SWAP; /* for now */
        break;
    }
}

static void ChkTwo( void )
{
    if( HWDisplay.alt == DISP_NONE ) {
        FlipMech = FLIP_PAGE;
        ChkPage();
    }
}

static void SetChrSet( uint_16 set )
{
    if( set != USER_CHR_SET ) {
        BIOSEGAChrSet( set );
    }
}

static unsigned GetChrSet( uint_8 rows )
{
    if( rows >= 43 ) {
        return( DOUBLE_DOT_CHR_SET );
    }
    if( rows >= 28 ) {
        return( COMPRESSED_CHR_SET );
    }
    return( USER_CHR_SET );
}

static void SetEGA_VGA( int_16 double_rows )
{
    if( ScrnMode == MD_EGA ) {
        DbgRows = double_rows;
        DbgChrSet = DOUBLE_DOT_CHR_SET;
    } else if( FlipMech != FLIP_SWAP && FlipMech != FLIP_CHEAPSWAP ) {
        DbgRows = BIOSGetRows();
        DbgChrSet = USER_CHR_SET;
    } else {
        DbgChrSet = GetChrSet( BIOSGetRows() );
        switch( DbgChrSet ) {
        case USER_CHR_SET:
            DbgRows = 25;
            break;
        case COMPRESSED_CHR_SET:
            DbgRows = 28;
            break;
        case DOUBLE_DOT_CHR_SET:
            DbgRows = double_rows;
            break;
        }
    }
}

static void SetMonitor( void )
{
    DbgChrSet = USER_CHR_SET;
    switch( HWDisplay.active ) {
    case DISP_MONOCHROME:
        DbgBiosMode = 7;
        break;
    case DISP_CGA:
    case DISP_PGA:              /* just guessing here */
    case DISP_MODEL30_MONO:
    case DISP_MODEL30_COLOUR:
        if( ( StartScrn.mode == 2 ) && !OnAlt ) {
            DbgBiosMode = 2;
        } else {
            DbgBiosMode = 3;
        }
        break;
    case DISP_EGA_MONO:
        DbgBiosMode = 7;
        SetEGA_VGA( 43 );
        break;
    case DISP_EGA_COLOUR:
        DbgBiosMode = 3;
        SetEGA_VGA( 43 );
        break;
    case DISP_VGA_MONO:
    case DISP_VGA_COLOUR:
        if( ( StartScrn.mode == 7 ) && !OnAlt ) {
            DbgBiosMode = 7;
        } else {
            DbgBiosMode = 3;
        }
        SetEGA_VGA( 50 );
        break;
    }
    if( DbgRows == 0 ) {
        DbgRows = 25;
    }
    VIDPort = DbgBiosMode == 7 ? VIDMONOINDXREG : VIDCOLRINDXREG;
    if( ( ( StartScrn.mode & 0x7f ) == DbgBiosMode ) &&
        ( StartScrn.strt.rows == DbgRows ) ) {
        GetBIOSData( BD_REGEN_LEN, PageSize );  /* get size from BIOS */
    } else {
        PageSize = DbgRows == 25 ? 4096 : ( DbgRows * 80 * 2 + 256 );
    }
}

static void SaveBIOSSettings( void )
{
    SaveScrn.swtchs = GetSwtchs();
    SaveScrn.mode = BIOSGetMode();
    SaveScrn.save.page = BIOSGetPage();
    SaveScrn.save.curpos = BIOSGetCurPos( SaveScrn.save.page );
    SaveScrn.curtyp = BIOSGetCurTyp( SaveScrn.save.page );
    if( ( SaveScrn.curtyp == CGA_CURSOR_ON ) && ( SaveScrn.mode == 7 ) ) {
        /* screwy hercules card lying about cursor type */
        SaveScrn.curtyp = MON_CURSOR_ON;
    }
    switch( HWDisplay.active ) {
    case DISP_EGA_MONO:
    case DISP_EGA_COLOUR:
    case DISP_VGA_MONO:
    case DISP_VGA_COLOUR:
        SaveScrn.points = BIOSGetPoints();
        break;
    default:
        SaveScrn.points = 8;
        break;
    }
}

/* ForceLines -- force a specified number of lines for MDA/CGA systems */
extern void ForceLines( uint_16 lines )
{
    DbgRows = lines;
}

static void GetAdapter( void )
{
    switch( ScrnMode ) {
    case MD_HERC: /* temp */
    case MD_DEFAULT:
        GetDefault();
        break;
    case MD_MONO:
        if( ChkMono() == FALSE ) {
            GetDefault();
        }
        break;
    case MD_COLOUR:
        if( ChkColour() == FALSE ) {
            GetDefault();
        }
        break;
    case MD_EGA:
        if( ChkEGA() == FALSE ) {
            GetDefault();
        }
        break;
    }
}

/* ConfigScreen -- figure out screen configuration we're going to use. */
extern uint_32 ConfigScreen( void )
{
    OnAlt = FALSE;
    GetDispConfig();
    SaveBIOSSettings();
    StartScrn.points = SaveScrn.points;
    StartScrn.curtyp = SaveScrn.curtyp;
    StartScrn.swtchs = SaveScrn.swtchs;
    StartScrn.mode = SaveScrn.mode;
    StartScrn.strt.attr = ( StartScrn.mode < 4 ) || ( StartScrn.mode == 7 ) ?
                          BIOSGetAttr( SaveScrn.save.page ) & 0x7f : 0;
    switch( HWDisplay.active ) {
    case DISP_EGA_MONO:
    case DISP_EGA_COLOUR:
    case DISP_VGA_MONO:
    case DISP_VGA_COLOUR:
        StartScrn.strt.rows = BIOSGetRows();
        break;
    }
    GetAdapter();
    /* get flip mechanism to use */
    switch( FlipMech ) {
    case FLIP_PAGE:
        ChkPage();
        break;
    case FLIP_TWO:
        ChkTwo();
        break;
    }
    if( uiisdbcs() ) {
        VirtScreen = video_buffer( COLOUR_VIDEO_BUFF );
        if( VirtScreen == COLOUR_VIDEO_BUFF ) {
            VirtScreen = NULL;
        } else if( FlipMech == FLIP_PAGE ) {
            FlipMech = FLIP_CHEAPSWAP;
        }
    } else if( FlipMech == FLIP_SWAP ) {
        FlipMech = FLIP_CHEAPSWAP;
    }
    SetMonitor();
    BIOSSetCurTyp( StartScrn.curtyp );
    return( PageSize );
}

static bool SetMode( uint_8 mode )
{
    if( ( BIOSGetMode() & 0x7f ) == ( mode & 0x7f ) ) {
        return( FALSE );
    }
    DoSetMode( mode );
    return( TRUE );
}

static void SetRegenClear( void )
{
    uint_8              regen;

    GetBIOSData( BD_VID_CTRL1, regen );
    regen &= 0x7f;
    regen |= SaveScrn.mode & 0x80;
    SetBIOSData( BD_VID_CTRL1, regen );
}

static uint_16 RegenSize( void )
{
    uint_16     regen_size;

    switch( HWDisplay.active ) {
    case DISP_MONOCHROME:
        regen_size = ( DbgRows * 80 * 2 + 0x3ff ) & ~0x3ff;
        break;
    case DISP_CGA:
    case DISP_PGA:
    case DISP_MODEL30_MONO:
    case DISP_MODEL30_COLOUR:
        regen_size = ( ( DbgRows * 80 * 2 + 0x3ff ) & ~0x3ff ) * 4;
        break;
    case DISP_VGA_MONO:
    case DISP_VGA_COLOUR:
    case DISP_EGA_COLOUR:
    case DISP_EGA_MONO:
        regen_size = PageSize * 2;
        break;
    }
    return( regen_size );
}

static void SetupEGA( void )
{
    _disablev( VIDPort + 6 );
    _seq_write( SEQ_MEM_MODE, MEM_NOT_ODD_EVEN );
    _graph_write( GRA_MISC, MIS_A000_64 | MIS_GRAPH_MODE );
    _graph_write( GRA_ENABLE_SR, 0 );
    _graph_write( GRA_DATA_ROT, ROT_UNMOD | 0 );
    _graph_write( GRA_GRAPH_MODE, GRM_EN_ROT );
}

static void SwapSave( void )
{
    switch( HWDisplay.active ) {
    case DISP_VGA_MONO:
    case DISP_VGA_COLOUR:
        _VidStateSave( VID_STATE_SWAP, SwapSeg.s.rm, StateOff );
        /* fall through */
    case DISP_EGA_MONO:
    case DISP_EGA_COLOUR:
        SetupEGA();
        if( FlipMech == FLIP_CHEAPSWAP ) {
            _graph_write( GRA_READ_MAP, RMS_MAP_0 );
            _fmemcpy( &RegenSave[0], EGA_VIDEO_BUFF, PageSize );
            _graph_write( GRA_READ_MAP, RMS_MAP_1 );
            _fmemcpy( &RegenSave[PageSize], EGA_VIDEO_BUFF, PageSize );
            _graph_write( GRA_READ_MAP, RMS_MAP_2 );
            _fmemcpy( MK_PM( SwapSeg.s.rm, 0 ), EGA_VIDEO_BUFF, 8*1024 );
            if( VirtScreen != NULL ) {
                _fmemcpy( &RegenSave[PageSize * 2], VirtScreen,  PageSize );
            }
        } else {
            _graph_write( GRA_READ_MAP, RMS_MAP_0 );
            _fmemcpy( &RegenSave[0*_64K], EGA_VIDEO_BUFF, _64K );
            _graph_write( GRA_READ_MAP, RMS_MAP_1 );
            _fmemcpy( &RegenSave[1*_64K], EGA_VIDEO_BUFF, _64K );
            _graph_write( GRA_READ_MAP, RMS_MAP_2 );
            _fmemcpy( &RegenSave[2*_64K], EGA_VIDEO_BUFF, _64K );
            _graph_write( GRA_READ_MAP, RMS_MAP_3 );
            _fmemcpy( &RegenSave[3*_64K], EGA_VIDEO_BUFF, _64K );
            if( VirtScreen != NULL ) {
                _fmemcpy( &RegenSave[4*_64K], VirtScreen,  PageSize );
            }
        }
        _graph_write( GRA_READ_MAP, RMS_MAP_0 );
        /* blank regen area (attributes) */
        _seq_write( SEQ_MAP_MASK, MSK_MAP_1 );
        Fillb( EGA_VIDEO_BUFF, 0, PageSize );
        DoSetMode( DbgBiosMode | 0x80 );
        SetChrSet( DbgChrSet );
        break;
    case DISP_MONOCHROME:
        _fmemcpy( &RegenSave[0], MONO_VIDEO_BUFF, RegenSize() );
        SetMode( DbgBiosMode );
        break;
    default:
        _fmemcpy( &RegenSave[0], COLOUR_VIDEO_BUFF, RegenSize() );
        SetMode( DbgBiosMode );
        break;
    }
}

static uint_8 RestoreEGA_VGA( void )
{
    uint_8       mode;

    if( FlipMech == FLIP_CHEAPSWAP ) {
        SetupEGA();
        _seq_write( SEQ_MAP_MASK, MSK_MAP_0 );
        _fmemcpy( EGA_VIDEO_BUFF, &RegenSave[0], PageSize );
        _seq_write( SEQ_MAP_MASK, MSK_MAP_1 );
        _fmemcpy( EGA_VIDEO_BUFF, &RegenSave[PageSize], PageSize );
        mode = SaveScrn.mode & 0x7f;
        if( ( mode < 4 ) || ( mode == 7 ) ) {
            if( VirtScreen != NULL ) {
                _fmemcpy( VirtScreen, &RegenSave[PageSize * 2], PageSize );
                _seq_write( SEQ_MAP_MASK, MSK_MAP_2 );
                _fmemcpy( EGA_VIDEO_BUFF, MK_PM( SwapSeg.s.rm, 0 ), 8*1024 );
                DoSetMode( SaveScrn.mode | 0x80 );
            } else {
                DoSetMode( SaveScrn.mode | 0x80 );
                BIOSCharSet( 0, 32, 256, 0, SwapSeg.s.rm, 0 );
            }
        } else {
            _seq_write( SEQ_MAP_MASK, MSK_MAP_2 );
            _fmemcpy( EGA_VIDEO_BUFF, MK_PM( SwapSeg.s.rm, 0 ), 8*1024 );
            DoSetMode( SaveScrn.mode | 0x80 );
        }
    } else {
        /* stupid thing doesn't respect the no-clear bit in DBCS mode */
        DoSetMode( SaveScrn.mode );
        if( VirtScreen != NULL ) {
            _fmemcpy( VirtScreen, &RegenSave[4*_64K], PageSize );
        }
        SetupEGA();
        _seq_write( SEQ_MAP_MASK, MSK_MAP_0 );
        _fmemcpy( EGA_VIDEO_BUFF, &RegenSave[0*_64K], _64K );
        _seq_write( SEQ_MAP_MASK, MSK_MAP_1 );
        _fmemcpy( EGA_VIDEO_BUFF, &RegenSave[1*_64K], _64K );
        _seq_write( SEQ_MAP_MASK, MSK_MAP_2 );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?