dsxscrn.c

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

C
1,333
字号
/****************************************************************************
*
*                            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 <stdui.h>
#include <string.h>
#include <dos.h>
#include <watcom.h>
#include "dbgdefn.h"
#include "dbgscrn.h"
#include "dbgmem.h"
#include "dbgtoggl.h"
#include "dbgwind.h"
#include "dsxutil.h"
#include "pcscrnio.h"
#include "dpmi.h"


#define _64K                    (64UL*1024)
#define EGA_VIDEO_BUFF          MK_PM( 0xa000, 0 )
#define MONO_VIDEO_BUFF         MK_PM( 0xb000, 0 )
#define COLOUR_VIDEO_BUFF       MK_PM( 0xb800, 0 )

#define CURS_LOCATION_LOW       0xf
#define CURS_LOCATION_HI        0xe
#define CURS_START_SCANLINE     0xa
#define CURS_END_SCANLINE       0xb

#define DOUBLE_DOT_CHR_SET      0x12
#define COMPRESSED_CHR_SET      0x11
#define USER_CHR_SET            0

#define EGA_CURSOR_OFF          0x1e00
#define NORM_CURSOR_OFF         0x2000
#define CGA_CURSOR_ON           0x0607
#define MON_CURSOR_ON           0x0b0c

#define MSMOUSE_VECTOR          0x33
#define VID_STATE_SWAP          VID_STATE_ALL

#define GetBIOSData( off, var ) var =                                        \
                                sizeof( var ) == 1 ?                         \
                                    *(uint_8 __far *)MK_PM( BD_SEG, off ) :     \
                                sizeof( var ) == 2 ?                         \
                                    *(uint_16 __far *)MK_PM( BD_SEG, off ) :    \
                                *(uint_32 __far *)MK_PM( BD_SEG, off );

#define SetBIOSData( off, var ) ( sizeof( var ) == 1 ) ?                             \
                                    ( *(uint_8 __far *)MK_PM( BD_SEG, off )          \
                                        = var ) :                            \
                                ( ( sizeof( var ) == 2 ) ?                           \
                                    ( *(uint_16 __far *)MK_PM( BD_SEG, off )         \
                                        = var ) :                            \
                                ( *(uint_32 __far *)MK_PM( BD_SEG, off ) = var ) );


enum {
    BD_SEG          = 0x40,
    BD_EQUIP_LIST   = 0x10,
    BD_CURR_MODE    = 0x49,
    BD_REGEN_LEN    = 0x4c,
    BD_CURPOS       = 0x50,
    BD_MODE_CTRL    = 0x65,
    BD_VID_CTRL1    = 0x87,
};

typedef enum {
    DISP_NONE,
    DISP_MONOCHROME,
    DISP_CGA,
    DISP_RESERVED1,
    DISP_EGA_COLOUR,
    DISP_EGA_MONO,
    DISP_PGA,
    DISP_VGA_MONO,
    DISP_VGA_COLOUR,
    DISP_RESERVED2,
    DISP_RESERVED3,
    DISP_MODEL30_MONO,
    DISP_MODEL30_COLOUR
} hw_display_type;

enum {
    ADAPTER_MONO   = -1,
    ADAPTER_NONE   = 0,
    ADAPTER_COLOUR = 1
};

typedef struct {
    hw_display_type     active;
    hw_display_type     alt;
} display_configuration;

typedef struct {
    uint_8              points;
    uint_8              mode;
    uint_8              swtchs;
    int_16              curtyp;
    union {
        struct {
            uint_8      rows;
            uint_8      attr;
        } strt;
        struct {
            uint_8      page;
            int_16      curpos;
        } save;
    };
} screen_info;


extern void                     StartupErr( char * );
extern int                      initmouse( int );
extern int                      GUIInitMouse( int );
extern void                     GUIFiniMouse( void );
extern void                     GUIInitGraphicsMouse( gui_window_styles );
extern bool                     UserScreen( void );

extern void                     far *video_buffer( void far * );

extern screen_state             ScrnState;
extern flip_types               FlipMech = 0;
extern mode_types               ScrnMode = 0;
extern gui_window_styles        WndStyle;


static rm_call_struct           CallStruct;
static uint_8                   OldRow;
static uint_8                   OldCol;
static uint_8                   OldTyp;
static bool                     OnAlt;
static screen_info              StartScrn;
static screen_info              SaveScrn;
static uint_16                  VIDPort;
static uint_16                  PageSize;
static uint_16                  CurOffst;
static uint_16                  RegCur;
static uint_16                  InsCur;
static uint_16                  NoCur;
static uint_8                   DbgBiosMode;
static uint_8                   DbgChrSet;
static uint_8                   DbgRows;
static dos_memory               SwapSeg;
static addr32_off               StateOff;
static addr32_off               PgmMouse;
static addr32_off               DbgMouse;
static display_configuration    HWDisplay;
static unsigned_8               *RegenSave;
static void                     far *VirtScreen;
static int_8                    ColourAdapters[] = {
                                    ADAPTER_NONE,     /* NONE              */
                                    ADAPTER_MONO,     /* MONOCHROME        */
                                    ADAPTER_COLOUR,   /* CGA               */
                                    ADAPTER_NONE,     /* RESERVED          */
                                    ADAPTER_COLOUR,   /* EGA COLOUR        */
                                    ADAPTER_MONO,     /* EGA MONO          */
                                    ADAPTER_COLOUR,   /* PGA               */
                                    ADAPTER_COLOUR,   /* VGA MONO          */
                                    ADAPTER_COLOUR,   /* VGA COLOUR        */
                                    ADAPTER_NONE,     /* RESERVED          */
                                    ADAPTER_NONE,     /* RESERVED          */
                                    ADAPTER_COLOUR,   /* MODEL 30 MONO     */
                                    ADAPTER_COLOUR    /* MODEL 30 COLOUR   */
                                };



static void _VidStateSave( uint_16 requested_state, addr_seg buff_rmseg,
                           addr32_off buff_offset )
{
    memset( &CallStruct, 0, sizeof( CallStruct ) );
    CallStruct.eax = 0x1c01;
    CallStruct.es = buff_rmseg;
    CallStruct.ebx = buff_offset;
    CallStruct.ecx = requested_state;
    DPMISimulateRealModeInterrupt( 0x10, 0, 0, &CallStruct );
}

static void _VidStateRestore( uint_16 requested_state, addr_seg buff_rmseg,
                              addr32_off buff_offset )
{
    memset( &CallStruct, 0, sizeof( CallStruct ) );
    CallStruct.eax = 0x1c02;
    CallStruct.es = buff_rmseg;
    CallStruct.ebx = buff_offset;
    CallStruct.ecx = requested_state;
    DPMISimulateRealModeInterrupt( 0x10, 0, 0, &CallStruct );
}

static void BIOSCharSet( uint_8 vidroutine, uint_8 bytesperchar,
                         uint_16 patterncount, uint_16 charoffset,
                         addr_seg table_rmseg, addr32_off table_offset )
{
    memset( &CallStruct, 0, sizeof( CallStruct ) );
    CallStruct.eax = 0x1100 | vidroutine;
    CallStruct.ebx = (uint_32)bytesperchar << 8;
    CallStruct.ecx = patterncount;
    CallStruct.edx = charoffset;
    CallStruct.es = table_rmseg;
    CallStruct.ebp = table_offset;
    DPMISimulateRealModeInterrupt( 0x10, 0, 0, &CallStruct );
}

static void MouseSaveState( addr_seg buff_rmseg, addr32_off buff_offset )
{
    memset( &CallStruct, 0, sizeof( CallStruct ) );
    CallStruct.eax = 0x16;
    CallStruct.es = buff_rmseg;
    CallStruct.edx = buff_offset;
    DPMISimulateRealModeInterrupt( 0x33, 0, 0, &CallStruct );
}

static void MouseRestoreState( addr_seg buff_rmseg, addr32_off buff_offset )
{
    memset( &CallStruct, 0, sizeof( CallStruct ) );
    CallStruct.eax = 0x17;
    CallStruct.es = buff_rmseg;
    CallStruct.edx = buff_offset;
    DPMISimulateRealModeInterrupt( 0x33, 0, 0, &CallStruct );
}

extern uint_16 MouseSaveSize( void );
#pragma aux MouseSaveSize =                             \
        " mov    ax, 15h        ",                      \
        " int    33h "                                  \
        modify exact [ ax bx ]                          \
        value [ bx ];

extern display_configuration BIOSDevCombCode( void );
#pragma aux BIOSDevCombCode =                           \
        " push   ebp            "                       \
        " mov    ax, 1a00h      "                       \
        _INT_10                                         \
        " cmp    al, 1ah        "                       \
        " jz     end            "                       \
        " mov    bx, 0          "                       \
        " end:                  "                       \
        " pop    ebp            "                       \
        modify exact [ ax bx ]                          \
        value [ bx ];

extern void DoRingBell( void );
#pragma aux DoRingBell =                                \
        " push   ebp            "                       \
        " mov    ax, 0e07h      "                       \
        _INT_10                                         \
        " pop    ebp            "                       \
        modify exact [ ax ];

extern void RingBell( void )
{
    DoRingBell();
}

static uint_8 VIDGetRow( uint_16 vidport )
{
    return( _ReadCRTCReg( vidport, CURS_LOCATION_LOW ) );
}

static void VIDSetRow( uint_16 vidport, uint_8 row )
{
    _WriteCRTCReg( vidport, CURS_LOCATION_LOW, row );
}

