Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
33b2d852
Commit
33b2d852
authored
Feb 02, 2018
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
krnl386: Remove support for VGA emulation.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
5ec54495
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
3 additions
and
3668 deletions
+3
-3668
Makefile.in
dlls/krnl386.exe16/Makefile.in
+1
-3
dosexe.h
dlls/krnl386.exe16/dosexe.h
+0
-4
int10.c
dlls/krnl386.exe16/int10.c
+0
-1462
int21.c
dlls/krnl386.exe16/int21.c
+0
-2
interrupts.c
dlls/krnl386.exe16/interrupts.c
+2
-15
ioports.c
dlls/krnl386.exe16/ioports.c
+0
-86
vga.c
dlls/krnl386.exe16/vga.c
+0
-1999
vga.h
dlls/krnl386.exe16/vga.h
+0
-97
No files found.
dlls/krnl386.exe16/Makefile.in
View file @
33b2d852
MODULE
=
krnl386.exe16
IMPORTLIB
=
kernel
IMPORTS
=
winecrt0 kernel32 ntdll
DELAYIMPORTS
=
d
draw d
sound user32
DELAYIMPORTS
=
dsound user32
EXTRADLLFLAGS
=
-m16
-nodefaultlibs
-Wb
,--dll-name,kernel
C_SRCS
=
\
...
...
@@ -15,7 +15,6 @@ C_SRCS = \
fpu.c
\
global.c
\
instr.c
\
int10.c
\
int13.c
\
int15.c
\
int21.c
\
...
...
@@ -40,7 +39,6 @@ C_SRCS = \
task.c
\
thunk.c
\
utthunk.c
\
vga.c
\
vxd.c
\
wowthunk.c
...
...
dlls/krnl386.exe16/dosexe.h
View file @
33b2d852
...
...
@@ -259,10 +259,6 @@ extern void WINAPI DOSVM_Int3cHandler(CONTEXT*) DECLSPEC_HIDDEN;
extern
void
WINAPI
DOSVM_Int3dHandler
(
CONTEXT
*
)
DECLSPEC_HIDDEN
;
extern
void
WINAPI
DOSVM_Int3eHandler
(
CONTEXT
*
)
DECLSPEC_HIDDEN
;
/* int10.c */
extern
void
WINAPI
DOSVM_Int10Handler
(
CONTEXT
*
)
DECLSPEC_HIDDEN
;
extern
void
DOSVM_PutChar
(
BYTE
ascii
)
DECLSPEC_HIDDEN
;
/* int13.c */
extern
void
WINAPI
DOSVM_Int13Handler
(
CONTEXT
*
)
DECLSPEC_HIDDEN
;
...
...
dlls/krnl386.exe16/int10.c
deleted
100644 → 0
View file @
5ec54495
/*
* BIOS interrupt 10h handler
*
* Copyright 1998 Ove Kåven
* Copyright 1998 Joseph Pranevich
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdlib.h>
#include "vga.h"
#include "wine/debug.h"
#include "dosexe.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
int
);
/*
* Display combination code for active display.
*
* Values (hex):
* 00 - no display
* 01 - monochrome adapter w/ monochrome display
* 02 - CGA w/ color display
* 03 - reserved
* 04 - EGA w/ color display
* 05 - EGA w/ monochrome display
* 06 - PGA w/ color display
* 07 - VGA w/ monochrome analog display
* 08 - VGA w/ color analog display
* 09 - reserved
* 0A - MCGA w/ digital color display
* 0B - MCGA w/ monochrome analog display
* 0C - MCGA w/ color analog display
* FF - unknown display type
*/
#define INT10_DCC 0x08
#include "pshpack1.h"
/*
* Structure for DOS data that can be accessed directly from applications.
* This structure must be correctly packed.
*/
typedef
struct
_INT10_HEAP
{
BYTE
StaticModeSupport
[
7
];
/* modes supported 1..7 */
BYTE
StaticScanlineSupport
;
/* scan lines supported */
BYTE
StaticNumberCharBlocks
;
/* total number of char blocks */
BYTE
StaticActiveCharBlocks
;
/* max number of active char blocks */
WORD
StaticMiscFlags
;
/* misc function support flags */
WORD
StaticReserved1
;
/* reserved */
BYTE
StaticSavePointerFlags
;
/* save pointer function flags */
BYTE
StaticReserved2
;
/* reserved */
WORD
VesaCurrentMode
;
WORD
VesaModeList
[
64
];
char
VesaOEMName
[
32
];
char
VesaProductName
[
32
];
char
VesaProductRev
[
32
];
char
VesaVendorName
[
32
];
WORD
WineHeapSegment
;
}
INT10_HEAP
;
/*
* Structure for VBE Mode Info Block. See the VBE 3.0 standard for details.
* This structure must be correctly packed.
*/
struct
_ModeInfoBlock
{
WORD
ModeAttributes
;
/* 0x00 */
BYTE
WinAAttributes
;
/* 0x02 */
BYTE
WinBAttributes
;
/* 0x03 */
WORD
WinGranularity
;
/* 0x04 */
WORD
WinSize
;
/* 0x06 */
WORD
WinASegment
;
/* 0x08 */
WORD
WinBSegment
;
/* 0x0A */
DWORD
WinFuncPtr
;
/* 0x0C */
WORD
BytesPerScanLine
;
/* 0x10 */
/* mandatory for VBE 1.2+ */
WORD
XResolution
;
/* 0x12 */
WORD
YResolution
;
/* 0x14 */
BYTE
XCharSize
;
/* 0x16 */
BYTE
YCharSize
;
/* 0x17 */
BYTE
NumberOfPlanes
;
/* 0x18 */
BYTE
BitsPerPixel
;
/* 0x19 */
BYTE
NumberOfBanks
;
/* 0x1A */
BYTE
MemoryModel
;
/* 0x1B */
BYTE
BankSize
;
/* 0x1C */
BYTE
NumberOfImagePages
;
/* 0x1D */
BYTE
Reserved1
;
/* 0x1E */
BYTE
RedMaskSize
;
/* 0x1F */
BYTE
RedFieldPosition
;
/* 0x20 */
BYTE
GreenMaskSize
;
/* 0x21 */
BYTE
GreenFieldPosition
;
/* 0x22 */
BYTE
BlueMaskSize
;
/* 0x23 */
BYTE
BlueFieldPosition
;
/* 0x24 */
BYTE
RsvdMaskSize
;
/* 0x25 */
BYTE
RsvdFieldPosition
;
/* 0x26 */
BYTE
DirectColorModeInfo
;
/* 0x27 */
/* mandatory for VBE 2.0+ */
DWORD
PhysBasePtr
;
/* 0x28 */
DWORD
Reserved2
;
/* 0x2C */
WORD
Reserved3
;
/* 0x30 */
/* mandatory for VBE 3.0+ */
WORD
LinBytesPerScanLine
;
/* 0x32 */
BYTE
BnkNumberOfImagePages
;
/* 0x34 */
BYTE
LinNumberOfImagePages
;
/* 0x35 */
BYTE
LinRedMaskSize
;
/* 0x36 */
BYTE
LinRedFieldPosition
;
/* 0x37 */
BYTE
LinGreenMaskSize
;
/* 0x38 */
BYTE
LinGreenFieldPosition
;
/* 0x39 */
BYTE
LinBlueMaskSize
;
/* 0x3A */
BYTE
LinBlueFieldPosition
;
/* 0x3B */
BYTE
LinRsvdMaskSize
;
/* 0x3C */
BYTE
LinRsvdFieldPosition
;
/* 0x3D */
DWORD
MaxPixelClock
;
/* 0x3E */
BYTE
Reserved4
[
190
];
/* 0x42 */
};
#include "poppack.h"
/* True if video mode is a vesa mode, false otherwise.
* More correct would be to use something like (x > 0xff || x == 0x6a)
* but as long as we have only the standard VGA and VESA modes this is ok too */
#define IS_VESA_MODE(x) ((x) >= 0x6a)
/* Forward declarations. */
static
INT10_HEAP
*
INT10_GetHeap
(
void
);
static
void
INT10_SetCursorPos
(
BIOSDATA
*
,
unsigned
,
unsigned
,
unsigned
);
/**********************************************************************
* INT10_FillControllerInformation
*
* Fill 256-byte (VBE1.x) or 512-byte buffer (VBE2.0+) with
* capabilities of the video controller.
*/
static
void
INT10_FillControllerInformation
(
BYTE
*
buffer
)
{
INT10_HEAP
*
heap
=
INT10_GetHeap
();
/* 00 - BYTE[4]: signature */
memmove
(
buffer
,
"VESA"
,
4
);
/* 04 - WORD: version number */
*
(
WORD
*
)(
buffer
+
4
)
=
0x0300
;
/* version 3.0 */
/* 06 - DWORD: pointer to OEM name */
*
(
SEGPTR
*
)(
buffer
+
6
)
=
MAKESEGPTR
(
heap
->
WineHeapSegment
,
offsetof
(
INT10_HEAP
,
VesaOEMName
)
);
/*
* 10 - DWORD: capabilities flags
* Bits:
* 0 - DAC can be switched into 8-bit mode
* 1 - non-VGA controller
* 2 - programmed DAC with blank bit
* 3 - controller supports hardware stereoscopic signalling
* 4 - =0 stereo signalling via external VESA stereo connector
* =1 stereo signalling via VESA EVC connector
* 5 - controller supports hardware mouse cursor
* 6 - controller supports hardware clipping
* 7 - controller supports transparent BitBLT
* 8-31 - reserved (0)
*/
*
(
DWORD
*
)(
buffer
+
10
)
=
0
;
/* FIXME */
/* 14 - DWORD: pointer to list of supported VESA and OEM video modes */
*
(
SEGPTR
*
)(
buffer
+
14
)
=
MAKESEGPTR
(
heap
->
WineHeapSegment
,
offsetof
(
INT10_HEAP
,
VesaModeList
)
);
/* 18 - WORD: total amount of video memory in 64K blocks */
*
(
WORD
*
)(
buffer
+
18
)
=
16
;
/* FIXME */
/* 20 - WORD: OEM software version (BCD, high byte = major) */
*
(
WORD
*
)(
buffer
+
20
)
=
0x0100
;
/* version 1.0 */
/* 22 - DWORD: pointer to vendor name */
*
(
SEGPTR
*
)(
buffer
+
22
)
=
MAKESEGPTR
(
heap
->
WineHeapSegment
,
offsetof
(
INT10_HEAP
,
VesaVendorName
)
);
/* 26 - DWORD: pointer to product name */
*
(
SEGPTR
*
)(
buffer
+
26
)
=
MAKESEGPTR
(
heap
->
WineHeapSegment
,
offsetof
(
INT10_HEAP
,
VesaProductName
)
);
/* 30 - DWORD: pointer to product revision string */
*
(
SEGPTR
*
)(
buffer
+
30
)
=
MAKESEGPTR
(
heap
->
WineHeapSegment
,
offsetof
(
INT10_HEAP
,
VesaProductRev
)
);
/* 34 - WORD: VBE/AF version (if capabilities bit 3 set) */
*
(
WORD
*
)(
buffer
+
34
)
=
0
;
/*
* 36 - DWORD: pointer to list of accelerated modes
* (if capabilities bit 3 set)
*/
*
(
SEGPTR
*
)(
buffer
+
36
)
=
0
;
/* 40 - BYTE[216]: reserved for VBE implementation, set to zero */
memset
(
buffer
+
40
,
0
,
216
);
/*
* 256 - BYTE[256]: reserved for VBE3.0 implementation,
* ignored in order to support older programs
*/
}
/**********************************************************************
* INT10_FillModeInformation
*
* Fill 256-byte buffer with extended information about display mode.
*
* Returns FALSE if mode is unknown and TRUE is mode is known
* even if it is not supported.
*/
static
BOOL
INT10_FillModeInformation
(
struct
_ModeInfoBlock
*
mib
,
WORD
mode
)
{
const
VGA_MODE
*
ptr
=
VGA_GetModeInfo
(
mode
);
if
(
!
ptr
)
return
FALSE
;
/*
* 00 - WORD: mode attributes
* Bits:
* 0 - Mode supported by present hardware configuration.
* 1 - Optional information available. Must be =1 for VBE v1.2+.
* 2 - BIOS output supported.
* Int10 functions 01, 02, 06, 07, 09, 0a and 0e are supported.
* 3 - Set if color, clear if monochrome.
* 4 - Set if graphics mode, clear if text mode.
* 5 - Mode is not VGA-compatible if set.
* VGA-compatible modes support standard VGA I/O ports.
* 6 - Bank-switched (or windowed) mode is not supported if set.
* 7 - Linear framebuffer mode supported.
* 8 - Double scanning supported.
* 9 - Interlaced operation supported.
* 10 - Triple buffering supported.
* 11 - Stereoscopic display supported.
* 12 - Dual display start address supported.
* 13-15 - Reserved.
*/
{
WORD
attr
=
0x0002
;
/* set optional info available */
/* Enable color mode - if both Colors & Depth are 0, then assume monochrome*/
if
(
ptr
->
Colors
||
ptr
->
Depth
)
{
attr
|=
0x0008
;
}
/*
* FIXME: Attribute handling is incomplete.
*/
/* Mode supported? */
if
(
ptr
->
Supported
)
{
attr
|=
0x0001
;
/* set display mode supported */
}
/* Graphical mode? */
if
(
ptr
->
ModeType
!=
TEXT
)
{
attr
|=
0x0010
;
/* set graphics mode on (text mode off) */
}
/* Not VGA-compatible? */
if
(
IS_VESA_MODE
(
mode
))
attr
|=
0x0020
;
/* disable VGA ports */
mib
->
ModeAttributes
=
attr
;
}
/*
* 02 - BYTE[2]: window attributes, window A and window B
* Bits:
* 0 - Window exists.
* 1 - Window is readable.
* 2 - Window is writable.
* 3-7 - Reserved.
*/
mib
->
WinAAttributes
=
0x07
;
/* window A exists, readable and writable */
mib
->
WinBAttributes
=
0x00
;
/* window B not supported */
/* 04 - WORD: window granularity in KB */
mib
->
WinGranularity
=
64
;
/* 06 - WORD: window size in KB */
mib
->
WinSize
=
64
;
/* 08 - WORD[2]: start segments, window A and window B */
mib
->
WinASegment
=
0xa000
;
/* window A segment */
mib
->
WinBSegment
=
0x0000
;
/* window B not supported */
/* 12 - DWORD: window positioning function */
mib
->
WinFuncPtr
=
0
;
/* not supported */
/* 16 - WORD: bytes per scan line */
/* FIXME: is this always correct? */
mib
->
BytesPerScanLine
=
ptr
->
Width
*
(
ptr
->
Depth
?
(
ptr
->
Depth
+
7
)
/
8
:
1
);
/* 18 - WORD: width in pixels (graphics) or characters (text) */
if
(
ptr
->
ModeType
==
TEXT
)
{
mib
->
XResolution
=
ptr
->
TextCols
;
}
else
{
mib
->
XResolution
=
ptr
->
Width
;
}
/* 20 - WORD: height in pixels (graphics) or characters (text) */
if
(
ptr
->
ModeType
==
TEXT
)
{
mib
->
YResolution
=
ptr
->
TextRows
;
}
else
{
mib
->
YResolution
=
ptr
->
Height
;
}
/* 22 - BYTE: width of character cell in pixels */
mib
->
XCharSize
=
ptr
->
CharWidth
;
/* 23 - BYTE: height of character cell in pixels */
mib
->
YCharSize
=
ptr
->
CharHeight
;
/* 24 - BYTE: number of memory planes */
mib
->
NumberOfPlanes
=
1
;
/* FIXME */
/* 25 - BYTE: number of bits per pixel */
mib
->
BitsPerPixel
=
ptr
->
Depth
;
/* FIXME: text modes? reserved bits? */
/* 26 - BYTE: number of banks */
mib
->
NumberOfBanks
=
1
;
/* FIXME */
/*
* 27 - BYTE: memory model type
* Values (hex):
* 00 - Text mode
* 01 - CGA graphics
* 02 - Hercules graphics
* 03 - Planar
* 04 - Packed pixel
* 05 - Non-chain 4, 256 color
* 06 - Direct color
* 07 - YUV
* 08-0F - Reserved for VESA.
* 10-FF - OEM memory models.
*/
if
(
ptr
->
ModeType
==
TEXT
)
mib
->
MemoryModel
=
0
;
/* text mode */
else
mib
->
MemoryModel
=
3
;
/* FIXME */
/* 28 - BYTE: size of bank in KB */
mib
->
BankSize
=
0
;
/* FIXME */
/* 29 - BYTE: number of image pages (less one) in video RAM */
mib
->
NumberOfImagePages
=
(
ptr
->
ScreenPages
)
-
1
;
/* 30 - BYTE: reserved (0x00 for VBE 1.0-2.0, 0x01 for VBE 3.0) */
mib
->
Reserved1
=
0x01
;
/*
* 31,33,35 - BYTE: red/green/blue mask size
* Size of red/green/blue color component in bits.
* 32,34,36 - BYTE: red/green/blue field position
* Bit position of the least significant bit of red/green/blue color
* component.
* Both should be only used when the memory model is direct color or YUV
* but "Imperium Romanum" uses this field even when the memory model is
* planar. So always fill this field when we have a depth bigger than 8,
* otherwise set them to zero.
*/
switch
(
ptr
->
Depth
)
{
case
24
:
mib
->
RedMaskSize
=
8
;
mib
->
GreenMaskSize
=
8
;
mib
->
BlueMaskSize
=
8
;
mib
->
RsvdMaskSize
=
0
;
mib
->
RedFieldPosition
=
16
;
mib
->
GreenFieldPosition
=
8
;
mib
->
BlueFieldPosition
=
0
;
mib
->
RsvdFieldPosition
=
0
;
break
;
case
16
:
mib
->
RedMaskSize
=
5
;
mib
->
GreenMaskSize
=
6
;
mib
->
BlueMaskSize
=
5
;
mib
->
RsvdMaskSize
=
0
;
mib
->
RedFieldPosition
=
11
;
mib
->
GreenFieldPosition
=
5
;
mib
->
BlueFieldPosition
=
0
;
mib
->
RsvdFieldPosition
=
0
;
break
;
case
15
:
mib
->
RedMaskSize
=
5
;
mib
->
GreenMaskSize
=
5
;
mib
->
BlueMaskSize
=
5
;
mib
->
RsvdMaskSize
=
1
;
mib
->
RedFieldPosition
=
10
;
mib
->
GreenFieldPosition
=
5
;
mib
->
BlueFieldPosition
=
0
;
mib
->
RsvdFieldPosition
=
15
;
break
;
default:
mib
->
RedMaskSize
=
0
;
mib
->
GreenMaskSize
=
0
;
mib
->
BlueMaskSize
=
0
;
mib
->
RsvdMaskSize
=
0
;
mib
->
RedFieldPosition
=
0
;
mib
->
GreenFieldPosition
=
0
;
mib
->
BlueFieldPosition
=
0
;
mib
->
RsvdFieldPosition
=
0
;
break
;
}
/*
* 39 - BYTE: direct color mode info
* Bits:
* 0 - Set if color ramp is programmable.
* 1 - Set if bytes in reserved field may be used by application.
*/
mib
->
DirectColorModeInfo
=
0
;
/* not supported */
/* 40 - DWORD: physical address of linear video buffer */
mib
->
PhysBasePtr
=
0
;
/* not supported */
/* 44 - DWORD: reserved, always zero */
mib
->
Reserved2
=
0
;
/* 48 - WORD: reserved, always zero */
mib
->
Reserved3
=
0
;
/* 50 - WORD: bytes per scan line in linear modes */
mib
->
LinBytesPerScanLine
=
mib
->
BytesPerScanLine
;
/* 52 - BYTE: number of images (less one) for banked video modes */
mib
->
BnkNumberOfImagePages
=
0
;
/* FIXME */
/* 53 - BYTE: number of images (less one) for linear video modes */
mib
->
LinNumberOfImagePages
=
mib
->
BnkNumberOfImagePages
;
/* 54 - BYTE: red mask size (linear modes) */
mib
->
LinRedMaskSize
=
mib
->
RedMaskSize
;
/* 55 - BYTE: red field position (linear modes) */
mib
->
LinRedFieldPosition
=
mib
->
RedFieldPosition
;
/* 56 - BYTE: green mask size (linear modes) */
mib
->
LinGreenMaskSize
=
mib
->
GreenMaskSize
;
/* 57 - BYTE: green field size (linear modes) */
mib
->
LinGreenFieldPosition
=
mib
->
GreenFieldPosition
;
/* 58 - BYTE: blue mask size (linear modes) */
mib
->
LinBlueMaskSize
=
mib
->
BlueMaskSize
;
/* 59 - BYTE: blue field position (linear modes) */
mib
->
LinBlueFieldPosition
=
mib
->
BlueFieldPosition
;
/* 60 - BYTE: reserved mask size (linear modes) */
mib
->
LinRsvdMaskSize
=
mib
->
RsvdMaskSize
;
/* 61 - BYTE: reserved mask position (linear modes) */
mib
->
LinRsvdFieldPosition
=
mib
->
RsvdFieldPosition
;
/* 62 - DWORD: maximum pixel clock for graphics video mode, in Hz */
mib
->
MaxPixelClock
=
0
;
/* FIXME */
/* 66 - BYTE[190]: reserved, set to zero */
memset
(
mib
->
Reserved4
,
0
,
190
);
return
TRUE
;
}
/**********************************************************************
* INT10_FillStateInformation
*
* Fill 64-byte buffer with VGA state and functionality information.
*/
static
void
INT10_FillStateInformation
(
BYTE
*
buffer
,
BIOSDATA
*
data
)
{
INT10_HEAP
*
heap
=
INT10_GetHeap
();
/* 00 - DWORD: address of static functionality table */
*
(
SEGPTR
*
)(
buffer
+
0
)
=
MAKESEGPTR
(
heap
->
WineHeapSegment
,
offsetof
(
INT10_HEAP
,
StaticModeSupport
)
);
/* 04 - BYTE[30]: copy of BIOS data starting from 0x49 (VideoMode) */
memmove
(
buffer
+
4
,
&
data
->
VideoMode
,
30
);
/* 34 - BYTE: number of rows - 1 */
buffer
[
34
]
=
data
->
RowsOnScreenMinus1
;
/* 35 - WORD: bytes/character */
*
(
WORD
*
)(
buffer
+
35
)
=
data
->
BytesPerChar
;
/* 37 - BYTE: display combination code of active display */
buffer
[
37
]
=
INT10_DCC
;
/* 38 - BYTE: DCC of alternate display */
buffer
[
38
]
=
0
;
/* no secondary display */
/* 39 - WORD: number of colors supported in current mode (0000h = mono) */
*
(
WORD
*
)(
buffer
+
39
)
=
16
;
/* FIXME */
/* 41 - BYTE: number of pages supported in current mode */
buffer
[
41
]
=
1
;
/* FIXME */
/*
* 42 - BYTE: number of scan lines active
* Values (hex):
* 00 = 200
* 01 = 350
* 02 = 400
* 03 = 480
*/
buffer
[
42
]
=
3
;
/* FIXME */
/* 43 - BYTE: primary character block */
buffer
[
43
]
=
0
;
/* FIXME */
/* 44 - BYTE: secondary character block */
buffer
[
44
]
=
0
;
/* FIXME */
/*
* 45 - BYTE: miscellaneous flags
* Bits:
* 0 - all modes on all displays on
* 1 - gray summing on
* 2 - monochrome display attached
* 3 - default palette loading disabled
* 4 - cursor emulation enabled
* 5 - 0 = intensity; 1 = blinking
* 6 - flat-panel display is active
* 7 - unused (0)
*/
/* FIXME: Correct value? */
buffer
[
45
]
=
(
data
->
VGASettings
&
0x0f
)
|
((
data
->
ModeOptions
&
1
)
<<
4
);
/* cursor emulation */
/*
* 46 - BYTE: non-VGA mode support
* Bits:
* 0 - BIOS supports information return for adapter interface
* 1 - adapter interface driver required
* 2 - 16-bit VGA graphics present
* 3 - =1 MFI attributes enabled
* =0 VGA attributes enabled
* 4 - 132-column mode supported
* 5-7 - reserved
*/
buffer
[
46
]
=
0
;
/* FIXME: correct value? */
/* 47 - BYTE[2]: reserved, set to zero */
memset
(
buffer
+
47
,
0
,
2
);
/*
* 49 - BYTE: video memory available
* Values (hex):
* 00 - 64K
* 01 - 128K
* 02 - 192K
* 03 - 256K
*/
buffer
[
49
]
=
(
data
->
ModeOptions
&
0x60
)
>>
5
;
/* FIXME */
/*
* 50 - BYTE: save pointer state flags
* Bits:
* 0 - 512 character set active
* 1 - dynamic save area present
* 2 - alpha font override active
* 3 - graphics font override active
* 4 - palette override active
* 5 - DCC override active
* 6-7 - unused (0)
*/
buffer
[
50
]
=
heap
->
StaticSavePointerFlags
;
/*
* 51 - BYTE: display information and status
* Bits:
* 0 - flat-panel display attached
* 1 - flat-panel display active
* 2 - color display
* 3-6 - reserved
* 7 - 640x480 flat-panel can be used simultaneously with CRT
*/
buffer
[
51
]
=
4
;
/* FIXME: correct value? */
/* 52 - BYTE[12]: reserved, set to zero */
memset
(
buffer
+
52
,
0
,
12
);
}
/**********************************************************************
* INT10_GetHeap
*/
static
INT10_HEAP
*
INT10_GetHeap
(
void
)
{
static
INT10_HEAP
*
heap_pointer
=
0
;
if
(
!
heap_pointer
)
{
WORD
segment
;
int
i
;
heap_pointer
=
DOSVM_AllocDataUMB
(
sizeof
(
INT10_HEAP
),
&
segment
,
0
);
for
(
i
=
0
;
i
<
7
;
i
++
)
heap_pointer
->
StaticModeSupport
[
i
]
=
0xff
;
/* FIXME */
heap_pointer
->
StaticScanlineSupport
=
7
;
/* FIXME */
heap_pointer
->
StaticNumberCharBlocks
=
0
;
/* FIXME */
heap_pointer
->
StaticActiveCharBlocks
=
0
;
/* FIXME */
heap_pointer
->
StaticMiscFlags
=
0x8ff
;
/* FIXME */
heap_pointer
->
StaticReserved1
=
0
;
heap_pointer
->
StaticSavePointerFlags
=
0x3f
;
/* FIXME */
heap_pointer
->
StaticReserved2
=
0
;
for
(
i
=
0
;
TRUE
;
i
++
)
{
heap_pointer
->
VesaModeList
[
i
]
=
VGA_modelist
[
i
].
Mode
;
if
(
VGA_modelist
[
i
].
Mode
==
0xffff
)
break
;
}
strcpy
(
heap_pointer
->
VesaOEMName
,
"WINE SVGA BOARD"
);
strcpy
(
heap_pointer
->
VesaVendorName
,
"WINE"
);
strcpy
(
heap_pointer
->
VesaProductName
,
"WINE SVGA"
);
strcpy
(
heap_pointer
->
VesaProductRev
,
"2008"
);
heap_pointer
->
VesaCurrentMode
=
0
;
/* Initialized later. */
heap_pointer
->
WineHeapSegment
=
segment
;
}
return
heap_pointer
;
}
/**********************************************************************
* INT10_SetVideoMode
*
* Change current video mode to any VGA or VESA mode.
* Returns TRUE if mode is supported.
*
* Mode bitfields:
* 0-6: .. Mode number (combined with bit 8).
* 7: =0 Clear screen.
* =1 Preserve display memory on mode change (VGA modes).
* 8: =0 VGA mode.
* =1 VESA mode.
* 9: .. Reserved, must be zero.
* 10: .. Reserved, must be zero.
* 11: =0 Use default refresh rate.
* =1 Use user specified refresh rate.
* 12: .. Reserved, must be zero.
* 13: .. Reserved, must be zero.
* 14: =0 Use windowed frame buffer model.
* =1 Use linear frame buffer model.
* 15: =0 Clear screen.
* =1 Preserve display memory on mode change (VESA modes).
*/
static
BOOL
INT10_SetVideoMode
(
BIOSDATA
*
data
,
WORD
mode
)
{
const
VGA_MODE
*
ptr
=
VGA_GetModeInfo
(
mode
);
INT10_HEAP
*
heap
=
INT10_GetHeap
();
BOOL
clearScreen
=
TRUE
;
if
(
!
ptr
)
return
FALSE
;
/*
* Linear framebuffer is not supported.
* FIXME - not sure this is valid since mode 19 is 256 color & linear
* of course only 1 window is addressable.
*/
if
(
mode
&
0x4000
)
return
FALSE
;
/*
* Check for VGA and VESA preserve video memory flag.
*/
if
((
mode
&
0x0080
)
||
(
mode
&
0x8000
))
clearScreen
=
FALSE
;
/*
* Note that we do not mask out flags here on purpose.
*/
heap
->
VesaCurrentMode
=
mode
;
if
(
mode
<=
0xff
)
data
->
VideoMode
=
mode
;
else
data
->
VideoMode
=
0
;
if
(
ptr
->
ModeType
==
TEXT
)
{
/* Text mode. */
TRACE
(
"Setting %s %dx%d text mode (screen %s)
\n
"
,
IS_VESA_MODE
(
mode
)
?
"VESA"
:
"VGA"
,
ptr
->
TextCols
,
ptr
->
TextRows
,
clearScreen
?
"cleared"
:
"preserved"
);
/*
* FIXME: We should check here if alpha mode could be set.
*/
VGA_SetAlphaMode
(
ptr
->
TextCols
,
ptr
->
TextRows
);
data
->
VideoColumns
=
ptr
->
TextCols
;
data
->
RowsOnScreenMinus1
=
ptr
->
TextRows
-
1
;
if
(
clearScreen
)
{
VGA_ClearText
(
0
,
0
,
ptr
->
TextCols
-
1
,
ptr
->
TextRows
-
1
,
0x07
);
INT10_SetCursorPos
(
data
,
0
,
0
,
0
);
VGA_SetCursorPos
(
0
,
0
);
}
}
else
{
/* Graphics mode. */
TRACE
(
"Setting %s %dx%dx%d graphics mode (screen %s)
\n
"
,
IS_VESA_MODE
(
mode
)
?
"VESA"
:
"VGA"
,
ptr
->
Width
,
ptr
->
Height
,
ptr
->
Depth
,
clearScreen
?
"cleared"
:
"preserved"
);
if
(
!
VGA_SetMode
(
mode
))
return
FALSE
;
}
return
TRUE
;
}
/**********************************************************************
* INT10_GetCursorPos
*/
static
void
INT10_GetCursorPos
(
BIOSDATA
*
data
,
unsigned
page
,
unsigned
*
X
,
unsigned
*
Y
)
{
*
X
=
data
->
VideoCursorPos
[
page
*
2
];
/* column */
*
Y
=
data
->
VideoCursorPos
[
page
*
2
+
1
];
/* row */
}
/**********************************************************************
* INT10_SetCursorPos
*/
static
void
INT10_SetCursorPos
(
BIOSDATA
*
data
,
unsigned
page
,
unsigned
X
,
unsigned
Y
)
{
data
->
VideoCursorPos
[
page
*
2
]
=
X
;
data
->
VideoCursorPos
[
page
*
2
+
1
]
=
Y
;
}
/**********************************************************************
* INT10_InitializeVideoMode
*
* The first time this function is called VGA emulation is set to the
* default text mode.
*/
static
void
INT10_InitializeVideoMode
(
BIOSDATA
*
data
)
{
static
BOOL
already_initialized
=
FALSE
;
unsigned
width
;
unsigned
height
;
if
(
already_initialized
)
return
;
already_initialized
=
TRUE
;
VGA_InitAlphaMode
(
&
width
,
&
height
);
/*
* FIXME: Add more mappings between initial size and
* text modes.
*/
if
(
width
>=
80
&&
height
>=
25
)
INT10_SetVideoMode
(
data
,
0x03
);
else
INT10_SetVideoMode
(
data
,
0x01
);
}
/**********************************************************************
* INT10_HandleVESA
*
* Handler for VESA functions (int10 function 0x4f).
*/
static
void
INT10_HandleVESA
(
CONTEXT
*
context
)
{
BIOSDATA
*
data
=
DOSVM_BiosData
();
switch
(
AL_reg
(
context
))
{
case
0x00
:
/* RETURN CONTROLLER INFORMATION */
TRACE
(
"VESA RETURN CONTROLLER INFORMATION
\n
"
);
{
BYTE
*
ptr
=
CTX_SEG_OFF_TO_LIN
(
context
,
context
->
SegEs
,
context
->
Edi
);
INT10_FillControllerInformation
(
ptr
);
SET_AL
(
context
,
0x4f
);
SET_AH
(
context
,
0x00
);
/* 0x00 = successful 0x01 = failed */
}
break
;
case
0x01
:
/* RETURN MODE INFORMATION */
TRACE
(
"VESA RETURN MODE INFORMATION %04x
\n
"
,
CX_reg
(
context
)
);
{
struct
_ModeInfoBlock
*
ptr
=
CTX_SEG_OFF_TO_LIN
(
context
,
context
->
SegEs
,
context
->
Edi
);
SET_AL
(
context
,
0x4f
);
if
(
INT10_FillModeInformation
(
ptr
,
CX_reg
(
context
)
))
SET_AH
(
context
,
0x00
);
/* status: success */
else
SET_AH
(
context
,
0x01
);
/* status: failed */
}
break
;
case
0x02
:
/* SET SuperVGA VIDEO MODE */
TRACE
(
"Set VESA video mode %04x
\n
"
,
BX_reg
(
context
)
);
SET_AL
(
context
,
0x4f
);
/* function supported */
if
(
INT10_SetVideoMode
(
data
,
BX_reg
(
context
)
))
SET_AH
(
context
,
0x00
);
/* success */
else
SET_AH
(
context
,
0x01
);
/* failed */
break
;
case
0x03
:
/* VESA SuperVGA BIOS - GET CURRENT VIDEO MODE */
SET_AL
(
context
,
0x4f
);
SET_AH
(
context
,
0x00
);
SET_BX
(
context
,
INT10_GetHeap
()
->
VesaCurrentMode
);
break
;
case
0x04
:
/* VESA SuperVGA BIOS - SAVE/RESTORE SuperVGA VIDEO STATE */
ERR
(
"VESA SAVE/RESTORE Video State - Not Implemented
\n
"
);
/* AL_reg(context) = 0x4f; = supported so not set since not implemented */
/* maybe we should do this instead ? */
/* AH_reg(context = 0x01; not implemented so just fail */
break
;
case
0x05
:
/* VESA SuperVGA BIOS - CPU VIDEO MEMORY CONTROL */
/*
* This subfunction supports only Window A (BL_reg == 0) and
* it assumes that window granularity is 64k.
*/
switch
(
BH_reg
(
context
))
{
case
0x00
:
/* select video memory window */
SET_AL
(
context
,
0x4f
);
/* function supported */
if
(
BL_reg
(
context
)
==
0
)
{
VGA_SetWindowStart
(
DX_reg
(
context
)
*
64
*
1024
);
SET_AH
(
context
,
0x00
);
/* status: successful */
}
else
SET_AH
(
context
,
0x01
);
/* status: failed */
break
;
case
0x01
:
/* get video memory window */
SET_AL
(
context
,
0x4f
);
/* function supported */
if
(
BL_reg
(
context
)
==
0
)
{
SET_DX
(
context
,
VGA_GetWindowStart
()
/
64
/
1024
);
SET_AH
(
context
,
0x00
);
/* status: successful */
}
else
SET_AH
(
context
,
0x01
);
/* status: failed */
break
;
default:
INT_BARF
(
context
,
0x10
);
}
break
;
case
0x06
:
/* VESA GET/SET LOGICAL SCAN LINE LENGTH */
ERR
(
"VESA GET/SET LOGICAL SCAN LINE LENGTH - Not Implemented
\n
"
);
/* AL_reg(context) = 0x4f; = supported so not set since not implemented */
/* maybe we should do this instead ? */
/* AH_reg(context = 0x001; not implemented so just fail */
break
;
case
0x07
:
/* GET/SET DISPLAY START */
ERR
(
"VESA GET/SET DISPLAY START - Not Implemented
\n
"
);
/* AL_reg(context) = 0x4f; = supported so not set since not implemented */
/* maybe we should do this instead ? */
/* AH_reg(context = 0x001; not implemented so just fail */
break
;
case
0x08
:
/* GET/SET DAC PALETTE CONTROL */
ERR
(
"VESA GET/SET DAC PALETTE CONTROL- Not Implemented
\n
"
);
/* AL_reg(context) = 0x4f; = supported so not set since not implemented */
/* maybe we should do this instead ? */
/* AH_reg(context = 0x001; not implemented so just fail */
break
;
case
0x09
:
/* SET PALETTE ENTRIES */
FIXME
(
"VESA Set palette entries - not implemented
\n
"
);
break
;
case
0x0a
:
/* GET PROTECTED-MODE CODE */
FIXME
(
"VESA Get protected-mode code - not implemented
\n
"
);
break
;
case
0x10
:
/* Display Power Management Extensions */
FIXME
(
"VESA Display Power Management Extensions - not implemented
\n
"
);
break
;
case
0xef
:
/* get video mode for hercules-compatibles */
/* There's no reason to really support this */
/* is there?....................(A.C.) */
TRACE
(
"Just report the video not hercules compatible
\n
"
);
SET_DX
(
context
,
0xffff
);
break
;
case
0xff
:
/* Turn VESA ON/OFF */
/* I don't know what to do */
break
;
default:
FIXME
(
"VESA Function (0x%x) - Not Supported
\n
"
,
AH_reg
(
context
));
break
;
}
}
/**********************************************************************
* DOSVM_Int10Handler
*
* Handler for int 10h (video).
*
* NOTE:
* Most INT 10 functions for text-mode, CGA, EGA, and VGA cards
* are present in this list. (SVGA and XGA are not) That is not
* to say that all these functions should be supported, but if
* anyone is brain-damaged enough to want to emulate one of these
* beasts then this should get you started.
*
* NOTE:
* Several common graphical extensions used by Microsoft hook
* off of here. I have *not* added them to this list (yet). They
* include:
*
* MSHERC.COM - More functionality for Hercules cards.
* EGA.SYS (also MOUSE.COM) - More for EGA cards.
*
* Yes, MS also added this support into their mouse driver. Don't
* ask me, I don't work for them.
*
* Joseph Pranevich - 9/98
*
* Jess Haas 2/99
* Added support for Vesa. It is not complete but is a start.
* NOTE: Im not sure if I did all this right or if any of it works.
* Currently I don't have a program that uses Vesa that actually gets far
* enough without crashing to do vesa stuff.
*
* Added additional vga graphic support - 3/99
*/
void
WINAPI
DOSVM_Int10Handler
(
CONTEXT
*
context
)
{
BIOSDATA
*
data
=
DOSVM_BiosData
();
INT10_InitializeVideoMode
(
data
);
switch
(
AH_reg
(
context
))
{
case
0x00
:
/* SET VIDEO MODE */
TRACE
(
"Set VGA video mode %02x
\n
"
,
AL_reg
(
context
)
);
if
(
!
INT10_SetVideoMode
(
data
,
AL_reg
(
context
)
))
FIXME
(
"Unsupported VGA video mode requested: %#x
\n
"
,
AL_reg
(
context
)
);
break
;
case
0x01
:
/* SET CURSOR SHAPE */
TRACE
(
"Set Cursor Shape start %d end %d options %d
\n
"
,
CH_reg
(
context
)
&
0x1f
,
CL_reg
(
context
)
&
0x1f
,
CH_reg
(
context
)
&
0xe0
);
data
->
VideoCursorType
=
CX_reg
(
context
);
/* direct copy */
VGA_SetCursorShape
(
CH_reg
(
context
),
CL_reg
(
context
));
break
;
case
0x02
:
/* SET CURSOR POSITION */
/* BH = Page Number */
/* Not supported */
/* DH = Row */
/* 0 is left */
/* DL = Column */
/* 0 is top */
INT10_SetCursorPos
(
data
,
BH_reg
(
context
),
DL_reg
(
context
),
DH_reg
(
context
));
if
(
BH_reg
(
context
))
{
FIXME
(
"Set Cursor Position: Cannot set to page %d
\n
"
,
BH_reg
(
context
));
}
else
{
VGA_SetCursorPos
(
DL_reg
(
context
),
DH_reg
(
context
));
TRACE
(
"Set Cursor Position: %d/%d
\n
"
,
DL_reg
(
context
),
DH_reg
(
context
));
}
break
;
case
0x03
:
/* GET CURSOR POSITION AND SIZE */
{
unsigned
row
,
col
;
TRACE
(
"Get cursor position and size (page %d)
\n
"
,
BH_reg
(
context
));
SET_CX
(
context
,
data
->
VideoCursorType
);
INT10_GetCursorPos
(
data
,
BH_reg
(
context
),
&
col
,
&
row
);
SET_DH
(
context
,
row
);
SET_DL
(
context
,
col
);
TRACE
(
"Cursor Position: %d/%d
\n
"
,
DL_reg
(
context
),
DH_reg
(
context
));
}
break
;
case
0x04
:
/* READ LIGHT PEN POSITION */
FIXME
(
"Read Light Pen Position - Not Supported
\n
"
);
SET_AH
(
context
,
0x00
);
/* Not down */
break
;
case
0x05
:
/* SELECT ACTIVE DISPLAY PAGE */
FIXME
(
"Select Active Display Page (%d) - Not Supported
\n
"
,
AL_reg
(
context
));
data
->
VideoCurPage
=
AL_reg
(
context
);
break
;
case
0x06
:
/* SCROLL UP WINDOW */
/* AL = Lines to scroll */
/* BH = Attribute */
/* CH,CL = row, col upper-left */
/* DH,DL = row, col lower-right */
TRACE
(
"Scroll Up Window %d
\n
"
,
AL_reg
(
context
));
if
(
AL_reg
(
context
)
==
0
)
VGA_ClearText
(
CH_reg
(
context
),
CL_reg
(
context
),
DH_reg
(
context
),
DL_reg
(
context
),
BH_reg
(
context
)
);
else
VGA_ScrollUpText
(
CH_reg
(
context
),
CL_reg
(
context
),
DH_reg
(
context
),
DL_reg
(
context
),
AL_reg
(
context
),
BH_reg
(
context
)
);
break
;
case
0x07
:
/* SCROLL DOWN WINDOW */
/* AL = Lines to scroll */
/* BH = Attribute */
/* CH,CL = row, col upper-left */
/* DH,DL = row, col lower-right */
TRACE
(
"Scroll Down Window %d
\n
"
,
AL_reg
(
context
));
if
(
AL_reg
(
context
)
==
0
)
VGA_ClearText
(
CH_reg
(
context
),
CL_reg
(
context
),
DH_reg
(
context
),
DL_reg
(
context
),
BH_reg
(
context
)
);
else
VGA_ScrollDownText
(
CH_reg
(
context
),
CL_reg
(
context
),
DH_reg
(
context
),
DL_reg
(
context
),
AL_reg
(
context
),
BH_reg
(
context
)
);
break
;
case
0x08
:
/* READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
{
if
(
BH_reg
(
context
))
/* Write to different page */
{
FIXME
(
"Read character and attribute at cursor position -"
" Can't read from non-0 page
\n
"
);
SET_AL
(
context
,
' '
);
/* That page is blank */
SET_AH
(
context
,
7
);
}
else
{
BYTE
ascii
,
attr
;
TRACE
(
"Read Character and Attribute at Cursor Position
\n
"
);
VGA_GetCharacterAtCursor
(
&
ascii
,
&
attr
);
SET_AL
(
context
,
ascii
);
SET_AH
(
context
,
attr
);
}
}
break
;
case
0x09
:
/* WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
case
0x0a
:
/* WRITE CHARACTER ONLY AT CURSOR POSITION */
/* AL = Character to display. */
/* BH = Page Number */
/* We can't write to non-0 pages, yet. */
/* BL = Attribute / Color */
/* CX = Times to Write Char */
/* Note here that the cursor is not advanced. */
{
unsigned
row
,
col
;
INT10_GetCursorPos
(
data
,
BH_reg
(
context
),
&
col
,
&
row
);
VGA_WriteChars
(
col
,
row
,
AL_reg
(
context
),
(
AH_reg
(
context
)
==
0x09
)
?
BL_reg
(
context
)
:
-
1
,
CX_reg
(
context
));
if
(
CX_reg
(
context
)
>
1
)
TRACE
(
"Write Character%s at Cursor Position (Rep. %d): %c
\n
"
,
(
AH_reg
(
context
)
==
0x09
)
?
" and Attribute"
:
""
,
CX_reg
(
context
),
AL_reg
(
context
));
else
TRACE
(
"Write Character%s at Cursor Position: %c
\n
"
,
(
AH_reg
(
context
)
==
0x09
)
?
" and Attribute"
:
""
,
AL_reg
(
context
));
}
break
;
case
0x0b
:
switch
(
BH_reg
(
context
))
{
case
0x00
:
/* SET BACKGROUND/BORDER COLOR */
/* In text modes, this sets only the border... */
/* According to the interrupt list and one of my books. */
/* Funny though that Beyond Zork seems to indicate that it
also sets up the default background attributes for clears
and scrolls... */
/* Bear in mind here that we do not want to change,
apparently, the foreground or attribute of the background
with this call, so we should check first to see what the
foreground already is... FIXME */
/* For CGA modes, background color change is the same as writing
to I/O address 0x3d9 bit 4 */
if
(
data
->
VideoMode
>=
4
&&
data
->
VideoMode
<=
6
)
{
VGA_SetBright
((
BL_reg
(
context
)
&
0x10
)
!=
0
);
VGA_UpdatePalette
();
}
else
FIXME
(
"Set Background/Border Color: %d/%d
\n
"
,
BH_reg
(
context
),
BL_reg
(
context
));
break
;
case
0x01
:
/* SET PALETTE */
/* For CGA modes, palette color change is the same as writing
to I/O address 0x3d9 bit 5 */
if
(
data
->
VideoMode
>=
4
&&
data
->
VideoMode
<=
6
)
{
VGA_SetPaletteIndex
(
BL_reg
(
context
)
&
1
);
VGA_UpdatePalette
();
}
else
FIXME
(
"Set Palette - Not Supported: %02X
\n
"
,
BL_reg
(
context
));
break
;
default:
FIXME
(
"INT 10 AH = 0x0b BH = 0x%x - Unknown
\n
"
,
BH_reg
(
context
));
break
;
}
break
;
case
0x0c
:
/* WRITE GRAPHICS PIXEL */
/* Only supported in CGA mode for now */
if
(
data
->
VideoMode
>=
4
&&
data
->
VideoMode
<=
6
)
{
VGA_WritePixel
(
AL_reg
(
context
),
BH_reg
(
context
),
CX_reg
(
context
),
DX_reg
(
context
));
}
else
FIXME
(
"Write pixel not implemented for current mode
\n
"
);
break
;
case
0x0d
:
/* READ GRAPHICS PIXEL */
/* Not in graphics mode, can ignore w/o error */
FIXME
(
"Read Graphics Pixel - Not Supported
\n
"
);
break
;
case
0x0e
:
/* TELETYPE OUTPUT */
TRACE
(
"Teletype Output
\n
"
);
DOSVM_PutChar
(
AL_reg
(
context
));
break
;
case
0x0f
:
/* GET CURRENT VIDEO MODE */
TRACE
(
"Get current video mode: -> mode %d, columns %d
\n
"
,
data
->
VideoMode
,
data
->
VideoColumns
);
/* Note: This should not be a constant value. */
SET_AL
(
context
,
data
->
VideoMode
);
SET_AH
(
context
,
data
->
VideoColumns
);
SET_BH
(
context
,
0
);
/* Display page 0 */
break
;
case
0x10
:
switch
(
AL_reg
(
context
))
{
case
0x00
:
/* SET SINGLE PALETTE REGISTER - A.C. */
TRACE
(
"Set Single Palette Register - Reg 0x0%x Value 0x0%x
\n
"
,
BL_reg
(
context
),
BH_reg
(
context
));
/* BH is the value BL is the register */
VGA_SetColor16
((
int
)
BL_reg
(
context
),(
int
)
BH_reg
(
context
));
break
;
case
0x01
:
/* SET BORDER (OVERSCAN) */
/* Text terminals have no overscan */
/* I'm setting it anyway. - A.C. */
TRACE
(
"Set Border (Overscan) - Ignored but set.
\n
"
);
VGA_SetColor16
(
16
,(
int
)
BH_reg
(
context
));
break
;
case
0x02
:
/* SET ALL PALETTE REGISTERS - A.C.*/
TRACE
(
"Set all palette registers
\n
"
);
/* ES:DX points to a 17 byte table of colors */
/* No return data listed */
/* I'll have to update my table and the default palette */
VGA_Set16Palette
(
CTX_SEG_OFF_TO_LIN
(
context
,
context
->
SegEs
,
context
->
Edx
));
break
;
case
0x03
:
/* TOGGLE INTENSITY/BLINKING BIT */
FIXME
(
"Toggle Intensity/Blinking Bit - Not Supported
\n
"
);
break
;
case
0x07
:
/* GET INDIVIDUAL PALETTE REGISTER - A.C.*/
TRACE
(
"Get Individual Palette Register 0x0%x
\n
"
,
BL_reg
(
context
));
/* BL is register to read [ 0-15 ] BH is return value */
SET_BH
(
context
,
VGA_GetColor16
((
int
)
BL_reg
(
context
))
);
break
;
case
0x08
:
/* READ OVERSCAN (BORDER COLOR) REGISTER - A.C. */
TRACE
(
"Read Overscan (Border Color) Register
\n
"
);
SET_BH
(
context
,
VGA_GetColor16
(
16
)
);
break
;
case
0x09
:
/* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER - A.C.*/
TRACE
(
"Read All Palette Registers and Overscan Register
\n
"
);
/* ES:DX points to a 17 byte table where the results */
/* of this call should be stored. */
VGA_Get16Palette
(
CTX_SEG_OFF_TO_LIN
(
context
,
context
->
SegEs
,
context
->
Edx
));
break
;
case
0x10
:
/* SET INDIVIDUAL DAC REGISTER */
{
PALETTEENTRY
paldat
;
TRACE
(
"Set Individual DAC register
\n
"
);
paldat
.
peRed
=
DH_reg
(
context
);
paldat
.
peGreen
=
CH_reg
(
context
);
paldat
.
peBlue
=
CL_reg
(
context
);
paldat
.
peFlags
=
0
;
VGA_SetPalette
(
&
paldat
,
BX_reg
(
context
)
&
0xFF
,
1
);
}
break
;
case
0x12
:
/* SET BLOCK OF DAC REGISTERS */
{
int
i
;
PALETTEENTRY
paldat
;
BYTE
*
pt
;
TRACE
(
"Set Block of DAC registers
\n
"
);
pt
=
CTX_SEG_OFF_TO_LIN
(
context
,
context
->
SegEs
,
context
->
Edx
);
for
(
i
=
0
;
i
<
CX_reg
(
context
);
i
++
)
{
paldat
.
peRed
=
(
*
(
pt
+
i
*
3
+
0
))
<<
2
;
paldat
.
peGreen
=
(
*
(
pt
+
i
*
3
+
1
))
<<
2
;
paldat
.
peBlue
=
(
*
(
pt
+
i
*
3
+
2
))
<<
2
;
paldat
.
peFlags
=
0
;
VGA_SetPalette
(
&
paldat
,(
BX_reg
(
context
)
+
i
)
&
0xFF
,
1
);
}
}
break
;
case
0x13
:
/* SELECT VIDEO DAC COLOR PAGE */
FIXME
(
"Select video DAC color page - Not Supported
\n
"
);
break
;
case
0x15
:
/* READ INDIVIDUAL DAC REGISTER */
FIXME
(
"Read individual DAC register - Not Supported
\n
"
);
break
;
case
0x17
:
/* READ BLOCK OF DAC REGISTERS */
FIXME
(
"Read block of DAC registers - Not Supported
\n
"
);
break
;
case
0x18
:
/* SET PEL MASK */
FIXME
(
"Set PEL mask - Not Supported
\n
"
);
break
;
case
0x19
:
/* READ PEL MASK */
FIXME
(
"Read PEL mask - Not Supported
\n
"
);
break
;
case
0x1a
:
/* GET VIDEO DAC COLOR PAGE STATE */
FIXME
(
"Get video DAC color page state - Not Supported
\n
"
);
break
;
case
0x1b
:
/* PERFORM GRAY-SCALE SUMMING */
FIXME
(
"Perform Gray-scale summing - Not Supported
\n
"
);
break
;
default:
FIXME
(
"INT 10 AH = 0x10 AL = 0x%x - Unknown
\n
"
,
AL_reg
(
context
));
break
;
}
break
;
case
0x11
:
/* TEXT MODE CHARGEN */
/* Note that second subfunction is *almost* identical. */
/* See INTERRUPT.A for details. */
switch
(
AL_reg
(
context
))
{
case
0x00
:
/* LOAD USER SPECIFIED PATTERNS */
case
0x10
:
FIXME
(
"Load User Specified Patterns - Not Supported
\n
"
);
break
;
case
0x01
:
/* LOAD ROM MONOCHROME PATTERNS */
case
0x11
:
FIXME
(
"Load ROM Monochrome Patterns - Not Supported
\n
"
);
break
;
case
0x02
:
/* LOAD ROM 8x8 DOUBLE-DOT PATTERNS */
case
0x12
:
FIXME
(
"Load ROM 8x8 Double Dot Patterns - Not Supported
\n
"
);
break
;
case
0x03
:
/* SET BLOCK SPECIFIER */
FIXME
(
"Set Block Specifier - Not Supported
\n
"
);
break
;
case
0x04
:
/* LOAD ROM 8x16 CHARACTER SET */
case
0x14
:
FIXME
(
"Load ROM 8x16 Character Set - Not Supported
\n
"
);
break
;
case
0x20
:
/* SET USER 8x16 GRAPHICS CHARS */
FIXME
(
"Set User 8x16 Graphics Chars - Not Supported
\n
"
);
break
;
case
0x21
:
/* SET USER GRAPICS CHARACTERS */
FIXME
(
"Set User Graphics Characters - Not Supported
\n
"
);
break
;
case
0x22
:
/* SET ROM 8x14 GRAPHICS CHARS */
FIXME
(
"Set ROM 8x14 Graphics Chars - Not Supported
\n
"
);
break
;
case
0x23
:
/* SET ROM 8x8 DBL DOT CHARS */
FIXME
(
"Set ROM 8x8 Dbl Dot Chars (Graphics) - Not Supported
\n
"
);
break
;
case
0x24
:
/* LOAD 8x16 GRAPHIC CHARS */
FIXME
(
"Load 8x16 Graphic Chars - Not Supported
\n
"
);
break
;
case
0x30
:
/* GET FONT INFORMATION */
FIXME
(
"Get Font Information - Not Supported
\n
"
);
break
;
default:
FIXME
(
"INT 10 AH = 0x11 AL = 0x%x - Unknown
\n
"
,
AL_reg
(
context
));
break
;
}
break
;
case
0x12
:
/* ALTERNATE FUNCTION SELECT */
switch
(
BL_reg
(
context
))
{
case
0x10
:
/* GET EGA INFO */
TRACE
(
"EGA info requested
\n
"
);
SET_BH
(
context
,
0x00
);
/* Color screen */
SET_BL
(
context
,
data
->
ModeOptions
>>
5
);
/* EGA memory size */
SET_CX
(
context
,
data
->
FeatureBitsSwitches
);
break
;
case
0x20
:
/* ALTERNATE PRTSC */
FIXME
(
"Install Alternate Print Screen - Not Supported
\n
"
);
break
;
case
0x30
:
/* SELECT VERTICAL RESOLUTION */
FIXME
(
"Select vertical resolution - not supported
\n
"
);
break
;
case
0x31
:
/* ENABLE/DISABLE DEFAULT PALETTE LOADING */
FIXME
(
"Default palette loading - not supported
\n
"
);
data
->
VGASettings
=
(
data
->
VGASettings
&
0xf7
)
|
((
AL_reg
(
context
)
==
1
)
<<
3
);
break
;
case
0x32
:
/* ENABLE/DISABLE VIDEO ADDRESSING */
FIXME
(
"Video Addressing - Not Supported
\n
"
);
break
;
case
0x33
:
/* ENABLE/DISABLE GRAY SCALE SUMMING */
FIXME
(
"Gray Scale Summing - Not Supported
\n
"
);
break
;
case
0x34
:
/* ENABLE/DISABLE CURSOR EMULATION */
TRACE
(
"Set cursor emulation to %d
\n
"
,
AL_reg
(
context
));
data
->
ModeOptions
=
(
data
->
ModeOptions
&
0xfe
)
|
(
AL_reg
(
context
)
==
1
);
break
;
case
0x36
:
/* VIDEO ADDRESS CONTROL */
FIXME
(
"Video Address Control - Not Supported
\n
"
);
break
;
default:
FIXME
(
"INT 10 AH = 0x11 AL = 0x%x - Unknown
\n
"
,
AL_reg
(
context
));
break
;
}
break
;
case
0x13
:
/* WRITE STRING */
/* This one does not imply that string be at cursor. */
FIXME
(
"Write String - Not Supported
\n
"
);
break
;
case
0x1a
:
switch
(
AL_reg
(
context
))
{
case
0x00
:
/* GET DISPLAY COMBINATION CODE */
TRACE
(
"Get Display Combination Code
\n
"
);
SET_AL
(
context
,
0x1a
);
/* Function supported */
SET_BL
(
context
,
INT10_DCC
);
/* Active display */
SET_BH
(
context
,
0x00
);
/* No alternate display */
break
;
case
0x01
:
/* SET DISPLAY COMBINATION CODE */
FIXME
(
"Set Display Combination Code - Not Supported
\n
"
);
break
;
default:
FIXME
(
"INT 10 AH = 0x1a AL = 0x%x - Unknown
\n
"
,
AL_reg
(
context
));
break
;
}
break
;
case
0x1b
:
/* FUNCTIONALITY/STATE INFORMATION */
TRACE
(
"Get functionality/state information
\n
"
);
if
(
BX_reg
(
context
)
==
0x0000
)
{
BYTE
*
ptr
=
CTX_SEG_OFF_TO_LIN
(
context
,
context
->
SegEs
,
context
->
Edi
);
SET_AL
(
context
,
0x1b
);
/* Function is supported */
INT10_FillStateInformation
(
ptr
,
data
);
}
break
;
case
0x1c
:
/* SAVE/RESTORE VIDEO STATE */
FIXME
(
"Save/Restore Video State - Not Supported
\n
"
);
break
;
case
0xef
:
/* get video mode for hercules-compatibles */
/* There's no reason to really support this */
/* is there?....................(A.C.) */
TRACE
(
"Just report the video not hercules compatible
\n
"
);
SET_DX
(
context
,
0xffff
);
break
;
case
0x4f
:
/* VESA */
INT10_HandleVESA
(
context
);
break
;
case
0xfe
:
/* GET SHADOW BUFFER */
TRACE
(
"GET SHADOW BUFFER %x:%x - ignored
\n
"
,
context
->
SegEs
,
DI_reg
(
context
)
);
break
;
default:
FIXME
(
"Unknown - 0x%x
\n
"
,
AH_reg
(
context
));
INT_BARF
(
context
,
0x10
);
}
}
/**********************************************************************
* DOSVM_PutChar
*
* Write single character to VGA console at the current
* cursor position and updates the BIOS cursor position.
*/
void
DOSVM_PutChar
(
BYTE
ascii
)
{
BIOSDATA
*
data
=
DOSVM_BiosData
();
unsigned
xpos
,
ypos
;
TRACE
(
"char: 0x%02x(%c)
\n
"
,
ascii
,
ascii
);
INT10_InitializeVideoMode
(
data
);
VGA_PutChar
(
ascii
);
VGA_GetCursorPos
(
&
xpos
,
&
ypos
);
INT10_SetCursorPos
(
data
,
0
,
xpos
,
ypos
);
}
dlls/krnl386.exe16/int21.c
View file @
33b2d852
...
...
@@ -4083,7 +4083,6 @@ void WINAPI DOSVM_Int21Handler( CONTEXT *context )
case
0x02
:
/* WRITE CHARACTER TO STANDARD OUTPUT */
TRACE
(
"Write Character to Standard Output
\n
"
);
DOSVM_PutChar
(
DL_reg
(
context
));
break
;
case
0x03
:
/* READ CHARACTER FROM STDAUX */
...
...
@@ -4104,7 +4103,6 @@ void WINAPI DOSVM_Int21Handler( CONTEXT *context )
else
{
TRACE
(
"Direct Console Output
\n
"
);
DOSVM_PutChar
(
DL_reg
(
context
));
/*
* At least DOS versions 2.1-7.0 return character
* that was written in AL register.
...
...
dlls/krnl386.exe16/interrupts.c
View file @
33b2d852
...
...
@@ -40,7 +40,6 @@ static void WINAPI DOSVM_Int17Handler(CONTEXT*);
static
void
WINAPI
DOSVM_Int19Handler
(
CONTEXT
*
);
static
void
WINAPI
DOSVM_Int1aHandler
(
CONTEXT
*
);
static
void
WINAPI
DOSVM_Int20Handler
(
CONTEXT
*
);
static
void
WINAPI
DOSVM_Int29Handler
(
CONTEXT
*
);
static
void
WINAPI
DOSVM_Int2aHandler
(
CONTEXT
*
);
static
void
WINAPI
DOSVM_Int41Handler
(
CONTEXT
*
);
static
void
WINAPI
DOSVM_Int4bHandler
(
CONTEXT
*
);
...
...
@@ -55,13 +54,13 @@ static const INTPROC DOSVM_VectorsBuiltin[] =
/* 04 */
0
,
0
,
0
,
0
,
/* 08 */
0
,
0
,
0
,
0
,
/* 0C */
0
,
0
,
0
,
0
,
/* 10 */
DOSVM_Int10Handler
,
DOSVM_Int11Handler
,
DOSVM_Int12Handler
,
DOSVM_Int13Handler
,
/* 10 */
0
,
DOSVM_Int11Handler
,
DOSVM_Int12Handler
,
DOSVM_Int13Handler
,
/* 14 */
0
,
DOSVM_Int15Handler
,
0
,
DOSVM_Int17Handler
,
/* 18 */
0
,
DOSVM_Int19Handler
,
DOSVM_Int1aHandler
,
0
,
/* 1C */
0
,
0
,
0
,
0
,
/* 20 */
DOSVM_Int20Handler
,
DOSVM_Int21Handler
,
0
,
0
,
/* 24 */
0
,
DOSVM_Int25Handler
,
DOSVM_Int26Handler
,
0
,
/* 28 */
0
,
DOSVM_Int29Handler
,
DOSVM_Int2aHandler
,
0
,
/* 28 */
0
,
0
,
DOSVM_Int2aHandler
,
0
,
/* 2C */
0
,
0
,
0
,
DOSVM_Int2fHandler
,
/* 30 */
0
,
DOSVM_Int31Handler
,
0
,
0
,
/* 34 */
DOSVM_Int34Handler
,
DOSVM_Int35Handler
,
DOSVM_Int36Handler
,
DOSVM_Int37Handler
,
...
...
@@ -798,18 +797,6 @@ static void WINAPI DOSVM_Int20Handler( CONTEXT *context )
/**********************************************************************
* DOSVM_Int29Handler
*
* Handler for int 29h (fast console output)
*/
static
void
WINAPI
DOSVM_Int29Handler
(
CONTEXT
*
context
)
{
/* Yes, it seems that this is really all this interrupt does. */
DOSVM_PutChar
(
AL_reg
(
context
));
}
/**********************************************************************
* DOSVM_Int2aHandler
*
* Handler for int 2ah (network).
...
...
dlls/krnl386.exe16/ioports.c
View file @
33b2d852
...
...
@@ -54,7 +54,6 @@
#include "winternl.h"
#include "kernel16_private.h"
#include "dosexe.h"
#include "vga.h"
#include "wine/unicode.h"
#include "wine/debug.h"
...
...
@@ -843,46 +842,6 @@ DWORD DOSVM_inport( int port, int size )
case
0x22e
:
res
=
(
DWORD
)
SB_ioport_in
(
port
);
break
;
/* VGA read registers */
case
0x3b4
:
/* CRT Controller Register - Index (MDA) */
case
0x3b5
:
/* CRT Controller Register - Other (MDA) */
case
0x3ba
:
/* General Register - Input status 1 (MDA) */
case
0x3c0
:
/* Attribute Controller - Address */
case
0x3c1
:
/* Attribute Controller - Other */
case
0x3c2
:
/* General Register - Input status 0 */
case
0x3c3
:
/* General Register - Video subsystem enable */
case
0x3c4
:
/* Sequencer Register - Address */
case
0x3c5
:
/* Sequencer Register - Other */
case
0x3c6
:
case
0x3c7
:
/* General Register - DAC State */
case
0x3c8
:
case
0x3c9
:
case
0x3ca
:
/* General Register - Feature control */
case
0x3cb
:
case
0x3cc
:
/* General Register - Misc output */
case
0x3cd
:
case
0x3ce
:
/* Graphics Controller Register - Address */
case
0x3cf
:
/* Graphics Controller Register - Other */
case
0x3d0
:
case
0x3d1
:
case
0x3d2
:
case
0x3d3
:
case
0x3d4
:
/* CRT Controller Register - Index (CGA) */
case
0x3d5
:
/* CRT Controller Register - Other (CGA) */
case
0x3d6
:
case
0x3d7
:
case
0x3d8
:
case
0x3d9
:
case
0x3da
:
case
0x3db
:
case
0x3dc
:
case
0x3dd
:
case
0x3de
:
case
0x3df
:
if
(
size
>
1
)
FIXME
(
"Trying to read more than one byte from VGA!
\n
"
);
res
=
(
DWORD
)
VGA_ioport_in
(
port
);
break
;
case
0x00
:
case
0x01
:
case
0x02
:
...
...
@@ -1080,51 +1039,6 @@ void DOSVM_outport( int port, int size, DWORD value )
case
0x22c
:
SB_ioport_out
(
port
,
(
BYTE
)
value
);
break
;
/* VGA Write registers */
case
0x3b4
:
/* CRT Controller Register - Index (MDA) */
case
0x3b5
:
/* CRT Controller Register - Other (MDA) */
case
0x3ba
:
/* General Register - Feature Control */
case
0x3c0
:
/* Attribute Controller - Address/Other */
case
0x3c1
:
case
0x3c2
:
/* General Register - Misc output */
case
0x3c3
:
/* General Register - Video subsystem enable */
case
0x3c4
:
/* Sequencer Register - Address */
case
0x3c5
:
/* Sequencer Register - Other */
case
0x3c6
:
case
0x3c7
:
case
0x3c8
:
case
0x3c9
:
case
0x3ca
:
case
0x3cb
:
case
0x3cc
:
case
0x3cd
:
case
0x3ce
:
/* Graphics Controller Register - Address */
case
0x3cf
:
/* Graphics Controller Register - Other */
case
0x3d0
:
case
0x3d1
:
case
0x3d2
:
case
0x3d3
:
case
0x3d4
:
/* CRT Controller Register - Index (CGA) */
case
0x3d5
:
/* CRT Controller Register - Other (CGA) */
case
0x3d6
:
case
0x3d7
:
case
0x3d8
:
case
0x3d9
:
case
0x3da
:
case
0x3db
:
case
0x3dc
:
case
0x3dd
:
case
0x3de
:
case
0x3df
:
VGA_ioport_out
(
port
,
LOBYTE
(
value
)
);
if
(
size
>
1
)
{
VGA_ioport_out
(
port
+
1
,
HIBYTE
(
value
)
);
if
(
size
>
2
)
{
VGA_ioport_out
(
port
+
2
,
LOBYTE
(
HIWORD
(
value
))
);
VGA_ioport_out
(
port
+
3
,
HIBYTE
(
HIWORD
(
value
))
);
}
}
break
;
case
0x00
:
case
0x01
:
case
0x02
:
...
...
dlls/krnl386.exe16/vga.c
deleted
100644 → 0
View file @
5ec54495
/*
* VGA hardware emulation
*
* Copyright 1998 Ove Kåven (with some help from Marcus Meissner)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <string.h>
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "wincon.h"
#include "dosexe.h"
#include "vga.h"
#include "ddraw.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
ddraw
);
static
IDirectDraw
*
lpddraw
=
NULL
;
static
IDirectDrawSurface
*
lpddsurf
;
static
IDirectDrawPalette
*
lpddpal
;
static
DDSURFACEDESC
sdesc
;
static
BOOL
vga_retrace_vertical
;
static
BOOL
vga_retrace_horizontal
;
/*
* Size and location of VGA controller window to framebuffer.
*
* Note: We support only single window even though some
* controllers support two. This should not be changed unless
* there are programs that depend on having two windows.
*/
#define VGA_WINDOW_SIZE (64 * 1024)
#define VGA_WINDOW_START ((char *)0xa0000)
/*
* Size and location of CGA controller window to framebuffer.
*/
#define CGA_WINDOW_SIZE (32 * 1024)
#define CGA_WINDOW_START ((char *)0xb8000)
/*
* VGA controller memory is emulated using linear framebuffer.
* This frambuffer also acts as an interface
* between VGA controller emulation and DirectDraw.
*
* vga_fb_width: Display width in pixels. Can be modified when
* display mode is changed.
* vga_fb_height: Display height in pixels. Can be modified when
* display mode is changed.
* vga_fb_depth: Number of bits used to store single pixel color information.
* Each pixel uses (vga_fb_depth+7)/8 bytes because
* 1-16 color modes are mapped to 256 color mode.
* Can be modified when display mode is changed.
* vga_fb_pitch: How many bytes to add to pointer in order to move
* from one row to another. This is fixed in VGA modes,
* but can be modified in SVGA modes.
* vga_fb_offset: Offset added to framebuffer start address in order
* to find the display origin. Programs use this to do
* double buffering and to scroll display. The value can
* be modified in VGA and SVGA modes.
* vga_fb_size: How many bytes are allocated to framebuffer.
* VGA framebuffers are always larger than display size and
* SVGA framebuffers may also be.
* vga_fb_data: Pointer to framebuffer start.
* vga_fb_window: Offset of 64k window 0xa0000 in bytes from framebuffer start.
* This value is >= 0, if mode uses linear framebuffer and
* -1, if mode uses color planes. This value is fixed
* in all modes except 0x13 (256 color VGA) where
* 0 means normal mode and -1 means Mode-X (unchained mode).
*/
static
int
vga_fb_width
;
static
int
vga_fb_height
;
static
int
vga_fb_depth
;
static
int
vga_fb_pitch
;
static
int
vga_fb_offset
;
static
int
vga_fb_size
=
0
;
static
char
*
vga_fb_data
=
0
;
static
int
vga_fb_window
=
0
;
static
int
vga_fb_window_size
;
static
char
*
vga_fb_window_data
;
static
PALETTEENTRY
*
vga_fb_palette
;
static
unsigned
vga_fb_palette_index
;
static
unsigned
vga_fb_palette_size
;
static
BOOL
vga_fb_bright
;
static
BOOL
vga_fb_enabled
;
/*
* VGA text mode data.
*
* vga_text_attr: Current active attribute.
* vga_text_old: Last data sent to console.
* This is used to optimize console updates.
* vga_text_width: Width of the text display in characters.
* vga_text_height: Height of the text display in characters.
* vga_text_x: Current cursor X-position. Starts from zero.
* vga_text_y: Current cursor Y-position. Starts from zero.
* vga_text_console: TRUE if stdout is console,
* FALSE if it is regular file.
*/
static
BYTE
vga_text_attr
;
static
char
*
vga_text_old
=
NULL
;
static
BYTE
vga_text_width
;
static
BYTE
vga_text_height
;
static
BYTE
vga_text_x
;
static
BYTE
vga_text_y
;
static
BOOL
vga_text_console
;
/*
* VGA controller ports 0x3c0, 0x3c4, 0x3ce and 0x3d4 are
* indexed registers. These ports are used to select VGA controller
* subregister that can be written to or read from using ports 0x3c1,
* 0x3c5, 0x3cf or 0x3d5. Selected subregister indexes are
* stored in variables vga_index_*.
*
* Port 0x3c0 is special because it is both index and
* data-write register. Flip-flop vga_address_3c0 tells whether
* the port acts currently as an address register. Reading from port
* 0x3da resets the flip-flop to address mode.
*/
static
BYTE
vga_index_3c0
;
static
BYTE
vga_index_3c4
;
static
BYTE
vga_index_3ce
;
static
BYTE
vga_index_3d4
;
static
BOOL
vga_address_3c0
=
TRUE
;
/*
* List of supported video modes.
*
* should be expanded to contain most or all information
* as required for SVGA VESA mode info block for VESA BIOS subsystem 1 (see _ModeInfoBlock)
* this will allow proper support for FIXME items in VGA/VESA mode configuration
*
* FIXME - verify and define support for VESA modes
* FIXME - add # bit planes, # video memory banks, & memory model
*/
static
WORD
VGA_CurrentMode
;
static
BOOL
CGA_ColorComposite
=
FALSE
;
/* behave like composite monitor */
const
VGA_MODE
VGA_modelist
[]
=
{
/* Mode, ModeType, TextCols, TextRows, CharWidth, CharHeight, Width, Height, Depth, Colors, ScreenPages, Supported*/
/* VGA modes */
{
0x0000
,
TEXT
,
40
,
25
,
9
,
16
,
360
,
400
,
0
,
16
,
8
,
TRUE
},
/* VGA/CGA text mode 0 */
{
0x0001
,
TEXT
,
40
,
25
,
9
,
16
,
360
,
400
,
0
,
16
,
8
,
TRUE
},
/* VGA/CGA text mode 1 */
{
0x0002
,
TEXT
,
80
,
25
,
9
,
16
,
360
,
400
,
0
,
16
,
8
,
TRUE
},
/* VGA/CGA text mode 2 */
{
0x0003
,
TEXT
,
80
,
25
,
9
,
16
,
360
,
400
,
0
,
16
,
8
,
TRUE
},
/* VGA/CGA text mode 3 */
{
0x0004
,
GRAPHIC
,
40
,
25
,
8
,
8
,
320
,
200
,
2
,
4
,
1
,
TRUE
},
/* VGA/CGA graphics mode 4 */
{
0x0005
,
GRAPHIC
,
40
,
25
,
8
,
8
,
320
,
200
,
2
,
4
,
1
,
TRUE
},
/* VGA/CGA graphics mode 5 */
{
0x0006
,
GRAPHIC
,
80
,
25
,
8
,
8
,
640
,
200
,
1
,
2
,
1
,
TRUE
},
/* VGA/CGA graphics mode 6 */
{
0x0007
,
TEXT
,
80
,
25
,
9
,
16
,
720
,
400
,
0
,
0
,
8
,
FALSE
},
/* VGA text mode 7 - FIXME bad default address */
{
0x000d
,
GRAPHIC
,
40
,
25
,
8
,
8
,
320
,
200
,
4
,
16
,
8
,
FALSE
},
/* VGA graphics mode 13 */
{
0x000e
,
GRAPHIC
,
80
,
25
,
8
,
8
,
640
,
200
,
4
,
16
,
4
,
FALSE
},
/* VGA graphics mode 14 */
{
0x000f
,
GRAPHIC
,
80
,
25
,
8
,
14
,
640
,
350
,
0
,
0
,
2
,
FALSE
},
/* VGA graphics mode 15 */
{
0x0010
,
GRAPHIC
,
80
,
25
,
8
,
14
,
640
,
350
,
4
,
16
,
2
,
FALSE
},
/* VGA graphics mode 16 */
{
0x0011
,
GRAPHIC
,
80
,
30
,
8
,
16
,
640
,
480
,
1
,
2
,
1
,
FALSE
},
/* VGA graphics mode 17 */
{
0x0012
,
GRAPHIC
,
80
,
30
,
8
,
16
,
640
,
480
,
4
,
16
,
1
,
FALSE
},
/* VGA graphics mode 18 */
{
0x0013
,
GRAPHIC
,
40
,
25
,
8
,
8
,
320
,
200
,
8
,
256
,
1
,
TRUE
},
/* VGA graphics mode 19 */
/* VESA 7-bit modes */
{
0x006a
,
GRAPHIC
,
0
,
0
,
0
,
0
,
800
,
600
,
4
,
16
,
1
,
TRUE
},
/* VESA graphics mode, same as 0x102 */
/* VESA 15-bit modes */
{
0x0100
,
GRAPHIC
,
0
,
0
,
0
,
0
,
640
,
400
,
8
,
256
,
1
,
TRUE
},
/* VESA graphics mode */
{
0x0101
,
GRAPHIC
,
0
,
0
,
0
,
0
,
640
,
480
,
8
,
256
,
1
,
TRUE
},
/* VESA graphics mode */
{
0x0102
,
GRAPHIC
,
0
,
0
,
0
,
0
,
800
,
600
,
4
,
16
,
1
,
TRUE
},
/* VESA graphics mode */
{
0x0103
,
GRAPHIC
,
0
,
0
,
0
,
0
,
800
,
600
,
8
,
256
,
1
,
TRUE
},
/* VESA graphics mode */
{
0x0104
,
GRAPHIC
,
0
,
0
,
0
,
0
,
1024
,
768
,
4
,
16
,
1
,
TRUE
},
/* VESA graphics mode */
{
0x0105
,
GRAPHIC
,
0
,
0
,
0
,
0
,
1024
,
768
,
8
,
256
,
1
,
TRUE
},
/* VESA graphics mode */
{
0x0106
,
GRAPHIC
,
0
,
0
,
0
,
0
,
1280
,
1024
,
4
,
16
,
1
,
TRUE
},
/* VESA graphics mode */
{
0x0107
,
GRAPHIC
,
0
,
0
,
0
,
0
,
1280
,
1024
,
8
,
256
,
1
,
TRUE
},
/* VESA graphics mode */
{
0x0108
,
TEXT
,
0
,
0
,
0
,
0
,
80
,
60
,
0
,
0
,
1
,
TRUE
},
/* VESA text mode */
{
0x0109
,
TEXT
,
0
,
0
,
0
,
0
,
132
,
25
,
0
,
0
,
1
,
TRUE
},
/* VESA text mode */
{
0x010a
,
TEXT
,
0
,
0
,
0
,
0
,
132
,
43
,
0
,
0
,
1
,
TRUE
},
/* VESA text mode */
{
0x010b
,
TEXT
,
0
,
0
,
0
,
0
,
132
,
50
,
0
,
0
,
1
,
TRUE
},
/* VESA text mode */
{
0x010c
,
TEXT
,
0
,
0
,
0
,
0
,
132
,
60
,
0
,
0
,
1
,
TRUE
},
/* VESA text mode */
/* VESA 1.2 modes */
{
0x010d
,
GRAPHIC
,
0
,
0
,
0
,
0
,
320
,
200
,
15
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 32K colors */
{
0x010e
,
GRAPHIC
,
0
,
0
,
0
,
0
,
320
,
200
,
16
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 64K colors */
{
0x010f
,
GRAPHIC
,
0
,
0
,
0
,
0
,
320
,
200
,
24
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 16.8 Million colors */
{
0x0110
,
GRAPHIC
,
0
,
0
,
0
,
0
,
640
,
480
,
15
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 32K colors */
{
0x0111
,
GRAPHIC
,
0
,
0
,
0
,
0
,
640
,
480
,
16
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 64K colors */
{
0x0112
,
GRAPHIC
,
0
,
0
,
0
,
0
,
640
,
480
,
24
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 16.8 Million colors */
{
0x0113
,
GRAPHIC
,
0
,
0
,
0
,
0
,
800
,
600
,
15
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 32K colors */
{
0x0114
,
GRAPHIC
,
0
,
0
,
0
,
0
,
800
,
600
,
16
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 64K colors */
{
0x0115
,
GRAPHIC
,
0
,
0
,
0
,
0
,
800
,
600
,
24
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 16.8 Million colors */
{
0x0116
,
GRAPHIC
,
0
,
0
,
0
,
0
,
1024
,
768
,
15
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 32K colors */
{
0x0117
,
GRAPHIC
,
0
,
0
,
0
,
0
,
1024
,
768
,
16
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 64K colors */
{
0x0118
,
GRAPHIC
,
0
,
0
,
0
,
0
,
1024
,
768
,
24
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 16.8 Million colors */
{
0x0119
,
GRAPHIC
,
0
,
0
,
0
,
0
,
1280
,
1024
,
15
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 32K colors */
{
0x011a
,
GRAPHIC
,
0
,
0
,
0
,
0
,
1280
,
1024
,
16
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 64K colors */
{
0x011b
,
GRAPHIC
,
0
,
0
,
0
,
0
,
1280
,
1024
,
24
,
0
,
1
,
TRUE
},
/* VESA graphics mode, 16.8 Million colors */
{
0xffff
,
TEXT
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
FALSE
}
};
/*
* This mutex is used to protect VGA state during asynchronous
* screen updates (see VGA_Poll). It makes sure that VGA state changes
* are atomic and the user interface is protected from flicker and
* corruption.
*
* The mutex actually serializes VGA operations and the screen update.
* Which means that whenever VGA_Poll occurs, application stalls if it
* tries to modify VGA state. This is not how real VGA adapters work,
* but it makes timing and correctness issues much easier to deal with.
*/
static
CRITICAL_SECTION
vga_lock
;
static
CRITICAL_SECTION_DEBUG
critsect_debug
=
{
0
,
0
,
&
vga_lock
,
{
&
critsect_debug
.
ProcessLocksList
,
&
critsect_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": vga_lock"
)
}
};
static
CRITICAL_SECTION
vga_lock
=
{
&
critsect_debug
,
-
1
,
0
,
0
,
0
,
0
};
static
void
CALLBACK
VGA_Poll
(
LPVOID
arg
,
DWORD
low
,
DWORD
high
);
static
HWND
vga_hwnd
=
NULL
;
/*
* CGA palette 1
*/
static
PALETTEENTRY
cga_palette1
[]
=
{
{
0x00
,
0x00
,
0x00
},
/* 0 - Black */
{
0x00
,
0xAA
,
0xAA
},
/* 1 - Cyan */
{
0xAA
,
0x00
,
0xAA
},
/* 2 - Magenta */
{
0xAA
,
0xAA
,
0xAA
}
/* 3 - White */
};
/*
* CGA palette 1 in the bright variant
* intensities, when signalled to do so
* in register 0x3d9
*/
static
PALETTEENTRY
cga_palette1_bright
[]
=
{
{
0x00
,
0x00
,
0x00
},
/* 0 - Black */
{
0x55
,
0xFF
,
0xFF
},
/* 1 - Light cyan */
{
0xFF
,
0x55
,
0xFF
},
/* 2 - Light magenta */
{
0xFF
,
0xFF
,
0xFF
},
/* 3 - Bright White */
};
/*
* CGA palette 2
*/
static
PALETTEENTRY
cga_palette2
[]
=
{
{
0x00
,
0x00
,
0x00
},
/* 0 - Black */
{
0x00
,
0xAA
,
0x00
},
/* 1 - Green */
{
0xAA
,
0x00
,
0x00
},
/* 2 - Red */
{
0xAA
,
0x55
,
0x00
}
/* 3 - Brown */
};
/*
* CGA palette 2 in the bright variant
* intensities, when signalled to do so
* in register 0x3d9
*/
static
PALETTEENTRY
cga_palette2_bright
[]
=
{
{
0x00
,
0x00
,
0x00
},
/* 0 - Black */
{
0x55
,
0xFF
,
0x55
},
/* 1 - Light green */
{
0xFF
,
0x55
,
0x55
},
/* 2 - Light red */
{
0xFF
,
0xFF
,
0x55
},
/* 3 - Yellow */
};
/*
* VGA Palette Registers, in actual 16 bit color
* port 3C0H - 6 bit rgbRGB format
*
* 16 color accesses will use these pointers and insert
* entries from the 64-color palette (mode 18) into the default
* palette. --Robert 'Admiral' Coeyman
*/
static
char
vga_16_palette
[
17
]
=
{
0x00
,
/* 0 - Black */
0x01
,
/* 1 - Blue */
0x02
,
/* 2 - Green */
0x03
,
/* 3 - Cyan */
0x04
,
/* 4 - Red */
0x05
,
/* 5 - Magenta */
0x14
,
/* 6 - Brown */
0x07
,
/* 7 - White (Light gray) */
0x38
,
/* 8 - Dark gray */
0x39
,
/* 9 - Light blue */
0x3a
,
/* A - Light green */
0x3b
,
/* B - Light cyan */
0x3c
,
/* C - Light red */
0x3d
,
/* D - Light magenta */
0x3e
,
/* E - Yellow */
0x3f
,
/* F - Bright White (White) */
0x00
/* Border Color */
};
/*
* Mode 19 Default Color Register Setting
* DAC palette registers, converted from actual 18 bit color to 24.
*/
static
PALETTEENTRY
vga_def_palette
[
256
]
=
{
/* red green blue */
/* 16 colors in IRGB values */
{
0x00
,
0x00
,
0x00
},
/* 0 (0) - Black */
{
0x00
,
0x00
,
0xAA
},
/* 1 (1) - Blue */
{
0x00
,
0xAA
,
0x00
},
/* 2 (2) - Green */
{
0x00
,
0xAA
,
0xAA
},
/* 3 (3) - Cyan */
{
0xAA
,
0x00
,
0x00
},
/* 4 (4) - Red */
{
0xAA
,
0x00
,
0xAA
},
/* 5 (5) - Magenta */
{
0xAA
,
0x55
,
0x00
},
/* 6 (6) - Brown */
{
0xAA
,
0xAA
,
0xAA
},
/* 7 (7) - White (Light gray) */
{
0x55
,
0x55
,
0x55
},
/* 8 (8) - Dark gray */
{
0x55
,
0x55
,
0xFF
},
/* 9 (9) - Light blue */
{
0x55
,
0xFF
,
0x55
},
/* 10 (A) - Light green */
{
0x55
,
0xFF
,
0xFF
},
/* 11 (B) - Light cyan */
{
0xFF
,
0x55
,
0x55
},
/* 12 (C) - Light red */
{
0xFF
,
0x55
,
0xFF
},
/* 13 (D) - Light magenta */
{
0xFF
,
0xFF
,
0x55
},
/* 14 (E) - Yellow */
{
0xFF
,
0xFF
,
0xFF
},
/* 15 (F) - Bright White (White) */
/* 16 shades of gray */
{
0x00
,
0x00
,
0x00
},
/* 16 (10) */
{
0x10
,
0x10
,
0x10
},
/* 17 (11) */
{
0x20
,
0x20
,
0x20
},
/* 18 (12) */
{
0x35
,
0x35
,
0x35
},
/* 19 (13) */
{
0x45
,
0x45
,
0x45
},
/* 20 (14) */
{
0x55
,
0x55
,
0x55
},
/* 21 (15) */
{
0x65
,
0x65
,
0x65
},
/* 22 (16) */
{
0x75
,
0x75
,
0x75
},
/* 23 (17) */
{
0x8A
,
0x8A
,
0x8A
},
/* 24 (18) */
{
0x9A
,
0x9A
,
0x9A
},
/* 25 (19) */
{
0xAA
,
0xAA
,
0xAA
},
/* 26 (1A) */
{
0xBA
,
0xBA
,
0xBA
},
/* 27 (1B) */
{
0xCA
,
0xCA
,
0xCA
},
/* 28 (1C) */
{
0xDF
,
0xDF
,
0xDF
},
/* 29 (1D) */
{
0xEF
,
0xEF
,
0xEF
},
/* 30 (1E) */
{
0xFF
,
0xFF
,
0xFF
},
/* 31 (1F) */
/* High Intensity group - 72 colors in 1/3 saturation groups (20H-37H high) */
{
0x00
,
0x00
,
0xFF
},
/* 32 (20) */
{
0x41
,
0x00
,
0xFF
},
/* 33 (21) */
{
0x82
,
0x00
,
0xFF
},
/* 34 (22) */
{
0xBE
,
0x00
,
0xFF
},
/* 35 (23) */
{
0xFF
,
0x00
,
0xFF
},
/* 36 (24) */
{
0xFF
,
0x00
,
0xBE
},
/* 37 (25) */
{
0xFF
,
0x00
,
0x82
},
/* 38 (26) */
{
0xFF
,
0x00
,
0x41
},
/* 39 (27) */
{
0xFF
,
0x00
,
0x00
},
/* 40 (28) */
{
0xFF
,
0x41
,
0x00
},
/* 41 (29) */
{
0xFF
,
0x82
,
0x00
},
/* 42 (2A) */
{
0xFF
,
0xBE
,
0x00
},
/* 43 (2B) */
{
0xFF
,
0xFF
,
0x00
},
/* 44 (2C) */
{
0xBE
,
0xFF
,
0x00
},
/* 45 (2D) */
{
0x82
,
0xFF
,
0x00
},
/* 46 (2E) */
{
0x41
,
0xFF
,
0x00
},
/* 47 (2F) */
{
0x00
,
0xFF
,
0x00
},
/* 48 (30) */
{
0x00
,
0xFF
,
0x41
},
/* 49 (31) */
{
0x00
,
0xFF
,
0x82
},
/* 50 (32) */
{
0x00
,
0xFF
,
0xBE
},
/* 51 (33) */
{
0x00
,
0xFF
,
0xFF
},
/* 52 (34) */
{
0x00
,
0xBE
,
0xFF
},
/* 53 (35) */
{
0x00
,
0x82
,
0xFF
},
/* 54 (36) */
{
0x00
,
0x41
,
0xFF
},
/* 55 (37) */
/* High Intensity group - 72 colors in 2/3 saturation groups (38H-4FH moderate) */
{
0x82
,
0x82
,
0xFF
},
/* 56 (38) */
{
0x9E
,
0x82
,
0xFF
},
/* 57 (39) */
{
0xBE
,
0x82
,
0xFF
},
/* 58 (3A) */
{
0xDF
,
0x82
,
0xFF
},
/* 59 (3B) */
{
0xFF
,
0x82
,
0xFF
},
/* 60 (3C) */
{
0xFF
,
0x82
,
0xDF
},
/* 61 (3D) */
{
0xFF
,
0x82
,
0xBE
},
/* 62 (3E) */
{
0xFF
,
0x82
,
0x9E
},
/* 63 (3F) */
{
0xFF
,
0x82
,
0x82
},
/* 64 (40) */
{
0xFF
,
0x9E
,
0x82
},
/* 65 (41) */
{
0xFF
,
0xBE
,
0x82
},
/* 66 (42) */
{
0xFF
,
0xDF
,
0x82
},
/* 67 (43) */
{
0xFF
,
0xFF
,
0x82
},
/* 68 (44) */
{
0xDF
,
0xFF
,
0x82
},
/* 69 (45) */
{
0xBE
,
0xFF
,
0x82
},
/* 70 (46) */
{
0x9E
,
0xFF
,
0x82
},
/* 71 (47) */
{
0x82
,
0xFF
,
0x82
},
/* 72 (48) */
{
0x82
,
0xFF
,
0x9E
},
/* 73 (49) */
{
0x82
,
0xFF
,
0xBE
},
/* 74 (4A) */
{
0x82
,
0xFF
,
0xDF
},
/* 75 (4B) */
{
0x82
,
0xFF
,
0xFF
},
/* 76 (4C) */
{
0x82
,
0xDF
,
0xFF
},
/* 77 (4D) */
{
0x82
,
0xBE
,
0xFF
},
/* 78 (4E) */
{
0x82
,
0x9E
,
0xFF
},
/* 79 (4F) */
/* High Intensity group - 72 colors in 3/3 saturation groups (50H-67H low) */
{
0xBA
,
0xBA
,
0xFF
},
/* 80 (50) */
{
0xCA
,
0xBA
,
0xFF
},
/* 81 (51) */
{
0xDF
,
0xBA
,
0xFF
},
/* 82 (52) */
{
0xEF
,
0xBA
,
0xFF
},
/* 83 (53) */
{
0xFF
,
0xBA
,
0xFF
},
/* 84 (54) */
{
0xFF
,
0xBA
,
0xEF
},
/* 85 (55) */
{
0xFF
,
0xBA
,
0xDF
},
/* 86 (56) */
{
0xFF
,
0xBA
,
0xCA
},
/* 87 (57) */
{
0xFF
,
0xBA
,
0xBA
},
/* 88 (58) */
{
0xFF
,
0xCA
,
0xBA
},
/* 89 (59) */
{
0xFF
,
0xDF
,
0xBA
},
/* 90 (5A) */
{
0xFF
,
0xEF
,
0xBA
},
/* 91 (5B) */
{
0xFF
,
0xFF
,
0xBA
},
/* 92 (5C) */
{
0xEF
,
0xFF
,
0xBA
},
/* 93 (5D) */
{
0xDF
,
0xFF
,
0xBA
},
/* 94 (5E) */
{
0xCA
,
0xFF
,
0xBA
},
/* 95 (5F) */
{
0xBA
,
0xFF
,
0xBA
},
/* 96 (60) */
{
0xBA
,
0xFF
,
0xCA
},
/* 97 (61) */
{
0xBA
,
0xFF
,
0xDF
},
/* 98 (62) */
{
0xBA
,
0xFF
,
0xEF
},
/* 99 (63) */
{
0xBA
,
0xFF
,
0xFF
},
/* 100 (64) */
{
0xBA
,
0xEF
,
0xFF
},
/* 101 (65) */
{
0xBA
,
0xDF
,
0xFF
},
/* 102 (66) */
{
0xBA
,
0xCA
,
0xFF
},
/* 103 (67) */
/* Medium Intensity group - 72 colors in 1/3 saturation groups (68H-7FH high) */
{
0x00
,
0x00
,
0x71
},
/* 104 (68) */
{
0x1C
,
0x00
,
0x71
},
/* 105 (69) */
{
0x39
,
0x00
,
0x71
},
/* 106 (6A) */
{
0x55
,
0x00
,
0x71
},
/* 107 (6B) */
{
0x71
,
0x00
,
0x71
},
/* 108 (6C) */
{
0x71
,
0x00
,
0x55
},
/* 109 (6D) */
{
0x71
,
0x00
,
0x39
},
/* 110 (6E) */
{
0x71
,
0x00
,
0x1C
},
/* 111 (6F) */
{
0x71
,
0x00
,
0x00
},
/* 112 (70) */
{
0x71
,
0x1C
,
0x00
},
/* 113 (71) */
{
0x71
,
0x39
,
0x00
},
/* 114 (72) */
{
0x71
,
0x55
,
0x00
},
/* 115 (73) */
{
0x71
,
0x71
,
0x00
},
/* 116 (74) */
{
0x55
,
0x71
,
0x00
},
/* 117 (75) */
{
0x39
,
0x71
,
0x00
},
/* 118 (76) */
{
0x1C
,
0x71
,
0x00
},
/* 119 (77) */
{
0x00
,
0x71
,
0x00
},
/* 120 (78) */
{
0x00
,
0x71
,
0x1C
},
/* 121 (79) */
{
0x00
,
0x71
,
0x39
},
/* 122 (7A) */
{
0x00
,
0x71
,
0x55
},
/* 123 (7B) */
{
0x00
,
0x71
,
0x71
},
/* 124 (7C) */
{
0x00
,
0x55
,
0x71
},
/* 125 (7D) */
{
0x00
,
0x39
,
0x71
},
/* 126 (7E) */
{
0x00
,
0x1C
,
0x71
},
/* 127 (7F) */
/* Medium Intensity group - 72 colors in 2/3 saturation groups (80H-97H moderate) */
{
0x39
,
0x39
,
0x71
},
/* 128 (80) */
{
0x45
,
0x39
,
0x71
},
/* 129 (81) */
{
0x55
,
0x39
,
0x71
},
/* 130 (82) */
{
0x61
,
0x39
,
0x71
},
/* 131 (83) */
{
0x71
,
0x39
,
0x71
},
/* 132 (84) */
{
0x71
,
0x39
,
0x61
},
/* 133 (85) */
{
0x71
,
0x39
,
0x55
},
/* 134 (86) */
{
0x71
,
0x39
,
0x45
},
/* 135 (87) */
{
0x71
,
0x39
,
0x39
},
/* 136 (88) */
{
0x71
,
0x45
,
0x39
},
/* 137 (89) */
{
0x71
,
0x55
,
0x39
},
/* 138 (8A) */
{
0x71
,
0x61
,
0x39
},
/* 139 (8B) */
{
0x71
,
0x71
,
0x39
},
/* 140 (8C) */
{
0x61
,
0x71
,
0x39
},
/* 141 (8D) */
{
0x55
,
0x71
,
0x39
},
/* 142 (8E) */
{
0x45
,
0x71
,
0x39
},
/* 143 (8F) */
{
0x39
,
0x71
,
0x39
},
/* 144 (90) */
{
0x39
,
0x71
,
0x45
},
/* 145 (91) */
{
0x39
,
0x71
,
0x55
},
/* 146 (92) */
{
0x39
,
0x71
,
0x61
},
/* 147 (93) */
{
0x39
,
0x71
,
0x71
},
/* 148 (94) */
{
0x39
,
0x61
,
0x71
},
/* 149 (95) */
{
0x39
,
0x55
,
0x71
},
/* 150 (96) */
{
0x39
,
0x45
,
0x71
},
/* 151 (97) */
/* Medium Intensity group - 72 colors in 3/3 saturation groups (98H-AFH low) */
{
0x51
,
0x51
,
0x71
},
/* 152 (98) */
{
0x59
,
0x51
,
0x71
},
/* 153 (99) */
{
0x61
,
0x51
,
0x71
},
/* 154 (9A) */
{
0x69
,
0x51
,
0x71
},
/* 155 (9B) */
{
0x71
,
0x51
,
0x71
},
/* 156 (9C) */
{
0x71
,
0x51
,
0x69
},
/* 157 (9D) */
{
0x71
,
0x51
,
0x61
},
/* 158 (9E) */
{
0x71
,
0x51
,
0x59
},
/* 159 (9F) */
{
0x71
,
0x51
,
0x51
},
/* 160 (A0) */
{
0x71
,
0x59
,
0x51
},
/* 161 (A1) */
{
0x71
,
0x61
,
0x51
},
/* 162 (A2) */
{
0x71
,
0x69
,
0x51
},
/* 163 (A3) */
{
0x71
,
0x71
,
0x51
},
/* 164 (A4) */
{
0x69
,
0x71
,
0x51
},
/* 165 (A5) */
{
0x61
,
0x71
,
0x51
},
/* 166 (A6) */
{
0x59
,
0x71
,
0x51
},
/* 167 (A7) */
{
0x51
,
0x71
,
0x51
},
/* 168 (A8) */
{
0x51
,
0x71
,
0x59
},
/* 169 (A9) */
{
0x51
,
0x71
,
0x61
},
/* 170 (AA) */
{
0x51
,
0x71
,
0x69
},
/* 171 (AB) */
{
0x51
,
0x71
,
0x71
},
/* 172 (AC) */
{
0x51
,
0x69
,
0x71
},
/* 173 (AD) */
{
0x51
,
0x61
,
0x71
},
/* 174 (AE) */
{
0x51
,
0x59
,
0x71
},
/* 175 (AF) */
/* Low Intensity group - 72 colors in 1/3 saturation groups (B0H-C7H high) */
{
0x00
,
0x00
,
0x41
},
/* 176 (B0) */
{
0x10
,
0x00
,
0x41
},
/* 177 (B1) */
{
0x20
,
0x00
,
0x41
},
/* 178 (B2) */
{
0x31
,
0x00
,
0x41
},
/* 179 (B3) */
{
0x41
,
0x00
,
0x41
},
/* 180 (B4) */
{
0x41
,
0x00
,
0x31
},
/* 181 (B5) */
{
0x41
,
0x00
,
0x20
},
/* 182 (B6) */
{
0x41
,
0x00
,
0x10
},
/* 183 (B7) */
{
0x41
,
0x00
,
0x00
},
/* 184 (B8) */
{
0x41
,
0x10
,
0x00
},
/* 185 (B9) */
{
0x41
,
0x20
,
0x00
},
/* 186 (BA) */
{
0x41
,
0x31
,
0x00
},
/* 187 (BB) */
{
0x41
,
0x41
,
0x00
},
/* 188 (BC) */
{
0x31
,
0x41
,
0x00
},
/* 189 (BD) */
{
0x20
,
0x41
,
0x00
},
/* 190 (BE) */
{
0x10
,
0x41
,
0x00
},
/* 191 (BF) */
{
0x00
,
0x41
,
0x00
},
/* 192 (C0) */
{
0x00
,
0x41
,
0x10
},
/* 193 (C1) */
{
0x00
,
0x41
,
0x20
},
/* 194 (C2) */
{
0x00
,
0x41
,
0x31
},
/* 195 (C3) */
{
0x00
,
0x41
,
0x41
},
/* 196 (C4) */
{
0x00
,
0x31
,
0x41
},
/* 197 (C5) */
{
0x00
,
0x20
,
0x41
},
/* 198 (C6) */
{
0x00
,
0x10
,
0x41
},
/* 199 (C7) */
/* Low Intensity group - 72 colors in 2/3 saturation groups (C8H-DFH moderate) */
{
0x20
,
0x20
,
0x41
},
/* 200 (C8) */
{
0x28
,
0x20
,
0x41
},
/* 201 (C9) */
{
0x31
,
0x20
,
0x41
},
/* 202 (CA) */
{
0x39
,
0x20
,
0x41
},
/* 203 (CB) */
{
0x41
,
0x20
,
0x41
},
/* 204 (CC) */
{
0x41
,
0x20
,
0x39
},
/* 205 (CD) */
{
0x41
,
0x20
,
0x31
},
/* 206 (CE) */
{
0x41
,
0x20
,
0x28
},
/* 207 (CF) */
{
0x41
,
0x20
,
0x20
},
/* 208 (D0) */
{
0x41
,
0x28
,
0x20
},
/* 209 (D1) */
{
0x41
,
0x31
,
0x20
},
/* 210 (D2) */
{
0x41
,
0x39
,
0x20
},
/* 211 (D3) */
{
0x41
,
0x41
,
0x20
},
/* 212 (D4) */
{
0x39
,
0x41
,
0x20
},
/* 213 (D5) */
{
0x31
,
0x41
,
0x20
},
/* 214 (D6) */
{
0x28
,
0x41
,
0x20
},
/* 215 (D7) */
{
0x20
,
0x41
,
0x20
},
/* 216 (D8) */
{
0x20
,
0x41
,
0x28
},
/* 217 (D9) */
{
0x20
,
0x41
,
0x31
},
/* 218 (DA) */
{
0x20
,
0x41
,
0x39
},
/* 219 (DB) */
{
0x20
,
0x41
,
0x41
},
/* 220 (DC) */
{
0x20
,
0x39
,
0x41
},
/* 221 (DD) */
{
0x20
,
0x31
,
0x41
},
/* 222 (DE) */
{
0x20
,
0x28
,
0x41
},
/* 223 (DF) */
/* Low Intensity group - 72 colors in 3/3 saturation groups (E0H-F7H low) */
{
0x2D
,
0x2D
,
0x41
},
/* 223 (E0) */
{
0x31
,
0x2D
,
0x41
},
/* 224 (E1) */
{
0x35
,
0x2D
,
0x41
},
/* 225 (E2) */
{
0x3D
,
0x2D
,
0x41
},
/* 226 (E3) */
{
0x41
,
0x2D
,
0x41
},
/* 227 (E4) */
{
0x41
,
0x2D
,
0x3D
},
/* 228 (E5) */
{
0x41
,
0x2D
,
0x35
},
/* 229 (E6) */
{
0x41
,
0x2D
,
0x31
},
/* 230 (E7) */
{
0x41
,
0x2D
,
0x2D
},
/* 231 (E8) */
{
0x41
,
0x31
,
0x2D
},
/* 232 (E9) */
{
0x41
,
0x35
,
0x2D
},
/* 233 (EA) */
{
0x41
,
0x3D
,
0x2D
},
/* 234 (EB) */
{
0x41
,
0x41
,
0x2D
},
/* 235 (EC) */
{
0x3D
,
0x41
,
0x2D
},
/* 236 (ED) */
{
0x35
,
0x41
,
0x2D
},
/* 237 (EE) */
{
0x31
,
0x41
,
0x2D
},
/* 238 (EF) */
{
0x2D
,
0x41
,
0x2D
},
/* 239 (F0) */
{
0x2D
,
0x41
,
0x31
},
/* 240 (F1) */
{
0x2D
,
0x41
,
0x35
},
/* 241 (F2) */
{
0x2D
,
0x41
,
0x3D
},
/* 242 (F3) */
{
0x2D
,
0x41
,
0x41
},
/* 243 (F4) */
{
0x2D
,
0x3D
,
0x41
},
/* 244 (F5) */
{
0x2D
,
0x35
,
0x41
},
/* 245 (F6) */
{
0x2D
,
0x31
,
0x41
},
/* 246 (F7) */
/* Fill up remainder of palettes with black */
{
0
,
0
,
0
}
};
/*
* Mode 18 Default Color Register Setting
* DAC palette registers, converted from actual 18 bit color to 24.
*
* This palette is the dos default, converted from 18 bit color to 24.
* It contains only 64 entries of colors--all others are zeros.
* --Robert 'Admiral' Coeyman
*/
static
PALETTEENTRY
vga_def64_palette
[
256
]
=
{
/* red green blue */
{
0x00
,
0x00
,
0x00
},
/* 0x00 Black */
{
0x00
,
0x00
,
0xaa
},
/* 0x01 Blue */
{
0x00
,
0xaa
,
0x00
},
/* 0x02 Green */
{
0x00
,
0xaa
,
0xaa
},
/* 0x03 Cyan */
{
0xaa
,
0x00
,
0x00
},
/* 0x04 Red */
{
0xaa
,
0x00
,
0xaa
},
/* 0x05 Magenta */
{
0xaa
,
0xaa
,
0x00
},
/* 0x06 */
{
0xaa
,
0xaa
,
0xaa
},
/* 0x07 White (Light Gray) */
{
0x00
,
0x00
,
0x55
},
/* 0x08 */
{
0x00
,
0x00
,
0xff
},
/* 0x09 */
{
0x00
,
0xaa
,
0x55
},
/* 0x0a */
{
0x00
,
0xaa
,
0xff
},
/* 0x0b */
{
0xaa
,
0x00
,
0x55
},
/* 0x0c */
{
0xaa
,
0x00
,
0xff
},
/* 0x0d */
{
0xaa
,
0xaa
,
0x55
},
/* 0x0e */
{
0xaa
,
0xaa
,
0xff
},
/* 0x0f */
{
0x00
,
0x55
,
0x00
},
/* 0x10 */
{
0x00
,
0x55
,
0xaa
},
/* 0x11 */
{
0x00
,
0xff
,
0x00
},
/* 0x12 */
{
0x00
,
0xff
,
0xaa
},
/* 0x13 */
{
0xaa
,
0x55
,
0x00
},
/* 0x14 Brown */
{
0xaa
,
0x55
,
0xaa
},
/* 0x15 */
{
0xaa
,
0xff
,
0x00
},
/* 0x16 */
{
0xaa
,
0xff
,
0xaa
},
/* 0x17 */
{
0x00
,
0x55
,
0x55
},
/* 0x18 */
{
0x00
,
0x55
,
0xff
},
/* 0x19 */
{
0x00
,
0xff
,
0x55
},
/* 0x1a */
{
0x00
,
0xff
,
0xff
},
/* 0x1b */
{
0xaa
,
0x55
,
0x55
},
/* 0x1c */
{
0xaa
,
0x55
,
0xff
},
/* 0x1d */
{
0xaa
,
0xff
,
0x55
},
/* 0x1e */
{
0xaa
,
0xff
,
0xff
},
/* 0x1f */
{
0x55
,
0x00
,
0x00
},
/* 0x20 */
{
0x55
,
0x00
,
0xaa
},
/* 0x21 */
{
0x55
,
0xaa
,
0x00
},
/* 0x22 */
{
0x55
,
0xaa
,
0xaa
},
/* 0x23 */
{
0xff
,
0x00
,
0x00
},
/* 0x24 */
{
0xff
,
0x00
,
0xaa
},
/* 0x25 */
{
0xff
,
0xaa
,
0x00
},
/* 0x26 */
{
0xff
,
0xaa
,
0xaa
},
/* 0x27 */
{
0x55
,
0x00
,
0x55
},
/* 0x28 */
{
0x55
,
0x00
,
0xff
},
/* 0x29 */
{
0x55
,
0xaa
,
0x55
},
/* 0x2a */
{
0x55
,
0xaa
,
0xff
},
/* 0x2b */
{
0xff
,
0x00
,
0x55
},
/* 0x2c */
{
0xff
,
0x00
,
0xff
},
/* 0x2d */
{
0xff
,
0xaa
,
0x55
},
/* 0x2e */
{
0xff
,
0xaa
,
0xff
},
/* 0x2f */
{
0x55
,
0x55
,
0x00
},
/* 0x30 */
{
0x55
,
0x55
,
0xaa
},
/* 0x31 */
{
0x55
,
0xff
,
0x00
},
/* 0x32 */
{
0x55
,
0xff
,
0xaa
},
/* 0x33 */
{
0xff
,
0x55
,
0x00
},
/* 0x34 */
{
0xff
,
0x55
,
0xaa
},
/* 0x35 */
{
0xff
,
0xff
,
0x00
},
/* 0x36 */
{
0xff
,
0xff
,
0xaa
},
/* 0x37 */
{
0x55
,
0x55
,
0x55
},
/* 0x38 Dark Gray */
{
0x55
,
0x55
,
0xff
},
/* 0x39 Light Blue */
{
0x55
,
0xff
,
0x55
},
/* 0x3a Light Green */
{
0x55
,
0xff
,
0xff
},
/* 0x3b Light Cyan */
{
0xff
,
0x55
,
0x55
},
/* 0x3c Light Red */
{
0xff
,
0x55
,
0xff
},
/* 0x3d Light Magenta */
{
0xff
,
0xff
,
0x55
},
/* 0x3e Yellow */
{
0xff
,
0xff
,
0xff
},
/* 0x3f White */
{
0
,
0
,
0
}
/* The next 192 entries are all zeros */
};
static
HANDLE
VGA_timer
;
static
HANDLE
VGA_timer_thread
;
/* set the timer rate; called in the polling thread context */
static
void
CALLBACK
set_timer_rate
(
ULONG_PTR
arg
)
{
LARGE_INTEGER
when
;
when
.
u
.
LowPart
=
when
.
u
.
HighPart
=
0
;
SetWaitableTimer
(
VGA_timer
,
&
when
,
arg
,
VGA_Poll
,
0
,
FALSE
);
}
static
DWORD
CALLBACK
VGA_TimerThread
(
void
*
dummy
)
{
for
(;;)
SleepEx
(
INFINITE
,
TRUE
);
return
0
;
}
static
void
VGA_DeinstallTimer
(
void
)
{
if
(
VGA_timer_thread
)
{
/*
* Make sure the update thread is not holding
* system resources when we kill it.
*
* Now, we only need to worry about update thread
* getting terminated while in EnterCriticalSection
* or WaitForMultipleObjectsEx.
*
* FIXME: Is this a problem?
*/
EnterCriticalSection
(
&
vga_lock
);
CancelWaitableTimer
(
VGA_timer
);
CloseHandle
(
VGA_timer
);
TerminateThread
(
VGA_timer_thread
,
0
);
CloseHandle
(
VGA_timer_thread
);
VGA_timer_thread
=
0
;
LeaveCriticalSection
(
&
vga_lock
);
/*
* Synchronize display. This makes sure that
* changes to display become visible even if program
* terminates before update thread had time to run.
*/
VGA_Poll
(
0
,
0
,
0
);
}
}
static
void
VGA_InstallTimer
(
unsigned
Rate
)
{
if
(
!
VGA_timer_thread
)
{
VGA_timer
=
CreateWaitableTimerA
(
NULL
,
FALSE
,
NULL
);
VGA_timer_thread
=
CreateThread
(
NULL
,
0
,
VGA_TimerThread
,
NULL
,
0
,
NULL
);
}
QueueUserAPC
(
set_timer_rate
,
VGA_timer_thread
,
(
ULONG_PTR
)
Rate
);
}
static
BOOL
VGA_IsTimerRunning
(
void
)
{
return
VGA_timer_thread
!=
0
;
}
static
HANDLE
VGA_AlphaConsole
(
void
)
{
/* this assumes that no Win32 redirection has taken place, but then again,
* only 16-bit apps are likely to use this part of Wine... */
return
GetStdHandle
(
STD_OUTPUT_HANDLE
);
}
static
char
*
VGA_AlphaBuffer
(
void
)
{
return
(
char
*
)
0xb8000
;
}
/*** GRAPHICS MODE ***/
typedef
struct
{
unsigned
Xres
,
Yres
,
Depth
;
BOOL
ret
;
}
ModeSet
;
/**********************************************************************
* VGA_SyncWindow
*
* Copy VGA window into framebuffer (if argument is TRUE) or
* part of framebuffer into VGA window (if argument is FALSE).
*/
static
void
VGA_SyncWindow
(
BOOL
target_is_fb
)
{
int
size
=
vga_fb_window_size
;
/* Window does not overlap framebuffer. */
if
(
vga_fb_window
>=
vga_fb_size
)
return
;
/* Check if window overlaps framebuffer only partially. */
if
(
vga_fb_size
-
vga_fb_window
<
vga_fb_window_size
)
size
=
vga_fb_size
-
vga_fb_window
;
if
(
target_is_fb
)
memmove
(
vga_fb_data
+
vga_fb_window
,
vga_fb_window_data
,
size
);
else
memmove
(
vga_fb_window_data
,
vga_fb_data
+
vga_fb_window
,
size
);
}
static
void
VGA_DoExit
(
ULONG_PTR
arg
)
{
VGA_DeinstallTimer
();
IDirectDrawSurface_SetPalette
(
lpddsurf
,
NULL
);
IDirectDrawSurface_Release
(
lpddsurf
);
lpddsurf
=
NULL
;
IDirectDrawPalette_Release
(
lpddpal
);
lpddpal
=
NULL
;
IDirectDraw_Release
(
lpddraw
);
lpddraw
=
NULL
;
}
static
void
VGA_DoSetMode
(
ModeSet
*
par
)
{
HRESULT
res
;
par
->
ret
=
FALSE
;
if
(
lpddraw
)
VGA_DoExit
(
0
);
if
(
!
lpddraw
)
{
res
=
DirectDrawCreate
(
NULL
,
&
lpddraw
,
NULL
);
if
(
!
lpddraw
)
{
ERR
(
"DirectDraw is not available (res = 0x%x)
\n
"
,
res
);
return
;
}
if
(
!
vga_hwnd
)
{
vga_hwnd
=
CreateWindowExA
(
0
,
"STATIC"
,
"WINEDOS VGA"
,
WS_POPUP
|
WS_VISIBLE
|
SS_NOTIFY
,
0
,
0
,
par
->
Xres
,
par
->
Yres
,
0
,
0
,
0
,
NULL
);
if
(
!
vga_hwnd
)
{
ERR
(
"Failed to create user window.
\n
"
);
IDirectDraw_Release
(
lpddraw
);
lpddraw
=
NULL
;
return
;
}
}
else
SetWindowPos
(
vga_hwnd
,
0
,
0
,
0
,
par
->
Xres
,
par
->
Yres
,
SWP_NOMOVE
|
SWP_NOZORDER
);
res
=
IDirectDraw_SetCooperativeLevel
(
lpddraw
,
vga_hwnd
,
DDSCL_FULLSCREEN
|
DDSCL_EXCLUSIVE
);
if
(
res
!=
S_OK
)
{
ERR
(
"Could not set cooperative level to exclusive (0x%x)
\n
"
,
res
);
}
res
=
IDirectDraw_SetDisplayMode
(
lpddraw
,
par
->
Xres
,
par
->
Yres
,
par
->
Depth
);
if
(
res
!=
S_OK
)
{
ERR
(
"DirectDraw does not support requested display mode (%dx%dx%d), res = 0x%x!
\n
"
,
par
->
Xres
,
par
->
Yres
,
par
->
Depth
,
res
);
IDirectDraw_Release
(
lpddraw
);
lpddraw
=
NULL
;
return
;
}
res
=
IDirectDraw_CreatePalette
(
lpddraw
,
DDPCAPS_8BIT
,
NULL
,
&
lpddpal
,
NULL
);
if
(
res
!=
S_OK
)
{
ERR
(
"Could not create palette (res = 0x%x)
\n
"
,
res
);
IDirectDraw_Release
(
lpddraw
);
lpddraw
=
NULL
;
return
;
}
res
=
IDirectDrawPalette_SetEntries
(
lpddpal
,
0
,
0
,
vga_fb_palette_size
,
vga_fb_palette
);
if
(
res
!=
S_OK
)
{
ERR
(
"Could not set default palette entries (res = 0x%x)
\n
"
,
res
);
}
memset
(
&
sdesc
,
0
,
sizeof
(
sdesc
));
sdesc
.
dwSize
=
sizeof
(
sdesc
);
sdesc
.
dwFlags
=
DDSD_CAPS
;
sdesc
.
ddsCaps
.
dwCaps
=
DDSCAPS_PRIMARYSURFACE
;
res
=
IDirectDraw_CreateSurface
(
lpddraw
,
&
sdesc
,
&
lpddsurf
,
NULL
);
if
(
res
!=
S_OK
||
!
lpddsurf
)
{
ERR
(
"DirectDraw surface is not available
\n
"
);
IDirectDraw_Release
(
lpddraw
);
lpddraw
=
NULL
;
return
;
}
IDirectDrawSurface_SetPalette
(
lpddsurf
,
lpddpal
);
vga_retrace_vertical
=
vga_retrace_horizontal
=
FALSE
;
/* poll every 20ms (50fps should provide adequate responsiveness) */
VGA_InstallTimer
(
20
);
}
par
->
ret
=
TRUE
;
return
;
}
/**********************************************************************\
* VGA_GetModeInfo
*
* Returns mode information, given mode number
\**********************************************************************/
const
VGA_MODE
*
VGA_GetModeInfo
(
WORD
mode
)
{
const
VGA_MODE
*
ModeInfo
=
VGA_modelist
;
/*
* Filter out flags.
*/
mode
&=
0x17f
;
while
(
ModeInfo
->
Mode
!=
0xffff
)
{
if
(
ModeInfo
->
Mode
==
mode
)
return
ModeInfo
;
ModeInfo
++
;
}
return
NULL
;
}
static
BOOL
VGA_SetGraphicMode
(
WORD
mode
)
{
ModeSet
par
;
int
newSize
;
/* get info on VGA mode & set appropriately */
const
VGA_MODE
*
ModeInfo
=
VGA_GetModeInfo
(
VGA_CurrentMode
);
/* check if we're assuming composite display */
if
((
mode
==
6
)
&&
(
CGA_ColorComposite
))
{
vga_fb_width
=
(
ModeInfo
->
Width
/
4
);
vga_fb_height
=
ModeInfo
->
Height
;
vga_fb_depth
=
(
ModeInfo
->
Depth
*
4
);
}
else
{
vga_fb_width
=
ModeInfo
->
Width
;
vga_fb_height
=
ModeInfo
->
Height
;
vga_fb_depth
=
ModeInfo
->
Depth
;
}
vga_fb_offset
=
0
;
vga_fb_pitch
=
vga_fb_width
*
((
vga_fb_depth
+
7
)
/
8
);
newSize
=
vga_fb_width
*
vga_fb_height
*
((
vga_fb_depth
+
7
)
/
8
);
if
(
newSize
<
256
*
1024
)
newSize
=
256
*
1024
;
if
(
vga_fb_size
<
newSize
)
{
HeapFree
(
GetProcessHeap
(),
0
,
vga_fb_data
);
vga_fb_data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
newSize
);
vga_fb_size
=
newSize
;
}
if
(
vga_fb_width
>=
640
||
vga_fb_height
>=
480
)
{
par
.
Xres
=
vga_fb_width
;
par
.
Yres
=
vga_fb_height
;
}
else
{
par
.
Xres
=
640
;
par
.
Yres
=
480
;
}
/* Setup window */
if
(
vga_fb_depth
>=
8
)
{
vga_fb_window_data
=
VGA_WINDOW_START
;
vga_fb_window_size
=
VGA_WINDOW_SIZE
;
vga_fb_palette
=
vga_def_palette
;
vga_fb_palette_size
=
256
;
}
else
{
vga_fb_window_data
=
CGA_WINDOW_START
;
vga_fb_window_size
=
CGA_WINDOW_SIZE
;
if
(
vga_fb_depth
==
2
)
{
/* Select default 2 bit CGA palette */
vga_fb_palette
=
cga_palette1
;
vga_fb_palette_size
=
4
;
}
else
{
/* Top of VGA palette is same as 4 bit CGA palette */
vga_fb_palette
=
vga_def_palette
;
vga_fb_palette_size
=
16
;
}
vga_fb_palette_index
=
0
;
vga_fb_bright
=
0
;
}
/* Clean the HW buffer */
memset
(
vga_fb_window_data
,
0x00
,
vga_fb_window_size
);
/* Reset window start */
VGA_SetWindowStart
(
0
);
par
.
Depth
=
(
vga_fb_depth
<
8
)
?
8
:
vga_fb_depth
;
VGA_DoSetMode
(
&
par
);
return
par
.
ret
;
}
BOOL
VGA_SetMode
(
WORD
mode
)
{
const
VGA_MODE
*
ModeInfo
;
/* get info on VGA mode & set appropriately */
VGA_CurrentMode
=
mode
;
ModeInfo
=
VGA_GetModeInfo
(
VGA_CurrentMode
);
/* check if mode is supported */
if
(
ModeInfo
->
Supported
)
{
FIXME
(
"Setting VGA mode %i - Supported mode - Improve reporting of missing capabilities for modes & modetypes.
\n
"
,
mode
);
}
else
{
FIXME
(
"Setting VGA mode %i - Unsupported mode - Will doubtfully work at all, but we'll try anyways.
\n
"
,
mode
);
}
/* set up graphic or text display */
if
(
ModeInfo
->
ModeType
==
TEXT
)
{
VGA_SetAlphaMode
(
ModeInfo
->
TextCols
,
ModeInfo
->
TextRows
);
}
else
{
return
VGA_SetGraphicMode
(
mode
);
}
return
TRUE
;
/* assume all good & return TRUE */
}
BOOL
VGA_GetMode
(
unsigned
*
Height
,
unsigned
*
Width
,
unsigned
*
Depth
)
{
if
(
!
lpddraw
)
return
FALSE
;
if
(
!
lpddsurf
)
return
FALSE
;
if
(
Height
)
*
Height
=
sdesc
.
dwHeight
;
if
(
Width
)
*
Width
=
sdesc
.
dwWidth
;
if
(
Depth
)
*
Depth
=
sdesc
.
ddpfPixelFormat
.
u1
.
dwRGBBitCount
;
return
TRUE
;
}
static
void
VGA_Exit
(
void
)
{
if
(
lpddraw
)
VGA_DoExit
(
0
);
}
void
VGA_SetPalette
(
PALETTEENTRY
*
pal
,
int
start
,
int
len
)
{
if
(
!
lpddraw
)
return
;
IDirectDrawPalette_SetEntries
(
lpddpal
,
0
,
start
,
len
,
pal
);
}
/* set a single [char wide] color in 16 color mode. */
void
VGA_SetColor16
(
int
reg
,
int
color
)
{
PALETTEENTRY
*
pal
;
if
(
!
lpddraw
)
return
;
pal
=
&
vga_def64_palette
[
color
];
IDirectDrawPalette_SetEntries
(
lpddpal
,
0
,
reg
,
1
,
pal
);
vga_16_palette
[
reg
]
=
(
char
)
color
;
}
/* Get a single [char wide] color in 16 color mode. */
char
VGA_GetColor16
(
int
reg
)
{
if
(
!
lpddraw
)
return
0
;
return
vga_16_palette
[
reg
];
}
/* set all 17 [char wide] colors at once in 16 color mode. */
void
VGA_Set16Palette
(
char
*
Table
)
{
PALETTEENTRY
*
pal
;
int
c
;
if
(
!
lpddraw
)
return
;
/* return if we're in text only mode */
memcpy
(
Table
,
vga_16_palette
,
17
);
/* copy the entries into the table */
for
(
c
=
0
;
c
<
17
;
c
++
)
{
/* 17 entries */
pal
=
&
vga_def64_palette
[(
int
)
vga_16_palette
[
c
]];
/* get color */
IDirectDrawPalette_SetEntries
(
lpddpal
,
0
,
c
,
1
,
pal
);
/* set entry */
TRACE
(
"Palette register %d set to %d
\n
"
,
c
,(
int
)
vga_16_palette
[
c
]);
}
/* end of the counting loop */
}
/* Get all 17 [ char wide ] colors at once in 16 color mode. */
void
VGA_Get16Palette
(
char
*
Table
)
{
if
(
!
lpddraw
)
return
;
/* return if we're in text only mode */
memcpy
(
vga_16_palette
,
Table
,
17
);
/* copy the entries into the table */
}
static
LPSTR
VGA_Lock
(
unsigned
*
Pitch
,
unsigned
*
Height
,
unsigned
*
Width
,
unsigned
*
Depth
)
{
if
(
!
lpddraw
)
return
NULL
;
if
(
!
lpddsurf
)
return
NULL
;
if
(
IDirectDrawSurface_Lock
(
lpddsurf
,
NULL
,
&
sdesc
,
0
,
0
)
!=
S_OK
)
{
ERR
(
"could not lock surface!
\n
"
);
return
NULL
;
}
if
(
Pitch
)
*
Pitch
=
sdesc
.
u1
.
lPitch
;
if
(
Height
)
*
Height
=
sdesc
.
dwHeight
;
if
(
Width
)
*
Width
=
sdesc
.
dwWidth
;
if
(
Depth
)
*
Depth
=
sdesc
.
ddpfPixelFormat
.
u1
.
dwRGBBitCount
;
return
sdesc
.
lpSurface
;
}
static
void
VGA_Unlock
(
void
)
{
IDirectDrawSurface_Unlock
(
lpddsurf
,
sdesc
.
lpSurface
);
}
/*
* Set start of 64k window at 0xa0000 in bytes.
* If value is -1, initialize color plane support.
* If value is >= 0, window contains direct copy of framebuffer.
*/
void
VGA_SetWindowStart
(
int
start
)
{
if
(
start
==
vga_fb_window
)
return
;
EnterCriticalSection
(
&
vga_lock
);
if
(
vga_fb_window
==
-
1
)
FIXME
(
"Remove VGA memory emulation.
\n
"
);
else
VGA_SyncWindow
(
TRUE
);
vga_fb_window
=
start
;
if
(
vga_fb_window
==
-
1
)
FIXME
(
"Install VGA memory emulation.
\n
"
);
else
VGA_SyncWindow
(
FALSE
);
LeaveCriticalSection
(
&
vga_lock
);
}
/*
* Get start of 64k window at 0xa0000 in bytes.
* Value is -1 in color plane modes.
*/
int
VGA_GetWindowStart
(
void
)
{
return
vga_fb_window
;
}
/**********************************************************************
* VGA_DoShowMouse
*
* Callback for VGA_ShowMouse.
*/
static
void
VGA_DoShowMouse
(
BOOL
show
)
{
INT
rv
;
do
{
rv
=
ShowCursor
(
show
);
}
while
(
show
?
(
rv
<
0
)
:
(
rv
>=
0
)
);
}
/**********************************************************************
* VGA_ShowMouse
*
* If argument is TRUE, unconditionally show mouse cursor.
* If argument is FALSE, unconditionally hide mouse cursor.
* This only works in graphics mode.
*/
void
VGA_ShowMouse
(
BOOL
show
)
{
if
(
lpddraw
)
VGA_DoShowMouse
(
show
);
}
/**********************************************************************
* VGA_UpdatePalette
*
* Update the current palette
*
* Note: When updating the current CGA palette, palette index 0
* refers to palette2, and index 1 is palette1 (default palette)
*/
void
VGA_UpdatePalette
(
void
)
{
/* Figure out which palette is used now */
if
(
vga_fb_bright
)
{
if
(
vga_fb_palette_index
==
0
)
{
vga_fb_palette
=
cga_palette2_bright
;
}
else
if
(
vga_fb_palette_index
==
1
)
{
vga_fb_palette
=
cga_palette1_bright
;
}
}
else
{
if
(
vga_fb_palette_index
==
0
)
{
vga_fb_palette
=
cga_palette2
;
}
else
if
(
vga_fb_palette_index
==
1
)
{
vga_fb_palette
=
cga_palette1
;
}
}
/* Now update the palette */
VGA_SetPalette
(
vga_fb_palette
,
0
,
4
);
}
/**********************************************************************
* VGA_SetBright
*
* Select if using a "bright" palette or not.
* This is a property of the CGA controller
*/
void
VGA_SetBright
(
BOOL
bright
)
{
TRACE
(
"%i
\n
"
,
bright
);
/* Remember the "bright" value used by the CGA controller */
vga_fb_bright
=
bright
;
}
/**********************************************************************
* VGA_SetEnabled
*
* Select if output is enabled or disabled
* This is a property of the CGA controller
*/
static
void
VGA_SetEnabled
(
BOOL
enabled
)
{
TRACE
(
"%i
\n
"
,
enabled
);
/* Check if going from enabled to disabled */
if
(
vga_fb_enabled
&&
!
enabled
)
{
/* Clear frame buffer */
memset
(
vga_fb_window_data
,
0x00
,
vga_fb_window_size
);
}
/* Remember the "enabled" value */
vga_fb_enabled
=
enabled
;
}
/**********************************************************************
* VGA_SetPaletteIndex
*
* Select the index of the palette which is currently in use
* This is a property of the CGA controller
*/
void
VGA_SetPaletteIndex
(
unsigned
index
)
{
TRACE
(
"%i
\n
"
,
index
);
/* Remember the palette index, which is only used by CGA for now */
vga_fb_palette_index
=
index
;
}
/**********************************************************************
* VGA_WritePixel
*
* Write data to the framebuffer
* This is a property of the CGA controller, but might be supported
* later by other framebuffer types
*/
void
VGA_WritePixel
(
unsigned
color
,
unsigned
page
,
unsigned
col
,
unsigned
row
)
{
int
off
;
int
bits
;
int
pos
;
/* Calculate CGA byte offset */
char
*
data
=
vga_fb_window_data
;
off
=
row
&
1
?
(
8
*
1024
)
:
0
;
off
+=
(
80
*
(
row
/
2
));
off
+=
col
/
4
;
/* Calculate bits offset */
pos
=
6
-
(
col
%
4
*
2
);
/* Clear current data */
bits
=
0x03
<<
pos
;
data
[
off
]
&=
~
bits
;
/* Set new data */
bits
=
color
<<
pos
;
data
[
off
]
|=
bits
;
}
/*** TEXT MODE ***/
/* prepare the text mode video memory copy that is used to only
* update the video memory line that did get updated. */
static
void
VGA_PrepareVideoMemCopy
(
unsigned
Xres
,
unsigned
Yres
)
{
char
*
p
,
*
p2
;
unsigned
int
i
;
/*
* Allocate space for char + attr.
*/
if
(
vga_text_old
)
vga_text_old
=
HeapReAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
vga_text_old
,
Xres
*
Yres
*
2
);
else
vga_text_old
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
Xres
*
Yres
*
2
);
p
=
VGA_AlphaBuffer
();
p2
=
vga_text_old
;
/* make sure the video mem copy contains the exact opposite of our
* actual text mode memory area to make sure the screen
* does get updated fully initially */
for
(
i
=
0
;
i
<
Xres
*
Yres
*
2
;
i
++
)
*
p2
++
=
*
p
++
^
0xff
;
/* XOR it */
}
/**********************************************************************
* VGA_SetAlphaMode
*
* Set VGA emulation to text mode.
*/
void
VGA_SetAlphaMode
(
unsigned
Xres
,
unsigned
Yres
)
{
VGA_Exit
();
VGA_DeinstallTimer
();
VGA_PrepareVideoMemCopy
(
Xres
,
Yres
);
vga_text_width
=
Xres
;
vga_text_height
=
Yres
;
if
(
vga_text_x
>=
vga_text_width
||
vga_text_y
>=
vga_text_height
)
VGA_SetCursorPos
(
0
,
0
);
if
(
vga_text_console
)
{
COORD
size
;
size
.
X
=
Xres
;
size
.
Y
=
Yres
;
SetConsoleScreenBufferSize
(
VGA_AlphaConsole
(),
size
);
/* poll every 30ms (33fps should provide adequate responsiveness) */
VGA_InstallTimer
(
30
);
}
}
/**********************************************************************
* VGA_InitAlphaMode
*
* Initialize VGA text mode handling and return default text mode.
* This function does not set VGA emulation to text mode.
*/
void
VGA_InitAlphaMode
(
unsigned
*
Xres
,
unsigned
*
Yres
)
{
CONSOLE_SCREEN_BUFFER_INFO
info
;
if
(
GetConsoleScreenBufferInfo
(
VGA_AlphaConsole
(),
&
info
))
{
vga_text_console
=
TRUE
;
vga_text_x
=
info
.
dwCursorPosition
.
X
;
vga_text_y
=
info
.
dwCursorPosition
.
Y
;
vga_text_attr
=
info
.
wAttributes
;
*
Xres
=
info
.
dwSize
.
X
;
*
Yres
=
info
.
dwSize
.
Y
;
}
else
{
vga_text_console
=
FALSE
;
vga_text_x
=
0
;
vga_text_y
=
0
;
vga_text_attr
=
0x0f
;
*
Xres
=
80
;
*
Yres
=
25
;
}
}
/**********************************************************************
* VGA_GetAlphaMode
*
* Get current text mode. Returns TRUE and sets resolution if
* any VGA text mode has been initialized.
*/
BOOL
VGA_GetAlphaMode
(
unsigned
*
Xres
,
unsigned
*
Yres
)
{
if
(
vga_text_width
!=
0
&&
vga_text_height
!=
0
)
{
*
Xres
=
vga_text_width
;
*
Yres
=
vga_text_height
;
return
TRUE
;
}
else
return
FALSE
;
}
void
VGA_SetCursorShape
(
unsigned
char
start_options
,
unsigned
char
end
)
{
CONSOLE_CURSOR_INFO
cci
;
/* standard cursor settings:
* 0x0607 == CGA, 0x0b0c == monochrome, 0x0d0e == EGA/VGA */
/* calculate percentage from bottom - assuming VGA (bottom 0x0e) */
cci
.
dwSize
=
((
end
&
0x1f
)
-
(
start_options
&
0x1f
))
/
0x0e
*
100
;
if
(
!
cci
.
dwSize
)
cci
.
dwSize
++
;
/* NULL cursor would make SCCI() fail ! */
cci
.
bVisible
=
((
start_options
&
0x60
)
!=
0x20
);
/* invisible ? */
SetConsoleCursorInfo
(
VGA_AlphaConsole
(),
&
cci
);
}
void
VGA_SetCursorPos
(
unsigned
X
,
unsigned
Y
)
{
vga_text_x
=
X
;
vga_text_y
=
Y
;
}
void
VGA_GetCursorPos
(
unsigned
*
X
,
unsigned
*
Y
)
{
if
(
X
)
*
X
=
vga_text_x
;
if
(
Y
)
*
Y
=
vga_text_y
;
}
static
void
VGA_PutCharAt
(
unsigned
x
,
unsigned
y
,
BYTE
ascii
,
int
attr
)
{
const
VGA_MODE
*
ModeInfo
=
VGA_GetModeInfo
(
VGA_CurrentMode
);
if
(
ModeInfo
->
ModeType
==
TEXT
)
{
char
*
dat
=
VGA_AlphaBuffer
()
+
((
vga_text_width
*
y
+
x
)
*
2
);
dat
[
0
]
=
ascii
;
if
(
attr
>=
0
)
dat
[
1
]
=
attr
;
}
else
{
FIXME
(
"Write %c at (%i,%i) - not yet supported in graphic modes.
\n
"
,
(
char
)
ascii
,
x
,
y
);
}
}
void
VGA_WriteChars
(
unsigned
X
,
unsigned
Y
,
unsigned
ch
,
int
attr
,
int
count
)
{
EnterCriticalSection
(
&
vga_lock
);
while
(
count
--
)
VGA_PutCharAt
(
X
+
count
,
Y
,
ch
,
attr
);
LeaveCriticalSection
(
&
vga_lock
);
}
void
VGA_PutChar
(
BYTE
ascii
)
{
DWORD
w
;
EnterCriticalSection
(
&
vga_lock
);
switch
(
ascii
)
{
case
'\b'
:
if
(
vga_text_x
)
{
vga_text_x
--
;
VGA_PutCharAt
(
vga_text_x
,
vga_text_y
,
' '
,
0
);
}
break
;
case
'\t'
:
vga_text_x
+=
((
vga_text_x
+
8
)
&
~
7
)
-
vga_text_x
;
break
;
case
'\n'
:
vga_text_y
++
;
vga_text_x
=
0
;
break
;
case
'\a'
:
break
;
case
'\r'
:
vga_text_x
=
0
;
break
;
default:
VGA_PutCharAt
(
vga_text_x
,
vga_text_y
,
ascii
,
vga_text_attr
);
vga_text_x
++
;
}
if
(
vga_text_x
>=
vga_text_width
)
{
vga_text_x
=
0
;
vga_text_y
++
;
}
if
(
vga_text_y
>=
vga_text_height
)
{
vga_text_y
=
vga_text_height
-
1
;
VGA_ScrollUpText
(
0
,
0
,
vga_text_height
-
1
,
vga_text_width
-
1
,
1
,
vga_text_attr
);
}
/*
* If we don't have a console, write directly to standard output.
*/
if
(
!
vga_text_console
)
WriteFile
(
VGA_AlphaConsole
(),
&
ascii
,
1
,
&
w
,
NULL
);
LeaveCriticalSection
(
&
vga_lock
);
}
void
VGA_ClearText
(
unsigned
row1
,
unsigned
col1
,
unsigned
row2
,
unsigned
col2
,
BYTE
attr
)
{
unsigned
x
,
y
;
EnterCriticalSection
(
&
vga_lock
);
for
(
y
=
row1
;
y
<=
row2
;
y
++
)
for
(
x
=
col1
;
x
<=
col2
;
x
++
)
VGA_PutCharAt
(
x
,
y
,
0x20
,
attr
);
LeaveCriticalSection
(
&
vga_lock
);
}
void
VGA_ScrollUpText
(
unsigned
row1
,
unsigned
col1
,
unsigned
row2
,
unsigned
col2
,
unsigned
lines
,
BYTE
attr
)
{
char
*
buffer
=
VGA_AlphaBuffer
();
unsigned
y
;
EnterCriticalSection
(
&
vga_lock
);
/*
* Scroll buffer.
*/
for
(
y
=
row1
;
y
<=
row2
-
lines
;
y
++
)
memmove
(
buffer
+
col1
+
y
*
vga_text_width
*
2
,
buffer
+
col1
+
(
y
+
lines
)
*
vga_text_width
*
2
,
(
col2
-
col1
+
1
)
*
2
);
/*
* Fill exposed lines.
*/
for
(
y
=
max
(
row1
,
row2
-
lines
+
1
);
y
<=
row2
;
y
++
)
VGA_WriteChars
(
col1
,
y
,
' '
,
attr
,
col2
-
col1
+
1
);
LeaveCriticalSection
(
&
vga_lock
);
}
void
VGA_ScrollDownText
(
unsigned
row1
,
unsigned
col1
,
unsigned
row2
,
unsigned
col2
,
unsigned
lines
,
BYTE
attr
)
{
char
*
buffer
=
VGA_AlphaBuffer
();
unsigned
y
;
EnterCriticalSection
(
&
vga_lock
);
/*
* Scroll buffer.
*/
for
(
y
=
row2
;
y
>=
row1
+
lines
;
y
--
)
memmove
(
buffer
+
col1
+
y
*
vga_text_width
*
2
,
buffer
+
col1
+
(
y
-
lines
)
*
vga_text_width
*
2
,
(
col2
-
col1
+
1
)
*
2
);
/*
* Fill exposed lines.
*/
for
(
y
=
row1
;
y
<=
min
(
row1
+
lines
-
1
,
row2
);
y
++
)
VGA_WriteChars
(
col1
,
y
,
' '
,
attr
,
col2
-
col1
+
1
);
LeaveCriticalSection
(
&
vga_lock
);
}
void
VGA_GetCharacterAtCursor
(
BYTE
*
ascii
,
BYTE
*
attr
)
{
char
*
dat
;
dat
=
VGA_AlphaBuffer
()
+
((
vga_text_width
*
vga_text_y
+
vga_text_x
)
*
2
);
*
ascii
=
dat
[
0
];
*
attr
=
dat
[
1
];
}
/*** CONTROL ***/
/* FIXME: optimize by doing this only if the data has actually changed
* (in a way similar to DIBSection, perhaps) */
static
void
VGA_Poll_Graphics
(
void
)
{
unsigned
int
Pitch
,
Height
,
Width
,
X
,
Y
;
char
*
surf
;
char
*
dat
=
vga_fb_data
+
vga_fb_offset
;
int
bpp
=
(
vga_fb_depth
+
7
)
/
8
;
surf
=
VGA_Lock
(
&
Pitch
,
&
Height
,
&
Width
,
NULL
);
if
(
!
surf
)
return
;
/*
* Synchronize framebuffer contents.
*/
if
(
vga_fb_window
!=
-
1
)
VGA_SyncWindow
(
TRUE
);
/*
* CGA framebuffer (160x200) - CGA_ColorComposite, special subtype of mode 6
* This buffer is encoded as following:
* - 4 bit pr. pixel, 2 pixels per byte
* - 80 bytes per row
* - Every second line has an offset of 8096
*/
if
(
vga_fb_depth
==
4
&&
vga_fb_width
==
160
&&
vga_fb_height
==
200
){
WORD
off
=
0
;
BYTE
bits
=
4
;
BYTE
value
;
for
(
Y
=
0
;
Y
<
vga_fb_height
;
Y
++
,
surf
+=
(
Pitch
*
2
)){
for
(
X
=
0
;
X
<
vga_fb_width
;
X
++
){
off
=
Y
&
1
?
(
8
*
1024
)
:
0
;
off
+=
(
80
*
(
Y
/
2
));
off
+=
X
/
2
;
value
=
(
dat
[
off
]
>>
bits
)
&
0xF
;
surf
[(
X
*
4
)
+
0
]
=
value
;
surf
[(
X
*
4
)
+
1
]
=
value
;
surf
[(
X
*
4
)
+
2
]
=
value
;
surf
[(
X
*
4
)
+
3
]
=
value
;
surf
[(
X
*
4
)
+
Pitch
+
0
]
=
value
;
surf
[(
X
*
4
)
+
Pitch
+
1
]
=
value
;
surf
[(
X
*
4
)
+
Pitch
+
2
]
=
value
;
surf
[(
X
*
4
)
+
Pitch
+
3
]
=
value
;
bits
-=
4
;
bits
&=
7
;
}
}
}
/*
* CGA framebuffer (320x200)
* This buffer is encoded as following:
* - 2 bits per color, 4 pixels per byte
* - 80 bytes per row
* - Every second line has an offset of 8096
*/
else
if
(
vga_fb_depth
==
2
&&
vga_fb_width
==
320
&&
vga_fb_height
==
200
){
WORD
off
=
0
;
BYTE
bits
=
6
;
BYTE
value
;
/* Iterate over the rows */
for
(
Y
=
0
;
Y
<
vga_fb_height
;
Y
++
,
surf
+=
(
Pitch
*
2
)){
for
(
X
=
0
;
X
<
vga_fb_width
;
X
++
){
off
=
Y
&
1
?
(
8
*
1024
)
:
0
;
off
+=
(
80
*
(
Y
/
2
));
off
+=
X
/
4
;
value
=
(
dat
[
off
]
>>
bits
)
&
0x3
;
surf
[(
X
*
2
)]
=
value
;
surf
[(
X
*
2
)
+
1
]
=
value
;
surf
[(
X
*
2
)
+
Pitch
]
=
value
;
surf
[(
X
*
2
)
+
Pitch
+
1
]
=
value
;
bits
-=
2
;
bits
&=
7
;
}
}
}
/*
* Double VGA framebuffer (320x200 -> 640x400), if needed.
*/
else
if
(
Height
>=
2
*
vga_fb_height
&&
Width
>=
2
*
vga_fb_width
&&
bpp
==
1
)
for
(
Y
=
0
;
Y
<
vga_fb_height
;
Y
++
,
surf
+=
Pitch
*
2
,
dat
+=
vga_fb_pitch
)
for
(
X
=
0
;
X
<
vga_fb_width
;
X
++
)
{
BYTE
value
=
dat
[
X
];
surf
[
X
*
2
]
=
value
;
surf
[
X
*
2
+
1
]
=
value
;
surf
[
X
*
2
+
Pitch
]
=
value
;
surf
[
X
*
2
+
Pitch
+
1
]
=
value
;
}
/*
* Linear Buffer, including mode 19
*/
else
for
(
Y
=
0
;
Y
<
vga_fb_height
;
Y
++
,
surf
+=
Pitch
,
dat
+=
vga_fb_pitch
)
memcpy
(
surf
,
dat
,
vga_fb_width
*
bpp
);
VGA_Unlock
();
}
static
void
VGA_Poll_Text
(
void
)
{
char
*
dat
,
*
old
,
*
p_line
;
unsigned
int
X
,
Y
;
CHAR_INFO
ch
[
256
];
/* that should suffice for the largest text width */
COORD
siz
,
off
;
SMALL_RECT
dest
;
HANDLE
con
=
VGA_AlphaConsole
();
BOOL
linechanged
=
FALSE
;
/* video memory area differs from stored copy? */
/* Synchronize cursor position. */
off
.
X
=
vga_text_x
;
off
.
Y
=
vga_text_y
;
SetConsoleCursorPosition
(
con
,
off
);
dat
=
VGA_AlphaBuffer
();
old
=
vga_text_old
;
/* pointer to stored video mem copy */
siz
.
X
=
vga_text_width
;
siz
.
Y
=
1
;
off
.
X
=
0
;
off
.
Y
=
0
;
/* copy from virtual VGA frame buffer to console */
for
(
Y
=
0
;
Y
<
vga_text_height
;
Y
++
)
{
linechanged
=
memcmp
(
dat
,
old
,
vga_text_width
*
2
);
if
(
linechanged
)
{
/*TRACE("line %d changed\n", Y);*/
p_line
=
dat
;
for
(
X
=
0
;
X
<
vga_text_width
;
X
++
)
{
ch
[
X
].
Char
.
AsciiChar
=
*
p_line
++
;
/* WriteConsoleOutputA doesn't like "dead" chars */
if
(
ch
[
X
].
Char
.
AsciiChar
==
'\0'
)
ch
[
X
].
Char
.
AsciiChar
=
' '
;
ch
[
X
].
Attributes
=
*
p_line
++
;
}
dest
.
Top
=
Y
;
dest
.
Bottom
=
Y
;
dest
.
Left
=
0
;
dest
.
Right
=
vga_text_width
+
1
;
WriteConsoleOutputA
(
con
,
ch
,
siz
,
off
,
&
dest
);
memcpy
(
old
,
dat
,
vga_text_width
*
2
);
}
/* advance to next text line */
dat
+=
vga_text_width
*
2
;
old
+=
vga_text_width
*
2
;
}
}
static
void
CALLBACK
VGA_Poll
(
LPVOID
arg
,
DWORD
low
,
DWORD
high
)
{
EnterCriticalSection
(
&
vga_lock
);
if
(
lpddraw
)
VGA_Poll_Graphics
();
else
VGA_Poll_Text
();
/*
* Fake start of retrace.
*/
vga_retrace_vertical
=
TRUE
;
LeaveCriticalSection
(
&
vga_lock
);
}
static
BYTE
palreg
,
palcnt
;
static
PALETTEENTRY
paldat
;
void
VGA_ioport_out
(
WORD
port
,
BYTE
val
)
{
switch
(
port
)
{
/* General Register - Feature Control */
case
0x3ba
:
FIXME
(
"Unsupported VGA register: general register - feature control 0x%04x (value 0x%02x)
\n
"
,
port
,
val
);
break
;
/* Attribute Controller - Address/Other */
case
0x3c0
:
if
(
vga_address_3c0
)
vga_index_3c0
=
val
;
else
FIXME
(
"Unsupported index, VGA attribute controller register 0x3c0: 0x%02x (value 0x%02x)
\n
"
,
vga_index_3c0
,
val
);
vga_address_3c0
=
!
vga_address_3c0
;
break
;
/* General Register - Misc output */
case
0x3c2
:
FIXME
(
"Unsupported VGA register: general register - misc output 0x%04x (value 0x%02x)
\n
"
,
port
,
val
);
break
;
/* General Register - Video subsystem enable */
case
0x3c3
:
FIXME
(
"Unsupported VGA register: general register - video subsystem enable 0x%04x (value 0x%02x)
\n
"
,
port
,
val
);
break
;
/* Sequencer Register - Address */
case
0x3c4
:
vga_index_3c4
=
val
;
break
;
/* Sequencer Register - Other */
case
0x3c5
:
switch
(
vga_index_3c4
)
{
case
0x04
:
/* Sequencer: Memory Mode Register */
if
(
vga_fb_depth
==
8
)
VGA_SetWindowStart
((
val
&
8
)
?
0
:
-
1
);
else
FIXME
(
"Memory Mode Register not supported in this mode.
\n
"
);
break
;
default:
FIXME
(
"Unsupported index, VGA sequencer register 0x3c4: 0x%02x (value 0x%02x)
\n
"
,
vga_index_3c4
,
val
);
}
break
;
case
0x3c8
:
palreg
=
val
;
palcnt
=
0
;
break
;
case
0x3c9
:
((
BYTE
*
)
&
paldat
)[
palcnt
++
]
=
val
<<
2
;
if
(
palcnt
==
3
)
{
VGA_SetPalette
(
&
paldat
,
palreg
++
,
1
);
palcnt
=
0
;
}
break
;
/* Graphics Controller Register - Address */
case
0x3ce
:
vga_index_3ce
=
val
;
break
;
/* Graphics Controller Register - Other */
case
0x3cf
:
FIXME
(
"Unsupported index, VGA graphics controller register - other 0x3ce: 0x%02x (value 0x%02x)
\n
"
,
vga_index_3ce
,
val
);
break
;
/* CRT Controller Register - Index (MDA) */
case
0x3b4
:
/* CRT Controller Register - Index (CGA) */
case
0x3d4
:
vga_index_3d4
=
val
;
break
;
/* CRT Controller Register - Other (MDA) */
case
0x3b5
:
/* CRT Controller Register - Other (CGA) */
case
0x3d5
:
FIXME
(
"Unsupported index, VGA crt controller register 0x3b4/0x3d4: 0x%02x (value 0x%02x)
\n
"
,
vga_index_3d4
,
val
);
break
;
/* Mode control register - 6845 Motorola (MDA) */
case
0x3b8
:
/* Mode control register - 6845 Motorola (CGA) */
case
0x3d8
:
/*
* xxxxxxx1 = 80x25 text
* xxxxxxx0 = 40x25 text (default)
* xxxxxx1x = graphics (320x200)
* xxxxxx0x = text
* xxxxx1xx = B/W
* xxxxx0xx = color
* xxxx1xxx = enable video signal
* xxx1xxxx = 640x200 B/W graphics
* xx1xxxxx = blink
*/
/* check bits 6 and 7 */
if
(
val
&
0xC0
)
{
FIXME
(
"Unsupported value, VGA register 0x3d8: 0x%02x - bits 7 and 6 not supported.
\n
"
,
val
);
}
/* check bits 5 - blink on */
if
(
val
&
0x20
)
{
FIXME
(
"Unsupported value, VGA register 0x3d8: 0x%02x (bit 5) - blink is not supported.
\n
"
,
val
);
}
/* Enable Video Signal (bit 3) - Set the enabled bit */
VGA_SetEnabled
((
val
&
0x08
)
!=
0
);
/* xxx1x010 - Detect 160x200, 16 color mode (CGA composite) */
if
(
(
val
&
0x17
)
==
0x12
)
{
/* Switch to 160x200x4 composite mode - special case of mode 6 */
CGA_ColorComposite
=
TRUE
;
VGA_SetMode
(
6
);
}
else
{
/* turn off composite colors otherwise, including 320x200 (80x200 16 color) */
CGA_ColorComposite
=
FALSE
;
}
/* xxx0x100 - Detect VGA mode 0 */
if
(
(
val
&
0x17
)
==
0x04
)
{
VGA_SetMode
(
0
);
}
/* xxx0x000 - Detect VGA mode 1 */
else
if
(
(
val
&
0x17
)
==
0x00
)
{
VGA_SetMode
(
1
);
}
/* xxx0x101 - Detect VGA mode 2 */
else
if
(
(
val
&
0x17
)
==
0x05
)
{
VGA_SetMode
(
2
);
}
/* xxx0x001 - Detect VGA mode 3 */
else
if
(
(
val
&
0x17
)
==
0x01
)
{
VGA_SetMode
(
3
);
}
/* xxx0x010 - Detect VGA mode 4 */
else
if
(
(
val
&
0x17
)
==
0x02
)
{
VGA_SetMode
(
4
);
}
/* xxx0x110 - Detect VGA mode 5 */
else
if
(
(
val
&
0x17
)
==
0x06
)
{
VGA_SetMode
(
5
);
}
/* xxx1x110 - Detect VGA mode 6 */
else
if
(
(
val
&
0x17
)
==
0x16
)
{
VGA_SetMode
(
6
);
}
/* unsupported mode */
else
{
FIXME
(
"Unsupported value, VGA register 0x3d8: 0x%02x - unrecognized MDA/CGA mode
\n
"
,
val
);
/* Set the enabled bit */
}
break
;
/* Colour control register (CGA) */
case
0x3d9
:
/* Set bright */
VGA_SetBright
((
val
&
0x10
)
!=
0
);
/* Set palette index */
VGA_SetPaletteIndex
((
val
&
0x20
)
!=
0
);
/* Now update the palette */
VGA_UpdatePalette
();
break
;
default:
FIXME
(
"Unsupported VGA register: 0x%04x (value 0x%02x)
\n
"
,
port
,
val
);
}
}
BYTE
VGA_ioport_in
(
WORD
port
)
{
BYTE
ret
;
switch
(
port
)
{
/* Attribute Controller - Other */
case
0x3c1
:
FIXME
(
"Unsupported index, VGA attribute controller register 0x3c0: 0x%02x
\n
"
,
vga_index_3c0
);
return
0xff
;
/* General Register - Input status 0 */
case
0x3c2
:
ret
=
0xff
;
FIXME
(
"Unsupported VGA register: general register - input status 0 0x%04x
\n
"
,
port
);
break
;
/* General Register - Video subsystem enable */
case
0x3c3
:
ret
=
0xff
;
FIXME
(
"Unsupported VGA register: general register - video subsystem enable 0x%04x
\n
"
,
port
);
break
;
/* Sequencer Register - Other */
case
0x3c5
:
switch
(
vga_index_3c4
)
{
case
0x04
:
/* Sequencer: Memory Mode Register */
return
(
VGA_GetWindowStart
()
==
-
1
)
?
0xf7
:
0xff
;
default:
FIXME
(
"Unsupported index, register 0x3c4: 0x%02x
\n
"
,
vga_index_3c4
);
return
0xff
;
}
/* General Register - DAC State */
case
0x3c7
:
ret
=
0xff
;
FIXME
(
"Unsupported VGA register: general register - DAC State 0x%04x
\n
"
,
port
);
break
;
/* General Register - Feature control */
case
0x3ca
:
ret
=
0xff
;
FIXME
(
"Unsupported VGA register: general register - Feature control 0x%04x
\n
"
,
port
);
break
;
/* General Register - Misc output */
case
0x3cc
:
ret
=
0xff
;
FIXME
(
"Unsupported VGA register: general register - Feature control 0x%04x
\n
"
,
port
);
break
;
/* Graphics Controller Register - Other */
case
0x3cf
:
FIXME
(
"Unsupported index, register 0x3ce: 0x%02x
\n
"
,
vga_index_3ce
);
return
0xff
;
/* CRT Controller Register - Other (MDA) */
case
0x3b5
:
/* CRT Controller Register - Other (CGA) */
case
0x3d5
:
FIXME
(
"Unsupported index, VGA crt controller register 0x3b4/0x3d4: 0x%02x
\n
"
,
vga_index_3d4
);
return
0xff
;
/* General Register - Input status 1 (MDA) */
case
0x3ba
:
/* General Register - Input status 1 (CGA) */
case
0x3da
:
/*
* Read from this register resets register 0x3c0 address flip-flop.
*/
vga_address_3c0
=
TRUE
;
/*
* Read from this register returns following bits:
* xxxx1xxx = Vertical retrace in progress if set.
* xxxxx1xx = Light pen switched on.
* xxxxxx1x = Light pen trigger set.
* xxxxxxx1 = Either vertical or horizontal retrace
* in progress if set.
*/
ret
=
0
;
if
(
vga_retrace_vertical
)
ret
|=
9
;
if
(
vga_retrace_horizontal
)
ret
|=
3
;
/*
* If VGA mode has been set, vertical retrace is
* turned on once a frame and cleared after each read.
* This might cause applications that synchronize with
* vertical retrace to actually skip one frame but that
* is probably not a problem.
*
* If no VGA mode has been set, vertical retrace is faked
* by toggling the value after every read.
*/
if
(
VGA_IsTimerRunning
())
vga_retrace_vertical
=
FALSE
;
else
vga_retrace_vertical
=
!
vga_retrace_vertical
;
/*
* Toggle horizontal retrace.
*/
vga_retrace_horizontal
=
!
vga_retrace_horizontal
;
break
;
default:
ret
=
0xff
;
FIXME
(
"Unsupported VGA register: 0x%04x
\n
"
,
port
);
}
return
ret
;
}
void
VGA_Clean
(
void
)
{
VGA_Exit
();
VGA_DeinstallTimer
();
}
dlls/krnl386.exe16/vga.h
deleted
100644 → 0
View file @
5ec54495
/*
* VGA emulation
*
* Copyright 1998 Ove Kåven
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_VGA_H
#define __WINE_VGA_H
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
/*
* VGA VESA definitions
*/
/* mode descriptor */
enum
modetype
{
TEXT
=
0
,
GRAPHIC
=
1
};
/* Wine internal information about video modes */
typedef
struct
{
WORD
Mode
;
BOOL
ModeType
;
WORD
TextCols
;
/* columns of text in display */
WORD
TextRows
;
/* rows of text in display */
WORD
CharWidth
;
WORD
CharHeight
;
WORD
Width
;
/* width of display in pixels */
WORD
Height
;
/* height of display in pixels */
WORD
Depth
;
/* bits per pixel */
WORD
Colors
;
/* total available colors */
WORD
ScreenPages
;
BOOL
Supported
;
}
VGA_MODE
;
extern
const
VGA_MODE
VGA_modelist
[]
DECLSPEC_HIDDEN
;
/* all vga modes */
const
VGA_MODE
*
VGA_GetModeInfo
(
WORD
mode
)
DECLSPEC_HIDDEN
;
BOOL
VGA_SetMode
(
WORD
mode
)
DECLSPEC_HIDDEN
;
/* graphics mode */
BOOL
VGA_GetMode
(
unsigned
*
Height
,
unsigned
*
Width
,
unsigned
*
Depth
)
DECLSPEC_HIDDEN
;
void
VGA_SetPalette
(
PALETTEENTRY
*
pal
,
int
start
,
int
len
)
DECLSPEC_HIDDEN
;
void
VGA_SetColor16
(
int
reg
,
int
color
)
DECLSPEC_HIDDEN
;
char
VGA_GetColor16
(
int
reg
)
DECLSPEC_HIDDEN
;
void
VGA_Set16Palette
(
char
*
Table
)
DECLSPEC_HIDDEN
;
void
VGA_Get16Palette
(
char
*
Table
)
DECLSPEC_HIDDEN
;
void
VGA_SetWindowStart
(
int
start
)
DECLSPEC_HIDDEN
;
int
VGA_GetWindowStart
(
void
)
DECLSPEC_HIDDEN
;
void
VGA_ShowMouse
(
BOOL
show
)
DECLSPEC_HIDDEN
;
void
VGA_UpdatePalette
(
void
)
DECLSPEC_HIDDEN
;
void
VGA_SetPaletteIndex
(
unsigned
index
)
DECLSPEC_HIDDEN
;
void
VGA_SetBright
(
BOOL
bright
)
DECLSPEC_HIDDEN
;
void
VGA_WritePixel
(
unsigned
color
,
unsigned
page
,
unsigned
col
,
unsigned
row
)
DECLSPEC_HIDDEN
;
/* text mode */
void
VGA_InitAlphaMode
(
unsigned
*
Xres
,
unsigned
*
Yres
)
DECLSPEC_HIDDEN
;
void
VGA_SetAlphaMode
(
unsigned
Xres
,
unsigned
Yres
)
DECLSPEC_HIDDEN
;
BOOL
VGA_GetAlphaMode
(
unsigned
*
Xres
,
unsigned
*
Yres
)
DECLSPEC_HIDDEN
;
void
VGA_SetCursorShape
(
unsigned
char
start_options
,
unsigned
char
end
)
DECLSPEC_HIDDEN
;
void
VGA_SetCursorPos
(
unsigned
X
,
unsigned
Y
)
DECLSPEC_HIDDEN
;
void
VGA_GetCursorPos
(
unsigned
*
X
,
unsigned
*
Y
)
DECLSPEC_HIDDEN
;
void
VGA_WriteChars
(
unsigned
X
,
unsigned
Y
,
unsigned
ch
,
int
attr
,
int
count
)
DECLSPEC_HIDDEN
;
void
VGA_PutChar
(
BYTE
ascii
)
DECLSPEC_HIDDEN
;
void
VGA_ClearText
(
unsigned
row1
,
unsigned
col1
,
unsigned
row2
,
unsigned
col2
,
BYTE
attr
)
DECLSPEC_HIDDEN
;
void
VGA_ScrollUpText
(
unsigned
row1
,
unsigned
col1
,
unsigned
row2
,
unsigned
col2
,
unsigned
lines
,
BYTE
attr
)
DECLSPEC_HIDDEN
;
void
VGA_ScrollDownText
(
unsigned
row1
,
unsigned
col1
,
unsigned
row2
,
unsigned
col2
,
unsigned
lines
,
BYTE
attr
)
DECLSPEC_HIDDEN
;
void
VGA_GetCharacterAtCursor
(
BYTE
*
ascii
,
BYTE
*
attr
)
DECLSPEC_HIDDEN
;
/* control */
void
VGA_ioport_out
(
WORD
port
,
BYTE
val
)
DECLSPEC_HIDDEN
;
BYTE
VGA_ioport_in
(
WORD
port
)
DECLSPEC_HIDDEN
;
void
VGA_Clean
(
void
)
DECLSPEC_HIDDEN
;
#endif
/* __WINE_VGA_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment