Moved video drivers to a separate directory and added initial version of VBE miniport driver.

svn path=/trunk/; revision=7548
This commit is contained in:
Filip Navara 2004-01-10 14:39:21 +00:00
parent cba93d012e
commit 095ab8c8dd
36 changed files with 5995 additions and 10 deletions

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.200 2004/01/09 19:55:29 ekohl Exp $
# $Id: Makefile,v 1.201 2004/01/10 14:39:20 navaraf Exp $
#
# Global makefile
#
@ -46,9 +46,6 @@ DLLS = libwine advapi32 cards crtdll fmifs freetype gdi32 kernel32 packet lzexpa
syssetup twain unicode user32 userenv version winspool ws2help ws2_32 wsock32 \
wshirda iphlpapi msgina mswsock msimg32 d3d8thk winmm comctl32 $(DLLS_KBD)
# Uncomment this after the update W32API headers will be released.
# DLLS += ole32 shlwapi
SUBSYS = smss win32k csrss ntvdm
#
@ -67,8 +64,8 @@ DRIVERS_LIB = bzip2
# Kernel mode device drivers
# Obsolete: ide
# beep blue floppy null parallel ramdrv serenum serial vga videoprt
DEVICE_DRIVERS = beep blue debugout floppy null serial vga videoprt bootvid
# beep blue floppy null parallel ramdrv serenum serial videoprt
DEVICE_DRIVERS = beep blue debugout floppy null serial videoprt bootvid
# Kernel mode input drivers
INPUT_DRIVERS = keyboard mouclass psaux sermouse
@ -111,7 +108,7 @@ EXT_MODULES =
endif
KERNEL_DRIVERS = $(DRIVERS_LIB) $(DEVICE_DRIVERS) $(INPUT_DRIVERS) $(FS_DRIVERS) \
$(NET_DRIVERS) $(NET_DEVICE_DRIVERS) $(STORAGE_DRIVERS)
$(NET_DRIVERS) $(NET_DEVICE_DRIVERS) $(STORAGE_DRIVERS) VIDEO_DRIVERS
# Regression tests
REGTESTS = regtests
@ -258,8 +255,9 @@ $(SYS_SVC:%=%_install): %_install:
$(APPS): %:
$(MAKE) -C apps/$*
$(APPS:%=%_implib): %_implib:
$(MAKE) -C apps/$* implib
# Not needed
# $(APPS:%=%_implib): %_implib:
# $(MAKE) -C apps/$* implib
$(APPS:%=%_clean): %_clean:
$(MAKE) -C apps/$* clean
@ -444,6 +442,28 @@ $(DEVICE_DRIVERS:%=%_bootcd): %_bootcd:
$(DEVICE_DRIVERS:%=%_install) $(DEVICE_DRIVERS:%=%_bootcd)
#
# Video device driver rules
#
VIDEO_DRIVERS:
$(MAKE) -C drivers/video
VIDEO_DRIVERS_implib:
$(MAKE) -C drivers/video implib
VIDEO_DRIVERS_clean:
$(MAKE) -C drivers/video clean
VIDEO_DRIVERS_install:
$(MAKE) -C drivers/video install
VIDEO_DRIVERS_bootcd:
$(MAKE) -C drivers/video bootcd
.PHONY: VIDEO_DRIVERS VIDEO_DRIVERS_implib VIDEO_DRIVERS_clean \
VIDEO_DRIVERS_install VIDEO_DRIVERS_bootcd
#
# Input driver rules
#
@ -465,7 +485,6 @@ $(INPUT_DRIVERS:%=%_bootcd): %_bootcd:
.PHONY: $(INPUT_DRIVERS) $(INPUT_DRIVERS:%=%_implib) $(INPUT_DRIVERS:%=%_clean)\
$(INPUT_DRIVERS:%=%_install) $(INPUT_DRIVERS:%=%_bootcd)
#
# Filesystem driver rules
#

View file

@ -0,0 +1,7 @@
vgaddi.coff
*.sym
*.o
*.dll
*.map
*.tmp
.*.d

View file

@ -0,0 +1,3 @@
*.o
*.map
.*.d

View file

@ -0,0 +1,608 @@
/*
* entry.c
*
* $Revision: 1.1 $
* $Author: navaraf $
* $Date: 2004/01/10 14:39:20 $
*
*/
#include "../vgaddi.h"
#include "../vgavideo/vgavideo.h"
#define NDEBUG
#include <debug.h>
#define DBG_PREFIX "VGADDI: "
static BOOL VGAInitialized = FALSE;
DRVFN FuncList[] =
{
/* Required Display driver fuctions */
{INDEX_DrvAssertMode, (PFN) DrvAssertMode},
{INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV},
{INDEX_DrvCopyBits, (PFN) DrvCopyBits},
{INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV},
{INDEX_DrvDisableSurface, (PFN) DrvDisableSurface},
{INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV},
{INDEX_DrvEnableSurface, (PFN) DrvEnableSurface},
{INDEX_DrvGetModes, (PFN) DrvGetModes},
{INDEX_DrvLineTo, (PFN) DrvLineTo},
{INDEX_DrvPaint, (PFN) DrvPaint},
{INDEX_DrvBitBlt, (PFN) DrvBitBlt},
{INDEX_DrvTransparentBlt, (PFN) DrvTransparentBlt},
{INDEX_DrvMovePointer, (PFN) DrvMovePointer},
{INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape},
#if 0
/* Optional Display driver functions */
{INDEX_, (PFN) },
{INDEX_DescribePixelFormat, (PFN) VGADDIDescribePixelFormat},
{INDEX_DrvDitherColor, (PFN) VGADDIDitherColor},
{INDEX_DrvFillPath, (PFN) VGADDIFillPath},
{INDEX_DrvGetTrueTypeFile, (PFN) VGADDIGetTrueTypeFile},
{INDEX_DrvLoadFontFile, (PFN) VGADDILoadFontFile},
{INDEX_DrvQueryFont, (PFN) VGADDIQueryFont},
{INDEX_DrvQueryFontCaps, (PFN) VGADDIQueryFontCaps},
{INDEX_DrvQueryFontData, (PFN) VGADDIQueryFontData},
{INDEX_DrvQueryFontFile, (PFN) VGADDIQueryFontFile},
{INDEX_DrvQueryFontTree, (PFN) VGADDIQueryFontTree},
{INDEX_DrvQueryTrueTypeOutline, (PFN) VGADDIQueryTrueTypeOutline},
{INDEX_DrvQueryTrueTypeTable, (PFN) VGADDIQueryTrueTypeTable},
{INDEX_DrvRealizeBrush, (PFN) VGADDIRealizeBrush},
{INDEX_DrvResetPDEV, (PFN) VGADDIResetPDEV},
{INDEX_DrvSetPalette, (PFN) VGADDISetPalette},
{INDEX_DrvSetPixelFormat, (PFN) VGADDISetPixelFormat},
{INDEX_DrvStretchBlt, (PFN) VGADDIStretchBlt},
{INDEX_DrvStrokePath, (PFN) VGADDIStrokePath},
{INDEX_DrvSwapBuffers, (PFN) VGADDISwapBuffers},
{INDEX_DrvTextOut, (PFN) VGADDITextOut},
{INDEX_DrvUnloadFontFile, (PFN) VGADDIUnloadFontFile},
#endif
};
GDIINFO gaulCap = {
GDI_DRIVER_VERSION,
DT_RASDISPLAY, // ulTechnology
0, // ulHorzSize
0, // ulVertSize
0, // ulHorzRes (filled in at initialization)
0, // ulVertRes (filled in at initialization)
4, // cBitsPixel
1, // cPlanes
16, // ulNumColors
0, // flRaster (DDI reserved field)
96, // ulLogPixelsX (must be set to 96 according to MSDN)
96, // ulLogPixelsY (must be set to 96 according to MSDN)
TC_RA_ABLE | TC_SCROLLBLT, // flTextCaps
6, // ulDACRed
6, // ulDACGree
6, // ulDACBlue
0x0024, // ulAspectX (one-to-one aspect ratio)
0x0024, // ulAspectY
0x0033, // ulAspectXY
1, // xStyleStep
1, // yStyleSte;
3, // denStyleStep
{ 0, 0 }, // ptlPhysOffset
{ 0, 0 }, // szlPhysSize
0, // ulNumPalReg (win3.1 16 color drivers say 0 too)
// These fields are for halftone initialization.
{ // ciDevice, ColorInfo
{ 6700, 3300, 0 }, // Red
{ 2100, 7100, 0 }, // Green
{ 1400, 800, 0 }, // Blue
{ 1750, 3950, 0 }, // Cyan
{ 4050, 2050, 0 }, // Magenta
{ 4400, 5200, 0 }, // Yellow
{ 3127, 3290, 0 }, // AlignmentWhite
20000, // RedGamma
20000, // GreenGamma
20000, // BlueGamma
0, 0, 0, 0, 0, 0
},
0, // ulDevicePelsDPI
PRIMARY_ORDER_CBA, // ulPrimaryOrder
HT_PATSIZE_4x4_M, // ulHTPatternSize
HT_FORMAT_4BPP_IRGB, // ulHTOutputFormat
HT_FLAG_ADDITIVE_PRIMS, // flHTFlags
0, // ulVRefresh
8, // ulBltAlignment
0, // ulPanningHorzRes
0, // ulPanningVertRes
};
// Palette for VGA
typedef struct _VGALOGPALETTE
{
USHORT ident;
USHORT NumEntries;
PALETTEENTRY PaletteEntry[16];
} VGALOGPALETTE;
const VGALOGPALETTE VGApalette =
{
0x400, // driver version
16, // num entries
{
{ 0x00, 0x00, 0x00, 0x00 }, // 0
{ 0x80, 0x00, 0x00, 0x00 }, // 1
{ 0x00, 0x80, 0x00, 0x00 }, // 2
{ 0x80, 0x80, 0x00, 0x00 }, // 3
{ 0x00, 0x00, 0x80, 0x00 }, // 4
{ 0x80, 0x00, 0x80, 0x00 }, // 5
{ 0x00, 0x80, 0x80, 0x00 }, // 6
{ 0x80, 0x80, 0x80, 0x00 }, // 7
{ 0xc0, 0xc0, 0xc0, 0x00 }, // 8
{ 0xff, 0x00, 0x00, 0x00 }, // 9
{ 0x00, 0xff, 0x00, 0x00 }, // 10
{ 0xff, 0xff, 0x00, 0x00 }, // 11
{ 0x00, 0x00, 0xff, 0x00 }, // 12
{ 0xff, 0x00, 0xff, 0x00 }, // 13
{ 0x00, 0xff, 0xff, 0x00 }, // 14
{ 0xff, 0xff, 0xff, 0x00 } // 15
}
};
// Devinfo structure passed back to the engine in DrvEnablePDEV
#define SYSTM_LOGFONT {16,7,0,0,700,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,VARIABLE_PITCH | FF_DONTCARE, L"System"}
#define HELVE_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_STROKE_PRECIS,PROOF_QUALITY,VARIABLE_PITCH | FF_DONTCARE, L"MS Sans Serif"}
#define COURI_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_STROKE_PRECIS,PROOF_QUALITY,FIXED_PITCH | FF_DONTCARE, L"Courier"}
DEVINFO devinfoVGA =
{
(GCAPS_OPAQUERECT | GCAPS_HORIZSTRIKE | GCAPS_ALTERNATEFILL | GCAPS_MONO_DITHER | GCAPS_COLOR_DITHER |
GCAPS_WINDINGFILL | GCAPS_DITHERONREALIZE
), // Graphics capabilities
SYSTM_LOGFONT, // Default font description
HELVE_LOGFONT, // ANSI variable font description
COURI_LOGFONT, // ANSI fixed font description
0, // Count of device fonts
BMF_4BPP, // preferred DIB format
8, // Width of color dither
8, // Height of color dither
0 // Default palette to use for this device
};
BOOL STDCALL
DrvEnableDriver(IN ULONG EngineVersion,
IN ULONG SizeOfDED,
OUT PDRVENABLEDATA DriveEnableData)
{
/* EngDebugPrint("VGADDI", "DrvEnableDriver called...\n", 0); */
vgaPreCalc();
// FIXME: Use Vidport to map the memory properly
vidmem = (char *)(0xd0000000 + 0xa0000);
VGADDI_InitializeOffScreenMem((640 * 480) >> 3, 65536 - ((640 * 480) >> 3));
DriveEnableData->pdrvfn = FuncList;
DriveEnableData->c = sizeof(FuncList) / sizeof(DRVFN);
DriveEnableData->iDriverVersion = DDI_DRIVER_VERSION_NT4;
return TRUE;
}
// DrvDisableDriver
// DESCRIPTION:
// This function is called by the KMGDI at exit. It should cleanup.
// ARGUMENTS:
// NONE
// RETURNS:
// NONE
VOID STDCALL
DrvDisableDriver(VOID)
{
return;
}
// ----------------------------------------------- Driver Implementation
// DrvEnablePDEV
// DESCRIPTION:
// This function is called after DrvEnableDriver to get information
// about the mode that is to be used. This function just returns
// information, and should not yet initialize the mode.
// ARGUMENTS:
// IN DEVMODEW * DM Describes the mode requested
// IN LPWSTR LogAddress
// IN ULONG PatternCount number of patterns expected
// OUT HSURF * SurfPatterns array to contain pattern handles
// IN ULONG GDIInfoSize the size of the GDIInfo object passed in
// OUT ULONG * GDIInfo GDI Info object
// IN ULONG DevInfoSize the size of the DevInfo object passed in
// OUT ULONG * DevInfo Device Info object
// IN LPWSTR DevDataFile ignore
// IN LPWSTR DeviceName Device name
// IN HANDLE Driver handle to KM driver
// RETURNS:
// DHPDEV a handle to a DPev object
DHPDEV STDCALL
DrvEnablePDEV(IN DEVMODEW *DM,
IN LPWSTR LogAddress,
IN ULONG PatternCount,
OUT HSURF *SurfPatterns,
IN ULONG GDIInfoSize,
OUT ULONG *GDIInfo,
IN ULONG DevInfoSize,
OUT DEVINFO *DevInfo,
IN HDEV Dev,
IN LPWSTR DeviceName,
IN HANDLE Driver)
{
PPDEV PDev;
PDev = EngAllocMem(FL_ZERO_MEMORY, sizeof(PDEV), ALLOC_TAG);
if (PDev == NULL)
{
EngDebugPrint(DBG_PREFIX, "EngAllocMem failed for PDEV\n", 0);
return(NULL);
}
PDev->KMDriver = Driver;
DPRINT( "PDev: %x, Driver: %x\n", PDev, PDev->KMDriver );
PDev->xyCursor.x = 320;
PDev->xyCursor.y = 240;
PDev->ptlExtent.x = 0;
PDev->ptlExtent.y = 0;
PDev->cExtent = 0;
PDev->flCursor = CURSOR_DOWN;
gaulCap.ulHorzRes = 640;
gaulCap.ulVertRes = 480;
if (sizeof(GDIINFO) < GDIInfoSize)
{
GDIInfoSize = sizeof(GDIINFO);
}
memcpy(GDIInfo, &gaulCap, GDIInfoSize);
devinfoVGA.hpalDefault = EngCreatePalette(PAL_INDEXED, 16, (ULONG *) VGApalette.PaletteEntry, 0, 0, 0);
if (sizeof(DEVINFO) < DevInfoSize)
{
DevInfoSize = sizeof(DEVINFO);
}
memcpy(DevInfo, &devinfoVGA, DevInfoSize);
return (DHPDEV) PDev;
}
// DrvCompletePDEV
// DESCRIPTION
// Called after initialization of PDEV is complete. Supplies
// a reference to the GDI handle for the PDEV.
VOID STDCALL
DrvCompletePDEV(IN DHPDEV PDev,
IN HDEV Dev)
{
((PPDEV) PDev)->GDIDevHandle = Dev; // Handle to the DC
}
BOOL STDCALL
DrvAssertMode(IN DHPDEV DPev,
IN BOOL Enable)
{
PPDEV ppdev = (PPDEV)DPev;
ULONG returnedDataLength;
if(Enable==TRUE)
{
// Reenable our graphics mode
if (!InitPointer(ppdev))
{
// Failed to set pointer
return FALSE;
}
if (!VGAInitialized)
{
if (!InitVGA(ppdev, FALSE))
{
// Failed to initialize the VGA
return FALSE;
}
VGAInitialized = TRUE;
}
} else {
// Go back to last known mode
DPRINT( "ppdev: %x, KMDriver: %x", ppdev, ppdev->KMDriver );
if (EngDeviceIoControl(ppdev->KMDriver, IOCTL_VIDEO_RESET_DEVICE, NULL, 0, NULL, 0, &returnedDataLength))
{
// Failed to go back to mode
return FALSE;
}
VGAInitialized = FALSE;
}
return TRUE;
}
VOID STDCALL
DrvDisablePDEV(IN DHPDEV PDev)
{
PPDEV ppdev = (PPDEV)PDev;
// EngDeletePalette(devinfoVGA.hpalDefault);
if (ppdev->pjPreallocSSBBuffer != NULL)
{
EngFreeMem(ppdev->pjPreallocSSBBuffer);
}
if (ppdev->pucDIB4ToVGAConvBuffer != NULL)
{
EngFreeMem(ppdev->pucDIB4ToVGAConvBuffer);
}
DPRINT( "Freeing PDEV\n" );
EngFreeMem(PDev);
}
VOID STDCALL
DrvDisableSurface(IN DHPDEV PDev)
{
PPDEV ppdev = (PPDEV)PDev;
PDEVSURF pdsurf = ppdev->AssociatedSurf;
CHECKPOINT;
DPRINT( "KMDriver: %x\n", ppdev->KMDriver );
// EngFreeMem(pdsurf->BankSelectInfo);
CHECKPOINT;
if (pdsurf->BankInfo != NULL) {
EngFreeMem(pdsurf->BankInfo);
}
CHECKPOINT;
if (pdsurf->BankInfo2RW != NULL) {
EngFreeMem(pdsurf->BankInfo2RW);
}
CHECKPOINT;
if (pdsurf->BankBufferPlane0 != NULL) {
EngFreeMem(pdsurf->BankBufferPlane0);
}
CHECKPOINT;
if (ppdev->pPointerAttributes != NULL) {
EngFreeMem(ppdev->pPointerAttributes);
}
CHECKPOINT;
// free any pending saved screen bit blocks
#if 0
pSSB = pdsurf->ssbList;
while (pSSB != (PSAVED_SCREEN_BITS) NULL) {
// Point to the next saved screen bits block
pSSBNext = (PSAVED_SCREEN_BITS) pSSB->pvNextSSB;
// Free the current block
EngFreeMem(pSSB);
pSSB = pSSBNext;
}
#endif
EngDeleteSurface((HSURF) ppdev->SurfHandle);
// EngFreeMem(pdsurf); // free the surface
}
static VOID
InitSavedBits(PPDEV ppdev)
{
if (!(ppdev->fl & DRIVER_OFFSCREEN_REFRESHED))
{
return;
}
// set up rect to right of visible screen
ppdev->SavedBitsRight.left = ppdev->sizeSurf.cx;
ppdev->SavedBitsRight.top = 0;
ppdev->SavedBitsRight.right = ppdev->sizeMem.cx-PLANAR_PELS_PER_CPU_ADDRESS;
ppdev->SavedBitsRight.bottom = ppdev->sizeSurf.cy;
if ((ppdev->SavedBitsRight.right <= ppdev->SavedBitsRight.left) ||
(ppdev->SavedBitsRight.bottom <= ppdev->SavedBitsRight.top))
{
ppdev->SavedBitsRight.left = 0;
ppdev->SavedBitsRight.top = 0;
ppdev->SavedBitsRight.right = 0;
ppdev->SavedBitsRight.bottom = 0;
}
// set up rect below visible screen
ppdev->SavedBitsBottom.left = 0;
ppdev->SavedBitsBottom.top = ppdev->sizeSurf.cy;
ppdev->SavedBitsBottom.right = ppdev->sizeMem.cx-PLANAR_PELS_PER_CPU_ADDRESS;
ppdev->SavedBitsBottom.bottom = ppdev->sizeMem.cy - ppdev->NumScansUsedByPointer;
if ((ppdev->SavedBitsBottom.right <= ppdev->SavedBitsBottom.left) ||
(ppdev->SavedBitsBottom.bottom <= ppdev->SavedBitsBottom.top))
{
ppdev->SavedBitsBottom.left = 0;
ppdev->SavedBitsBottom.top = 0;
ppdev->SavedBitsBottom.right = 0;
ppdev->SavedBitsBottom.bottom = 0;
}
ppdev->BitsSaved = FALSE;
return;
}
HSURF STDCALL
DrvEnableSurface(IN DHPDEV PDev)
{
PPDEV ppdev = (PPDEV)PDev;
PDEVSURF pdsurf;
DHSURF dhsurf;
HSURF hsurf;
DPRINT("DrvEnableSurface() called\n");
// Initialize the VGA
if (!VGAInitialized)
{
if (!InitVGA(ppdev, TRUE))
{
goto error_done;
}
VGAInitialized = TRUE;
}
// dhsurf is of type DEVSURF, which is the drivers specialized surface type
dhsurf = (DHSURF)EngAllocMem(0, sizeof(DEVSURF), ALLOC_TAG);
if (dhsurf == (DHSURF) 0)
{
goto error_done;
}
pdsurf = (PDEVSURF) dhsurf;
pdsurf->ident = DEVSURF_IDENT;
pdsurf->flSurf = 0;
pdsurf->Format = BMF_PHYSDEVICE;
pdsurf->jReserved1 = 0;
pdsurf->jReserved2 = 0;
pdsurf->ppdev = ppdev;
pdsurf->sizeSurf.cx = ppdev->sizeSurf.cx;
pdsurf->sizeSurf.cy = ppdev->sizeSurf.cy;
pdsurf->NextPlane = 0;
pdsurf->Scan0 = ppdev->fbScreen;
pdsurf->BitmapStart = ppdev->fbScreen;
pdsurf->StartBmp = ppdev->fbScreen;
/* pdsurf->Conv = &ConvertBuffer[0]; */
if (!InitPointer(ppdev)) {
DbgPrint("DrvEnablePDEV failed bInitPointer\n");
goto error_clean;
}
/* if (!SetUpBanking(pdsurf, ppdev)) {
DISPDBG((0, "DrvEnablePDEV failed SetUpBanking\n"));
goto error_clean;
} BANKING CODE UNIMPLEMENTED */
if ((hsurf = EngCreateDeviceSurface(dhsurf, ppdev->sizeSurf, BMF_4BPP)) ==
(HSURF)0)
{
// Call to EngCreateDeviceSurface failed
EngDebugPrint("VGADDI:", "EngCreateDeviceSurface call failed\n", 0);
goto error_clean;
}
InitSavedBits(ppdev);
if (EngAssociateSurface(hsurf, ppdev->GDIDevHandle, HOOK_BITBLT | HOOK_PAINT | HOOK_LINETO | HOOK_COPYBITS |
HOOK_TRANSPARENTBLT))
{
/* EngDebugPrint("VGADDI:", "Successfully associated surface\n", 0); */
ppdev->SurfHandle = hsurf;
ppdev->AssociatedSurf = pdsurf;
// Set up an empty saved screen block list
pdsurf->ssbList = NULL;
return(hsurf);
}
DPRINT( "EngAssociateSurface() failed\n" );
EngDeleteSurface(hsurf);
error_clean:
EngFreeMem(dhsurf);
error_done:
return((HSURF)0);
}
ULONG STDCALL
DrvGetModes(IN HANDLE Driver,
IN ULONG DataSize,
OUT PDEVMODEW DM)
{
DWORD NumModes;
DWORD ModeSize;
DWORD OutputSize;
DWORD OutputModes = DataSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
PVIDEO_MODE_INFORMATION VideoModeInformation, VideoTemp;
NumModes = getAvailableModes(Driver,
(PVIDEO_MODE_INFORMATION *) &VideoModeInformation,
&ModeSize);
if (NumModes == 0)
{
return 0;
}
if (DM == NULL)
{
OutputSize = NumModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
} else {
OutputSize=0;
VideoTemp = VideoModeInformation;
do
{
if (VideoTemp->Length != 0)
{
if (OutputModes == 0)
{
break;
}
memset(DM, 0, sizeof(DEVMODEW));
memcpy(DM->dmDeviceName, DLL_NAME, sizeof(DLL_NAME));
DM->dmSpecVersion = DM_SPECVERSION;
DM->dmDriverVersion = DM_SPECVERSION;
DM->dmSize = sizeof(DEVMODEW);
DM->dmDriverExtra = DRIVER_EXTRA_SIZE;
DM->dmBitsPerPel = VideoTemp->NumberOfPlanes *
VideoTemp->BitsPerPlane;
DM->dmPelsWidth = VideoTemp->VisScreenWidth;
DM->dmPelsHeight = VideoTemp->VisScreenHeight;
DM->dmDisplayFrequency = VideoTemp->Frequency;
DM->dmDisplayFlags = 0;
DM->dmFields = DM_BITSPERPEL |
DM_PELSWIDTH |
DM_PELSHEIGHT |
DM_DISPLAYFREQUENCY |
DM_DISPLAYFLAGS ;
// next DEVMODE entry
OutputModes--;
DM = (PDEVMODEW) ( ((ULONG)DM) + sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
OutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
}
VideoTemp = (PVIDEO_MODE_INFORMATION)(((PUCHAR)VideoTemp) + ModeSize);
} while (--NumModes);
}
return OutputSize;
}
/* EOF */

View file

@ -0,0 +1,47 @@
# $Id: makefile,v 1.1 2004/01/10 14:39:20 navaraf Exp $
PATH_TO_TOP = ../../../..
TARGET_BASE = 0x70000000
TARGET_TYPE = gdi_driver
TARGET_NAME = vgaddi
TARGET_CFLAGS = -Wall -Werror
MAIN_OBJECTS = \
main/enable.o
OTHER_OBJECTS = \
objects/screen.o \
objects/pointer.o \
objects/lineto.o \
objects/paint.o \
objects/bitblt.o \
objects/transblt.o \
objects/offscreen.o \
objects/copybits.o
VGAVIDEO_OBJECTS = \
vgavideo/vgavideo.o
TARGET_OBJECTS = \
$(MAIN_OBJECTS) \
$(OTHER_OBJECTS) \
$(VGAVIDEO_OBJECTS)
TARGET_CLEAN = \
main/*.o \
objects/*.o \
vgavideo/*.o
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
# Automatic dependency tracking
DEP_OBJECTS := $(TARGET_OBJECTS)
include $(PATH_TO_TOP)/tools/depend.mk
# EOF

View file

@ -0,0 +1,3 @@
*.o
*.map
.*.d

View file

@ -0,0 +1,475 @@
#include <ntddk.h>
#define NDEBUG
#include <debug.h>
#include "../vgaddi.h"
#include "../vgavideo/vgavideo.h"
#include "brush.h"
#include "bitblt.h"
typedef BOOL (*PFN_VGABlt)(SURFOBJ*, SURFOBJ*, XLATEOBJ*, RECTL*, POINTL*);
typedef BOOL STDCALL (*PBLTRECTFUNC)(SURFOBJ* OutputObj,
SURFOBJ* InputObj,
SURFOBJ* Mask,
XLATEOBJ* ColorTranslation,
RECTL* OutputRect,
POINTL* InputPoint,
POINTL* MaskOrigin,
BRUSHOBJ* Brush,
POINTL* BrushOrigin,
ROP4 Rop4);
static BOOL FASTCALL VGADDI_IntersectRect(RECTL* prcDst, RECTL* prcSrc1, RECTL* prcSrc2)
{
static const RECTL rclEmpty = { 0, 0, 0, 0 };
prcDst->left = max(prcSrc1->left, prcSrc2->left);
prcDst->right = min(prcSrc1->right, prcSrc2->right);
if (prcDst->left < prcDst->right)
{
prcDst->top = max(prcSrc1->top, prcSrc2->top);
prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
if (prcDst->top < prcDst->bottom) return(TRUE);
}
*prcDst = rclEmpty;
return(FALSE);
}
void DIB_BltToVGA_Fixed(int x, int y, int w, int h, void *b, int Source_lDelta, int mod);
BOOL
DIBtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint)
{
LONG dx, dy;
dx = DestRect->right - DestRect->left;
dy = DestRect->bottom - DestRect->top;
if (NULL == ColorTranslation || 0 != (ColorTranslation->flXlate & XO_TRIVIAL))
{
DIB_BltToVGA(DestRect->left, DestRect->top, dx, dy,
Source->pvScan0 + SourcePoint->y * Source->lDelta + (SourcePoint->x >> 1),
Source->lDelta, SourcePoint->x % 2);
}
else
{
/* Perform color translation */
DIB_BltToVGAWithXlate(DestRect->left, DestRect->top, dx, dy,
Source->pvScan0 + SourcePoint->y * Source->lDelta + (SourcePoint->x >> 1),
Source->lDelta, ColorTranslation);
}
return FALSE;
}
BOOL
VGAtoDIB(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint)
{
LONG i, j, dx, dy;
BYTE *GDIpos, *initial;
// Used by the temporary DFB
DEVSURF DestDevSurf;
// FIXME: Optimize to retrieve entire bytes at a time (see /display/vgavideo/vgavideo.c:vgaGetByte)
GDIpos = Dest->pvBits /* + (DestRect->top * Dest->lDelta) + (DestRect->left >> 1) */ ;
dx = DestRect->right - DestRect->left;
dy = DestRect->bottom - DestRect->top;
if(ColorTranslation == NULL)
{
// Prepare a Dest Dev Target and copy from the DFB to the DIB
DestDevSurf.NextScan = Dest->lDelta;
DestDevSurf.StartBmp = Dest->pvScan0;
DIB_BltFromVGA(SourcePoint->x, SourcePoint->y, dx, dy, Dest->pvBits, Dest->lDelta);
} else {
// Color translation
for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
{
initial = GDIpos;
for(i=SourcePoint->x; i<SourcePoint->x+dx; i++)
{
*GDIpos = XLATEOBJ_iXlate(ColorTranslation, vgaGetPixel(i, j));
GDIpos+=1;
}
GDIpos = initial + Dest->lDelta;
}
}
return FALSE;
}
BOOL
DFBtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint)
{
return FALSE;
// Do DFBs need color translation??
}
BOOL
VGAtoDFB(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint)
{
return FALSE;
// Do DFBs need color translation??
}
BOOL
VGAtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint)
{
LONG i, i2, j, dx, dy, alterx, altery;
//LARGE_INTEGER Start, End; // for performance measurement only
static char buf[640];
// Calculate deltas
dx = DestRect->right - DestRect->left;
dy = DestRect->bottom - DestRect->top;
alterx = DestRect->left - SourcePoint->x;
altery = DestRect->top - SourcePoint->y;
//KeQueryTickCount ( &Start );
i = SourcePoint->x;
i2 = i + alterx;
if (SourcePoint->y >= DestRect->top)
{
for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
{
LONG j2 = j + altery;
vgaReadScan ( i, j, dx, buf );
vgaWriteScan ( i2, j2, dx, buf );
}
}
else
{
for(j=(SourcePoint->y+dy-1); j>=SourcePoint->y; j--)
{
LONG j2 = j + altery;
vgaReadScan ( i, j, dx, buf );
vgaWriteScan ( i2, j2, dx, buf );
}
}
//KeQueryTickCount ( &End );
//DbgPrint ( "VgaBitBlt timing: %lu\n", (ULONG)(End.QuadPart-Start.QuadPart) );
return TRUE;
}
BOOL STDCALL
VGADDI_BltBrush(SURFOBJ* Dest, SURFOBJ* Source, SURFOBJ* MaskSurf,
XLATEOBJ* ColorTranslation, RECTL* DestRect,
POINTL* SourcePoint, POINTL* MaskPoint,
BRUSHOBJ* Brush, POINTL* BrushPoint, ROP4 Rop4)
{
UCHAR SolidColor = 0;
ULONG Left;
ULONG Length;
PUCHAR Video;
UCHAR Mask;
ULONG i, j;
ULONG RasterOp = VGA_NORMAL;
/* Punt brush blts to non-device surfaces. */
if (Dest->iType != STYPE_DEVICE)
{
return(FALSE);
}
/* Punt pattern fills. */
if ((Rop4 == PATCOPY || Rop4 == PATINVERT) &&
Brush->iSolidColor == 0xFFFFFFFF)
{
return(FALSE);
}
/* Get the brush colour. */
switch (Rop4)
{
case PATCOPY: SolidColor = Brush->iSolidColor; break;
case PATINVERT: SolidColor = Brush->iSolidColor; RasterOp = VGA_XOR; break;
case WHITENESS: SolidColor = 0xF; break;
case BLACKNESS: SolidColor = 0x0; break;
case DSTINVERT: SolidColor = 0xF; RasterOp = VGA_XOR; break;
}
/* Select write mode 3. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x03);
/* Setup set/reset register. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x00);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, (UCHAR)SolidColor);
/* Enable writes to all pixels. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF);
/* Set up data rotate. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, RasterOp);
/* Fill any pixels on the left which don't fall into a full row of eight. */
if ((DestRect->left % 8) != 0)
{
/* Disable writes to pixels outside of the destination rectangle. */
Mask = (1 << (8 - (DestRect->left % 8))) - 1;
if ((DestRect->right - DestRect->left) < (8 - (DestRect->left % 8)))
{
Mask &= ~((1 << (8 - (DestRect->right % 8))) - 1);
}
/* Write the same color to each pixel. */
Video = (PUCHAR)vidmem + DestRect->top * 80 + (DestRect->left >> 3);
for (i = DestRect->top; i < DestRect->bottom; i++, Video+=80)
{
(VOID)READ_REGISTER_UCHAR(Video);
WRITE_REGISTER_UCHAR(Video, Mask);
}
/* Have we finished. */
if ((DestRect->right - DestRect->left) < (8 - (DestRect->left % 8)))
{
/* Restore write mode 2. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
/* Set up data rotate. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
return TRUE;
}
}
/* Fill any whole rows of eight pixels. */
Left = (DestRect->left + 7) & ~0x7;
Length = (DestRect->right >> 3) - (Left >> 3);
for (i = DestRect->top; i < DestRect->bottom; i++)
{
Video = (PUCHAR)vidmem + i * 80 + (Left >> 3);
for (j = 0; j < Length; j++, Video++)
{
(VOID)READ_REGISTER_UCHAR(Video);
WRITE_REGISTER_UCHAR(Video, 0xFF);
}
}
/* Fill any pixels on the right which don't fall into a complete row. */
if ((DestRect->right % 8) != 0)
{
/* Disable writes to pixels outside the destination rectangle. */
Mask = ~((1 << (8 - (DestRect->right % 8))) - 1);
Video = (PUCHAR)vidmem + DestRect->top * 80 + (DestRect->right >> 3);
for (i = DestRect->top; i < DestRect->bottom; i++, Video+=80)
{
(VOID)READ_REGISTER_UCHAR(Video);
WRITE_REGISTER_UCHAR(Video, Mask);
}
}
/* Restore write mode 2. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
/* Set up data rotate. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
return TRUE;
}
BOOL STDCALL
VGADDI_BltSrc(SURFOBJ* Dest, SURFOBJ* Source, SURFOBJ* Mask,
XLATEOBJ* ColorTranslation, RECTL* DestRect, POINTL* SourcePoint,
POINTL* MaskOrigin, BRUSHOBJ* Brush, POINTL* BrushOrigin, ROP4 Rop4)
{
PFN_VGABlt BltOperation;
ULONG SourceType;
SourceType = Source->iType;
if (SourceType == STYPE_BITMAP && Dest->iType == STYPE_DEVICE)
{
BltOperation = DIBtoVGA;
}
else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_BITMAP)
{
BltOperation = VGAtoDIB;
}
else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_DEVICE)
{
BltOperation = VGAtoVGA;
}
else if (SourceType == STYPE_DEVBITMAP && Dest->iType == STYPE_DEVICE)
{
BltOperation = DFBtoVGA;
}
else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_DEVBITMAP)
{
BltOperation = VGAtoDFB;
}
else
{
/* Punt blts not involving a device or a device-bitmap. */
return(FALSE);
}
BltOperation(Dest, Source, ColorTranslation, DestRect, SourcePoint);
return(TRUE);
}
BOOL STDCALL
VGADDI_BltMask(SURFOBJ* Dest, SURFOBJ* Source, SURFOBJ* Mask,
XLATEOBJ* ColorTranslation, RECTL* DestRect,
POINTL* SourcePoint, POINTL* MaskPoint, BRUSHOBJ* Brush,
POINTL* BrushPoint, ROP4 Rop4)
{
LONG i, j, dx, dy, c8;
BYTE *tMask, *lMask;
dx = DestRect->right - DestRect->left;
dy = DestRect->bottom - DestRect->top;
if (ColorTranslation == NULL)
{
if (Mask != NULL)
{
tMask = Mask->pvBits;
for (j=0; j<dy; j++)
{
lMask = tMask;
c8 = 0;
for (i=0; i<dx; i++)
{
if((*lMask & maskbit[c8]) != 0)
{
vgaPutPixel(DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
}
c8++;
if(c8 == 8) { lMask++; c8=0; }
}
tMask += Mask->lDelta;
}
}
}
return TRUE;
}
BOOL STDCALL
DrvBitBlt(SURFOBJ *Dest,
SURFOBJ *Source,
SURFOBJ *Mask,
CLIPOBJ *Clip,
XLATEOBJ *ColorTranslation,
RECTL *DestRect,
POINTL *SourcePoint,
POINTL *MaskPoint,
BRUSHOBJ *Brush,
POINTL *BrushPoint,
ROP4 rop4)
{
PBLTRECTFUNC BltRectFunc;
RECTL CombinedRect;
BOOL Ret;
RECT_ENUM RectEnum;
BOOL EnumMore;
unsigned i;
POINTL Pt;
ULONG Direction;
switch (rop4)
{
case BLACKNESS:
case PATCOPY:
case WHITENESS:
case PATINVERT:
case DSTINVERT:
BltRectFunc = VGADDI_BltBrush;
break;
case SRCCOPY:
if (BMF_4BPP == Source->iBitmapFormat && BMF_4BPP == Dest->iBitmapFormat)
{
BltRectFunc = VGADDI_BltSrc;
}
else
{
return FALSE;
}
break;
case 0xAACC:
BltRectFunc = VGADDI_BltMask;
break;
default:
return FALSE;
}
switch(NULL == Clip ? DC_TRIVIAL : Clip->iDComplexity)
{
case DC_TRIVIAL:
Ret = (*BltRectFunc)(Dest, Source, Mask, ColorTranslation, DestRect,
SourcePoint, MaskPoint, Brush, BrushPoint,
rop4);
break;
case DC_RECT:
// Clip the blt to the clip rectangle
VGADDI_IntersectRect(&CombinedRect, DestRect, &(Clip->rclBounds));
Pt.x = SourcePoint->x + CombinedRect.left - DestRect->left;
Pt.y = SourcePoint->y + CombinedRect.top - DestRect->top;
Ret = (*BltRectFunc)(Dest, Source, Mask, ColorTranslation, &CombinedRect,
&Pt, MaskPoint, Brush, BrushPoint,
rop4);
break;
case DC_COMPLEX:
Ret = TRUE;
if (Dest == Source)
{
if (DestRect->top <= SourcePoint->y)
{
Direction = DestRect->left < SourcePoint->x ? CD_RIGHTDOWN : CD_LEFTDOWN;
}
else
{
Direction = DestRect->left < SourcePoint->x ? CD_RIGHTUP : CD_LEFTUP;
}
}
else
{
Direction = CD_ANY;
}
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, Direction, 0);
do
{
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
for (i = 0; i < RectEnum.c; i++)
{
VGADDI_IntersectRect(&CombinedRect, DestRect, RectEnum.arcl + i);
Pt.x = SourcePoint->x + CombinedRect.left - DestRect->left;
Pt.y = SourcePoint->y + CombinedRect.top - DestRect->top;
Ret = (*BltRectFunc)(Dest, Source, Mask, ColorTranslation, &CombinedRect,
&Pt, MaskPoint, Brush, BrushPoint, rop4) &&
Ret;
}
}
while (EnumMore);
break;
}
return Ret;
}

View file

@ -0,0 +1,22 @@
/// Define the A vector polynomial bits
// Each bit corresponds to one of the terms in the polynomial
//
// Rop(D,S,P) = a + a D + a S + a P + a DS + a DP + a SP + a DSP
// 0 d s p ds dp sp dsp
#define AVEC_NOT 0x01
#define AVEC_D 0x02
#define AVEC_S 0x04
#define AVEC_P 0x08
#define AVEC_DS 0x10
#define AVEC_DP 0x20
#define AVEC_SP 0x40
#define AVEC_DSP 0x80
#define AVEC_NEED_SOURCE (AVEC_S | AVEC_DS | AVEC_SP | AVEC_DSP)
#define AVEC_NEED_PATTERN (AVEC_P | AVEC_DP | AVEC_SP | AVEC_DSP)
#define BB_TARGET_SCREEN 0x0001
#define BB_TARGET_ONLY 0x0002
#define BB_SOURCE_COPY 0x0004
#define BB_PATTERN_COPY 0x0008

View file

@ -0,0 +1,58 @@
typedef struct _BRUSHINST
{
// We need to removed ajC0-3 when color pattern code is complete!!!
//
BYTE ajC0[8]; // Color bits for plane 0
BYTE ajC1[8]; // Color bits for plane 1
BYTE ajC2[8]; // Color bits for plane 2
BYTE ajC3[8]; // Color bits for plane 3
BYTE ajPattern[32]; // Color bits for the mask
USHORT usStyle; // Brush style
BYTE fjAccel; // Accelerator flags
BYTE jFgColor; // Current foreground color
BYTE jBkColor; // Current background color
BYTE RealWidth; //
BYTE YShiftValue; //
BYTE jOldBrushRealized; //
DWORD Width; // Width of brush
DWORD Height;
BYTE *pPattern; //Pointer to realized mono pattern
} BRUSHINST;
#define BRI_SOLID 0
#define BRI_HOLLOW 1
#define BRI_HATCHED 2
#define BRI_PATTERN 3
#define BRI_MONO_PATTERN 4
#define BRI_COLOR_PATTERN 5
// Definitions for the pcol_C3 byte of the physical color
//
// Some of these definitions have limitations as to when they
// are valid. They are as follows:
//
// C0_BIT color device, phys color, solid brushes if SOLID_COLOR
// C1_BIT color device, phys color, solid brushes if SOLID_COLOR
// C2_BIT color device, phys color, solid brushes if SOLID_COLOR
// C3_BIT color device, phys color, solid brushes if SOLID_COLOR
// MONO_BIT mono device, phys color
// ONES_OR_ZEROS color device, phys color, solid brushes if SOLID_COLOR
// GREY_SCALE color device, dithered solid and hatched brushes
// SOLID_BRUSH color device, solid brush qualifier
//
// There may be brushes where the accelerators could have been set,
// but wasn't. That's life.
#define C0_BIT 0x01 // C0 color
#define C1_BIT 0x02 // C1 color
#define C2_BIT 0x04 // C2 color
#define C3_BIT 0x08 // C3 color
#define COLOR_BITS 0x0f // All the color bits
#define MONO_BIT 0x10 // Monochrome bit
#define ONES_OR_ZEROS 0x20 // Color is really all 1's or all 0's
#define GREY_SCALE 0x40 // Indicates a real grey scale brush
#define SOLID_BRUSH 0x80 // Indicates a solid color brush
#define PTRI_INVERT 0x0001
#define PTRI_ANIMATE 0x0002

View file

@ -0,0 +1,40 @@
#include "../vgaddi.h"
#include "../vgavideo/vgavideo.h"
#define DBG
#include <debug.h>
BOOL STDCALL
DrvCopyBits(OUT SURFOBJ* DestObj,
IN SURFOBJ* SourceObj,
IN CLIPOBJ* ClipObj,
IN XLATEOBJ* XLateObj,
IN RECTL* DestRectL,
IN POINTL* SrcPointL)
{
BOOL Done = FALSE;
if (STYPE_BITMAP == DestObj->iType && BMF_4BPP == DestObj->iBitmapFormat &&
STYPE_DEVICE == SourceObj->iType)
{
/* Screen to 4 BPP DIB */
DIB_BltFromVGA(SrcPointL->x, SrcPointL->y,
DestRectL->right - DestRectL->left,
DestRectL->bottom - DestRectL->top,
DestObj->pvScan0, DestObj->lDelta);
Done = TRUE;
}
else if (STYPE_DEVICE == DestObj->iType &&
STYPE_BITMAP == SourceObj->iType && BMF_4BPP == SourceObj->iBitmapFormat)
{
/* 4 BPP DIB to Screen */
DIB_BltToVGA(DestRectL->left, DestRectL->top,
DestRectL->right - DestRectL->left,
DestRectL->bottom - DestRectL->top,
SourceObj->pvScan0, SourceObj->lDelta,
0);
Done = TRUE;
}
return Done;
}

View file

@ -0,0 +1,413 @@
/*
* ReactOS VGA driver
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: lineto.c,v 1.1 2004/01/10 14:39:20 navaraf Exp $
*/
#include "../vgaddi.h"
#include "../vgavideo/vgavideo.h"
/*
* Draw a line from top-left to bottom-right
*/
static void FASTCALL
vgaNWtoSE(CLIPOBJ* Clip, BRUSHOBJ* Brush, LONG x, LONG y, LONG deltax, LONG deltay)
{
int i;
int error;
BOOLEAN EnumMore;
PRECTL ClipRect;
RECT_ENUM RectEnum;
ULONG Pixel = Brush->iSolidColor;
LONG delta;
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
delta = max(deltax, deltay);
i = 0;
error = delta/2;
while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
{
while ((ClipRect < RectEnum.arcl + RectEnum.c /* there's still a current clip rect */
&& (ClipRect->bottom <= y /* but it's above us */
|| (ClipRect->top <= y && ClipRect->right <= x))) /* or to the left of us */
|| EnumMore) /* no current clip rect, but rects left */
{
/* Skip to the next clip rect */
if (RectEnum.arcl + RectEnum.c <= ClipRect)
{
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
}
else
{
ClipRect++;
}
}
if ( ClipRect < RectEnum.arcl + RectEnum.c ) /* If there's no current clip rect we're done */
{
if (ClipRect->left <= x && ClipRect->top <= y)
{
vgaPutPixel ( x, y, Pixel );
}
if ( deltax < deltay )
{
y++;
error += deltax;
if ( error >= deltay )
{
x++;
error -= deltay;
}
}
else
{
x++;
error += deltay;
if ( error >= deltax )
{
y++;
error -= deltax;
}
}
i++;
}
}
}
static void FASTCALL
vgaSWtoNE(CLIPOBJ* Clip, BRUSHOBJ* Brush, LONG x, LONG y, LONG deltax, LONG deltay)
{
int i;
int error;
BOOLEAN EnumMore;
PRECTL ClipRect;
RECT_ENUM RectEnum;
ULONG Pixel = Brush->iSolidColor;
LONG delta;
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTUP, 0);
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
delta = max(deltax, deltay);
i = 0;
error = delta/2;
while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
{
while ((ClipRect < RectEnum.arcl + RectEnum.c
&& (y < ClipRect->top
|| (y < ClipRect->bottom && ClipRect->right <= x)))
|| EnumMore)
{
if (RectEnum.arcl + RectEnum.c <= ClipRect)
{
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
}
else
{
ClipRect++;
}
}
if (ClipRect < RectEnum.arcl + RectEnum.c)
{
if (ClipRect->left <= x && y < ClipRect->bottom)
{
vgaPutPixel(x, y, Pixel);
}
if (deltax < deltay)
{
y--;
error = error + deltax;
if (deltay <= error)
{
x++;
error = error - deltay;
}
}
else
{
x++;
error = error + deltay;
if (deltax <= error)
{
y--;
error = error - deltax;
}
}
i++;
}
}
}
static void FASTCALL
vgaNEtoSW(CLIPOBJ* Clip, BRUSHOBJ* Brush, LONG x, LONG y, LONG deltax, LONG deltay)
{
int i;
int error;
BOOLEAN EnumMore;
PRECTL ClipRect;
RECT_ENUM RectEnum;
ULONG Pixel = Brush->iSolidColor;
LONG delta;
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_LEFTDOWN, 0);
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
delta = max(deltax, deltay);
i = 0;
error = delta/2;
while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
{
while ((ClipRect < RectEnum.arcl + RectEnum.c
&& (ClipRect->bottom <= y
|| (ClipRect->top <= y && x < ClipRect->left)))
|| EnumMore)
{
if (RectEnum.arcl + RectEnum.c <= ClipRect)
{
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
}
else
{
ClipRect++;
}
}
if (ClipRect < RectEnum.arcl + RectEnum.c)
{
if (x < ClipRect->right && ClipRect->top <= y)
{
vgaPutPixel(x, y, Pixel);
}
if (deltax < deltay)
{
y++;
error = error + deltax;
if (deltay <= error)
{
x--;
error = error - deltay;
}
}
else
{
x--;
error = error + deltay;
if (deltax <= error)
{
y++;
error = error - deltax;
}
}
i++;
}
}
}
static void FASTCALL
vgaSEtoNW(CLIPOBJ* Clip, BRUSHOBJ* Brush, LONG x, LONG y, LONG deltax, LONG deltay)
{
int i;
int error;
BOOLEAN EnumMore;
PRECTL ClipRect;
RECT_ENUM RectEnum;
ULONG Pixel = Brush->iSolidColor;
LONG delta;
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_LEFTUP, 0);
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
delta = max(deltax, deltay);
i = 0;
error = delta/2;
while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
{
while ((ClipRect < RectEnum.arcl + RectEnum.c
&& (y < ClipRect->top
|| (y < ClipRect->bottom && x < ClipRect->left)))
|| EnumMore)
{
if (RectEnum.arcl + RectEnum.c <= ClipRect)
{
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
}
else
{
ClipRect++;
}
}
if (ClipRect < RectEnum.arcl + RectEnum.c)
{
if (x < ClipRect->right && y < ClipRect->bottom)
{
vgaPutPixel(x, y, Pixel);
}
if (deltax < deltay)
{
y--;
error = error + deltax;
if (deltay <= error)
{
x--;
error = error - deltay;
}
}
else
{
x--;
error = error + deltay;
if (deltax <= error)
{
y--;
error = error - deltax;
}
}
i++;
}
}
}
/*
* FIXME: Use Mix to perform ROPs
* FIXME: Non-solid Brush
*/
BOOL STDCALL
DrvLineTo(SURFOBJ *DestObj,
CLIPOBJ *Clip,
BRUSHOBJ *Brush,
LONG x1,
LONG y1,
LONG x2,
LONG y2,
RECTL *RectBounds,
MIX mix)
{
LONG x, y, deltax, deltay, i, xchange, ychange, hx, vy;
ULONG Pixel = Brush->iSolidColor;
RECT_ENUM RectEnum;
BOOL EnumMore;
x = x1;
y = y1;
deltax = x2 - x1;
deltay = y2 - y1;
if (deltax < 0)
{
xchange = -1;
deltax = - deltax;
hx = x2+1;
//x--;
}
else
{
xchange = 1;
hx = x1;
}
if (deltay < 0)
{
ychange = -1;
deltay = - deltay;
vy = y2+1;
//y--;
}
else
{
ychange = 1;
vy = y1;
}
if (y1 == y2)
{
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
do
{
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= y1; i++)
{
if (y1 < RectEnum.arcl[i].bottom &&
RectEnum.arcl[i].left <= hx + deltax &&
hx < RectEnum.arcl[i].right)
{
vgaHLine(max(hx, RectEnum.arcl[i].left), y1,
min(hx + deltax, RectEnum.arcl[i].right)
-max(hx, RectEnum.arcl[i].left), Pixel);
}
}
}
while (EnumMore);
}
else if (x1 == x2)
{
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
do
{
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
for (i = 0; i < RectEnum.c; i++)
{
if (RectEnum.arcl[i].left <= x1 &&
x1 < RectEnum.arcl[i].right &&
RectEnum.arcl[i].top <= vy + deltay &&
vy < RectEnum.arcl[i].bottom)
{
vgaVLine(x1,
max(vy, RectEnum.arcl[i].top),
min(vy + deltay, RectEnum.arcl[i].bottom)
- max(vy, RectEnum.arcl[i].top),
Pixel);
}
}
}
while (EnumMore);
}
else
{
if (0 < xchange)
{
if (0 < ychange)
{
vgaNWtoSE(Clip, Brush, x, y, deltax, deltay);
}
else
{
vgaSWtoNE(Clip, Brush, x, y, deltax, deltay);
}
}
else
{
if (0 < ychange)
{
vgaNEtoSW(Clip, Brush, x, y, deltax, deltay);
}
else
{
vgaSEtoNW(Clip, Brush, x, y, deltax, deltay);
}
}
}
return TRUE;
}
/* EOF */

View file

@ -0,0 +1,193 @@
/*
* ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: offscreen.c,v 1.1 2004/01/10 14:39:20 navaraf Exp $
*
* PROJECT: ReactOS VGA16 display driver
* FILE: drivers/dd/vga/display/objects/offscreen.c
* PURPOSE: Manages off-screen video memory.
*/
/* INCLUDES ******************************************************************/
#include "../vgaddi.h"
#include "../vgavideo/vgavideo.h"
#include <debug.h>
/* GLOBALS *******************************************************************/
static LIST_ENTRY SavedBitsList;
/* FUNCTIONS *****************************************************************/
VOID
VGADDI_BltFromSavedScreenBits(ULONG DestX,
ULONG DestY,
PSAVED_SCREEN_BITS Src,
ULONG SizeX,
ULONG SizeY)
{
PUCHAR DestOffset;
PUCHAR SrcOffset;
ULONG i, j;
/* Select write mode 1. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 1);
SrcOffset = (PUCHAR)vidmem + Src->Offset;
for (i = 0; i < SizeY; i++)
{
DestOffset = (PUCHAR)vidmem + (i + DestY) * 80 + (DestX >> 3);
//FIXME: in the loop below we should treat the case when SizeX is not divisible by 8, i.e. partial bytes
for (j = 0; j < SizeX>>3; j++, SrcOffset++, DestOffset++)
{
(VOID)READ_REGISTER_UCHAR(SrcOffset);
WRITE_REGISTER_UCHAR(DestOffset, 0);
}
}
/* Select write mode 2. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 2);
}
VOID
VGADDI_BltToSavedScreenBits(PSAVED_SCREEN_BITS Dest,
ULONG SourceX,
ULONG SourceY,
ULONG SizeX,
ULONG SizeY)
{
PUCHAR DestOffset;
PUCHAR SrcOffset;
ULONG i, j;
/* Select write mode 1. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 1);
DestOffset = (PUCHAR)vidmem + Dest->Offset;
for (i = 0; i < SizeY; i++)
{
SrcOffset = (PUCHAR)vidmem + (SourceY + i) * 80 + (SourceX >> 3);
//FIXME: in the loop below we should treat the case when SizeX is not divisible by 8, i.e. partial bytes
for (j = 0; j < SizeX>>3; j++, SrcOffset++, DestOffset++)
{
(VOID)READ_REGISTER_UCHAR(SrcOffset);
WRITE_REGISTER_UCHAR(DestOffset, 0);
}
}
/* Select write mode 2. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 2);
}
VOID
VGADDI_FreeSavedScreenBits(PSAVED_SCREEN_BITS SavedBits)
{
SavedBits->Free = TRUE;
if (SavedBits->ListEntry.Blink != &SavedBitsList)
{
PSAVED_SCREEN_BITS Previous;
Previous = CONTAINING_RECORD(SavedBits->ListEntry.Blink,
SAVED_SCREEN_BITS, ListEntry);
if (Previous->Free)
{
Previous->Size += SavedBits->Size;
RemoveEntryList(&SavedBits->ListEntry);
EngFreeMem(SavedBits);
SavedBits = Previous;
}
}
if (SavedBits->ListEntry.Flink != &SavedBitsList)
{
PSAVED_SCREEN_BITS Next;
Next = CONTAINING_RECORD(SavedBits->ListEntry.Flink, SAVED_SCREEN_BITS,
ListEntry);
if (Next->Free)
{
SavedBits->Size += Next->Size;
RemoveEntryList(&SavedBits->ListEntry);
EngFreeMem(SavedBits);
}
}
}
PSAVED_SCREEN_BITS
VGADDI_AllocSavedScreenBits(ULONG Size)
{
PSAVED_SCREEN_BITS Current;
PLIST_ENTRY CurrentEntry;
PSAVED_SCREEN_BITS Best;
PSAVED_SCREEN_BITS New;
Best = NULL;
CurrentEntry = SavedBitsList.Flink;
while (CurrentEntry != &SavedBitsList)
{
Current = CONTAINING_RECORD(CurrentEntry, SAVED_SCREEN_BITS, ListEntry);
if (Current->Free && Current->Size >= Size &&
(Best == NULL || (Current->Size - Size) < (Best->Size - Size)))
{
Best = Current;
}
CurrentEntry = CurrentEntry->Flink;
}
if (Best == NULL)
{
return(NULL);
}
if (Best->Size == Size)
{
Best->Free = FALSE;
return(Best);
}
else
{
New = EngAllocMem(0, sizeof(SAVED_SCREEN_BITS), ALLOC_TAG);
New->Free = FALSE;
New->Offset = Best->Offset + Size;
New->Size = Size;
Best->Size -= Size;
InsertHeadList(&Best->ListEntry, &New->ListEntry);
return(New);
}
}
VOID
VGADDI_InitializeOffScreenMem(ULONG Start, ULONG Length)
{
PSAVED_SCREEN_BITS FreeBits;
InitializeListHead(&SavedBitsList);
FreeBits = EngAllocMem(0, sizeof(SAVED_SCREEN_BITS), ALLOC_TAG);
FreeBits->Free = TRUE;
FreeBits->Offset = Start;
FreeBits->Size = Length;
InsertHeadList(&SavedBitsList, &FreeBits->ListEntry);
}

View file

@ -0,0 +1,245 @@
#include "../vgaddi.h"
#include "../vgavideo/vgavideo.h"
#include "brush.h"
#include <debug.h>
BOOL VGADDIFillSolid(SURFOBJ *Surface, RECTL Dimensions, ULONG iColor)
{
int x, y, x2, y2, w, h;
ULONG offset, j, pre1;
ULONG orgpre1, orgx, midpre1, tmppre1;
ULONG ileftpix, imidpix, irightpix;
double leftpix, midpix, rightpix;
UCHAR a;
DPRINT("VGADDIFillSolid: x:%d, y:%d, w:%d, h:%d\n", x, y, w, h);
// Swap dimensions so that x, y are at topmost left
if ( Dimensions.right < Dimensions.left )
{
x = Dimensions.right;
x2 = Dimensions.left;
}
else
{
x2 = Dimensions.right;
x = Dimensions.left;
}
if ( Dimensions.bottom < Dimensions.top )
{
y = Dimensions.bottom;
y2 = Dimensions.top;
}
else
{
y2 = Dimensions.bottom;
y = Dimensions.top;
}
// Calculate the width and height
w = x2 - x;
h = y2 - y;
// Calculate the starting offset
offset = xconv[x]+y80[y];
// Make a note of original x
orgx = x;
// Calculate the left mask pixels, middle bytes and right mask pixel
ileftpix = 7 - mod8(x-1);
rightpix = mod8(x+w);
midpix = (w-leftpix-rightpix) / 8;
ileftpix = leftpix;
irightpix = rightpix;
imidpix = midpix;
pre1 = xconv[(x-1)&~7] + y80[y];
orgpre1=pre1;
// check for overlap ( very horizontally skinny rect )
if ( (ileftpix+irightpix) > w )
{
int mask = startmasks[ileftpix] & endmasks[irightpix];
WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08); // set the mask
WRITE_PORT_UCHAR((PUCHAR)GRA_D,mask);
tmppre1 = pre1;
for ( j = y; j < y+h; j++ )
{
a = READ_REGISTER_UCHAR ( vidmem+tmppre1 );
WRITE_REGISTER_UCHAR ( vidmem+tmppre1, iColor );
tmppre1 += 80;
}
return TRUE;
}
if ( ileftpix > 0 )
{
// Write left pixels
WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08); // set the mask
WRITE_PORT_UCHAR((PUCHAR)GRA_D,startmasks[ileftpix]);
tmppre1 = pre1;
for ( j = y; j < y+h; j++ )
{
a = READ_REGISTER_UCHAR(vidmem + tmppre1);
WRITE_REGISTER_UCHAR(vidmem + tmppre1, iColor);
tmppre1 += 80;
}
// Prepare new x for the middle
x = orgx + 8;
}
if ( imidpix > 0 )
{
midpre1=xconv[x] + y80[y];
// Set mask to all pixels in byte
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xff);
for ( j = y; j < y+h; j++ )
{
memset(vidmem+midpre1, iColor, imidpix); // write middle pixels, no need to read in latch because of the width
midpre1 += 80;
}
}
x = orgx + w - irightpix;
pre1 = xconv[x] + y80[y];
// Write right pixels
WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08); // set the mask bits
WRITE_PORT_UCHAR((PUCHAR)GRA_D,endmasks[irightpix]);
for ( j = y; j < y+h; j++ )
{
a = READ_REGISTER_UCHAR(vidmem + pre1);
WRITE_REGISTER_UCHAR(vidmem + pre1, iColor);
pre1 += 80;
}
return TRUE;
}
BOOL VGADDIPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
BRUSHINST *BrushInst, POINTL *BrushPoint)
{
RECT_ENUM RectEnum;
BOOL EnumMore;
DPRINT("VGADDIPaintRgn: iMode: %d, iDComplexity: %d\n Color:%d\n", ClipRegion->iMode, ClipRegion->iDComplexity, iColor);
switch(ClipRegion->iMode) {
case TC_RECTANGLES:
/* Rectangular clipping can be handled without enumeration.
Note that trivial clipping is not possible, since the clipping
region defines the area to fill */
if (ClipRegion->iDComplexity == DC_RECT)
{
DPRINT("VGADDIPaintRgn Rect:%d %d %d %d\n", ClipRegion->rclBounds.left, ClipRegion->rclBounds.top, ClipRegion->rclBounds.right, ClipRegion->rclBounds.bottom);
VGADDIFillSolid(Surface, ClipRegion->rclBounds, iColor);
} else {
/* Enumerate all the rectangles and draw them */
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 0);
do {
int i;
EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
DPRINT("EnumMore: %d, count: %d\n", EnumMore, RectEnum.c);
for( i=0; i<RectEnum.c; i++){
DPRINT("VGADDI enum Rect:%d %d %d %d\n", RectEnum.arcl[i].left, RectEnum.arcl[i].top, RectEnum.arcl[i].right, RectEnum.arcl[i].bottom);
VGADDIFillSolid(Surface, RectEnum.arcl[i], iColor);
}
} while (EnumMore);
}
return(TRUE);
default:
return(FALSE);
}
}
BOOL STDCALL
DrvPaint(IN SURFOBJ *Surface,
IN CLIPOBJ *ClipRegion,
IN BRUSHOBJ *Brush,
IN POINTL *BrushOrigin,
IN MIX Mix)
{
ULONG iSolidColor;
iSolidColor = Brush->iSolidColor; // FIXME: Realizations and the like
// If the foreground and background Mixes are the same,
// (LATER or if there's no brush mask)
// then see if we can use the solid brush accelerators
// FIXME: Put in the mix switch below
// Brush color parameter doesn't matter for these rops
return(VGADDIPaintRgn(Surface, ClipRegion, iSolidColor, Mix, NULL, BrushOrigin));
if ((Mix & 0xFF) == ((Mix >> 8) & 0xFF))
{
switch (Mix & 0xFF)
{
case 0:
break;
// FIXME: Implement all these millions of ROPs
// For now we don't support brushes -- everything is solid
case R2_MASKNOTPEN:
case R2_NOTCOPYPEN:
case R2_XORPEN:
case R2_MASKPEN:
case R2_NOTXORPEN:
case R2_MERGENOTPEN:
case R2_COPYPEN:
case R2_MERGEPEN:
case R2_NOTMERGEPEN:
case R2_MASKPENNOT:
case R2_NOTMASKPEN:
case R2_MERGEPENNOT:
// Rops that are implicit solid colors
case R2_NOT:
case R2_WHITE:
case R2_BLACK:
// FIXME: The Paint region belongs HERE
case R2_NOP:
return(TRUE);
default:
break;
}
}
/*
doBitBlt:
// If VGADDIPaint can't do it, VGADDIBitBlt can.. or it might just loop back
// here and we have a nice infinite loop
return( VGADDIBitBlt(Surface, (SURFOBJ *)NULL, (SURFOBJ *)NULL, ClipRegion,
(XLATEOBJ *)NULL, &ClipRegion->rclBounds,
NULL, (POINTL *)NULL, Brush, BrushOrigin,
NULL) ); UNIMPLEMENTED */
}

View file

@ -0,0 +1,382 @@
/*
* ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: pointer.c,v 1.1 2004/01/10 14:39:20 navaraf Exp $
*
* PROJECT: ReactOS VGA16 display driver
* FILE: drivers/dd/vga/display/objects/pointer.c
* PURPOSE: Draws the mouse pointer.
*/
/* INCLUDES ******************************************************************/
#include "../vgaddi.h"
#include "../vgavideo/vgavideo.h"
/* GLOBALS *******************************************************************/
static LONG oldx, oldy;
static PSAVED_SCREEN_BITS ImageBehindCursor = NULL;
VOID VGADDI_HideCursor(PPDEV ppdev);
VOID VGADDI_ShowCursor(PPDEV ppdev);
/* FUNCTIONS *****************************************************************/
VOID
VGADDI_BltPointerToVGA(LONG StartX, LONG StartY, ULONG SizeX,
ULONG SizeY, PUCHAR MaskBits, ULONG MaskPitch, ULONG MaskOp)
{
ULONG DestX, EndX, DestY, EndY;
UCHAR Mask;
PUCHAR Video;
PUCHAR Src;
UCHAR SrcValue;
ULONG i, j;
ULONG Left;
ULONG Length;
LONG Bits;
DestX = StartX < 0 ? 0 : StartX;
DestY = StartY < 0 ? 0 : StartY;
EndX = StartX + SizeX;
EndY = StartY + SizeY;
/* Set write mode zero. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0);
/* Select raster op. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 3);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, MaskOp);
if ((DestX % 8) != 0)
{
/* Disable writes to pixels outside of the destination rectangle. */
Mask = (1 << (8 - (DestX % 8))) - 1;
if ((EndX - DestX) < (8 - (DestX % 8)))
{
Mask &= ~((1 << (8 - (EndX % 8))) - 1);
}
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, Mask);
/* Write the mask. */
Video = (PUCHAR)vidmem + DestY * 80 + (DestX >> 3);
Src = MaskBits + (SizeY - (DestY - StartY)) * MaskPitch;
for (i = DestY; i < EndY; i++, Video += 80)
{
Src -= MaskPitch;
SrcValue = (*Src) >> (DestX % 8);
(VOID)READ_REGISTER_UCHAR(Video);
WRITE_REGISTER_UCHAR(Video, SrcValue);
}
}
/* Enable writes to all pixels. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF);
/* Have we finished. */
if ((EndX - DestX) < (8 - (DestX % 8)))
{
return;
}
/* Fill any whole rows of eight pixels. */
Left = (DestX + 7) & ~0x7;
Length = (EndX >> 3) - (Left >> 3);
Bits = StartX;
while (Bits < 0)
{
Bits += 8;
}
Bits = Bits % 8;
for (i = DestY; i < EndY; i++)
{
Video = (PUCHAR)vidmem + i * 80 + (Left >> 3);
Src = MaskBits + (EndY - i - 1) * MaskPitch + ((DestX - StartX) >> 3);
for (j = 0; j < Length; j++, Video++, Src++)
{
if (Bits != 0)
{
SrcValue = (Src[0] << (8 - Bits));
SrcValue |= (Src[1] >> Bits);
}
else
{
SrcValue = Src[0];
}
(VOID)READ_REGISTER_UCHAR(Video);
WRITE_REGISTER_UCHAR(Video, SrcValue);
}
}
/* Fill any pixels on the right which don't fall into a complete row. */
if ((EndX % 8) != 0)
{
/* Disable writes to pixels outside the destination rectangle. */
Mask = ~((1 << (8 - (EndX % 8))) - 1);
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, Mask);
Video = (PUCHAR)vidmem + DestY * 80 + (EndX >> 3);
Src = MaskBits + (SizeY - (DestY - StartY)) * MaskPitch + (SizeX >> 3) - 1;
for (i = DestY; i < EndY; i++, Video+=80)
{
Src -= MaskPitch;
SrcValue = (Src[0] << (8 - Bits));
(VOID)READ_REGISTER_UCHAR(Video);
WRITE_REGISTER_UCHAR(Video, SrcValue);
}
/* Restore the default write masks. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF);
}
/* Set write mode two. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 2);
/* Select raster op replace. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 3);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0);
}
BOOL InitPointer(PPDEV ppdev)
{
ULONG CursorWidth = 32, CursorHeight = 32;
ULONG PointerAttributesSize;
ULONG SavedMemSize;
/* Determine the size of the pointer attributes */
PointerAttributesSize = sizeof(VIDEO_POINTER_ATTRIBUTES) +
((CursorWidth * CursorHeight * 2) >> 3);
/* Allocate memory for pointer attributes */
ppdev->pPointerAttributes = EngAllocMem(0, PointerAttributesSize, ALLOC_TAG);
ppdev->pPointerAttributes->Flags = 0; /* FIXME: Do this right */
ppdev->pPointerAttributes->Width = CursorWidth;
ppdev->pPointerAttributes->Height = CursorHeight;
ppdev->pPointerAttributes->WidthInBytes = CursorWidth >> 3;
ppdev->pPointerAttributes->Enable = 0;
ppdev->pPointerAttributes->Column = 0;
ppdev->pPointerAttributes->Row = 0;
/* Allocate memory for the pixels behind the cursor */
SavedMemSize = ((((CursorWidth + 7) & ~0x7) + 16) * CursorHeight) >> 3;
ImageBehindCursor = VGADDI_AllocSavedScreenBits(SavedMemSize);
return(TRUE);
}
VOID STDCALL
DrvMovePointer(IN SURFOBJ* pso,
IN LONG x,
IN LONG y,
IN PRECTL prcl)
{
PPDEV ppdev = (PPDEV)pso->dhpdev;
if (x < 0 && 0 == (ppdev->flCursor & CURSOR_DOWN))
{
/* x < 0 and y < 0 indicates we must hide the cursor */
VGADDI_HideCursor(ppdev);
return;
}
ppdev->xyCursor.x = x;
ppdev->xyCursor.y = y;
if (0 == (ppdev->flCursor & CURSOR_DOWN))
{
VGADDI_ShowCursor(ppdev);
}
/* Give feedback on the new cursor rectangle */
/*if (prcl != NULL) ComputePointerRect(ppdev, prcl);*/
}
ULONG STDCALL
DrvSetPointerShape(SURFOBJ* pso,
SURFOBJ* psoMask,
SURFOBJ* psoColor,
XLATEOBJ* pxlo,
LONG xHot,
LONG yHot,
LONG x,
LONG y,
PRECTL prcl,
ULONG fl)
{
PPDEV ppdev = (PPDEV)pso->dhpdev;
ULONG NewWidth, NewHeight;
PUCHAR Src, Dest;
ULONG i;
/* Hide the cursor */
if (ppdev->pPointerAttributes->Enable != 0
&& 0 == (ppdev->flCursor & CURSOR_DOWN))
{
VGADDI_HideCursor(ppdev);
}
if (! psoMask)
{
ppdev->flCursor = CURSOR_DOWN;
return SPS_ACCEPT_EXCLUDE;
}
ppdev->flCursor = ppdev->flCursor & (~ CURSOR_DOWN);
NewWidth = psoMask->lDelta << 3;
NewHeight = (psoMask->cjBits / psoMask->lDelta) / 2;
/* Reallocate the space for the cursor if necessary. */
if (ppdev->pPointerAttributes->Width != NewWidth ||
ppdev->pPointerAttributes->Height != NewHeight)
{
ULONG PointerAttributesSize;
PVIDEO_POINTER_ATTRIBUTES NewPointerAttributes;
ULONG SavedMemSize;
/* Determine the size of the pointer attributes */
PointerAttributesSize = sizeof(VIDEO_POINTER_ATTRIBUTES) +
((NewWidth * NewHeight * 2) >> 3);
/* Allocate memory for pointer attributes */
NewPointerAttributes = EngAllocMem(0, PointerAttributesSize, ALLOC_TAG);
*NewPointerAttributes = *ppdev->pPointerAttributes;
NewPointerAttributes->Width = NewWidth;
NewPointerAttributes->Height = NewHeight;
NewPointerAttributes->WidthInBytes = NewWidth >> 3;
EngFreeMem(ppdev->pPointerAttributes);
ppdev->pPointerAttributes = NewPointerAttributes;
/* Reallocate the space for the saved bits. */
VGADDI_FreeSavedScreenBits(ImageBehindCursor);
SavedMemSize = ((((NewWidth + 7) & ~0x7) + 16) * NewHeight) >> 3;
ImageBehindCursor = VGADDI_AllocSavedScreenBits(SavedMemSize);
}
/* Copy the new cursor in. */
for (i = 0; i < (NewHeight * 2); i++)
{
Src = (PUCHAR)psoMask->pvBits;
Src += (i * (NewWidth >> 3));
Dest = (PUCHAR)ppdev->pPointerAttributes->Pixels;
if (i >= NewHeight)
{
Dest += (((NewHeight * 3) - i - 1) * (NewWidth >> 3));
}
else
{
Dest += ((NewHeight - i - 1) * (NewWidth >> 3));
}
memcpy(Dest, Src, NewWidth >> 3);
}
/* Set the new cursor position */
ppdev->xyCursor.x = x;
ppdev->xyCursor.y = y;
ppdev->xyHotSpot.x = xHot;
ppdev->xyHotSpot.y = yHot;
/* Show the cursor */
VGADDI_ShowCursor(ppdev);
return SPS_ACCEPT_EXCLUDE;
}
VOID
VGADDI_HideCursor(PPDEV ppdev)
{
ULONG SizeX, SizeY;
/* Display what was behind cursor */
SizeX = min(((oldx + ppdev->pPointerAttributes->Width) + 7) & ~0x7, ppdev->sizeSurf.cx);
SizeX -= (oldx & ~0x7);
SizeY = min(ppdev->pPointerAttributes->Height, ppdev->sizeSurf.cy - oldy);
VGADDI_BltFromSavedScreenBits(max(oldx, 0) & ~0x7,
max(oldy, 0),
ImageBehindCursor,
SizeX,
SizeY);
ppdev->pPointerAttributes->Enable = 0;
}
VOID
VGADDI_ShowCursor(PPDEV ppdev)
{
LONG cx, cy;
PUCHAR AndMask, XorMask;
ULONG SizeX, SizeY;
if (ppdev->pPointerAttributes->Enable != 0)
{
VGADDI_HideCursor(ppdev);
}
/* Capture pixels behind the cursor */
cx = ppdev->xyCursor.x - ppdev->xyHotSpot.x;
cy = ppdev->xyCursor.y - ppdev->xyHotSpot.y;
/* Used to repaint background */
SizeX = min(((cx + ppdev->pPointerAttributes->Width) + 7) & ~0x7, ppdev->sizeSurf.cx);
SizeX -= (cx & ~0x7);
SizeY = min(ppdev->pPointerAttributes->Height, ppdev->sizeSurf.cy - cy);
VGADDI_BltToSavedScreenBits(ImageBehindCursor,
max(cx, 0) & ~0x7,
max(cy, 0),
SizeX,
SizeY);
/* Display the cursor. */
SizeX = min(ppdev->pPointerAttributes->Width, ppdev->sizeSurf.cx - cx);
SizeY = min(ppdev->pPointerAttributes->Height, ppdev->sizeSurf.cy - cy);
AndMask = ppdev->pPointerAttributes->Pixels +
(ppdev->pPointerAttributes->Height - SizeY) * ppdev->pPointerAttributes->WidthInBytes;
VGADDI_BltPointerToVGA(cx,
cy,
SizeX,
SizeY,
AndMask,
ppdev->pPointerAttributes->WidthInBytes,
VGA_AND);
XorMask = AndMask +
ppdev->pPointerAttributes->WidthInBytes *
ppdev->pPointerAttributes->Height;
VGADDI_BltPointerToVGA(cx,
cy,
SizeX,
SizeY,
XorMask,
ppdev->pPointerAttributes->WidthInBytes,
VGA_XOR);
/* Save the new cursor location. */
oldx = cx;
oldy = cy;
/* Mark the cursor as currently displayed. */
ppdev->pPointerAttributes->Enable = 1;
}

View file

@ -0,0 +1,168 @@
#include "../vgaddi.h"
static WORD PaletteBuffer[] = {
16, 0, // 16 entries, start with 0
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
};
static BYTE ColorBuffer[] = {
16, // 16 entries
0, 0,
0, // start with 0
0x00, 0x00, 0x00, 0x00, // black
0x2A, 0x00, 0x15, 0x00, // red
0x00, 0x2A, 0x15, 0x00, // green
0x2A, 0x2A, 0x15, 0x00, // brown
0x00, 0x00, 0x2A, 0x00, // blue
0x2A, 0x15, 0x2A, 0x00, // magenta
0x15, 0x2A, 0x2A, 0x00, // cyan
0x21, 0x22, 0x23, 0x00, // dark gray
0x30, 0x31, 0x32, 0x00, // light gray
0x3F, 0x00, 0x00, 0x00, // bright red
0x00, 0x3F, 0x00, 0x00, // bright green
0x3F, 0x3F, 0x00, 0x00, // bright yellow
0x00, 0x00, 0x3F, 0x00, // bright blue
0x3F, 0x00, 0x3F, 0x00, // bright magenta
0x00, 0x3F, 0x3F, 0x00, // bright cyan
0x3F, 0x3F, 0x3F, 0x00 // bright white
};
DWORD getAvailableModes(HANDLE Driver,
PVIDEO_MODE_INFORMATION *modeInformation,
DWORD *ModeSize)
{
ULONG Temp;
VIDEO_NUM_MODES modes;
PVIDEO_MODE_INFORMATION VideoTemp;
// get number of modes supported
if (EngDeviceIoControl(Driver,
IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,
NULL,
0,
&modes,
sizeof(VIDEO_NUM_MODES),
&Temp))
{
// get modes failed
return(0);
}
*ModeSize = modes.ModeInformationLength;
// allocate buffer for the mini-port to write the modes in
*modeInformation = (PVIDEO_MODE_INFORMATION)
EngAllocMem(0, modes.NumModes *
modes.ModeInformationLength, ALLOC_TAG);
if (*modeInformation == (PVIDEO_MODE_INFORMATION) NULL)
{
// couldn't allocate buffer
return 0;
}
// Ask the mini-port to fill in the available modes.
if (EngDeviceIoControl(Driver,
IOCTL_VIDEO_QUERY_AVAIL_MODES,
NULL,
0,
*modeInformation,
modes.NumModes * modes.ModeInformationLength,
&Temp))
{
// failed to query modes
EngFreeMem(*modeInformation);
*modeInformation = (PVIDEO_MODE_INFORMATION) NULL;
return(0);
}
// Which modes supported by miniport driver are also suppoted by us, the
// display driver
Temp = modes.NumModes;
VideoTemp = *modeInformation;
// Reject mode if it's not 4 planes or not graphic or not 1 bits per pel
while (Temp--)
{
if ((VideoTemp->NumberOfPlanes != 4 ) ||
!(VideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) ||
(VideoTemp->BitsPerPlane != 1) ||
BROKEN_RASTERS(VideoTemp->ScreenStride, VideoTemp->VisScreenHeight))
{
VideoTemp->Length = 0;
}
VideoTemp = (PVIDEO_MODE_INFORMATION)(((PUCHAR)VideoTemp) + modes.ModeInformationLength);
}
return modes.NumModes;
}
BOOL InitVGA(PPDEV ppdev, BOOL bFirst)
{
ULONG ReturnedDataLength;
ppdev->sizeSurf.cx = 640;
ppdev->sizeSurf.cy = 480;
ppdev->ModeNum = 12;
// Set the mode that was requested
if (EngDeviceIoControl(ppdev->KMDriver,
IOCTL_VIDEO_SET_CURRENT_MODE,
&ppdev->ModeNum,
sizeof(VIDEO_MODE),
NULL,
0,
&ReturnedDataLength)) {
return(FALSE);
}
// set up internal palette
if (EngDeviceIoControl(ppdev->KMDriver,
IOCTL_VIDEO_SET_PALETTE_REGISTERS,
(PVOID) PaletteBuffer,
sizeof (PaletteBuffer),
NULL,
0,
&ReturnedDataLength)) {
return(FALSE);
}
// set up the DAC
if (EngDeviceIoControl(ppdev->KMDriver,
IOCTL_VIDEO_SET_COLOR_REGISTERS,
(PVOID) ColorBuffer,
sizeof (ColorBuffer),
NULL,
0,
&ReturnedDataLength)) {
return(FALSE);
}
/*
gotta fix this up.. it prevents drawing to vidmem right now
if (bFirst) {
// map video memory into virtual memory
VideoMemory.RequestedVirtualAddress = NULL;
if (EngDeviceIoControl(ppdev->KMDriver,
IOCTL_VIDEO_MAP_VIDEO_MEMORY,
(PVOID) &VideoMemory,
sizeof (VIDEO_MEMORY),
(PVOID) &VideoMemoryInfo,
sizeof (VideoMemoryInfo),
&ReturnedDataLength)) {
// Failed to map to virtual memory
return (FALSE);
}
ppdev->fbScreen = VideoMemoryInfo.FrameBufferBase;
}
*/
return TRUE;
}

View file

@ -0,0 +1,34 @@
#include <ntddk.h>
#define NDEBUG
#include <debug.h>
#include "../vgaddi.h"
#include "../vgavideo/vgavideo.h"
#include "brush.h"
#include "bitblt.h"
BOOL STDCALL
DrvTransparentBlt(SURFOBJ* Dest,
SURFOBJ* Source,
CLIPOBJ* Clip,
XLATEOBJ* ColorTranslation,
RECTL* DestRect,
RECTL* SourceRect,
ULONG TransparentColor,
ULONG Reserved)
{
LONG dx, dy, sx, sy;
dx = abs(DestRect->right - DestRect->left);
dy = abs(DestRect->bottom - DestRect->top);
sx = abs(SourceRect->right - SourceRect->left);
sy = abs(SourceRect->bottom - SourceRect->top);
if(sx<dx) dx = sx;
if(sy<dy) dy = sy;
// FIXME: adjust using SourceRect
DIB_TransparentBltToVGA(DestRect->left, DestRect->top, dx, dy, Source->pvBits, Source->lDelta, TransparentColor);
return TRUE;
}

View file

@ -0,0 +1,11 @@
; $Id: vgaddi.def,v 1.1 2004/01/10 14:39:20 navaraf Exp $
;
; vgaddi.def
;
; ReactOS Operating System
;
; From Anders Norlander's w32api-0.1.5 vgaddi.def.
;
LIBRARY vgaddi.dll
EXPORTS
DrvEnableDriver@12

View file

@ -0,0 +1,11 @@
; $Id: vgaddi.edf,v 1.1 2004/01/10 14:39:20 navaraf Exp $
;
; vgaddi.def
;
; ReactOS Operating System
;
; From Anders Norlander's w32api-0.1.5 vgaddi.def.
;
LIBRARY vgaddi.dll
EXPORTS
DrvEnableDriver=DrvEnableDriver@12

View file

@ -0,0 +1,246 @@
#include <ddk/ntddk.h>
#include <ddk/winddi.h>
#include <ddk/ntddvid.h>
#define DS_SOLIDBRUSH 0x00000001
#define DS_GREYBRUSH 0x00000002
#define DS_BRUSH 0x00000004
#define DS_DIB 0x00000008
#define POW2(stride) (!((stride) & ((stride)-1))) // TRUE if stride is power of 2
#define BROKEN_RASTERS(stride,cy) ((!(POW2(stride))) && ((stride*cy) > 0x10000))
#define ENUM_RECT_LIMIT 50
typedef struct _RECT_ENUM
{
ULONG c;
RECTL arcl[ENUM_RECT_LIMIT];
} RECT_ENUM;
// Cursor coordinates
typedef struct _XYPAIR
{
USHORT x;
USHORT y;
} XYPAIR;
// Cursor states
#define CURSOR_DOWN 0x00000001
#define CURSOR_COLOR 0x00000004
#define CURSOR_HW 0x00000010
#define CURSOR_HW_ACTIVE 0x00000020
#define CURSOR_ANIMATE 0x00000040
typedef struct _PDEV
{
ULONG fl; // driver flags
// Handles
HANDLE KMDriver;
HDEV GDIDevHandle; // engine's handle to PDEV
HSURF SurfHandle; // engine's handle to surface
PVOID AssociatedSurf; // associated surface
// Cursor
XYPAIR xyCursor; // cursor position
XYPAIR xyHotSpot; // cursor hotspot
POINTL ptlExtent; // cursor extent
ULONG cExtent; // effective cursor extent
ULONG flCursor; // cursor status
// Pointer
PVIDEO_POINTER_ATTRIBUTES pPointerAttributes; // HW Pointer Attributes
ULONG XorMaskStartOffset; // Start offset of hardware pointer
// XOR mask relative to AND mask for
// passing to HW pointer
DWORD PointerAttributes; // Size of buffer allocated
DWORD flPreallocSSBBufferInUse; // True if preallocated saved screen
// bits buffer is in use
PUCHAR pjPreallocSSBBuffer; // Pointer to preallocated saved screen
// bits buffer, if there is one
ULONG ulPreallocSSBSize; // Size of preallocated saved screen
// bits buffer
VIDEO_POINTER_CAPABILITIES PointerCapabilities; // HW pointer abilities
PUCHAR pucDIB4ToVGAConvBuffer; // DIB4->VGA conversion table buffer
PUCHAR pucDIB4ToVGAConvTables; // Pointer to DIB4->VGA conversion
// Misc
ULONG ModeNum; // mode index for current VGA mode
SIZEL sizeSurf; // displayed size of the surface
PBYTE fbScreen; // pointer to the frame buffer
RECTL SavedBitsRight; // invisible part right of screen
RECTL SavedBitsBottom; // invisible part at the bottom of the screen
BOOL BitsSaved; // TRUE if bits are currently saved
SIZEL sizeMem; // actual size (in pixels) of video memory
LONG NumScansUsedByPointer; // # scans of offscreen memory used by
} PDEV, *PPDEV;
typedef struct {
RECTL BankBounds; // Pixels addressable in this bank
ULONG BankOffset; // Offset of bank start from bitmap start if linearly addressable
} BANK_INFO, *PBANK_INFO;
typedef enum {
JustifyTop = 0,
JustifyBottom,
} BANK_JUST;
// bank control function vector
//typedef VOID (*PFN_BankControl)(PDEVSURF, ULONG, BANK_JUST);
typedef VOID (*PFN_BankControl)(PVOID, ULONG, BANK_JUST);
#if 0
// descriptor for a saved screen bits block
typedef struct _SAVED_SCREEN_BITS
{
BOOL bFlags;
PBYTE pjBuffer; // pointer to save buffer start
ULONG ulSize; // size of save buffer (per plane; display memory only)
ULONG ulSaveWidthInBytes; // # of bytes across save area (including
// partial edge bytes, if any)
ULONG ulDelta; // # of bytes from end of one saved scan's saved bits to
// start of next (system memory only)
PVOID pvNextSSB; // pointer to next saved screen bits block
// for system memory blocks, saved bits start immediately
// after this structure
} SAVED_SCREEN_BITS, *PSAVED_SCREEN_BITS;
#else
typedef struct _SAVED_SCREEN_BITS
{
BOOL Free;
DWORD Offset;
ULONG Size;
LIST_ENTRY ListEntry;
} SAVED_SCREEN_BITS, *PSAVED_SCREEN_BITS;
#endif
// DEVSURF -- definition of a surface as seen and used by the various VGA
// drivers
typedef struct _DEVSURF
{
IDENT ident; // Identifier for debugging ease
ULONG flSurf; // DS_ flags as defined below
BYTE Color; // Solid color surface if DS_SOLIDBRUSH
// If DS_SOLIDBRUSH, the following fields are undefined and not guaranteed to
// have been allocated!
BYTE Format; // BMF_*, BMF_PHYSDEVICE
BYTE jReserved1; // Reserved
BYTE jReserved2; // Reserved
PPDEV ppdev; // Pointer to associated PDEV
SIZEL sizeSurf; // Size of the surface
ULONG NextScan; // Offset from scan "n" to "n+1"
ULONG NextPlane; // Offset from plane "n" to "n+1"
PVOID Scan0; // Pointer to scan 0 of bitmap
// (actual address of start of bank, for banked VGA surface)
PVOID StartBmp; // Pointer to start of bitmap
PVOID Conv; // Pointer to DIB/Planer conversion buffer
// Banking variables; used only for banked VGA surfaces
PVIDEO_BANK_SELECT BankSelectInfo;
ULONG Bank2RWSkip; // Offset from one bank index to next to make two 32K banks appear to be
// one seamless 64K bank
PFN pfnBankSwitchCode;
VIDEO_BANK_TYPE BankingType;
ULONG BitmapSize; // Length of bitmap if there were no banking, in CPU addressable bytes
ULONG PtrBankScan; // Last scan line in pointer work bank
RECTL WindowClip1; // Single-window banking clip rect
RECTL WindowClip2[2]; // Double-window banking clip rects for
// windows 0 & 1
ULONG WindowBank[2]; // Current banks mapped into windows
// 0 & 1 (used in 2 window mode only)
PBANK_INFO BankInfo; // Pointer to array of bank clip info
ULONG BankInfoLength; // Length of pbiBankInfo, in entries
PBANK_INFO BankInfo2RW; // Same as above, but for 2RW window
ULONG BankInfo2RWLength; // case
PFN_BankControl pfnBankControl; // Pointer to bank control function
PFN_BankControl pfnBankControl2Window; // Pointer to double-window bank
// control function
PVOID BitmapStart; // Single-window bitmap start pointer (adjusted as
// necessary to make window map in at proper offset)
PVOID BitmapStart2Window[2]; // Double-window window 0 and 1 bitmap start
PVOID BankBufferPlane0; // Pointer to temp buffer capable of
// storing one full bank for plane 0 for 1
// R/W case; capable of storing one full
// bank height of edge bytes for all four
// planes for the 1R/1W case. Also used to
// point to text building buffer in all
// cases. This is the pointer used to
// dealloc bank working storage for all
// four planes
// The following 3 pointers used by 1 R/W banked devices
PVOID BankBufferPlane1; // Like above, but for plane 1
PVOID BankBufferPlane2; // Like above, but for plane 2
PVOID BankBufferPlane3; // Like above, but for plane 3
ULONG TempBufferSize; // Full size of temp buffer pointed to
// by pvBankBufferPlane0
ULONG ajBits[1]; // Bits will start here for device bitmaps
PSAVED_SCREEN_BITS ssbList; // Pointer to start of linked list of
// saved screen bit blocks
} DEVSURF, *PDEVSURF;
typedef VOID (*PFN_ScreenToScreenBlt)(PDEVSURF, PRECTL, PPOINTL, INT);
// BMF_PHYSDEVICE format type
#define BMF_PHYSDEVICE 0xFF
#define BMF_DFB 0xFE
// Identifiers used in debugging (DEVSURF.ident)
#define PDEV_IDENT ('V' + ('P' << 8) + ('D' << 16) + ('V' << 24))
#define DEVSURF_IDENT ('V' + ('S' << 8) + ('R' << 16) + ('F' << 24))
BOOL InitVGA(PPDEV ppdev, BOOL bFirst); // screen.c: initialize VGA mode
#define DRIVER_EXTRA_SIZE 0
#define ALLOC_TAG TAG('D', 'v', 'g', 'a') // Dvga tag
#define DLL_NAME L"vga" // DLL name in Unicode
#define MAX_SCAN_WIDTH 2048 // pixels
#define DRIVER_OFFSCREEN_REFRESHED 0x04L // if not set, don't use offscreen memory
#define PLANAR_PELS_PER_CPU_ADDRESS 8
#define PACKED_PELS_PER_CPU_ADDRESS 2
BOOL VGAtoGDI(
SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint);
VOID
VGADDI_BltFromSavedScreenBits(ULONG DestX,
ULONG DestY,
PSAVED_SCREEN_BITS Src,
ULONG SizeX,
ULONG SizeY);
VOID
VGADDI_BltToSavedScreenBits(PSAVED_SCREEN_BITS Dest,
ULONG SourceX,
ULONG SourceY,
ULONG SizeX,
ULONG SizeY);
VOID
VGADDI_FreeSavedScreenBits(PSAVED_SCREEN_BITS SavedBits);
PSAVED_SCREEN_BITS
VGADDI_AllocSavedScreenBits(ULONG Size);
VOID
VGADDI_InitializeOffScreenMem(ULONG Start, ULONG Length);
BOOL InitPointer(PPDEV ppdev);
DWORD getAvailableModes(HANDLE Driver,
PVIDEO_MODE_INFORMATION *modeInformation,
DWORD *ModeSize);
void FASTCALL
vgaReadScan ( int x, int y, int w, void *b );
void FASTCALL
vgaWriteScan ( int x, int y, int w, void *b );

View file

@ -0,0 +1,38 @@
#include <defines.h>
#include <reactos/resource.h>
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", RES_STR_COMPANY_NAME
VALUE "FileDescription", "VGA Display Driver\0"
VALUE "FileVersion", RES_STR_FILE_VERSION
VALUE "InternalName", "vgaddi\0"
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
VALUE "OriginalFilename", "vgaddi.dll\0"
VALUE "ProductName", RES_STR_PRODUCT_NAME
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View file

@ -0,0 +1,3 @@
*.o
*.map
.*.d

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,75 @@
// FIXME: Make these variables so we can also use modes like 800x600
#define SCREEN_X 640
#define SCREEN_Y 480
#define SCREEN_STRIDE 80
#define VGA_NORMAL 0
#define VGA_AND 8
#define VGA_OR 16
#define VGA_XOR 24
//This is in mingw standard headers
//typedef struct { int quot, rem; } div_t;
extern int maskbit[640];
extern int y80[480];
extern int xconv[640];
extern int bit8[640];
extern int startmasks[8];
extern int endmasks[8];
extern UCHAR PreCalcReverseByte[256];
extern char* vidmem;
#define MISC 0x3c2
#define SEQ 0x3c4
#define CRTC 0x3d4
#define GRAPHICS 0x3ce
#define FEATURE 0x3da
#define ATTRIB 0x3c0
#define STATUS 0x3da
typedef struct _VideoMode {
unsigned short VidSeg;
unsigned char Misc;
unsigned char Feature;
unsigned char Seq[5];
unsigned char Crtc[25];
unsigned char Gfx[9];
unsigned char Attrib[21];
} VideoMode;
VOID vgaPreCalc();
VOID vgaPutPixel(INT x, INT y, UCHAR c);
VOID vgaPutByte(INT x, INT y, UCHAR c);
VOID vgaGetByte(ULONG offset,
UCHAR *b, UCHAR *g,
UCHAR *r, UCHAR *i);
INT vgaGetPixel(INT x, INT y);
BOOL vgaHLine(INT x, INT y, INT len, UCHAR c);
BOOL vgaVLine(INT x, INT y, INT len, UCHAR c);
INT abs(INT nm);
BOOL VGADDIIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2);
#define SEQ_I 0x3C4 /* Sequencer Index */
#define SEQ_D 0x3C5 /* Sequencer Data Register */
#define GRA_I 0x3CE /* Graphics Controller Index */
#define GRA_D 0x3CF /* Graphics Controller Data Register */
#define LowByte(w) (*((unsigned char *)&(w) + 0))
#define HighByte(w) (*((unsigned char *)&(w) + 1))
#define ASSIGNVP4(x, y, vp) vp = vidmem /* VBUF */ + (((x) + (y)*SCREEN_X) >> 3);
#define ASSIGNMK4(x, y, mask) mask = 0x80 >> ((x) & 7);
void get_masks(int x, int w);
#define mod8(n) ((n)&7)
#define mod2(n) ((n)&1)
void DIB_BltFromVGA(int x, int y, int w, int h, void *b, int Dest_lDelta);
void DIB_BltToVGA(int x, int y, int w, int h, void *b, int Source_lDelta, int StartMod);
void DIB_BltToVGAWithXlate(int x, int y, int w, int h, void *b, int Source_lDelta, XLATEOBJ* Xlate);
void DIB_TransparentBltToVGA(int x, int y, int w, int h, void *b, int Source_lDelta, ULONG trans);

View file

@ -0,0 +1,57 @@
DISPLAY_DRIVERS = vga
MINIPORT_DRIVERS = vga vbe
all: $(DISPLAY_DRIVERS:%=DD%) $(MINIPORT_DRIVERS:%=MP%)
implib: $(DISPLAY_DRIVERS:%=DD%_implib) $(MINIPORT_DRIVERS:%=MP%_implib)
clean: $(DISPLAY_DRIVERS:%=DD%_clean) $(MINIPORT_DRIVERS:%=MP%_clean)
install: $(DISPLAY_DRIVERS:%=DD%_install) $(MINIPORT_DRIVERS:%=MP%_install)
bootcd: $(DISPLAY_DRIVERS:%=DD%_bootcd) $(MINIPORT_DRIVERS:%=MP%_bootcd)
#
# Video display driver rules
#
$(DISPLAY_DRIVERS:%=DD%): DD%:
$(MAKE) -C displays/$*
$(DISPLAY_DRIVERS:%=DD%_implib): DD%_implib:
$(MAKE) -C displays/$* implib
$(DISPLAY_DRIVERS:%=DD%_clean): DD%_clean:
$(MAKE) -C displays/$* clean
$(DISPLAY_DRIVERS:%=DD%_install): DD%_install:
$(MAKE) -C displays/$* install
$(DISPLAY_DRIVERS:%=DD%_bootcd): DD%_bootcd:
$(MAKE) -C displays/$* bootcd
.PHONY: $(DISPLAY_DRIVERS:%=DD%) $(DISPLAY_DRIVERS:%=DD%_implib) $(DISPLAY_DRIVERS:%=DD%_clean)\
$(DISPLAY_DRIVERS:%=DD%_install) $(DISPLAY_DRIVERS:%=DD%_bootcd)
#
# Video miniport driver rules
#
$(MINIPORT_DRIVERS:%=MP%): MP%:
$(MAKE) -C miniport/$*
$(MINIPORT_DRIVERS:%=MP%_implib): MP%_implib:
$(MAKE) -C miniport/$* implib
$(MINIPORT_DRIVERS:%=MP%_clean): MP%_clean:
$(MAKE) -C miniport/$* clean
$(MINIPORT_DRIVERS:%=MP%_install): MP%_install:
$(MAKE) -C miniport/$* install
$(MINIPORT_DRIVERS:%=MP%_bootcd): MP%_bootcd:
$(MAKE) -C miniport/$* bootcd
.PHONY: $(MINIPORT_DRIVERS:%=MP%) $(MINIPORT_DRIVERS:%=MP%_implib) $(MINIPORT_DRIVERS:%=MP%_clean)\
$(MINIPORT_DRIVERS:%=MP%_install) $(MINIPORT_DRIVERS:%=MP%_bootcd)

View file

@ -0,0 +1,8 @@
junk.tmp
base.tmp
temp.exp
vbemp.coff
*.o
*.sym
*.sys
*.map

View file

@ -0,0 +1,16 @@
PATH_TO_TOP = ../../../..
TARGET_TYPE = driver
TARGET_NAME = vbemp
TARGET_DDKLIBS = videoprt.a ntoskrnl.a
TARGET_CFLAGS = -Werror -Wall -I$(PATH_TO_TOP)/ntoskrnl/include -D__USE_W32API
TARGET_OBJECTS = \
vbemp.o
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk

View file

@ -0,0 +1,699 @@
/*
* ReactOS VBE miniport video driver
*
* Copyright (C) 2004 Filip Navara
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* FIXMEs:
* - Check input parameters everywhere.
* - Add some comments.
* - Implement support power management.
*/
#include "vbemp.h"
/******************************************************************************/
PVOID FASTCALL
MapPM(ULONG Address, ULONG Size)
{
LARGE_INTEGER Offset;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING PhysMemName;
HANDLE PhysMemHandle;
NTSTATUS Status;
PVOID BaseAddress;
ULONG ViewSize;
/*
* Open the physical memory section
*/
RtlInitUnicodeString(&PhysMemName, L"\\Device\\PhysicalMemory");
InitializeObjectAttributes(&ObjectAttributes,
&PhysMemName,
0,
NULL,
NULL);
Status = ZwOpenSection(&PhysMemHandle, SECTION_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT(("VBEMP: Couldn't open \\Device\\PhysicalMemory\n"));
return NULL;
}
/*
* Map the BIOS and device registers into the address space
*/
Offset.QuadPart = Address;
ViewSize = Size;
BaseAddress = (PVOID)Address;
Status = NtMapViewOfSection(PhysMemHandle,
NtCurrentProcess(),
&BaseAddress,
0,
8192,
&Offset,
&ViewSize,
ViewUnmap,
0,
PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT(("VBEMP: Couldn't map physical memory (%x)\n", Status));
NtClose(PhysMemHandle);
return NULL;
}
NtClose(PhysMemHandle);
if (BaseAddress != (PVOID)Address)
{
DPRINT(("VBEMP: Couldn't map physical memory at the right address "
"(was %x)(%x)\n", BaseAddress, Address));
return NULL;
}
return BaseAddress;
}
ULONG FASTCALL
InitializeVideoAddressSpace(VOID)
{
NTSTATUS Status;
PVOID BaseAddress;
PVOID NullAddress;
ULONG ViewSize;
CHAR IVT[1024];
CHAR BDA[256];
if (MapPM(0xa0000, 0x30000) == NULL)
{
return FALSE;
}
/*
* Map some memory to use for the non-BIOS parts of the v86 mode address
* space
*/
BaseAddress = (PVOID)0x1;
ViewSize = 0x20000;
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
&BaseAddress,
0,
&ViewSize,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT(("VBEMP: Failed to allocate virtual memory (Status %x)\n", Status));
return 0;
}
if (BaseAddress != (PVOID)0x0)
{
DPRINT(("VBEMP: Failed to allocate virtual memory at right address "
"(was %x)\n", BaseAddress));
return 0;
}
/*
* Get the real mode IVT from the kernel
*/
Status = NtVdmControl(0, IVT);
if (!NT_SUCCESS(Status))
{
DPRINT(("VBEMP: NtVdmControl failed (status %x)\n", Status));
return 0;
}
/*
* Copy the real mode IVT into the right place
*/
NullAddress = (PVOID)0x0; /* Workaround for GCC 3.4 */
memcpy(NullAddress, IVT, 1024);
/*
* Get the BDA from the kernel
*/
Status = NtVdmControl(1, BDA);
if (!NT_SUCCESS(Status))
{
DPRINT(("VBEMP: NtVdmControl failed (status %x)\n", Status));
return 0;
}
/*
* Copy the BDA into the right place
*/
memcpy((PVOID)0x400, BDA, 256);
return 1;
}
VP_STATUS STDCALL
DriverEntry(IN PVOID Context1, IN PVOID Context2)
{
VIDEO_HW_INITIALIZATION_DATA InitData;
VideoPortZeroMemory(&InitData, sizeof(InitData));
InitData.HwFindAdapter = VBEFindAdapter;
InitData.HwInitialize = VBEInitialize;
InitData.HwStartIO = VBEStartIO;
InitData.HwDeviceExtensionSize = sizeof(VBE_DEVICE_EXTENSION);
return VideoPortInitialize(Context1, Context2, &InitData, NULL);
}
VP_STATUS STDCALL
VBEFindAdapter(IN PVOID HwDeviceExtension, IN PVOID HwContext,
IN PWSTR ArgumentString, IN OUT PVIDEO_PORT_CONFIG_INFO ConfigInfo,
OUT PUCHAR Again)
{
KV86M_REGISTERS BiosRegisters;
DWORD ViewSize;
NTSTATUS Status;
PVBE_INFO VbeInfo;
PVBE_DEVICE_EXTENSION VBEDeviceExtension =
(PVBE_DEVICE_EXTENSION)HwDeviceExtension;
/*
* We support only one adapter.
*/
*Again = FALSE;
/*
* Map the BIOS parts of memory into our memory space and intitalize
* the real mode interrupt table.
*/
InitializeVideoAddressSpace();
/*
* Allocate a bit of memory that will be later used for VBE transport
* buffer. This memory must be accessible from V86 mode so it must fit
* in the first megabyte of physical memory.
*/
VBEDeviceExtension->TrampolineMemory = (PVOID)0x20000;
ViewSize = 0x400;
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
(PVOID*)&VBEDeviceExtension->TrampolineMemory, 0, &ViewSize, MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT(("Failed to allocate virtual memory (Status %x)\n", Status));
return 0;
}
if (VBEDeviceExtension->TrampolineMemory > (PVOID)(0x100000 - 0x400))
{
DPRINT(("Failed to allocate virtual memory at right address "
"(was %x)\n", VBEDeviceExtension->TrampolineMemory));
return 0;
}
VBEDeviceExtension->PhysicalAddress.QuadPart =
(UINT_PTR)VBEDeviceExtension->TrampolineMemory;
/*
* Get the VBE general information.
*/
VbeInfo = (PVBE_INFO)VBEDeviceExtension->TrampolineMemory;
strncpy(VbeInfo->Signature, "VBE2", 4);
memset(&BiosRegisters, 0, sizeof(BiosRegisters));
BiosRegisters.Eax = 0x4F00;
BiosRegisters.Edi = VBEDeviceExtension->PhysicalAddress.QuadPart & 0xFF;
BiosRegisters.Es = VBEDeviceExtension->PhysicalAddress.QuadPart >> 4;
Ke386CallBios(0x10, &BiosRegisters);
if (BiosRegisters.Eax == 0x4F)
{
if (VbeInfo->Version >= 0x200)
{
DPRINT(("VBE BIOS Present (%d.%d, %8ld Kb)\n",
VbeInfo->Version / 0x100, VbeInfo->Version & 0xFF,
VbeInfo->TotalMemory * 16));
return NO_ERROR;
}
else
{
DPRINT(("VBE BIOS present, but incompatible version.\n"));
return ERROR_DEV_NOT_EXIST;
}
}
else
{
DPRINT(("No VBE BIOS found.\n"));
return ERROR_DEV_NOT_EXIST;
}
}
BOOLEAN STDCALL
VBEInitialize(PVOID HwDeviceExtension)
{
/*
* Build a mode list here that can be later used by
* IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES and IOCTL_VIDEO_QUERY_AVAIL_MODES
* calls.
*/
ULONG ModeCount;
ULONG CurrentMode;
KV86M_REGISTERS BiosRegisters;
PVBE_DEVICE_EXTENSION VBEDeviceExtension =
(PVBE_DEVICE_EXTENSION)HwDeviceExtension;
PVBE_INFO VbeInfo;
PVBE_MODEINFO VbeModeInfo;
VBE_MODEINFO TempVbeModeInfo;
WORD TempVbeModeNumber;
WORD *ModeList;
WORD DefaultMode;
InitializeVideoAddressSpace();
/*
* Get the VBE general information.
*/
VbeInfo = (PVBE_INFO)VBEDeviceExtension->TrampolineMemory;
strncpy(VbeInfo->Signature, "VBE2", 4);
memset(&BiosRegisters, 0, sizeof(BiosRegisters));
BiosRegisters.Eax = 0x4F00;
BiosRegisters.Edi = VBEDeviceExtension->PhysicalAddress.QuadPart & 0xFF;
BiosRegisters.Es = VBEDeviceExtension->PhysicalAddress.QuadPart >> 4;
Ke386CallBios(0x10, &BiosRegisters);
VBEDeviceExtension->VBEVersion = VbeInfo->Version;
VBEDeviceExtension->VGACompatible = !(VbeInfo->Capabilities & 2);
/*
* Get the number of supported video modes.
*/
/*
* No need to be mapped, it's either in BIOS memory or in our trampoline
* memory. Both of them are already mapped.
*/
ModeList = (WORD *)((HIWORD(VbeInfo->VideoModePtr) << 4) + LOWORD(VbeInfo->VideoModePtr));
for (CurrentMode = 0, ModeCount = 0;
ModeList[CurrentMode] != 0xFFFF && ModeList[CurrentMode] != 0;
CurrentMode++)
{
ModeCount++;
}
/*
* Allocate space for video modes information.
*/
VBEDeviceExtension->ModeInfo =
ExAllocatePool(PagedPool, ModeCount * sizeof(VBE_MODEINFO));
VBEDeviceExtension->ModeNumbers =
ExAllocatePool(PagedPool, ModeCount * sizeof(WORD));
/*
* Get the actual mode infos.
*/
for (CurrentMode = 0, ModeCount = 0, DefaultMode = 0;
ModeList[CurrentMode] != 0xFFFF && CurrentMode < 0x400;
CurrentMode++)
{
BiosRegisters.Eax = 0x4F01;
BiosRegisters.Ecx = ModeList[CurrentMode];
BiosRegisters.Edi = VBEDeviceExtension->PhysicalAddress.QuadPart & 0xF;
BiosRegisters.Es = VBEDeviceExtension->PhysicalAddress.QuadPart >> 4;
Ke386CallBios(0x10, &BiosRegisters);
VbeModeInfo = (PVBE_MODEINFO)VBEDeviceExtension->TrampolineMemory;
if (BiosRegisters.Eax == 0x4F &&
VbeModeInfo->XResolution >= 640 &&
VbeModeInfo->YResolution >= 480 &&
/* (VbeModeInfo->MemoryModel == 5 || VbeModeInfo->MemoryModel == 6) &&*/
(VbeModeInfo->ModeAttributes & VBE_MODEATTR_LINEAR))
{
memcpy(VBEDeviceExtension->ModeInfo + ModeCount,
VBEDeviceExtension->TrampolineMemory,
sizeof(VBE_MODEINFO));
VBEDeviceExtension->ModeNumbers[ModeCount] = ModeList[CurrentMode] | 0x4000;
if (VbeModeInfo->XResolution == 640 &&
VbeModeInfo->YResolution == 480 &&
VbeModeInfo->BitsPerPixel == 8)
{
DefaultMode = ModeCount;
}
ModeCount++;
}
}
/*
* Exchange the default mode so it's at the first place in list.
*/
memcpy(&TempVbeModeInfo,
VBEDeviceExtension->ModeInfo,
sizeof(VBE_MODEINFO));
memcpy(VBEDeviceExtension->ModeInfo,
VBEDeviceExtension->ModeInfo + DefaultMode,
sizeof(VBE_MODEINFO));
memcpy(VBEDeviceExtension->ModeInfo + DefaultMode,
&TempVbeModeInfo,
sizeof(VBE_MODEINFO));
TempVbeModeNumber = VBEDeviceExtension->ModeNumbers[0];
VBEDeviceExtension->ModeNumbers[0] = VBEDeviceExtension->ModeNumbers[DefaultMode];
VBEDeviceExtension->ModeNumbers[DefaultMode] = TempVbeModeNumber;
if (ModeCount == 0)
{
DPRINT(("VBEMP: No video modes supported\n"));
return FALSE;
}
VBEDeviceExtension->ModeCount = ModeCount;
#ifdef DBG
for (CurrentMode = 0;
CurrentMode < ModeCount;
CurrentMode++)
{
DPRINT(("%dx%dx%d\n",
VBEDeviceExtension->ModeInfo[CurrentMode].XResolution,
VBEDeviceExtension->ModeInfo[CurrentMode].YResolution,
VBEDeviceExtension->ModeInfo[CurrentMode].BitsPerPixel));
}
#endif
return TRUE;
}
BOOLEAN STDCALL
VBEStartIO(PVOID HwDeviceExtension, PVIDEO_REQUEST_PACKET RequestPacket)
{
BOOL Result;
RequestPacket->StatusBlock->Status = STATUS_UNSUCCESSFUL;
switch (RequestPacket->IoControlCode)
{
case IOCTL_VIDEO_SET_CURRENT_MODE:
if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE))
{
RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
return TRUE;
}
Result = VBESetCurrentMode((PVBE_DEVICE_EXTENSION)HwDeviceExtension,
(PVIDEO_MODE)RequestPacket->InputBuffer, RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_RESET_DEVICE:
Result = VBEResetDevice((PVBE_DEVICE_EXTENSION)HwDeviceExtension,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION) ||
RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
{
RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
return TRUE;
}
Result = VBEMapVideoMemory((PVBE_DEVICE_EXTENSION)HwDeviceExtension,
(PVIDEO_MEMORY)RequestPacket->InputBuffer,
(PVIDEO_MEMORY_INFORMATION)RequestPacket->OutputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
Result = VBEUnmapVideoMemory((PVBE_DEVICE_EXTENSION)HwDeviceExtension,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
if (RequestPacket->OutputBufferLength < sizeof(VIDEO_NUM_MODES))
{
RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
return TRUE;
}
Result = VBEQueryNumAvailModes((PVBE_DEVICE_EXTENSION)HwDeviceExtension,
(PVIDEO_NUM_MODES)RequestPacket->OutputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_QUERY_AVAIL_MODES:
if (RequestPacket->OutputBufferLength <
((PVBE_DEVICE_EXTENSION)HwDeviceExtension)->ModeCount * sizeof(VIDEO_MODE_INFORMATION))
{
RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
return TRUE;
}
Result = VBEQueryAvailModes((PVBE_DEVICE_EXTENSION)HwDeviceExtension,
(PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_QUERY_CURRENT_MODE:
UNIMPLEMENTED;
break;
case IOCTL_VIDEO_SET_COLOR_REGISTERS:
/* FIXME: Check buffer size! */
Result = VBESetColorRegisters((PVBE_DEVICE_EXTENSION)HwDeviceExtension,
(PVIDEO_CLUT)RequestPacket->InputBuffer, RequestPacket->StatusBlock);
break;
default:
RequestPacket->StatusBlock->Status = STATUS_NOT_IMPLEMENTED;
return FALSE;
}
if (Result)
RequestPacket->StatusBlock->Status = STATUS_SUCCESS;
return TRUE;
}
BOOL FASTCALL
VBESetCurrentMode(PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_MODE RequestedMode, PSTATUS_BLOCK StatusBlock)
{
KV86M_REGISTERS BiosRegisters;
memset(&BiosRegisters, 0, sizeof(BiosRegisters));
BiosRegisters.Eax = 0x4F02;
BiosRegisters.Ebx = DeviceExtension->ModeNumbers[RequestedMode->RequestedMode];
Ke386CallBios(0x10, &BiosRegisters);
if (BiosRegisters.Eax == 0x4F)
{
DeviceExtension->CurrentMode = RequestedMode->RequestedMode;
}
else
{
DPRINT(("VBEMP: VBESetCurrentMode failed (%x)\n", BiosRegisters.Eax));
DeviceExtension->CurrentMode = -1;
}
return (BiosRegisters.Eax == 0x4F);
}
BOOL FASTCALL
VBEResetDevice(PVBE_DEVICE_EXTENSION DeviceExtension,
PSTATUS_BLOCK StatusBlock)
{
VIDEO_X86_BIOS_ARGUMENTS BiosRegisters;
memset(&BiosRegisters, 0, sizeof(BiosRegisters));
BiosRegisters.Eax = 0x4F02;
BiosRegisters.Ebx = 0x3;
VideoPortInt10(NULL, &BiosRegisters);
return TRUE;
}
BOOL FASTCALL
VBEMapVideoMemory(PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_MEMORY RequestedAddress, PVIDEO_MEMORY_INFORMATION MapInformation,
PSTATUS_BLOCK StatusBlock)
{
KV86M_REGISTERS BiosRegisters;
PVBE_MODEINFO VbeModeInfo;
PHYSICAL_ADDRESS FrameBuffer;
ULONG inIoSpace = 0;
StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION);
BiosRegisters.Eax = 0x4F01;
BiosRegisters.Ecx = DeviceExtension->ModeNumbers[DeviceExtension->CurrentMode];
BiosRegisters.Edi = DeviceExtension->PhysicalAddress.QuadPart & 0xF;
BiosRegisters.Es = DeviceExtension->PhysicalAddress.QuadPart >> 4;
Ke386CallBios(0x10, &BiosRegisters);
VbeModeInfo = (PVBE_MODEINFO)DeviceExtension->TrampolineMemory;
if (BiosRegisters.Eax == 0x4F &&
(VbeModeInfo->ModeAttributes & VBE_MODEATTR_LINEAR))
{
FrameBuffer.QuadPart = VbeModeInfo->PhysBasePtr;
MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
MapInformation->VideoRamLength = (
DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].XResolution *
DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].YResolution *
DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].BitsPerPixel
) >> 3;
VideoPortMapMemory(DeviceExtension, FrameBuffer,
&MapInformation->VideoRamLength, &inIoSpace,
&MapInformation->VideoRamBase);
MapInformation->FrameBufferBase = MapInformation->VideoRamBase;
MapInformation->FrameBufferLength = MapInformation->VideoRamLength;
DeviceExtension->FrameBufferMemory = MapInformation->VideoRamBase;
return TRUE;
}
else
{
DPRINT(("VBEMP: VBEMapVideoMemory Failed (%lx)\n", BiosRegisters.Eax));
return FALSE;
}
}
BOOL FASTCALL
VBEUnmapVideoMemory(PVBE_DEVICE_EXTENSION DeviceExtension,
PSTATUS_BLOCK StatusBlock)
{
VideoPortUnmapMemory(DeviceExtension, DeviceExtension->FrameBufferMemory,
NULL);
return TRUE;
}
BOOL FASTCALL
VBEQueryNumAvailModes(PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_NUM_MODES Modes, PSTATUS_BLOCK StatusBlock)
{
Modes->NumModes = DeviceExtension->ModeCount;
Modes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
StatusBlock->Information = sizeof(VIDEO_NUM_MODES);
return TRUE;
}
BOOL FASTCALL
VBEQueryAvailModes(PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_MODE_INFORMATION ReturnedModes, PSTATUS_BLOCK StatusBlock)
{
ULONG CurrentModeId;
PVIDEO_MODE_INFORMATION CurrentMode;
PVBE_MODEINFO CurrentVBEMode;
for (CurrentModeId = 0, CurrentMode = ReturnedModes,
CurrentVBEMode = DeviceExtension->ModeInfo;
CurrentModeId < DeviceExtension->ModeCount;
CurrentModeId++, CurrentMode++, CurrentVBEMode++)
{
CurrentMode->Length = sizeof(VIDEO_MODE_INFORMATION);
CurrentMode->ModeIndex = CurrentModeId;
CurrentMode->VisScreenWidth = CurrentVBEMode->XResolution;
CurrentMode->VisScreenHeight = CurrentVBEMode->YResolution;
CurrentMode->ScreenStride = CurrentVBEMode->BytesPerScanLine;
CurrentMode->NumberOfPlanes = CurrentVBEMode->NumberOfPlanes;
CurrentMode->BitsPerPlane = CurrentVBEMode->BitsPerPixel /
CurrentVBEMode->NumberOfPlanes;
CurrentMode->Frequency = 0; /* FIXME */
CurrentMode->XMillimeter = 0; /* FIXME */
CurrentMode->YMillimeter = 0; /* FIXME */
if (CurrentVBEMode->BitsPerPixel > 8)
{
if (DeviceExtension->VBEVersion < 0x300)
{
CurrentMode->NumberRedBits = CurrentVBEMode->RedMaskSize;
CurrentMode->NumberGreenBits = CurrentVBEMode->GreenMaskSize;
CurrentMode->NumberBlueBits = CurrentVBEMode->BlueMaskSize;
CurrentMode->RedMask = ((1 << CurrentVBEMode->RedMaskSize) - 1) << CurrentVBEMode->RedFieldPosition;
CurrentMode->GreenMask = ((1 << CurrentVBEMode->GreenMaskSize) - 1) << CurrentVBEMode->GreenFieldPosition;
CurrentMode->BlueMask = ((1 << CurrentVBEMode->BlueMaskSize) - 1) << CurrentVBEMode->BlueFieldPosition;
}
else
{
CurrentMode->NumberRedBits = CurrentVBEMode->LinRedMaskSize;
CurrentMode->NumberGreenBits = CurrentVBEMode->LinGreenMaskSize;
CurrentMode->NumberBlueBits = CurrentVBEMode->LinBlueMaskSize;
CurrentMode->RedMask = ((1 << CurrentVBEMode->LinRedMaskSize) - 1) << CurrentVBEMode->LinRedFieldPosition;
CurrentMode->GreenMask = ((1 << CurrentVBEMode->LinGreenMaskSize) - 1) << CurrentVBEMode->LinGreenFieldPosition;
CurrentMode->BlueMask = ((1 << CurrentVBEMode->LinBlueMaskSize) - 1) << CurrentVBEMode->LinBlueFieldPosition;
}
}
else
{
CurrentMode->NumberRedBits =
CurrentMode->NumberGreenBits =
CurrentMode->NumberBlueBits = 6;
CurrentMode->RedMask =
CurrentMode->GreenMask =
CurrentMode->BlueMask = 0;
}
CurrentMode->VideoMemoryBitmapWidth = CurrentVBEMode->XResolution;
CurrentMode->VideoMemoryBitmapHeight = CurrentVBEMode->YResolution;
CurrentMode->AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR |
VIDEO_MODE_NO_OFF_SCREEN;
if (CurrentMode->BitsPerPlane <= 8)
CurrentMode->AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN;
CurrentMode->DriverSpecificAttributeFlags = 0;
}
StatusBlock->Information =
sizeof(VIDEO_MODE_INFORMATION) * DeviceExtension->ModeCount;
return TRUE;
}
BOOL FASTCALL
VBESetColorRegisters(PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_CLUT ColorLookUpTable, PSTATUS_BLOCK StatusBlock)
{
KV86M_REGISTERS BiosRegisters;
if (DeviceExtension->VGACompatible)
{
ULONG Entry;
for (Entry = ColorLookUpTable->FirstEntry;
Entry < ColorLookUpTable->NumEntries + ColorLookUpTable->FirstEntry;
Entry++)
{
VideoPortWritePortUchar((PUCHAR)0x03c8, Entry);
VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[Entry].RgbArray.Red);
VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[Entry].RgbArray.Green);
VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[Entry].RgbArray.Blue);
}
return TRUE;
}
else
{
/*
* FIXME:
* This is untested code path, it's possible that it will
* not work at all or that Red and Blue colors will be swapped.
*/
memcpy(DeviceExtension->TrampolineMemory,
&ColorLookUpTable->LookupTable[0].RgbArray,
sizeof(DWORD) * ColorLookUpTable->NumEntries);
BiosRegisters.Eax = 0x4F09;
BiosRegisters.Ebx = 0;
BiosRegisters.Ecx = ColorLookUpTable->NumEntries;
BiosRegisters.Edx = ColorLookUpTable->FirstEntry;
BiosRegisters.Edi = DeviceExtension->PhysicalAddress.QuadPart & 0xF;
BiosRegisters.Es = DeviceExtension->PhysicalAddress.QuadPart >> 4;
Ke386CallBios(0x10, &BiosRegisters);
return (BiosRegisters.Eax == 0x4F);
}
}

View file

@ -0,0 +1,208 @@
/*
* ReactOS VBE miniport video driver
*
* Copyright (C) 2004 Filip Navara
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef VBEMP_H
#define VBEMP_H
/* INCLUDES *******************************************************************/
#include "stddef.h"
#include "windef.h"
#include "wingdi.h"
#include <ddk/miniport.h>
#include <ddk/video.h>
#include <ddk/ntddvdeo.h>
#include <ddk/ntapi.h>
/* For Ke386CallBios */
#include "internal/v86m.h"
/* FIXME: Missing define in w32api! */
#ifndef NtCurrentProcess
#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)
#endif
/*
* Print a message and hang for unimplemented functions.
*/
#define UNIMPLEMENTED DbgPrint("%s:%d UNIMPLEMENTED", __FILE__, __LINE__); for (;;)
#ifdef DBG
#define DPRINT(arg) DbgPrint arg;
#else
#define DPRINT(arg)
#endif
#include <pshpack1.h>
/*
* VBE specification defined structure for general adapter info
* returned by function 0x4F00.
*/
typedef struct
{
CHAR Signature[4];
WORD Version;
DWORD OemStringPtr;
LONG Capabilities;
DWORD VideoModePtr;
WORD TotalMemory;
WORD OemSoftwareRevision;
DWORD OemVendorNamePtr;
DWORD OemProductNamePtr;
DWORD OemProductRevPtr;
CHAR Reserved[222];
CHAR OemData[256];
} VBE_INFO, *PVBE_INFO;
/*
* VBE specification defined structure for specific video mode
* info returned by function 0x4F01.
*/
typedef struct {
/* Mandatory information for all VBE revisions */
WORD ModeAttributes;
BYTE WinAAttributes;
BYTE WinBAttributes;
WORD WinGranularity;
WORD WinSize;
WORD WinASegment;
WORD WinBSegment;
DWORD WinFuncPtr;
WORD BytesPerScanLine;
/* Mandatory information for VBE 1.2 and above */
WORD XResolution;
WORD YResolution;
BYTE XCharSize;
BYTE YCharSize;
BYTE NumberOfPlanes;
BYTE BitsPerPixel;
BYTE NumberOfBanks;
BYTE MemoryModel;
BYTE BankSize;
BYTE NumberOfImagePages;
BYTE Reserved1;
/* Direct Color fields (required for Direct/6 and YUV/7 memory models) */
BYTE RedMaskSize;
BYTE RedFieldPosition;
BYTE GreenMaskSize;
BYTE GreenFieldPosition;
BYTE BlueMaskSize;
BYTE BlueFieldPosition;
BYTE ReservedMaskSize;
BYTE ReservedFieldPosition;
BYTE DirectColorModeInfo;
/* Mandatory information for VBE 2.0 and above */
DWORD PhysBasePtr;
DWORD Reserved2;
WORD Reserved3;
/* Mandatory information for VBE 3.0 and above */
WORD LinBytesPerScanLine;
BYTE BnkNumberOfImagePages;
BYTE LinNumberOfImagePages;
BYTE LinRedMaskSize;
BYTE LinRedFieldPosition;
BYTE LinGreenMaskSize;
BYTE LinGreenFieldPosition;
BYTE LinBlueMaskSize;
BYTE LinBlueFieldPosition;
BYTE LinReservedMaskSize;
BYTE LinReservedFieldPosition;
DWORD MaxPixelClock;
CHAR Reserved4[189];
} VBE_MODEINFO, *PVBE_MODEINFO;
#define VBE_MODEATTR_LINEAR 0x80
#include <poppack.h>
typedef struct {
/* Trampoline memory for communication with VBE real-mode interface. */
PHYSICAL_ADDRESS PhysicalAddress;
PVOID TrampolineMemory;
/* Pointer to mapped frame buffer memory */
PVOID FrameBufferMemory;
/* General controller/BIOS information */
BOOL VGACompatible;
WORD VBEVersion;
/* Saved information about video modes */
ULONG ModeCount;
WORD *ModeNumbers;
PVBE_MODEINFO ModeInfo;
WORD CurrentMode;
} VBE_DEVICE_EXTENSION, *PVBE_DEVICE_EXTENSION;
VP_STATUS STDCALL
VBEFindAdapter(IN PVOID HwDeviceExtension, IN PVOID HwContext,
IN PWSTR ArgumentString, IN OUT PVIDEO_PORT_CONFIG_INFO ConfigInfo,
OUT PUCHAR Again);
BOOLEAN STDCALL
VBEInitialize(PVOID HwDeviceExtension);
BOOLEAN STDCALL
VBEStartIO(PVOID HwDeviceExtension, PVIDEO_REQUEST_PACKET RequestPacket);
VP_STATUS STDCALL
VBESetPowerState(PVOID HwDeviceExtension, ULONG HwId,
PVIDEO_POWER_MANAGEMENT VideoPowerControl);
VP_STATUS STDCALL
VBEGetPowerState(PVOID HwDeviceExtension, ULONG HwId,
PVIDEO_POWER_MANAGEMENT VideoPowerControl);
BOOL FASTCALL
VBESetCurrentMode(PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_MODE RequestedMode, PSTATUS_BLOCK StatusBlock);
BOOL FASTCALL
VBEResetDevice(PVBE_DEVICE_EXTENSION DeviceExtension,
PSTATUS_BLOCK StatusBlock);
BOOL FASTCALL
VBEMapVideoMemory(PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_MEMORY RequestedAddress, PVIDEO_MEMORY_INFORMATION MapInformation,
PSTATUS_BLOCK StatusBlock);
BOOL FASTCALL
VBEUnmapVideoMemory(PVBE_DEVICE_EXTENSION DeviceExtension,
PSTATUS_BLOCK StatusBlock);
BOOL FASTCALL
VBEQueryNumAvailModes(PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_NUM_MODES Modes, PSTATUS_BLOCK StatusBlock);
BOOL FASTCALL
VBEQueryAvailModes(PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_MODE_INFORMATION ReturnedModes, PSTATUS_BLOCK StatusBlock);
BOOL FASTCALL
VBESetColorRegisters(PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_CLUT ColorLookUpTable, PSTATUS_BLOCK StatusBlock);
#endif /* VBEMP_H */

View file

@ -0,0 +1,38 @@
#include <defines.h>
#include <reactos/resource.h>
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", RES_STR_COMPANY_NAME
VALUE "FileDescription", "VGA Miniport Device Driver\0"
VALUE "FileVersion", "0.0.0\0"
VALUE "InternalName", "vgamp\0"
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
VALUE "OriginalFilename", "vgamp.sys\0"
VALUE "ProductName", RES_STR_PRODUCT_NAME
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View file

@ -0,0 +1,8 @@
junk.tmp
base.tmp
temp.exp
vgamp.coff
*.o
*.sym
*.sys
*.map

View file

@ -0,0 +1,129 @@
#include <ntddk.h>
#include <rosrtl/string.h>
#include "vgavideo.h"
#define NDEBUG
#include <debug.h>
void outxay(PUSHORT ad, UCHAR x, UCHAR y)
{
USHORT xy = (x << 8) + y;
VideoPortWritePortUshort(ad, xy);
}
void setMode(VideoMode mode)
{
unsigned char x;
VideoPortWritePortUchar((PUCHAR)MISC, mode.Misc);
VideoPortWritePortUchar((PUCHAR)STATUS, 0);
VideoPortWritePortUchar((PUCHAR)FEATURE, mode.Feature);
for(x=0; x<5; x++)
{
outxay((PUSHORT)SEQ, mode.Seq[x], x);
}
VideoPortWritePortUshort((PUSHORT)CRTC, 0x11);
VideoPortWritePortUshort((PUSHORT)CRTC, (mode.Crtc[0x11] & 0x7f));
for(x=0; x<25; x++)
{
outxay((PUSHORT)CRTC, mode.Crtc[x], x);
}
for(x=0; x<9; x++)
{
outxay((PUSHORT)GRAPHICS, mode.Gfx[x], x);
}
x=VideoPortReadPortUchar((PUCHAR)FEATURE);
for(x=0; x<21; x++)
{
VideoPortWritePortUchar((PUCHAR)ATTRIB, x);
VideoPortWritePortUchar((PUCHAR)ATTRIB, mode.Attrib[x]);
}
x=VideoPortReadPortUchar((PUCHAR)STATUS);
VideoPortWritePortUchar((PUCHAR)ATTRIB, 0x20);
}
VideoMode Mode12 = {
0xa000, 0xe3, 0x00,
{0x03, 0x01, 0x0f, 0x00, 0x06 },
{0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, 0x00, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x59, 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
0xff},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x81, 0x00, 0x0f, 0x00, 0x00}
};
void InitVGAMode()
{
int i;
VIDEO_X86_BIOS_ARGUMENTS vxba;
VP_STATUS vps;
// FIXME: Use Vidport to map the memory properly
vidmem = (char *)(0xd0000000 + 0xa0000);
memset(&vxba, 0, sizeof(vxba));
vxba.Eax = 0x0012;
vps = VideoPortInt10(NULL, &vxba);
// Get VGA registers into the correct state (mainly for setting up the palette registers correctly)
setMode(Mode12);
// Get the VGA into the mode we want to work with
WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08); // Set
WRITE_PORT_UCHAR((PUCHAR)GRA_D,0); // the MASK
WRITE_PORT_USHORT((PUSHORT)GRA_I,0x0205); // write mode = 2 (bits 0,1) read mode = 0 (bit 3)
i = READ_REGISTER_UCHAR(vidmem); // Update bit buffer
WRITE_REGISTER_UCHAR(vidmem, 0); // Write the pixel
WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08);
WRITE_PORT_UCHAR((PUCHAR)GRA_D,0xff);
// Zero out video memory (clear a possibly trashed screen)
RtlZeroMemory(vidmem, 64000);
vgaPreCalc();
}
VOID VGAResetDevice(OUT PSTATUS_BLOCK StatusBlock)
{
HANDLE Event;
OBJECT_ATTRIBUTES Attr;
UNICODE_STRING Name = ROS_STRING_INITIALIZER(L"\\TextConsoleRefreshEvent");
NTSTATUS Status;
VIDEO_X86_BIOS_ARGUMENTS vxba;
VP_STATUS vps;
ULONG ThreadRelease = 1;
CHECKPOINT;
Event = 0;
memset(&vxba, 0, sizeof(vxba));
vxba.Eax = 0x0003;
vps = VideoPortInt10(NULL, &vxba);
memset(&vxba, 0, sizeof(vxba));
vxba.Eax = 0x1112;
vps = VideoPortInt10(NULL, &vxba);
InitializeObjectAttributes( &Attr, &Name, 0, 0, 0 );
Status = ZwOpenEvent( &Event, STANDARD_RIGHTS_ALL, &Attr );
if( !NT_SUCCESS( Status ) )
DbgPrint( "VGA: Failed to open refresh event\n" );
else {
ZwSetEvent( Event, &ThreadRelease );
ZwClose( Event );
}
}

View file

@ -0,0 +1,20 @@
# $Id: makefile,v 1.1 2004/01/10 14:39:21 navaraf Exp $
PATH_TO_TOP = ../../../..
TARGET_TYPE = driver
TARGET_NAME = vgamp
TARGET_DDKLIBS = videoprt.a
TARGET_CFLAGS = -Werror -Wall
TARGET_OBJECTS = \
initvga.o \
vgamp.o \
vgavideo.o
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk

View file