static void VIDSetCol( uint_16 vidport, uint_8 col )
{
    _WriteCRTCReg( vidport, CURS_LOCATION_HI, col );
}

static void VIDSetPos( uint_16 vidport, uint_16 cursorpos )
{
    VIDSetRow( vidport, cursorpos & 0xff );
    VIDSetCol( vidport, cursorpos >> 8 );
}

static void VIDSetCurTyp( uint_16 vidport, uint_16 cursortyp )
{
    _WriteCRTCReg( vidport, CURS_START_SCANLINE, cursortyp >> 8 );
    _WriteCRTCReg( vidport, CURS_END_SCANLINE, cursortyp & 0xf );
}

static uint_16 VIDGetCurTyp( uint_16 vidport )
{
    return( (uint_16)_ReadCRTCReg( vidport, CURS_START_SCANLINE ) << 8 |
            _ReadCRTCReg( vidport, CURS_END_SCANLINE ) );
}

static bool ChkCntrlr( int_16 port )
{
    uint_8              curr;
    bool                rtrn;

    curr = VIDGetRow( port );
    VIDSetRow( port, 0x5a );
    VIDWait();
    VIDWait();
    VIDWait();
    rtrn = VIDGetRow( port ) == 0x5a;
    VIDSetRow( port, curr );
    return( rtrn );
}

static uint_8 GetSwtchs( void )
{
    uint_8              equip;

    GetBIOSData( BD_EQUIP_LIST, equip );
    return( equip );
}

static void SetSwtchs( uint_8 new )
{
    SetBIOSData( BD_EQUIP_LIST, new );
}

static void DoSetMode( uint_8 mode )
{
    switch( mode & 0x7f ) {
    case 0x7:
    case 0xf:
        SetSwtchs( ( StartScrn.swtchs & 0xcf ) | 0x30 );
        break;
    default:
        SetSwtchs( ( StartScrn.swtchs & 0xcf ) | 0x20 );
        break;
    }
    BIOSSetMode( mode );
}

static bool TstMono( void )
{
    return( ChkCntrlr( VIDMONOINDXREG ) ? TRUE : FALSE );
}

static bool TstColour( void )
{
    return( ChkCntrlr( VIDCOLRINDXREG ) ? TRUE : FALSE );
}

static void GetEGAConfig( uint_8 colour, uint_8 curr_mode )
{
    hw_display_type     temp;

    if( colour ) {
        HWDisplay.active = DISP_EGA_MONO;
        if( TstColour() ) {
            HWDisplay.alt = DISP_CGA;
        }
    } else {
        HWDisplay.active = DISP_EGA_COLOUR;
        if( TstMono() ) {
            HWDisplay.alt = DISP_MONOCHROME;
        }
    }
    if( ( ( HWDisplay.active == DISP_EGA_COLOUR ) &&
          ( ( curr_mode == 7 ) || ( curr_mode == 15 ) ) ) ||
        ( ( HWDisplay.active == DISP_EGA_MONO ) &&
          ( ( curr_mode != 7 ) && ( curr_mode != 15 ) ) ) ) {
        /* EGA is not the active display */
        temp = HWDisplay.active;
        HWDisplay.active = HWDisplay.alt;
        HWDisplay.alt = temp;
    }
}

static void GetMonoConfig( uint_8 curr_mode )
{
    HWDisplay.active = DISP_MONOCHROME;
    if( TstColour() ) {
        if( curr_mode == 7 ) {
            HWDisplay.alt    = DISP_CGA;
        } else {
            HWDisplay.active = DISP_CGA;
            HWDisplay.alt = DISP_MONOCHROME;
        }
    }
}

static void GetDispConfig( void )
{
    int_32       info;
    uint_8       colour;
    uint_8       memory;
    uint_8       swtchs;
    uint_8       curr_mode;

    HWDisplay = BIOSDevCombCode();
    if( HWDisplay.active == DISP_NONE ) {
        /* have to figure it out ourselves */
        curr_mode = BIOSGetMode() & 0x7f;
        info = BIOSEGAInfo();
        memory = info;
        colour = info >> 8;
        swtchs = info >> 16;
        if( ( swtchs < 12 ) && ( memory <= 3 ) && ( colour <= 1 ) ) {
            /* we have an EGA display */
            GetEGAConfig( colour, curr_mode );
        } else if( TstMono() ) {
            /* we have a monochrome display */
            GetMonoConfig( curr_mode );
        } else {
            /* only thing left is a single CGA display */
            HWDisplay.active = DISP_CGA;
        }
    }
}

static bool ChkForColour( hw_display_type display )
{
    if( ColourAdapters[ display ] <= 0 ) {
        return( FALSE );
    }
    ScrnMode = MD_COLOUR;
    return( TRUE );
}

static void SwapActAlt( void )

⌨️ 快捷键说明

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