uibios.c

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

C
515
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include <string.h>
#include <extender.h>
#include "uidos.h"
#include "biosui.h"
#include "uidef.h"
#include "dpmi.h"

typedef struct {
    unsigned short  int_num;
    unsigned short  real_ds;
    unsigned short  real_es;
    unsigned short  real_fs;
    unsigned short  real_gs;
    long            real_eax;
    long            real_edx;
} PHARLAP_block;

void intern DBCSCharacterMap( void );

static          MONITOR                 ui_data         =       {
                25,
                80,
                M_CGA,
                NULL,
                NULL,
                NULL,
                NULL,
                4,
                1
};


unsigned    BIOSVidPage;

#ifdef __386__
void far *firstmeg( unsigned segment, unsigned offset )
{
#if defined(__OSI__) || __WATCOMC__ >= 1000
    return( MK_FP( _ExtenderRealModeSelector, (unsigned) (segment << 4) + offset ) );
#else
    if( _IsRational() ) {
        return( MK_FP( FP_SEG( &BIOSVidPage ), (unsigned) ( segment << 4 ) + offset ) );
    } else {
        return( MK_FP( REAL_SEGMENT, (unsigned) ( segment << 4 ) + offset ) );
    }
#endif
}
#endif

void intern setvideomode( unsigned mode )
/***************************************/
{
    BIOSSetMode( mode );
}


bool global uiset80col( void )
/****************************/

{
    register    bool            status;

    status = FALSE;
    if( UIData->width != 80 ) {
        if( UIData->colour == M_MONO ) {
            setvideomode( 7 );
        } else if( UIData->colour == M_BW ) {
            setvideomode( 2 );
        } else {
            setvideomode( 3 );
        }
        status = TRUE;
    }
    return( status );
}

extern unsigned char DOS_int( unsigned short, unsigned short, unsigned short );
#pragma aux DOS_int =   \
        _INT_21         \
    parm [ax] [cx] [dx] value [al];

#define desqview_present() (DOS_int(0x2b01,0x4445,0x5351)!=0xff)

/*
    The code for video_buffer is identical for DOS/V and desqview
    (Get Video Buffer: int 10h, AH=FEh)
*/

void far * global video_buffer( void far *vbuff )
/***********************************************/
{
#ifdef __386__
    union REGPACK       regs;
    rm_call_struct      dblock;

    if( _IsPharLap() ) {
        memset( &regs, 0, sizeof( regs ) );
        regs.h.ah = 0xfe;
        regs.x.edi = FP_OFF( vbuff );
        regs.w.es = FP_SEG( vbuff );
        intr( BIOS_VIDEO, &regs );
        if( FP_OFF( vbuff ) != regs.x.edi ) {
            /* we use FP_OFF since old_selector==0x34 and new_selector==0x37 */
            vbuff = MK_FP( regs.w.es, regs.x.edi );
        }
    } else if( _IsRational() ) {
        memset( &dblock, 0, sizeof( dblock ) );
        dblock.eax = 0xfe00;                /* get video buffer addr */
        dblock.es = FP_OFF( vbuff ) >> 4;
        dblock.edi = (FP_OFF( vbuff ) & 0x0f);
        DPMISimulateRealModeInterrupt( BIOS_VIDEO, 0, 0, &dblock );
        return( firstmeg( dblock.es, dblock.edi ) );
    }
    return( vbuff );
#else
extern void far *       get_video_buffer( void far * );
#pragma aux             get_video_buffer = \
        0xb4 0xfe       /* mov ah,0xfe */ \
        0xcd 0x10       /* int 0x10 */ \
        parm caller     [es di] \
        value           [es di] \
        modify          [ah];

    return( get_video_buffer( vbuff ) );
#endif
}


typedef struct {
    unsigned char       start_range;
    unsigned char       end_range;
} dbcs_pair;

#ifndef __386__

extern dbcs_pair far *  dbcs_vector_table( void );
#pragma aux             dbcs_vector_table = \
        "push ds"       \
        "mov ax,6300h"  /* get DBCS vector table */ \
        "int 21h"       \
        "mov di,ds"     \
        "pop ds"        \
        value           [di si] \
        modify          [ax];

#else

dbcs_pair far * intern dbcs_vector_table( void )
/***************************************************/
{
    union       REGPACK                 regs;
    static dbcs_pair dbcs_dummy = { 0, 0 };

    if( UIData->colour == M_MONO ) return( &dbcs_dummy );
    if( _IsPharLap() ) {
        PHARLAP_block pblock;

        memset( &pblock, 0, sizeof( pblock ) );
        memset( &regs, 0, sizeof( regs ) );
        pblock.real_eax = 0x6300;           /* get DBCS vector table */
        pblock.int_num = 0x21;              /* DOS call */
        regs.x.eax = 0x2511;                /* issue real-mode interrupt */
        regs.x.edx = FP_OFF( &pblock );     /* DS:EDX -> parameter block */
        regs.w.ds = FP_SEG( &pblock );
        intr( 0x21, &regs );
        if( pblock.real_ds == 0xFFFF ) { // wierd OS/2 value
            return( &dbcs_dummy );
        } else {
            return( firstmeg( (unsigned) pblock.real_ds, (unsigned) regs.w.si ) );
        }
    } else if( _IsRational() ) {
        rm_call_struct dblock;

        memset( &dblock, 0, sizeof( dblock ) );
        dblock.eax = 0x6300;                    /* get DBCS vector table */
        DPMISimulateRealModeInterrupt( 0x21, 0, 0, &dblock );
        if( (dblock.flags & 1) == 0 ) {
            return( firstmeg( dblock.ds, dblock.esi ) );
        }
    }
    return( &dbcs_dummy );
}

#endif

static dbcs_pair        Pairs[5];       // safe enough for now
static int              Init;

void intern initdbcs( void )
{
    dbcs_pair           *p;
    dbcs_pair           far *s;

    s = dbcs_vector_table();
    p = Pairs;
    while( s->start_range != 0 ) {
        p->start_range = s->start_range;
        p->end_range = s->end_range;
        ++p;
        ++s;
    }
    p->start_range = 0;
    p->end_range = 0;
    Init = TRUE;
}

int global uiisdbcs( void )
{
    if( !Init ) initdbcs();
    return( Pairs[0].start_range != 0 );
}

int global uionnec( void )
{
    return( FALSE );
}

int global uicharlen( int ch )
{
    dbcs_pair           *p;


    if( !Init ) initdbcs();

⌨️ 快捷键说明

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