Debugging the S3 driver is difficult because the kernel debugger does not support source-level debugging of C code. The bulk of the code that must be modified is in assembler, and the kernel debugger handles this adequately. However, there will be occasions when the C portions of the driver must be modified and debugged. Some of the C functions are quite large, and have no internal symbols that are public. Therefore, if you trap in the middle of a large C function, it is often difficult to determine the problem. Also, if you need to set a breakpoint in the middle of a C function, it is often difficult to know precisely where to put it. The way around this particular problem is to put INT 3 instructions near the portion of the code where you suspect the problem to occur. There are two ways to do this. One way is to insert a call to the function haltproc() into the C code. The other is to add the following statement:

_asm {int 3};

Usually it is more convenient to add the _asm {INT 3} statement, as this breaks into the debugger at the point in the code at which you are interested. The haltproc() routine will also break into the kernel debugger, but it is less convenient because you have to trace out of haltproc() to see the real breakpoint location.

Most of the data in this driver is passed around in data structures, such as AIxfer. It is possible to dump these structures easily, even if they are being manipulated by C code. This tends to be easier than dumping stack frames. The ability to recognize which assembler code corresponds to a particular C language statement is necessary when debugging the portions of the driver that are written in C. However, using the C compiler to generate an assembler language version of the module is also helpful. This is accomplished using the /Fa compiler option. Also, when debugging C code, use /Od, which disables optimizations. This makes the code easier to follow.

The first time you build and test your driver, there is a possibility that it might not load, or that it will load, trap, and then immediately unload. The first challenge you face is getting the driver to load, initialize, and set the desired video mode. The first place to set a breakpoint is either loadproc(), which is in DYNA32.ASM, or in XGA_DLLInit, which is in INIT.C. Also, OS2_PM_DRV_ENABLE, in EDDENABL.C, is a good place to break, as it is called very early in the initialization process. FillLdb(), in EDDEFLDB.C, is another place to break. It is the first function in the driver that does any real work. FillPdb()in EDDEFPDB.C, and QueryAndSelectNativeMode(), in EDDESRES.C, are also good candidates for break points. You might want to trace through FillLdb(), FillPdb(), and QueryAndSelectNativeMode() until the driver initialization phase is stable. Any problems thus far are very likely to be in one of these three functions, or in a function that they call.

Some other good breakpoint locations include eddh_SrcDestBlt, eddh_PatDestBlt, eddh_DestOnlyBlt, eddh_DrawText, eddh_PMLINES, eddh_PMSCANLINE, and eddh_PMIMAGEDATA. Many early problems will be drawing related and will be confined to one of these functions.

If a trap error occurs, such as trap d (General protection error) or trap e, use the "vcf*" debugger command to break on instructions that cause traps. When the debugger breaks on the offending instruction, use "ln" (list near) to give you a nearby label, and also the "ks" to give you a stack trace, which gives a "map" detailing where you have been.

Often graphics chips must be polled to determine if they are ready to accept another command. Consider making the polling loop a macro. In the macro, for debugging mode only, add a drop-dead timer, such as counting down "ecx" from 1,000,000. If the "timer" expires, fall through to an INT 3, so the debugger breaks. This enables you to find situations where the driver will hang while waiting on the video chip. Typically, this is caused by a programming error such as an invalid command to the graphics chip.

Consider using Debug32Output to print a trace of the functions called in the driver when you are unable to determine your present location. The following is an example that traces every major driver entry point.

pmtrace.asm:


.386p

_DATA   segment dword use32 public 'DATA'
_DATA   ends

trace   macro   fn
        _DATA   segment
        s_&fn   db      '&fn, ', 0
        _DATA   ends

        extrn   fn : near
        public  T&fn
        T&fn proc near
                push    offset ds:s_&fn
                call    Debug32Output
                pop     eax
                jmp     fn
        T&fn endp

        endm

_TEXT   segment use32 dword public 'CODE'
        assume  cs:FLAT, ds:FLAT, es:FLAT

extrn   Debug32Output : near

trace eddl_PolyLine
trace eddl_GetCurrentPosition
trace eddl_SetCurrentPosition
trace eddl_DrawLinesInPath
trace eddl_PolyShortLine
trace edds_PolyScanLine
trace DrawBits
trace eddb_DeviceCreatebit map
trace eddb_DeviceDeletebit map
trace eddb_DeviceSelectbit map
trace eddb_BitBlt
trace eddb_GetPel
trace eddb_SetPel
trace eddb_ImageData
trace ScanLR
trace eddm_SaveScreenBits
trace eddb_DrawBorder
trace eddm_DeviceSetCursor
trace Getbit mapBits
trace Setbit mapBits
trace eddm_SetColorCursor
trace eddt_CharString
trace eddt_CharStringPos
trace eddb_PolyMarker
trace eddv_CharRect
trace eddv_CharStr
trace eddv_ScrollRect
trace eddv_UpdateCursor
trace edda_DeviceGetAttribut
trace eddv_DeviceSetAVIOFont2
trace edda_GetPairKerningTable
trace edda_DeviceSetAttributes
trace edda_DeviceSetGlobalAttribute
trace edda_NotifyClipChange
trace eddm_NotifyTransformChange
trace edda_RealizeFont
trace eddm_ErasePS
trace eddl_SetStyleRatio
trace edda_DeviceQueryFontAttributes
trace edda_DeviceQueryFonts
trace edda_DeviceInvalidateVisRegion
trace eddg_GetPickWindow
trace eddg_SetPickWindow
trace eddg_ResetBounds
trace eddg_GetBoundsData
trace eddg_AccumulateBounds
trace edda_GetCodePage
trace edda_SetCodePage
trace eddm_LockDevice
trace eddm_UnlockDevice
trace eddm_Death
trace eddm_Resurrection
trace edda_GetDCOrigin
trace edda_DeviceSetDCOrigin
trace eddl_GetLineOrigin
trace eddl_SetLineOrigin
trace eddl_GetStyleRatio
trace eddc_QueryColorData
trace eddc_QueryLogColorTable
trace eddc_CreateLogColorTable
trace eddc_RealizeColorTable
trace eddc_UnrealizeColorTable
trace eddc_QueryRealColors
trace eddc_QueryNearestColor
trace eddc_QueryColorIndex
trace eddc_QueryRGBColor
trace eddq_QueryDevicebit maps
trace eddq_QueryDeviceCaps
trace eddq_Escape
trace eddq_QueryHardcopyCaps
trace eddm_QueryDevResource
trace DeviceCreatePalette
trace DeviceDeletePalette
trace DeviceSetPaletteEntries
trace DeviceAnimatePalette
trace DeviceResizePalette
trace RealizePalette
trace QueryHWPaletteInfo
trace UpdateColors
trace QueryPaletteRealization

_TEXT   ends

        end

This file, along with the following changes to EDDEFLDB.C will cause the name of every driver entry point that is called to be printed on the debug terminal:

//Changes to eddefldb.c - Replace real driver entry points with dummies
//that print a trace, and then call the real entry point.
DSPENTRY Teddl_PolyLine ();
DSPENTRY Teddl_GetCurrentPosition ();
DSPENTRY Teddl_SetCurrentPosition ();
DSPENTRY Teddl_DrawLinesInPath ();
DSPENTRY Teddl_PolyShortLine ();
DSPENTRY Tedds_PolyScanLine ();
DSPENTRY TGetScreenBits ();
DSPENTRY TSetScreenBits ();
DSPENTRY TDrawBits ();
DSPENTRY Teddb_DeviceCreatebit map ();
DSPENTRY Teddb_DeviceDeletebit map ();
DSPENTRY Teddb_DeviceSelectbit map ();
DSPENTRY Teddb_BitBlt ();
DSPENTRY Teddb_GetPel ();
DSPENTRY Teddb_SetPel ();
DSPENTRY Teddb_ImageData ();
DSPENTRY TScanLR ();
DSPENTRY Teddm_SaveScreenBits ();
DSPENTRY Teddb_DrawBorder ();
DSPENTRY Teddm_DeviceSetCursor ();
DSPENTRY TGetbit mapBits ();
DSPENTRY TSetbit mapBits ();
DSPENTRY Teddm_SetColorCursor ();
DSPENTRY Teddt_CharString ();
DSPENTRY Teddt_CharStringPos ();
DSPENTRY Teddb_PolyMarker ();
DSPENTRY Teddv_CharRect ();
DSPENTRY Teddv_CharStr ();
DSPENTRY Teddv_ScrollRect ();
DSPENTRY Teddv_UpdateCursor ();
DSPENTRY Tedda_DeviceGetAttributes ();
DSPENTRY Teddv_DeviceSetAVIOFont2 ();
DSPENTRY Tedda_GetPairKerningTable ();
DSPENTRY Tedda_DeviceSetAttributes ();
DSPENTRY Tedda_DeviceSetGlobalAttribute ();
DSPENTRY Tedda_NotifyClipChange ();
DSPENTRY Teddm_NotifyTransformChange ();
DSPENTRY Tedda_RealizeFont ();
DSPENTRY Teddm_ErasePS ();
DSPENTRY Teddl_SetStyleRatio ();
DSPENTRY Tedda_DeviceQueryFontAttributes ();
DSPENTRY Tedda_DeviceQueryFonts ();
DSPENTRY Tedda_DeviceInvalidateVisRegion ();
DSPENTRY Teddg_GetPickWindow ();
DSPENTRY Teddg_SetPickWindow ();
DSPENTRY Teddg_ResetBounds ();
DSPENTRY Teddg_GetBoundsData ();
DSPENTRY Teddg_AccumulateBounds ();
DSPENTRY Tedda_GetCodePage ();
DSPENTRY Tedda_SetCodePage ();
DSPENTRY Teddm_LockDevice ();
DSPENTRY Teddm_UnlockDevice ();
DSPENTRY Teddm_Death ();
DSPENTRY Teddm_Resurrection ();
DSPENTRY Tedda_GetDCOrigin ();
DSPENTRY Tedda_DeviceSetDCOrigin ();
DSPENTRY Teddl_GetLineOrigin ();
DSPENTRY Teddl_SetLineOrigin ();
DSPENTRY Teddl_GetStyleRatio ();
DSPENTRY Teddc_QueryColorData ();
DSPENTRY Teddc_QueryLogColorTable ();
DSPENTRY Teddc_CreateLogColorTable ();
DSPENTRY Teddc_RealizeColorTable ();
DSPENTRY Teddc_UnrealizeColorTable ();
DSPENTRY Teddc_QueryRealColors ();
DSPENTRY Teddc_QueryNearestColor ();
DSPENTRY Teddc_QueryColorIndex ();
DSPENTRY Teddc_QueryRGBColor ();
DSPENTRY Teddq_QueryDevicebit maps ();
DSPENTRY Teddq_QueryDeviceCaps ();
DSPENTRY Teddq_Escape ();
DSPENTRY Teddq_QueryHardcopyCaps ();
DSPENTRY Teddm_QueryDevResource ();
DSPENTRY TDeviceCreatePalette ();
DSPENTRY TDeviceDeletePalette ();
DSPENTRY TDeviceSetPaletteEntries ();
DSPENTRY TDeviceAnimatePalette ();
DSPENTRY TDeviceResizePalette ();
DSPENTRY TRealizePalette ();
DSPENTRY TQueryHWPaletteInfo ();
DSPENTRY TUpdateColors ();
DSPENTRY TQueryPaletteRealization ();
#define C(F) F                  /* Just call it */
#if 1
#define T(F) T##F               /* Print trace message and call */
#else
#define T(F) F                  /* Print trace message and call */
#endif
PPFNL   EnginesDispatchTable;
PFNL    DriversDispatchTable[] = {
    C(0),                            //GreGetArcParameters
0x4000
    C(0),                            //GreSetArcParameters
0x4001
    C(0),                            //GreArc
0x4002
    C(0),                            //GrePartialArc
0x4003
    C(0),                            //GreFullArcInterior
0x4004
    C(0),                            //GreFullArcBoundary
0x4005
    C(0),                            //GreFullArcBoth
0x4006
    C(0),                            //GreBoxInterior
0x4007
    C(0),                            //GreBoxBoundary
0x4008
    C(0),                            //GreBoxBoth
0x4009
    C(0),                            //GrePolyFillet
0x400A
    C(0),                            //GrePolyFilletSharp
0x400B
    C(0),                            //GrePolySpline
0x400C
    C(0),                            //GreDrawConicsInPath
0x400D
    C(0),                            //GreCookWholePath
0x400E
    C(0),                            //GreCookPathCurves
0x400F
    C(0),                            //
0x4010
    C(0),                            //GreRenderPath
0x4011
#ifdef DCAF
//DCAF
    C(OpenScreenChangeArea),
//GreOpenScreenChangeArea 0x4012//DCAF
    C(GetScreenChangeArea),
//GreGetScreenChangeArea       0x4013//DCAF
    C(CloseScreenChangeArea),
//GreCloseScreenChangeArea     0x4014//DCAF
#else
//DCAF
    C(0),                            //
0x4012
    C(0),                            //
0x4013
    C(0),                            //
0x4014
#endif
//DCAF
    C(0),                            //
0x4015
    T(eddl_PolyLine),                //GreDisjointLines
0x4016
    T(eddl_GetCurrentPosition),      //GreGetCurrentPosition
0x4017
    T(eddl_SetCurrentPosition),      //GreSetCurrentPosition
0x4018
    T(eddl_PolyLine),                //GrePolyLine
0x4019
    T(eddl_DrawLinesInPath),         //GreDrawLinesInPath
0x401A
    T(eddl_PolyShortLine),           //GrePolyShortLine
0x401B
    T(edds_PolyScanLine),            //GrePolyScanline
0x401C
#ifdef DCAF
//DCAF
    T(GetScreenBits),                //GreGetScreenBits
0x401D//DCAF
    T(SetScreenBits),                //GreSetScreenBits
0x401E//DCAF
#else
//DCAF
    C(0),                            //
0x401D
    C(0),                            //
0x401E
#endif
//DCAF
    C(0),                            //
0x401F
    C(0),                            //
0x4020
    C(0),                            //
0x4021
    T(DrawBits),                     //GreDrawBits
0x6022
    T(eddb_DeviceCreatebit map),      //GreDeviceCreatebit map
0x6023
    T(eddb_DeviceDeletebit map),      //GreDeviceDeletebit map
0x4024
    C(eddb_DeviceSelectbit map),      //GreDeviceSelectbit map
0x4025
    T(eddb_BitBlt),                  //GreBitblt
0x6026
    T(eddb_GetPel),                  //GreGetPel
0x6027
    T(eddb_SetPel),                  //GreSetPel
0x4028
    T(eddb_ImageData),               //GreImageData
0x4029
    T(ScanLR),                       //GreScanLR
0x602A
    C(0),                            //GreFloodFill
0x602B
    T(eddm_SaveScreenBits),          //GreSaveScreenBits
0x402C
    C(0),                            //GreRestoreScreenBits
0x402D
    T(eddb_DrawBorder),              //GreDrawBorder
0x602E
    T(eddm_DeviceSetCursor),         //GreDeviceSetCursor
0x402F
    T(Getbit mapBits),                //GreGetbit mapBits
0x6030
    T(Setbit mapBits),                //GreSetbit mapBits
0x6031
    T(eddm_SetColorCursor),          //GreSetColorCursor
0x4032
    C(0),                            //
0x4033
    C(0),                            //
0x4034
    T(eddt_CharString),              //GreCharString
0x5035
    T(eddt_CharStringPos),           //GreCharStringPos
0x7036
    C(0),                            //GreQueryTextBox
0x5037
    C(0),                            //GreQueryCharPositions
0x5038
    C(0),                            //GreQueryWidthTable
0x5039
    T(eddb_PolyMarker),              //GrePolyMarker
0x403A
    T(eddv_CharRect),                //GreCharRect
0x403B
    T(eddv_CharStr),                 //GreCharStr
0x403C
    T(eddv_ScrollRect),              //GreScrollRect
0x403D
    T(eddv_UpdateCursor),            //GreUpdateCursor
0x403E
    C(0),                            //
0x403F
    C(0),                            //
0x4040
    C(0),                            //
0x4041
    C(0),                            //
0x4042
    C(0),                            //
0x4043
    C(0),                            //
0x4044
    C(0),                            //
0x4045
    C(0),                            //GreBeginArea
0x4046
    C(0),                            //GreEndArea
0x4047
    C(0),                            //GreBeginPath
0x4048
    C(0),                            //GreEndPath
0x4049
    C(0),                            //GreCloseFigure
0x404A
    C(0),                            //GreFillPath
0x404B
    C(0),                            //GreOutlinePath
0x404C
    C(0),                            //GreModifyPath
0x404D
    C(0),                            //GreStrokePath
0x404E
    C(0),                            //GreSelectClipPath
0x404F
    C(0),                            //GreSavePath
0x4050
    C(0),                            //GreRestorePath
0x4051
    C(0),                            //GreClip1DPath
0x4052
    C(0),                            //GreDrawRawPath
0x4053
    C(0),                            //GreDrawCookedPath
0x4054
    C(0),                            //GreAreaSetAttributes
0x6055
    C(0),                            //GrePolygon
0x4056
    C(0),                            //GrePathToRegion
0x4057
    C(0),                            //GreDrawRLE
0x4058
    C(0),                            //
0x4059
    C(0),                            //
0x405A
    C(0),                            //
0x405B
    C(0),                            //
0x405C
    C(0),                            //GreGetRegionBox
0x405D
    C(0),                            //GreGetRegionRects
0x405E
    C(0),                            //GreOffsetRegion
0x405F
    C(0),                            //GrePtInRegion
0x4060
    C(0),                            //GreRectInRegion
0x4061
    C(0),                            //GreCreateRectRegion
0x4062
    C(0),                            //GreDestroyRegion
0x4063
    C(0),                            //GreSetRectRegion
0x4064
    C(0),                            //GreCombineRegion
0x4065
    C(0),                            //GreCombineRectRegion
0x4066
    C(0),                            //GreCombineShortLineRegion
0x4067
    C(0),                            //GreEqualRegion
0x4068
    C(0),                            //GrePaintRegion
0x4069
    C(0),                            //GreSetRegionOwner
0x406A
    C(0),                            //GreFrameRegion
0x406B
    C(0),                            //
0x406C
    C(0),                            //
0x406D
    C(0),                            //GreGetClipBox
0x406E
    C(0),                            //GreGetClipRects
0x406F
    C(0),                            //GreOffsetClipRegion
0x4070
    C(0),                            //GrePtVisible
0x4071
    C(0),                            //GreRectVisible
0x4072
    C(0),                            //GreQueryClipRegion
0x4073
    C(0),                            //GreSelectClipRegion
0x4074
    C(0),                            //GreIntersectClipRectangle
0x4075
    C(0),                            //GreExcludeClipRectangle
0x4076
    C(0),                            //GreSetXformRect
0x4077
    C(0),                            //
0x4078
    C(0),                            //
0x4079
    C(0),                            //
0x407A
    C(0),                            //GreSaveRegion
0x407B
    C(0),                            //GreRestoreRegion
0x407C
    C(0),                            //GreClipPathCurves
0x407D
    C(0),                            //GreSelectPathRegion
0x407E
    C(0),                            //GreRegionSelectbit map
0x407F
    C(0),                            //GreCopyClipRegion
0x4080
    C(0),                            //GreSetupDC
0x4081
    C(0),                            //
0x4082
    C(0),                            //GreGetPageUnits
0x4083
    C(0),                            //GreSetPageUnits
0x4084
    C(0),                            //GreGetModelXform
0x4085
    C(0),                            //GreSetModelXform
0x4086
    C(0),                            //GreGetWindowViewportXform
0x4087
    C(0),                            //GreSetWindowViewportXform
0x4088
    C(0),                            //GreGetGlobalViewingXform
0x4089
    C(0),                            //GreSetGlobalViewingXform
0x408A
    C(0),                            //GreSaveXformData
0x408B
    C(0),                            //GreRestoreXformData
0x408C
    C(0),                            //GreGetPageViewport
0x408D
    C(0),                            //GreSetPageViewport
0x408E
    C(0),                            //
0x408F
    C(0),                            //
0x4090
    C(0),                            //GreGetGraphicsField
0x4091
    C(0),                            //GreSetGraphicsField
0x4092
    C(0),                            //GreGetViewingLimits
0x4093
    C(0),                            //GreSetViewingLimits
0x4094
    C(0),                            //GreQueryViewportSize
0x4095
    C(0),                            //GreConvert
0x4096
    C(0),                            //GreConvertPath
0x4097
    C(0),                            //GreSaveXform
0x4098
    C(0),                            //GreRestoreXform
0x4099
    C(0),                            //GreMultiplyXforms
0x409A
    C(0),                            //GreConvertWithMatrix
0x409B
    C(0),                            //
0x409C
    T(edda_DeviceGetAttributes),     //GreDeviceGetAttributes
0x609D
    T(eddv_DeviceSetAVIOFont2),      //GreDeviceSetAVIOFont2
0x409E
    C(0),                            //
0x409F
    T(edda_GetPairKerningTable),     //GreGetPairKerningTable
0x40A0
    C(0),                            //GreDeviceSetAVIOFont
0x40A1
    T(edda_DeviceSetAttributes),     //GreDeviceSetAttributes
0x60A2
    C(edda_DeviceSetGlobalAttribute),    //GreDeviceSetGlobalAttribut
0x60A3
    C(edda_NotifyClipChange),        //GreNotifyClipChange
0x40A4
    T(eddm_NotifyTransformChange),   //GreNotifyTransformChange
0x40A5
    T(edda_RealizeFont),             //GreRealizeFont
0x40A6
    T(eddm_ErasePS),                 //GreErasePS
0x40A7
    T(eddl_SetStyleRatio),           //GreSetStyleRatio
0x40A8
    T(edda_DeviceQueryFontAttributes),//GreDeviceQueryFontAttributes
0x40A9
    T(edda_DeviceQueryFonts),        //GreDeviceQueryFonts
0x40AA
    C(edda_DeviceInvalidateVisRegion),//GreDeviceInvalidateVisRegion
0x40AB
    T(eddg_GetPickWindow),           //GreGetPickWindow
0x40AC
    T(eddg_SetPickWindow),           //GreSetPickWindow
0x40AD
    C(eddg_ResetBounds),             //GreResetBounds
0x40AE
    C(eddg_GetBoundsData),           //GreGetBoundsData
0x40AF
    C(eddg_AccumulateBounds),        //GreAccumulateBounds
0x40B0
    C(0),                            //GreGetExtraError
0x40B1
    C(0),                            //GreSetExtraError
0x40B2
    C(edda_GetCodePage),             //GreGetCodePage
0x40B3
    C(edda_SetCodePage),             //GreSetCodePage
0x40B4
    C(eddm_LockDevice),              //GreLockDevice
0x40B5
    C(eddm_UnlockDevice),            //GreUnlockDevice
0x40B6
    T(eddm_Death),                   //GreDeath
0x40B7
    T(eddm_Resurrection),            //GreResurrection
0x40B8
    C(0),                            //
0x40B9
    C(edda_GetDCOrigin),             //GreGetDCOrigin
0x40BA
    C(edda_DeviceSetDCOrigin),       //GreDeviceSetDCOrigin
0x40BB
    T(eddl_GetLineOrigin),           //GreGetLineOrigin
0x40BC
    T(eddl_SetLineOrigin),           //GreSetLineOrigin
0x40BD
    T(eddl_GetStyleRatio),           //GreGetStyleRatio
0x40BE
    C(0),                            //
0x40BF
    C(0),                            //
0x40C0
    C(0),                            //
0x40C1
    C(0),                            //
0x40C2
    T(eddc_QueryColorData),          //GreQueryColorData
0x60C3
    T(eddc_QueryLogColorTable),      //GreQueryLogColorTable
0x60C4
    C(eddc_CreateLogColorTable),
//GreCreateLogColorTable     0x60C5
    T(eddc_RealizeColorTable),       //GreRealizeColorTable
0x60C6
    T(eddc_UnrealizeColorTable),
//GreUnrealizeColorTable     0x60C7
    T(eddc_QueryRealColors),         //GreQueryRealColors
0x40C8
    C(eddc_QueryNearestColor),       //GreQueryNearestColor
0x40C9
    C(eddc_QueryColorIndex),         //GreQueryColorIndex
0x60CA
    T(eddc_QueryRGBColor),           //GreQueryRGBColor
0x60CB
    C(0),                            //
0x40CC
    C(0),                            //
0x40CD
    C(0),                            //
0x40CE
    C(0),                            //
0x40CF
    T(eddq_QueryDevicebit maps),      //GreQueryDevicebit maps
0x40D0
    C(eddq_QueryDeviceCaps),         //GreQueryDeviceCaps
0x40D1
    T(eddq_Escape),                  //GreEscape
0x40D2
    T(eddq_QueryHardcopyCaps),       //GreQueryHardcopyCaps
0x40D3
    C(eddm_QueryDevResource),        //GreQueryDevResource2
0x40D4
    T(DeviceCreatePalette),          //GreDeviceCreatePalette
0x40D5
    T(DeviceDeletePalette),          //GreDeviceDeletePalette
0x40D6
    T(DeviceSetPaletteEntries),      //GreDeviceSetPaletteEntries
0x40D7
    T(DeviceAnimatePalette),         //GreDeviceAnimatePalette
0x40D8
    T(DeviceResizePalette),          //GreDeviceResizePalette
0x40D9
    T(RealizePalette),               //GreRealizePalette
0x40DA
    T(QueryHWPaletteInfo),           //GreQueryHWPaletteInfo
0x40DB
    T(UpdateColors),                 //GreUpdateColors
0x40DC
    T(QueryPaletteRealization),      //GreQueryPaletteRealization
0x40DD
    C(0),                            //GreGetVisRects
0x40DE
    C(0),                            //GreDevicePolySet
0x40DF
};