@ -0,0 +1,486 @@
/*
* VGA.C - a generic VGA miniport driver
*
*/
#include <ddk/ntddk.h>
#include <ddk/ntddvid.h>
#define UNIMPLEMENTED do {DbgPrint("%s:%d: Function not implemented", __FILE__, __LINE__); for(;;);} while (0)
#define VERSION "0.0.0"
void InitVGAMode();
// ---------------------------------------------------- Forward Declarations
static VP_STATUS STDCALL
VGAFindAdapter(PVOID DeviceExtension,
PVOID Context,
PWSTR ArgumentString,
PVIDEO_PORT_CONFIG_INFO ConfigInfo,
PUCHAR Again);
static BOOLEAN STDCALL
VGAInitialize(PVOID DeviceExtension);
static BOOLEAN STDCALL
VGAStartIO(PVOID DeviceExtension,
PVIDEO_REQUEST_PACKET RequestPacket);
/*
static BOOLEAN STDCALL
VGAInterrupt(PVOID DeviceExtension);*/
static BOOLEAN STDCALL
VGAResetHw(PVOID DeviceExtension,
ULONG Columns,
ULONG Rows);
/*static VOID STDCALL
VGATimer(PVOID DeviceExtension);
*/
/* Mandatory IoControl routines */
VOID VGAMapVideoMemory(IN PVIDEO_MEMORY RequestedAddress,
OUT PVIDEO_MEMORY_INFORMATION MapInformation,
OUT PSTATUS_BLOCK StatusBlock);
VOID VGAQueryAvailModes(OUT PVIDEO_MODE_INFORMATION ReturnedModes,
OUT PSTATUS_BLOCK StatusBlock);
VOID VGAQueryCurrentMode(OUT PVIDEO_MODE_INFORMATION CurrentMode,
OUT PSTATUS_BLOCK StatusBlock);
VOID VGAQueryNumAvailModes(OUT PVIDEO_NUM_MODES NumberOfModes,
OUT PSTATUS_BLOCK StatusBlock);
VOID VGAResetDevice(OUT PSTATUS_BLOCK StatusBlock);
VOID VGASetColorRegisters(IN PVIDEO_CLUT ColorLookUpTable,
OUT PSTATUS_BLOCK StatusBlock);
VOID VGASetPaletteRegisters(IN PWORD PaletteRegisters,
OUT PSTATUS_BLOCK StatusBlock);
VOID VGASetCurrentMode(IN PVIDEO_MODE RequestedMode,
OUT PSTATUS_BLOCK StatusBlock);
VOID VGAShareVideoMemory(IN PVIDEO_SHARE_MEMORY RequestedMemory,
OUT PVIDEO_MEMORY_INFORMATION ReturnedMemory,
OUT PSTATUS_BLOCK StatusBlock);
VOID VGAUnmapVideoMemory(IN PVIDEO_MEMORY MemoryToUnmap,
OUT PSTATUS_BLOCK StatusBlock);
VOID VGAUnshareVideoMemory(IN PVIDEO_MEMORY MemoryToUnshare,
OUT PSTATUS_BLOCK StatusBlock);
// ------------------------------------------------------- Public Interface
// DriverEntry
//
// DESCRIPTION:
// This function initializes the driver.
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
// ARGUMENTS:
// IN PVOID Context1 Context parameter to pass to VidPortInitialize
// IN PVOID Context2 Context parameter to pass to VidPortInitialize
// RETURNS:
// VP_STATUS
VP_STATUS STDCALL
DriverEntry(IN PVOID Context1,
IN PVOID Context2)
{
VIDEO_HW_INITIALIZATION_DATA InitData;
VideoPortZeroMemory(&InitData, sizeof InitData);
/* FIXME: Fill in InitData members */
InitData.StartingDeviceNumber = 0;
/* Export driver entry points... */
InitData.HwFindAdapter = VGAFindAdapter;
InitData.HwInitialize = VGAInitialize;
InitData.HwStartIO = VGAStartIO;
/* InitData.HwInterrupt = VGAInterrupt; */
InitData.HwResetHw = VGAResetHw;
/* InitData.HwTimer = VGATimer; */
return VideoPortInitialize(Context1, Context2, &InitData, NULL);
}
// VGAFindAdapter
//
// DESCRIPTION:
// This routine is called by the videoport driver to find and allocate
// the adapter for a given bus. The miniport driver needs to do the
// following in this routine:
// - Determine if the adapter is present
// - Claim any necessary memory/IO resources for the adapter
// - Map resources into system memory for the adapter
// - fill in relevant information in the VIDEO_PORT_CONFIG_INFO buffer
// - update registry settings for adapter specifics.
// - Set 'Again' based on whether the function should be called again
// another adapter on the same bus.
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
// ARGUMENTS:
// PVOID DeviceExtension
// PVOID Context
// PWSTR ArgumentString
// PVIDEO_PORT_CONFIG_INFO ConfigInfo
// PUCHAR Again
// RETURNS:
// VP_STATUS
static VP_STATUS STDCALL
VGAFindAdapter(PVOID DeviceExtension,
PVOID Context,
PWSTR ArgumentString,
PVIDEO_PORT_CONFIG_INFO ConfigInfo,
PUCHAR Again)
{
/* FIXME: Determine if the adapter is present */
*Again = FALSE;
return STATUS_SUCCESS;
/* FIXME: Claim any necessary memory/IO resources for the adapter */
/* FIXME: Map resources into system memory for the adapter */
/* FIXME: Fill in relevant information in the VIDEO_PORT_CONFIG_INFO buffer */
/* FIXME: Update registry settings for adapter specifics. */
// return NO_ERROR;
}
// VGAInitialize
//
// DESCRIPTION:
// Perform initialization tasks, but leave the adapter in the same
// user visible state
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
// ARGUMENTS:
// PVOID DeviceExtension
// RETURNS:
// BOOLEAN Success or failure
static BOOLEAN STDCALL
VGAInitialize(PVOID DeviceExtension)
{
return TRUE;
}
// VGAStartIO
//
// DESCRIPTION:
// This function gets called in responce to GDI EngDeviceIoControl
// calls. Device requests are passed in VRPs.
// Required VRPs:
// IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
// IOCTL_VIDEO_QUERY_AVAIL_MODES
// IOCTL_VIDEO_QUERY_CURRENT_MODE
// IOCTL_VIDEO_SET_CURRENT_MODE
// IOCTL_VIDEO_RESET_DEVICE
// IOCTL_VIDEO_MAP_VIDEO_MEMORY
// IOCTL_VIDEO_UNMAP_VIDEO_MEMORY
// IOCTL_VIDEO_SHARE_VIDEO_MEMORY
// IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY
// Optional VRPs:
// IOCTL_VIDEO_GET_PUBLIC_ACCESS_RANGES
// IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES
// IOCTL_VIDEO_GET_POWER_MANAGEMENT
// IOCTL_VIDEO_SET_POWER_MANAGEMENT
// IOCTL_QUERY_COLOR_CAPABILITIES
// IOCTL_VIDEO_SET_COLOR_REGISTERS (required if the device has a palette)
// IOCTL_VIDEO_DISABLE_POINTER
// IOCTL_VIDEO_ENABLE_POINTER
// IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES
// IOCTL_VIDEO_QUERY_POINTER_ATTR
// IOCTL_VIDEO_SET_POINTER_ATTR
// IOCTL_VIDEO_QUERY_POINTER_POSITION
// IOCTL_VIDEO_SET_POINTER_POSITION
// IOCTL_VIDEO_SAVE_HARDWARE_STATE
// IOCTL_VIDEO_RESTORE_HARDWARE_STATE
// IOCTL_VIDEO_DISABLE_CURSOR
// IOCTL_VIDEO_ENABLE_CURSOR
// IOCTL_VIDEO_QUERY_CURSOR_ATTR
// IOCTL_VIDEO_SET_CURSOR_ATTR
// IOCTL_VIDEO_QUERY_CURSOR_POSITION
// IOCTL_VIDEO_SET_CURSOR_POSITION
// IOCTL_VIDEO_GET_BANK_SELECT_CODE
// IOCTL_VIDEO_SET_PALETTE_REGISTERS
// IOCTL_VIDEO_LOAD_AND_SET_FONT
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
// ARGUMENTS:
// PVOID DeviceExtension
// PVIDEO_REQUEST_PACKET RequestPacket
// RETURNS:
// BOOLEAN This function must return TRUE, and complete the work or
// set an error status in the VRP.
static BOOLEAN STDCALL
VGAStartIO(PVOID DeviceExtension,
PVIDEO_REQUEST_PACKET RequestPacket)
{
switch (RequestPacket->IoControlCode)
{
case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
VGAMapVideoMemory((PVIDEO_MEMORY) RequestPacket->InputBuffer,
(PVIDEO_MEMORY_INFORMATION)
RequestPacket->OutputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_QUERY_AVAIL_MODES:
VGAQueryAvailModes((PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_QUERY_CURRENT_MODE:
VGAQueryCurrentMode((PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
VGAQueryNumAvailModes((PVIDEO_NUM_MODES) RequestPacket->OutputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_RESET_DEVICE:
VGAResetDevice(RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_SET_COLOR_REGISTERS:
VGASetColorRegisters((PVIDEO_CLUT) RequestPacket->InputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_SET_CURRENT_MODE:
VGASetCurrentMode((PVIDEO_MODE) RequestPacket->InputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
VGAShareVideoMemory((PVIDEO_SHARE_MEMORY) RequestPacket->InputBuffer,
(PVIDEO_MEMORY_INFORMATION) RequestPacket->OutputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
VGAUnmapVideoMemory((PVIDEO_MEMORY) RequestPacket->InputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
VGAUnshareVideoMemory((PVIDEO_MEMORY) RequestPacket->InputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_SET_PALETTE_REGISTERS:
VGASetPaletteRegisters((PWORD) RequestPacket->InputBuffer,
RequestPacket->StatusBlock);
break;
#if 0
case IOCTL_VIDEO_DISABLE_CURSOR:
case IOCTL_VIDEO_DISABLE_POINTER:
case IOCTL_VIDEO_ENABLE_CURSOR:
case IOCTL_VIDEO_ENABLE_POINTER:
case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES:
VGAFreePublicAccessRanges((PVIDEO_PUBLIC_ACCESS_RANGES)
RequestPacket->InputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_GET_BANK_SELECT_CODE:
case IOCTL_VIDEO_GET_POWER_MANAGEMENT:
case IOCTL_VIDEO_LOAD_AND_SET_FONT:
case IOCTL_VIDEO_QUERY_CURSOR_POSITION:
case IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES:
case IOCTL_VIDEO_QUERY_CURSOR_ATTR:
case IOCTL_VIDEO_QUERY_POINTER_ATTR:
case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES:
case IOCTL_VIDEO_QUERY_POINTER_POSITION:
case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES:
VGAQueryPublicAccessRanges((PVIDEO_PUBLIC_ACCESS_RANGES)
RequestPacket->OutputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_RESTORE_HARDWARE_STATE:
case IOCTL_VIDEO_SAVE_HARDWARE_STATE:
case IOCTL_VIDEO_SET_CURSOR_ATTR:
case IOCTL_VIDEO_SET_CURSOR_POSITION:
case IOCTL_VIDEO_SET_POINTER_ATTR:
case IOCTL_VIDEO_SET_POINTER_POSITION:
case IOCTL_VIDEO_SET_POWER_MANAGEMENT:
#endif
default:
RequestPacket->StatusBlock->Status = STATUS_NOT_IMPLEMENTED;
break;
}
return TRUE;
}
#if 0
// VGAInterrupt
//
// DESCRIPTION:
// This function will be called upon receipt of a adapter generated
// interrupt when enabled.
//
// RUN LEVEL:
// IRQL
//
// ARGUMENTS:
// PVOID DeviceExtension
// RETURNS:
// BOOLEAN TRUE if the interrupt was handled by the routine
static BOOLEAN STDCALL
VGAInterrupt(PVOID DeviceExtension)
{
return(TRUE);
}
#endif
// VGAResetHw
//
// DESCRIPTION:
// This function is called to reset the hardware to a known state
// if calling a BIOS int 10 reset will not achieve this result.
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
// ARGUMENTS:
// PVOID DeviceExtension
// ULONG Columns Columns and Rows specify the mode parameters
// ULONG Rows to reset to.
// RETURNS:
// BOOLEAN TRUE if no further action is necessary, FALSE if the system
// needs to still do a BOIS int 10 reset.
static BOOLEAN STDCALL
VGAResetHw(PVOID DeviceExtension,
ULONG Columns,
ULONG Rows)
{
/* We don't anything to the vga that int10 can't cope with. */
return(FALSE);
}
#if 0
// VGATimer
//
// DESCRIPTION:
// This function will be called once a second when enabled
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
// ARGUMENTS:
// PVOID DeviceExtension
// RETURNS:
// VOID
static VOID STDCALL
VGATimer(PVOID DeviceExtension)
{
}
#endif
VOID VGAMapVideoMemory(IN PVIDEO_MEMORY RequestedAddress,
OUT PVIDEO_MEMORY_INFORMATION MapInformation,
OUT PSTATUS_BLOCK StatusBlock)
{
UNIMPLEMENTED;
}
VOID VGAQueryAvailModes(OUT PVIDEO_MODE_INFORMATION ReturnedModes,
OUT PSTATUS_BLOCK StatusBlock)
{
UNIMPLEMENTED;
}
VOID VGAQueryCurrentMode(OUT PVIDEO_MODE_INFORMATION CurrentMode,
OUT PSTATUS_BLOCK StatusBlock)
{
UNIMPLEMENTED;
}
VOID VGAQueryNumAvailModes(OUT PVIDEO_NUM_MODES NumberOfModes,
OUT PSTATUS_BLOCK StatusBlock)
{
UNIMPLEMENTED;
}
VOID VGASetPaletteRegisters(IN PWORD PaletteRegisters,
OUT PSTATUS_BLOCK StatusBlock)
{
;
/*
We don't need the following code because the palette registers are set correctly on VGA initialization.
Still, we may include\test this is in the future.
int i, j = 2;
char tmp, v;
tmp = VideoPortReadPortUchar(0x03da);
v = VideoPortReadPortUchar(0x03c0);
// Set the first 16 palette registers to map to the first 16 palette colors
for (i=PaletteRegisters[1]; i<PaletteRegisters[0]; i++)
{
tmp = VideoPortReadPortUchar(0x03da);
VideoPortWritePortUchar(0x03c0, i);
VideoPortWritePortUchar(0x03c0, PaletteRegisters[j++]);
}
tmp = VideoPortReadPortUchar(0x03da);
VideoPortWritePortUchar(0x03d0, v | 0x20);
*/
}
VOID VGASetColorRegisters(IN PVIDEO_CLUT ColorLookUpTable,
OUT PSTATUS_BLOCK StatusBlock)
{
int i;
for (i=ColorLookUpTable->FirstEntry; i<ColorLookUpTable->NumEntries; i++)
{
VideoPortWritePortUchar((PUCHAR)0x03c8, i);
VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Red);
VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Green);
VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Blue);
}
}
VOID VGASetCurrentMode(IN PVIDEO_MODE RequestedMode,
OUT PSTATUS_BLOCK StatusBlock)
{
if(RequestedMode->RequestedMode == 12)
{
InitVGAMode();
} else {
DbgPrint("Unrecognised mode for VGASetCurrentMode\n");
}
}
VOID VGAShareVideoMemory(IN PVIDEO_SHARE_MEMORY RequestedMemory,
OUT PVIDEO_MEMORY_INFORMATION ReturnedMemory,
OUT PSTATUS_BLOCK StatusBlock)
{
UNIMPLEMENTED;
}
VOID VGAUnmapVideoMemory(IN PVIDEO_MEMORY MemoryToUnmap,
OUT PSTATUS_BLOCK StatusBlock)
{
UNIMPLEMENTED;
}
VOID VGAUnshareVideoMemory(IN PVIDEO_MEMORY MemoryToUnshare,
OUT PSTATUS_BLOCK StatusBlock)
{
UNIMPLEMENTED;
}

View file

@ -0,0 +1,38 @@
#include <defines.h>
#include <reactos/resource.h>
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", RES_STR_COMPANY_NAME
VALUE "FileDescription", "VGA Miniport Device Driver\0"
VALUE "FileVersion", "0.0.0\0"
VALUE "InternalName", "vgamp\0"
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
VALUE "OriginalFilename", "vgamp.sys\0"
VALUE "ProductName", RES_STR_PRODUCT_NAME
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View file

@ -0,0 +1,94 @@
#include "vgavideo.h"
div_t div(int num, int denom)
{
div_t r;
if (num > 0 && denom < 0) {
num = -num;
denom = -denom;
}
r.quot = num / denom;
r.rem = num % denom;
if (num < 0 && denom > 0)
{
if (r.rem > 0)
{
r.quot++;
r.rem -= denom;
}
}
return r;
}
int mod(int num, int denom)
{
div_t dvt = div(num, denom);
return dvt.rem;
}
VOID vgaPreCalc()
{
ULONG j;
startmasks[1] = 127;
startmasks[2] = 63;
startmasks[3] = 31;
startmasks[4] = 15;
startmasks[5] = 7;
startmasks[6] = 3;
startmasks[7] = 1;
startmasks[8] = 255;
endmasks[0] = 128;
endmasks[1] = 192;
endmasks[2] = 224;
endmasks[3] = 240;
endmasks[4] = 248;
endmasks[5] = 252;
endmasks[6] = 254;
endmasks[7] = 255;
endmasks[8] = 255;
for(j=0; j<80; j++)
{
maskbit[j*8] = 128;
maskbit[j*8+1] = 64;
maskbit[j*8+2] = 32;
maskbit[j*8+3] = 16;
maskbit[j*8+4] = 8;
maskbit[j*8+5] = 4;
maskbit[j*8+6] = 2;
maskbit[j*8+7] = 1;
bit8[j*8] = 7;
bit8[j*8+1] = 6;
bit8[j*8+2] = 5;
bit8[j*8+3] = 4;
bit8[j*8+4] = 3;
bit8[j*8+5] = 2;
bit8[j*8+6] = 1;
bit8[j*8+7] = 0;
}
for(j=0; j<480; j++)
{
y80[j] = j*80;
}
for(j=0; j<640; j++)
{
xconv[j] = j >> 3;
}
}
void vgaSetWriteMode(char mode)
{
VideoPortWritePortUchar((PUCHAR)GRA_I, 0x03);
VideoPortWritePortUchar((PUCHAR)GRA_D, mode);
}
void vgaSetColor(int cindex, int red, int green, int blue)
{
VideoPortWritePortUchar((PUCHAR)0x03c8, cindex);
VideoPortWritePortUchar((PUCHAR)0x03c9, red);
VideoPortWritePortUchar((PUCHAR)0x03c9, green);
VideoPortWritePortUchar((PUCHAR)0x03c9, blue);
}

View file

@ -0,0 +1,41 @@
#include <ddk/ntddk.h>
#include <ddk/ntddvid.h>
#define VGA_NORMAL 0
#define VGA_AND 8
#define VGA_OR 16
#define VGA_XOR 24
//This is in mingw standard headers
//typedef struct { int quot, rem; } div_t;
int maskbit[640], y80[480], xconv[640], bit8[640], startmasks[8], endmasks[8];
char* vidmem;
#define MISC 0x3c2
#define SEQ 0x3c4
#define CRTC 0x3d4
#define GRAPHICS 0x3ce
#define FEATURE 0x3da
#define ATTRIB 0x3c0
#define STATUS 0x3da
#define SEQ_I 0x3C4 /* Sequencer Index */
#define SEQ_D 0x3C5 /* Sequencer Data Register */
#define GRA_I 0x3CE /* Graphics Controller Index */
#define GRA_D 0x3CF /* Graphics Controller Data Register */
typedef struct _VideoMode {
unsigned short VidSeg;
unsigned char Misc;
unsigned char Feature;
unsigned short Seq[6];
unsigned short Crtc[25];
unsigned short Gfx[9];
unsigned char Attrib[21];
} VideoMode;
VOID vgaPreCalc();