The T() macro in EDDEFLDB.C appends a "T" to the beginning of each entry point in the driver. The trace macro in PMTRACE.ASM creates a function with the name "T", in addition to the name of the real entry point. It then prints out the name of the entry point with Debug32Output, and then calls the real driver entry point.

If your driver supports cached-monochrome bit maps, it is often difficult to determine if the code is working correctly while copying monochrome bit maps from system memory to the display in eddh_SrcDestBlt. Almost any monochrome bit map will fit into the bit-map cache, because monochrome bit maps are small. As a result, the code in eddh_SrcDestBlt that handles monochrome data is rarely used. Disabling monochrome bit-map caching in PixBltThroughClipsViaPhunk() enables you to exercise the monochrome code in eddh_SrcDestBlt. (See BitBlt for further details on this.)

If you are familiar with the Microsoft** Windows** debugger, wdeb386, the OS/2 kernel debugger lacks a "z" command to eliminate INT 3 instructions you added to your code but now no longer need. The command e eip 90;g will perform the same function (by examining the byte at the current instruction pointer, replacing it with a no-op, and restarting execution). Another useful debugger command is the DP command, which dumps the page tables. This is useful for getting information about any linear pointer to the video aperture that you obtain.


[Back: Miscellaneous]
[Next: S3.DSP (Sample File for Installation and Configuration)]