NM2160 Registers 

2002,2.11. 2005-05-05 Avi’s findings. Based on IDA pro disassembly of neo20xx.dll

1. Overlay

  GRB0  bit5    Format; 0:YUY2/1:RGB

        bit1    1

        bit0    Enable overlay ; 1:enable/0:disable

  GRB1  bit7:4  X2[11:8]

        bit3:0  X1[11:8]

  GRB2          X1[7:0]

  GRB3          X2[7:0]

  GRB4  bit7:4  Y2[11:8]

        bit3:0  Y1[11:8]

  GRB5          Y1[7:0]

  GRB6          Y2[7:0]

  GRB7          VRAM offset[24:17]

  GRB8          VRAM offset[16:9]

  GRB9          VRAM offset[8:1]

  GRBA          Width in byte[15:8]

  GRBB          Width in byte[7:0]

  GRBC          0x4f

  GRBD          -

  GRBE          -

  GRBF  bit2    0:normal/1:mirror

        bit1:0  b'10'

  GRC0          X scale[15:8] ; x1.0 == 0x1000

  GRC1          X scale[7:0]

  GRC2          Y scale[15:8] ; x1.0 == 0x1000

  GRC3          Y scale[7:0]

  GRC4          brightness   ; -128 to +127

  GRC5          Color key(R)

  GRC6          Color key(G) / Color key(8bpp)

  GRC7          Color key(B)

 

2. ZV capture

  GR0A  bit5    Enable extended SR reg. ; 1:enable/0:disable

        bit0    1

 

  SR08        bit7:6 b'00' ; display every field

                     b'01' ; display interlaced frame

                     b'10' ; display one field

              bit5    1=interlaced 0=non interlaced?

       bit4:2  b'000'

              bit1    YUV2=0 RGB=1

              bit0    Enable capture ; 1:enable/0:disable

  SR09      (0x11)

              bit7          VREF: 0 =sync high  1 = sync active low

              bit6:5 HREF: 11=sync high 00 = sync active low

              bit4          1=invert polarity

              bit3

              bit2:1 Flip Ctrl:  b’11’          Enable Flip

              bit0          Enable Capture Prescaling

                           b’1’          enable prescaling

  SR0A       bit7:4 ; Y prescale bit [10:8]

             bit3:0 ; X prescale bit [10:8]

  SR0B          -

  SR0C          VRAM offset[8:1]

  SR0D          VRAM offset[16:9]

  SR0E          VRAM offset[24:17]

  SR0F          ZV Capture Register 4:  Bit0    : Flip = 1

  SR10          -

  SR11          -

  SR12          -

  SR13          -

  SR14          Y1[7:0]

  SR15          Y2[7:0]

  SR16  bit7:4  Y2[11:4]

        bit3:0  Y1[11:4]

  SR17          X1[7:0]

  SR18          X2[7:0]

  SR19  bit7:4  X2[11:8]

        bit3:0  X1[11:8]

  SR1A          Width in byte[7:0]

  SR1B          Width in byte[15:8]

  SR1C          X prescale (0xfb)  [7:0]

  SR1D          Y prescale (0x00)  [7:0]]

  SR1E          0xe2  ZV status:

                  Bit 2: Field: Even=1 Odd=0

                  Bit 6: Vertical blank

  SR1F          0x02 Capture FIFO Treshold register

 

s.nomura@mba.nifty.ne.jp

avi.cohemstuart@infor.com

 

ZV Capture registers (SR08-SR1F)

 

 

bit7

bit6

bit5

bit4

bit3

bit2

bit1

bit0

RW

 

SR08

00:display every field

01:interlace frame

10:display one field

0:non interlaced

1: interlaced

0

0

0

0:YUV2

1:RGB

 

capture enable

0:disable

1:enable

RW

ZV Capture Control Reg1

SR09

VREF sync

0:high

1:low

HREF sync

00: high

11: low

pol

1:

invert

 

Flip

11: enable flip

prescale

1:enable

RW

ZV Capture Control Reg2

SR0A

Height prescale [10:8]

Width prescale [10:8]

RW

ZV Port Data Scaling

SR0B

 

R

ZV Capt. Frame Count

SR0C

VRAM offset [8:1]

RW

Buffer Start Addr.0

SR0D

VRAM offset [16:9]

RW

Buffer Start Addr.1

SR0E

VRAM offset [24:17]

RW

Buffer Start Addr.2

SR0F

 

 

 

 

 

 

 

Flip

1:enable

RW

ZV Capture Control Reg 4

ZV GPIO Control Registers

SR10

 

 

 

 

 

 

 

 

 

ZV GPIO Cntl Reg 1

SR11

 

 

 

 

 

 

 

 

 

ZV GPIO Cntl Reg 2

SR12

 

 

 

 

 

 

 

 

 

ZV GPIO Status Reg

SR13

 

 

 

 

 

 

 

 

 

Reserved

ZV Crop Window Registers

SR14

Top [7:0]

RW

Top Low

SR15

Bottom [7:0]

RW

Bottom Low

SR16

Bottom [11:8]

Top [11:8]

RW

Top/Bottom High

SR17

Left [7:0]

RW

Left Low

SR18

Right [7:0]

RW

Right Low

SR19

Right [11:8]

Left [11:8]

RW

Right/Left High

ZV Buffer Pitch

SR1A

Width in bytes [7:0]

RW

byte 0

SR1B

Width in bytes [15:8]

RW

byte 1

SR1C

Width Prescale [7:0]

RW

ZV Data X Scaling

SR1D

Height Prescale [7:0]

RW

ZV Data Y Scaling

SR1E

 

 

 

 

 

 

 

 

R

ZV Status Reg

SR1F

 

 

 

 

 

 

 

 

R

ZV FIFO Threshold

 

Important DirectX structures as found in MSDN

 

typedef struct _DDVIDEOPORTDESC {
  DWORD  dwSize;
  DWORD  dwFieldWidth;
  DWORD  dwVBIWidth;
  DWORD  dwFieldHeight;
  DWORD  dwMicrosecondsPerField;
  DWORD  dwMaxPixelsPerSecond;
  DWORD  dwVideoPortID;
  DWORD  dwReserved1;
  DDVIDEOPORTCONNECT  VideoPortType; ->

typedef struct _DDVIDEOPORTCONNECT {
       DWORD  dwSize;
       DWORD  dwPortWidth;
       GUID  guidTypeID;
       DWORD  dwFlags;
       ULONG_PTR  dwReserved1;
} DDVIDEOPORTCONNECT;

  ULONG_PTR  dwReserved2;
  ULONG_PTR  dwReserved3;
} DDVIDEOPORTDESC;

 

 

typedef struct _DDVIDEOPORTINFO { 

DWORD  dwSize; 

DWORD  dwOriginX; 

DWORD  dwOriginY; 

DWORD  dwVPFlags; 

RECT   rCrop;  ->   typedef struct tagRECT { 
LONG left
LONG top
LONG right
LONG bottom

  } RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT; 

 

DWORD  dwPrescaleWidth; 

DWORD  dwPrescaleHeight; 

LPDDPIXELFORMAT  lpddpfInputFormat; 

LPDDPIXELFORMAT  lpddpfVBIInputFormat; 

LPDDPIXELFORMAT  lpddpfVBIOutputFormat; 

DWORD  dwVBIHeight; 

ULONG_PTR  dwReserved1; 

ULONG_PTR  dwReserved2;

} DDVIDEOPORTINFO;

 

Inportant parameters:

-Surface: dwOriginX and dwOriginY point to the upper left corner of the surface where the video is being drawn in.

dwPrescaleWidth and  dwPrescaleHeight specify the size of the surface.

-Video: dwFieldWidth and dwFieldWidth of the video size. If rCrop.left and rCrop.right are specified then rCrop.right-rCrop.left is used as the dwFieldWidth. The same applies to rCrop.top and rCrop.bottom, rCrop.bottom-rCrop.top is used as dwFieldHeight.

 

 

Text Box: dwPrescaleHeightText Box: dwFieldHeight

 

 

Reversed engineered neomagic.dll

 

#define VGASR_Index  0x3c4

#define VGASR_Data   0x3c5

#define SR09               0x09

#define SR09_prescale      (1<<0)

 

int __stdcall UpdateVideoPort32(DD_UPDATEVPORTDATA *dd_upv)

{

ulong video_width;

ulong scale_width;

ulong video_height;

ulong scale_height;

uchar reg_SR09;

uchar reg_SR0A;

 

SR08 = 0x20;  //Combine both fields

if !(dwFlags & DDVPCONNECT_INTERLACED) {

              if !(dwVPFlags & DDVP_SKIPEVENFLIEDS) {

                     SR08 = 0x20 | 0x80;  // 0xA0 one field

              } else {

                     SR08 = 0x20 | 0x40; // 0x60 interlaced fields

                     if (dwVPFlags & DDVP_SKIPODDFIELDS) {

                           SR08 |= 0x80; // 0xE0

                     }

              }

}

 

if (dd_upv->lpVideoInfo. dwVPFlags & DDVP_CROP) {

       video_width = rCrop.right – rCrop.left;

} else {

       video_width = 0;

}

 

if (video_width == 0 ) {

       video_width = dd_upv->lpVideoPort->ddvpDesc.dwFieldWidth;

}

 

scale_width = dd_upv->lpVideoInfo.dwPrescaleWidth;

dd_upv->lpVideoInfo.dwPrescaleWidth = 0;

 

if (scale_width != video_width) {

       dd_upv->lpVideoInfo.dwPrescaleWidth = 2048–((scale_width*2048)/video_width);

}

if (dd_upv->lpVideoInfo.dwPrescaleWidth != 0) {

       reg_SR09 |= SR09_prescale;

}

 

//Write reg_SR09 info SR09

 

if (dd_upv->lpVideoInfo. dwVPFlags & DDVP_CROP) {

       video_height = rCrop.bottom – rCrop.top;

} else {

       video_height = 0;

}

 

if (video_height == 0 ) {

       video_height = dd_upv->lpVideoPort->ddvpDesc.dwFieldHeight;

}

 

scale_height = dd_upv->lpVideoInfo.dwPrescaleHeight;

dd_upv->lpVideoInfo.dwPrescaleHeight = 0;

 

if (scale_height != video_height) {

       dd_upv->lpVideoInfo.dwPrescaleHeight = 2048–((scale_height*2048)/video_height);

}

 

reg_SR0A = ( ( ( (scale_height>>8)&7)<<4) | ( ( (scale_width >>8)&7)   ) );

reg_SR1C = (scale_width  & 0xFF);   

reg_SR1D = (scale_heigth & 0xFF);

 

// Update Video memory area

// Sets SR0C, SR0D and SR0E

 

// Set Crop Registers

ushort top, bottom, top, bottom;

if (dd_upv->rCrop.left == 0) {

       top = dd_upv->lpVideoPort->ddpvDesc.dwFieldHeight;

       dd_upv->rCrop.left = top;

}

reg_SR14 = (top & 0xFF);

bottom = top+dd_upv->dwPrescaleWidth;

reg_SR15 = (bottom & 0xFF);

reg_SR16 = ( ( (bottom>>8) & 0x0F) <<4) |

                 (top   >>8) & 0x0F)    ) );

 

 

}


Overlay Registers (GRB0-GRC7)



 

bit7

bit6

bit5

bit4

bit3

bit2

bit1

bit0

RW

 

GRB0

 

 

format:

0 – YUV2

1 - RGB

 

 

 

1

overlay:

0:disable

1:enable

RW

Magic Video Control

GRB1

Horizontal Start [11:8]

Horizontal End [11:8]

 

Wind H Start/End X1/X2 Hi

GRB2

Horizontal Start [7:0]

 

Wind H Start X1 Low

GRB3

Horizontal End [7:0]

 

Wind H End X2 Low

GRB4

Vertical Start [11:8]

Vertical End [11:8]

 

Wind V Start/End Y1/Y2 Hi

GRB5

Vertical Start [7:0]

 

Wind V Start Y1 Low

GRB6

Vertical End [7:0]

 

Wind V End Y2 Low

GRB7

Memory Start addr [24:17]

 

Wind Memory Start Addr Hi 2

GRB8

Memory Start addr [16:9]

 

Wind Memory Start Addr Hi 2

GRB9

Memory Start addr [8:1]

 

Wind Memory Start Addr Low

GRBA

Width in byte[15:8]

 

Window Offset Hi

GRBB

Width in byte[7:0]

 

Window Offset Low

GRBC

 

 

Window Memory Fetch Control

GRBD

 

 

 

 

 

 

 

 

 

Wind FIFO Stretchband Ctrl

GRBE

 

 

 

 

 

 

 

 

 

FIFO Control

GRC0

X Scale [15:8]: 1.0 = 0x1000

 

X Scale Factor Hi

GRC1

X Scale [7:0]

 

X Scale Factor Low

GRC2

Y Scale [15:8]: 1.0 = 0x1000

 

Y Scale Factor Hi

GRC3

Y Scale [7:0]

 

Y Scale Factor Low

GRC4

Brightness: -128 to 127

 

Brightness Control

GRC5

Color Key (Red)

 

Red Chroma Key Control

GRC6

Color Key (Green) / Color Key(8bpp)

 

Green Chroma Key Control

GRC7

Color Key (Blue)

 

Blue Chroma Key Control

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 




Xv(3v) Interface call XvPutVideo

XvPutVideo(dpy, port, d, gc, vx, vy, vw, vh, dx, dy, dw, dh)

Display *dpy;
XvPortID port;
Drawable d;
GC gc;
int vx, vy, dx, dy;
unsigned int vw, vh;
unsigned int dw, dh;

vx,vy,vw,vh

Define the size and location of the source (video) region to be written. vx and vy define the upper-left pixel of the region. vw and vh define the width and height, in pixels, of the region.

dx,dy,dw,dh

Define the location and size of the destination (drawable) region into which the video image is written. dx and dy define the upper-left pixel of the region. dw and dh define the width and height, in pixels, of the region.

 

 

XvPutVideo arguments

Upper Byte

Lower Byte

Register names

 

Enable Capture

 

 

SR08

ZV Capt Cntrl 1

bit0 enable capture

Enables capturing via ZV port

dwPrescaleWidth != dwFieldWidth

or

dwPrescaleWidth !=

rCrop.right-rCrop.left[1]

 

 

SR09

ZV Capture Control

bit0 enable prescale

Enables the use of the ZV Port Scaling to select a part of the ZV Stream

dwOriginX

dx

 

 

 

X coordinate of display area

dwOriginY

dy

 

 

 

Y coordinate of display area

dwPrescaleWidth

dw

SR0A[3:0]

SR1C

ZV Port X Scaling

Width of the display area

dwPrescaleHeight

dh

SR0A[7:4]

SR1D

ZV Port Y Scaling

Height of the display area

dwFieldWidth or

rCrop.right-rCrop.left

720

or vw

 

 

 

Video Field Width with or without cropping of video

dwFieldHeight or

rCrop.bottom-rCrop.top

288

or vh

 

 

 

Video Field Height with or without cropping of video

rCrop.left

vx

SR19[3:0]

SR17

ZV Crop Wndw Left

Crop Start Field Left

rCrop.right

vx+vw

SR19[7:4]

SR18

ZV Crop Wndw Right

Crop End Field Right

rCrop.top

vy

SR16[3:0]

SR14

ZV Crop Wndw Top

Crop Start Field Top

rCrop.bottom

vy+vh

SR16[7:4]

SR15

ZV Crop Wndw Bottom

Crop End Field Bottom

lPitch

 

SR1A

SR1B

ZV Buffer Pitch

Total size of one Video line in bytes ?

 

 

 

SR0B

ZV Capture Frames

 

Capture buffer offset

 

SR0E/SR0D

SR0C

ZV Capt buf offset

Offset in Video Memory

 


/***************************************************************************

 ** BYTE CSampleDVDPlay::ChangeVideoSize(int Size)                        **

 ***************************************************************************/

BOOL CSampleDVDPlay::ChangeVideoSize(int Size)

{

 

  RECT   ScreenRect;

  SystemParametersInfo(SPI_GETWORKAREA, NULL, &ScreenRect, 0);

  int    Left, Top, Width, Height;

 

  if (m_bAspectRatio != Size)

  {

    switch (Size)

    {

      case ASPECT16_9:

         Left = 30;

         Top   = 10;

         Width = ScreenRect.right - Left * 2;

         Height = ((Width >> 4 )* 9) + 25;

         m_VWSize.x = Width;

         m_VWSize.y = Height;

 

//     SetWindowPos(m_hWnd, HWND_NOTOPMOST, Left, Top, Width, Height, NULL);

         m_bAspectRatio = ASPECT16_9;

         return TRUE;

             

      case ASPECT4_3:   

         Left = (ScreenRect.right >> 3) + 30;

         Top   = 10;

         Width = ScreenRect.right - Left * 2;

         Height = ((Width >> 2) * 3) + 15;

         m_VWSize.x = Width;

         m_VWSize.y = Height;

 

//     SetWindowPos(m_hWnd, HWND_NOTOPMOST, Left, Top, Width, Height, NULL);       

         m_bAspectRatio = ASPECT4_3;

         return TRUE;

      default :

         DbgMsg(DBG_MASAG,"Unexpected video size\r\n");             

         return FALSE;

    }

  }

 

Neo20xx.dll entry points

 

DDUpdateOverlay()

            ProgramOverlagRegisters:

signed int __stdcall DdSetOverlayPosition(DD_SETOVERLAYPOSITIONDATA *a1)

{

  DD_SETOVERLAYPOSITIONDATA *_dd_sop; // esi@1

  struct NeoMagicHW *neohw; // edi@1

  tOverlayData *p_OverlayD; // [sp+1Ch] [bp-10h]@1

  tOverlayData *p_OverlayD2; // [sp+Ch] [bp-20h]@1

 

  _dd_sop = a1;

  neohw = (struct NeoMagicHW *)a1->lpDD->dhpdev;

  a1 = (DD_SETOVERLAYPOSITIONDATA *)a1->lpDD->dhpdev;

  NeoWritePortUShort((enum IOPORTS)974, 9737);

  OverlayData.src_width = OverlayData.src.right - OverlayData.src.left;

  OverlayData.src_height = OverlayData.src.bottom - OverlayData.src.top;

  OverlayData.dest_width = OverlayData.dest.right - OverlayData.dest.left;

  OverlayData.dest_height = OverlayData.dest.bottom - OverlayData.dest.top;

  OverlayData.Ovl_lXpos = _dd_sop->lXPos;

  OverlayData.Ovl_lYpos = _dd_sop->lYPos;

  OverlayData2.src_width = OverlayData2.src.right - OverlayData2.src.left;

  OverlayData2.src_height = OverlayData2.src.bottom - OverlayData2.src.top;

  OverlayData2.dest_width = OverlayData2.dest.right - OverlayData2.dest.left;

  OverlayData2.dest_height = OverlayData2.dest.bottom - OverlayData2.dest.top;

  OverlayData2.Ovl_lXpos = _dd_sop->lXPos;

  OverlayData2.Ovl_lYpos = _dd_sop->lYPos;

  SetOverlayStretchScale(neohw, &OverlayData);

  SetOverlayStretchScale((struct NeoMagicHW *)a1, &OverlayData2);

  OverlayPanningCheck((struct NeoMagicHW *)a1, (struct tOverlayData *)&OverlayData, (struct tOverlayData *)&p_OverlayD);

  OverlayPanningCheck(

    (struct NeoMagicHW *)a1,

    (struct tOverlayData *)&OverlayData2,

    (struct tOverlayData *)&p_OverlayD2);

  ProgramOverlayRegisters((struct NeoMagicHW *)a1, &OverlayData, (tOverlayData *)&p_OverlayD);

  ProgramOverlayRegisters((struct NeoMagicHW *)a1, &OverlayData2, (tOverlayData *)&p_OverlayD2);

  _dd_sop->ddRVal = 0;

  return 1;

}

                        tOverlayData

 

int __stdcall SetOverlayStretchScale(struct NeoMagicHW *a1,tOverlayData *pOvl)

{

  int result; // eax@0

  int dest_width; // edx@1

  tOverlayData *_pOvl; // esi@1

  int c4096; // ecx@2

  int dest_height; // edx@4

  char v7; // bl@8

  unsigned __int8 v8; // cl@9

 

  _pOvl = pOvl;

  dest_width = pOvl->dest_width;

  if ( dest_width == 1 )  {

    c4096 = 4096;

    pOvl->width_ratio_src_dest = 4096;

  }  else  {

    c4096 = 4096;

    result = (4096 * pOvl->src_width - 4096) / (dest_width + 1);

    pOvl->width_ratio_src_dest = result;

  }

  dest_height = pOvl->dest_height;

  if ( dest_height == 1 )  {

    pOvl->height_ratio_src_dest = c4096;

  }  else  {

    result = (4096 * pOvl->src_height - c4096) / (dest_height + 1);

    pOvl->height_ratio_src_dest = result;

  }

  if ( pOvl->VideoPortID == 1 )  {

    NeoWritePortUChar(0x3CEu, 0x25u);

    result = NeoReadPortUChar(0x3CFu);

    v7 = result;

    if ( result & 0x84 )    {

      NeoWritePortUChar(0x3CEu, 0x20u);

      result = NeoReadPortUChar(0x3CFu);

      v8 = ((_BYTE)result >> 3) & 0xF;

      if ( v7 & 0x80 )      {

        if ( result & 2 )

          _pOvl->width_ratio_src_dest = _pOvl->width_ratio_src_dest * scales[v8] >> 12;

      }

      if ( v7 & 4 )      {

        if ( result & 2 )        {

          result = _pOvl->height_ratio_src_dest * scales[v8] >> 12;

          _pOvl->height_ratio_src_dest = result;

        }

      }

    }

  }

  return result;

}

 

DDSetOverlayPosition()

 

UpdateVideoPort32

 

DWORD __stdcall UpdateVideoPort32(DD_UPDATEVPORTDATA *dd_upv)

{

  struct NeoMagicHW *pNeoHW; // ebp@1

  DD_UPDATEVPORTDATA *_dd_upv; // edi@1

  DWORD v3; // edx@3

  unsigned __int8 reg_SR08; // bl@3

  DWORD dwFlags; // eax@8

  unsigned __int8 SR0F; // al@13

  char reg_SR0F_vp; // al@14

  unsigned int _dwVPFlags; // eax@18

  LPDDPIXELFORMAT lpInFormat; // eax@21

  signed int dwFourCC; // ecx@21

  PDD_VIDEOPORT_LOCAL _lpVideoPort; // eax@37

  unsigned __int8 reg_SR09; // bl@37

  int v13; // ecx@41

  int v14; // ecx@42

  PDD_VIDEOPORTINFO _lpVideoInfo; // edx@47

  signed int field_width; // ecx@48

  signed int prescale_width; // eax@52

  PDD_VIDEOPORTINFO _lpVideoInfo; // eax@56

  signed int field_height; // ecx@57

  signed int prescale_height; // eax@61

  int scale_Y; // ebx@61

  LONG crop_top; // ebx@63

  LONG crop_left; // ebx@65

  char v25; // al@2

  PDD_VIDEOPORT_LOCAL lpVideoPort; // eax@3

  DWORD dwVPFlags; // ecx@3

  PDD_SURFACE_INT *Surface_int_arr; // eax@5

  unsigned __int16 v29; // cx@16

  char *v30; // ecx@17

  PDD_VIDEOPORT_LOCAL _lpVideoPort; // eax@17

  __int16 reg_SR08_vp; // ax@37

  __int16 reg_SR09_vp; // ax@56

  WORD reg_SR0A_vp; // cx@63

  __int16 ZV_DataScaling_X; // ax@63

  __int16 ZV_DataScaling_Y; // ax@63

  char *v37; // ecx@63

  int v38; // eax@63

  unsigned int _pitch0; // eax@63

  char _pitch1; // dh@63

  char _pitch1; // bl@63

  __int16 reg_CaptReg0; // ax@63

  __int16 reg_CaptReg1; // ax@63

  PDD_VIDEOPORTINFO _lpVideoInfo; // eax@63

  int crop_width; // eax@63

  __int16 reg_CropTopLow; // ax@65

  char crop_top_hi; // ah@65

  signed int crop_right; // ebx@65

  __int16 reg_CropBottomLow; // ax@65

  __int16 reg_CropTB_High; // ax@65

  int crop_width; // eax@65

  __int16 reg_CropLeftLow; // ax@67

  char crop_lefthigh; // ah@67

  signed int crop_right; // ebx@67

  __int16 reg_CropRightLow; // ax@67

  __int16 reg_CropLR_High; // ax@67

  int v57; // ebx@67

  int reg_ZVPitch0; // eax@67

  __int16 reg_ZVPitch1; // ax@67

  unsigned __int8 SR08; // al@67

  int CurrentSurface; // [sp+10h] [bp-Ch]@1

  DWORD dwVideoPortID; // [sp+14h] [bp-8h]@3

  char *v63; // [sp+18h] [bp-4h]@17

 

  _dd_upv = dd_upv;

  CurrentSurface = 0;

  pNeoHW = (struct NeoMagicHW *)*(dd_upv->lpDD->lpGbl->dhpdev + 205);

  if ( dd_upv->dwFlags == 2 )

  {

    *((_WORD *)pNeoHW + 87) = UnlockZV();

    NeoWritePortUChar((enum IOPORTS)964, 8u);

    v25 = NeoReadPortUChar(965);

    NeoWritePortUChar((enum IOPORTS)965, v25 & 0xFE);

LABEL_69:

    _dd_upv->ddRVal = 0;

    return 1;

  }

  lpVideoPort = dd_upv->lpVideoPort;

  reg_SR08 = 32;

  dwVPFlags = dd_upv->lpVideoInfo->dwVPFlags;

  v3 = lpVideoPort->ddvpDesc.dwVideoPortID;

  dwVideoPortID = lpVideoPort->ddvpDesc.dwVideoPortID;

  if ( dwVPFlags & 1 )

  {

    if ( dd_upv->dwNumAutoflip <= 2 )

    {

      Surface_int_arr = dd_upv->lplpDDSurface;

      CurrentSurface = 1;

      myfpVidMem = (*(Surface_int_arr + 1))->lpLcl->lpGbl->fpVidMem;

    }

    if ( !CurrentSurface )

    {

      dd_upv->ddRVal = -2005532085;

      return 1;

    }

  }

  dwFlags = dd_upv->dwFlags;

  if ( dwFlags != 3 && dwFlags != 1 )

    goto LABEL_68;

  if ( dwFlags == 1 )

  {

    if ( *((_WORD *)pNeoHW + (v3 == 0) + 85) )

    {

      dd_upv->ddRVal = -2005532312;

      return 1;

    }

    *((_WORD *)pNeoHW + 87) = UnlockZV();

    NeoWritePortUChar((enum IOPORTS)964, 15u);

    SR0F = NeoReadPortUChar(965);

    if ( dwVideoPortID )

      reg_SR0F_vp = SR0F | 1;

    else

      reg_SR0F_vp = SR0F & 0xFE;

    LOBYTE(v29) = 0;

    HIBYTE(v29) = reg_SR0F_vp;

    NeoWritePortUShort((enum IOPORTS)964, v29 | 0xF);

  }

  v30 = (char *)pNeoHW + 4 * dwVideoPortID + 160;

  *(_DWORD *)v30 = 2 * _dd_upv->lpVideoInfo->dwOriginY * _dd_upv->lpVideoInfo->dwOriginX;

  _lpVideoPort = _dd_upv->lpVideoPort;

  v63 = v30;

  if ( LOBYTE(_lpVideoPort->ddvpDesc.VideoPortType.dwFlags) & 0x20 )

  {

    _dwVPFlags = _dd_upv->lpVideoInfo->dwVPFlags;

    if ( _dwVPFlags & 0x80 )

      reg_SR08 = -96;

    else

      reg_SR08 = (_dwVPFlags >> 1) & 0xE0 | 0x60;

  }

  lpInFormat = _dd_upv->lpVideoInfo->lpddpfInputFormat;

  dwFourCC = lpInFormat->dwFourCC;

  if ( !dwFourCC )

  {

    if ( (!(lpInFormat->dwFlags & 0x40)

       || lpInFormat->dwRGBBitCount != 16

       || lpInFormat->dwRBitMask != 63488

       || lpInFormat->dwGBitMask != 2016

       || lpInFormat->dwBBitMask != 31)

      && (!(lpInFormat->dwFlags & 0x40)

       || lpInFormat->dwRGBBitCount != 16

       || lpInFormat->dwRBitMask != 31744

       || lpInFormat->dwGBitMask != 992

       || lpInFormat->dwBBitMask != 31) )

    {

      RestoreZV(*((_WORD *)pNeoHW + 87));

      _dd_upv->ddRVal = -2005532527;

      return 0;

    }

    reg_SR08 |= 2u;

    goto LABEL_35;

  }

  if ( dwFourCC == 844715353 )

  {

LABEL_35:

    if ( !(*(_BYTE *)(**(_DWORD **)_dd_upv->lplpDDSurface + 11) & 8) )

    {

      RestoreZV(*((_WORD *)pNeoHW + 87));

      _dd_upv->ddRVal = -2005532572;

      return 0;

    }

    *((_WORD *)pNeoHW + 87) = UnlockZV();

    HIBYTE(reg_SR08_vp) = reg_SR08;

    LOBYTE(reg_SR08_vp) = 8;

    NeoWritePortUShort((enum IOPORTS)964, reg_SR08_vp);

    NeoWritePortUChar((enum IOPORTS)964, 9u);

    reg_SR09 = -((NeoReadPortUChar(965) & 0xC0) != 0) & 0x10;

    _lpVideoPort = _dd_upv->lpVideoPort;

    if ( LOBYTE(_lpVideoPort->ddvpDesc.VideoPortType.dwFlags) & 4 )

      reg_SR09 ^= 16u;

    if ( CurrentSurface )

      reg_SR09 |= 6u;

    v13 = *((_DWORD *)pNeoHW + dwVideoPortID + 39);

    if ( v13 )

    {

      v14 = v13 - 1;

      if ( v14 )

      {

        if ( v14 == 2 )

          reg_SR09 |= 128u;

      }

      else

        reg_SR09 |= 224u;

    }

    else

      reg_SR09 |= 96u;

    _lpVideoInfo = _dd_upv->lpVideoInfo;

    if ( LOBYTE(_lpVideoInfo->dwVPFlags) & 4 )

      field_width = _lpVideoInfo->rCrop.right - _lpVideoInfo->rCrop.left;

    else

      field_width = 0;

    if ( !field_width )

      field_width = _lpVideoPort->ddvpDesc.dwFieldWidth;

    prescale_width = _lpVideoInfo->dwPrescaleWidth;

    dd_upv = 0;

    if ( prescale_width != field_width )

      dd_upv = (DD_UPDATEVPORTDATA *)(2048 - 2048 * prescale_width / field_width);

    if ( dd_upv )

      reg_SR09 |= 1u;

    HIBYTE(reg_SR09_vp) = reg_SR09;

    LOBYTE(reg_SR09_vp) = 9;

    NeoWritePortUShort((enum IOPORTS)964, reg_SR09_vp);

    _lpVideoInfo = _dd_upv->lpVideoInfo;

    if ( LOBYTE(_lpVideoInfo->dwVPFlags) & 4 )

      field_height = _lpVideoInfo->rCrop.bottom - _lpVideoInfo->rCrop.top;

    else

      field_height = 0;

    if ( !field_height )

      field_height = _dd_upv->lpVideoPort->ddvpDesc.dwFieldHeight;

    prescale_height = _lpVideoInfo->dwPrescaleHeight;

    LOWORD(scale_Y) = 0;

    if ( prescale_height != field_height )

      scale_Y = 2048 - 2048 * prescale_height / field_height;

    LOBYTE(reg_SR0A_vp) = 0;

    *(WORD *)((char *)&reg_SR0A_vp + 1) = (unsigned __int8)(16 * (BYTE1(scale_Y) & 7)) | BYTE1(dd_upv->lpDD) & 7;

    NeoWritePortUShort((enum IOPORTS)964, reg_SR0A_vp | 0xA);

    HIBYTE(ZV_DataScaling_X) = (_BYTE)dd_upv;

    LOBYTE(ZV_DataScaling_X) = 28;

    NeoWritePortUShort((enum IOPORTS)964, ZV_DataScaling_X);

    HIBYTE(ZV_DataScaling_Y) = scale_Y;

    LOBYTE(ZV_DataScaling_Y) = 29;

    NeoWritePortUShort((enum IOPORTS)964, ZV_DataScaling_Y);

    NeoWritePortUShort((enum IOPORTS)964, 11);

    v37 = v63;

    v38 = *(_DWORD *)(***(_DWORD ***)_dd_upv->lplpDDSurface + 8);

    VideoMemoryPtr = *(_DWORD *)(***(_DWORD ***)_dd_upv->lplpDDSurface + 8);

    *((_DWORD *)pNeoHW + 46) = v38;

    _pitch0 = (unsigned int)(*(_DWORD *)v37 + VideoMemoryPtr) >> 1;

    VideoMemoryPtr = (unsigned int)(*(_DWORD *)v37 + VideoMemoryPtr) >> 1;

    _pitch1 = BYTE1(_pitch0);

    LOWORD(dd_upv->lpDD) = (unsigned __int8)(_pitch0 >> 16);

    BYTE1(_pitch0) = _pitch0;

    LOBYTE(_pitch0) = 12;

    _pitch1 = _pitch1;

    NeoWritePortUShort((enum IOPORTS)964, _pitch0);

    HIBYTE(reg_CaptReg0) = _pitch1;

    LOBYTE(reg_CaptReg0) = 13;

    NeoWritePortUShort((enum IOPORTS)964, reg_CaptReg0);

    HIBYTE(reg_CaptReg1) = (_BYTE)dd_upv;

    LOBYTE(reg_CaptReg1) = 14;

    NeoWritePortUShort((enum IOPORTS)964, reg_CaptReg1);

    *((_DWORD *)pNeoHW + 15) = VideoMemoryPtr;

    _lpVideoInfo = _dd_upv->lpVideoInfo;

    crop_top = _lpVideoInfo->rCrop.top;

    crop_width = _lpVideoInfo->rCrop.bottom - crop_top;

    CurrentSurface = crop_width;

    if ( !crop_width )

      CurrentSurface = _dd_upv->lpVideoPort->ddvpDesc.dwFieldHeight;

    HIBYTE(reg_CropTopLow) = crop_top;

    LOBYTE(reg_CropTopLow) = 20;

    NeoWritePortUShort((enum IOPORTS)964, reg_CropTopLow);

    crop_top_hi = BYTE1(crop_top);

    crop_right = CurrentSurface + crop_top;

    LOBYTE(dd_upv->lpDD) = crop_top_hi & 0xF;

    HIBYTE(reg_CropBottomLow) = crop_right;

    LOBYTE(reg_CropBottomLow) = 21;

    NeoWritePortUShort((enum IOPORTS)964, reg_CropBottomLow);

    HIBYTE(reg_CropTB_High) = (_BYTE)dd_upv | (unsigned __int8)((crop_right >> 4) & 0xF0);

    LOBYTE(reg_CropTB_High) = 22;

    NeoWritePortUShort((enum IOPORTS)964, reg_CropTB_High);

    crop_left = _dd_upv->lpVideoInfo->rCrop.left;

    *((_DWORD *)pNeoHW + 16) = _dd_upv->lpVideoInfo->rCrop.left;

    crop_width = _dd_upv->lpVideoInfo->rCrop.right - crop_left;

    CurrentSurface = _dd_upv->lpVideoInfo->rCrop.right - crop_left;

    if ( !crop_width )

      CurrentSurface = _dd_upv->lpVideoPort->ddvpDesc.dwFieldWidth;

    HIBYTE(reg_CropLeftLow) = crop_left;

    LOBYTE(reg_CropLeftLow) = 23;

    NeoWritePortUShort((enum IOPORTS)964, reg_CropLeftLow);

    crop_lefthigh = BYTE1(crop_left);

    crop_right = CurrentSurface + crop_left;

    LOBYTE(dd_upv->lpDD) = crop_lefthigh & 0xF;

    HIBYTE(reg_CropRightLow) = crop_right;

    LOBYTE(reg_CropRightLow) = 24;

    NeoWritePortUShort((enum IOPORTS)964, reg_CropRightLow);

    LOBYTE(dd_upv->lpDD) = (unsigned __int8)((crop_right >> 4) & 0xF0) | (_BYTE)dd_upv;

    HIBYTE(reg_CropLR_High) = (_BYTE)dd_upv;

    LOBYTE(reg_CropLR_High) = 25;

    NeoWritePortUShort((enum IOPORTS)964, reg_CropLR_High);

    v57 = *(_DWORD *)(***(_DWORD ***)_dd_upv->lplpDDSurface + 12) >> 1;

    *(_WORD *)((char *)&reg_ZVPitch0 + 1) = (unsigned __int8)(*(_DWORD *)(***(_DWORD ***)_dd_upv->lplpDDSurface + 12) >> 1);

    LOBYTE(reg_ZVPitch0) = 26;

    NeoWritePortUShort((enum IOPORTS)964, reg_ZVPitch0);

    HIBYTE(reg_ZVPitch1) = BYTE1(v57);

    LOBYTE(reg_ZVPitch1) = 27;

    NeoWritePortUShort((enum IOPORTS)964, reg_ZVPitch1);

    NeoWritePortUChar((enum IOPORTS)964, 8u);

    SR08 = NeoReadPortUChar(965);

    NeoWritePortUChar((enum IOPORTS)965, SR08 | 1);

    *((_WORD *)pNeoHW + dwVideoPortID + 85) = 1;

LABEL_68:

    RestoreZV(*((_WORD *)pNeoHW + 87));

    goto LABEL_69;

  }

  _dd_upv->ddRVal = -2005532162;

  return 0;

}

 


# ChildEBP RetAddr  Args to Child             

00 fdb2682c bf8873a0 fdb26880 e1703248 e10fd670 neo20xx_bff40000!DdUpdateOverlay (FPO: [Uses EBP] [1,13,4])

01 fdb26864 bf9c6d64 fdb26880 fdb26934 0012f69c win32k!WatchdogDdUpdateOverlay+0x38 (FPO: [Non-Fpo])

02 fdb26920 804df06b 06400002 09400004 0012f6c4 dxg!DxDdUpdateOverlay+0x212 (FPO: [Non-Fpo])

03 fdb26920 7c90ebab 06400002 09400004 0012f6c4 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ fdb26934)

04 0012f684 77f28aa0 77f28a8b 06400002 09400004 ntdll!KiIntSystemCall+0x6 (FPO: [0,0,0])

05 0012f6f8 77f504d2 77f3d9e1 07800003 0012f724 GDI32!NtGdiDdUpdateOverlay+0xc

06 0012f7b8 5df92a1c 00197078 0012f82c 001904b8 GDI32!NtGdiDvpGetVideoPortOutputFormats+0xc

07 0012f854 5df9a6cf 00197078 0012f8cc 001904b8 qdvd!COMFilter::CallUpdateOverlay+0x220 (FPO: [Non-Fpo])

08 0012f878 5df8fd97 00978ba0 00197078 0012f8cc qdvd!COMInputPin::CallUpdateOverlay+0x23 (FPO: [Non-Fpo])

09 0012f904 5df8ff84 0012f924 00000004 00e0b6f8 qdvd!CAMVideoPort::DrawImage+0x222 (FPO: [Non-Fpo])

0a 0012f974 5df9b495 00df900c 00000004 2704017e qdvd!CAMVideoPort::OnClipChange+0x1ae (FPO: [Non-Fpo])

0b 0012f9b4 5df940c7 0012fa44 0003017a 00000000 qdvd!COMInputPin::OnClipChange+0x1a3 (FPO: [Non-Fpo])

0c 0012fadc 5df9e8d8 0012fdbc 5df9e80e 00000000 qdvd!COMFilter::OnDrawAll+0x312 (FPO: [Non-Fpo])

0d 0012fd54 77d48709 0003017a 0000000f 00000000 qdvd!COMOutputPin::NewWndProc+0xca (FPO: [Non-Fpo])

WARNING: Frame IP not in any known module. Following frames may be wrong.

0e 0012fe64 7c90eae3 0012fe74 00000018 00676de8 0x77d48709

0f 0012fe64 804e3199 0012fe74 00000018 00676de8 ntdll!KiUserCallbackDispatcher+0x13 (FPO: [0,0,0])

10 fdb26bec 80566730 fdb26ca8 fdb26cac fdb26c7c nt!KiCallUserMode+0x4 (FPO: [2,3,4])

11 fdb26c48 bf813d09 00000002 fdb26c8c 00000018 nt!KeUserModeCallback+0x87 (FPO: [Non-Fpo])

12 fdb26ccc bf803522 bc646de8 0000000f 00000000 win32k!SfnDWORD+0xa8 (FPO: [Non-Fpo])

13 fdb26d0c bf80f40a 5df9e80e fdb26d64 0012fe98 win32k!xxxDispatchMessage+0x1dc (FPO: [Non-Fpo])

14 fdb26d58 804df06b 004671c0 0012fed0 7c90ebab win32k!NtUserDispatchMessage+0x39 (FPO: [Non-Fpo])

15 fdb26d58 7c90ebab 004671c0 0012fed0 7c90ebab nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ fdb26d64)

16 0012fe64 7c90eae3 0012fe74 00000018 00676de8 ntdll!KiIntSystemCall+0x6 (FPO: [0,0,0])

17 0012fee0 0043ad96 004671c0 00000001 00467190 ntdll!KiUserCallbackDispatcher+0x13 (FPO: [0,0,0])

18 0012fef0 0043a880 00467190 00467190 0012ffc0 DVDPlay+0x3ad96

19 00467190 00000000 00000000 00000000 00000000 DVDPlay+0x3a880

 

 


Sequence of events during Margi DVD-to-GO play

 

During CreateVideoPort32:

# ChildEBP RetAddr  Args to Child             

00 fbb16ca0 bf9cfe66 fbb16cd0 fbb16d64 0012ec78 neo20xx_bff40000!CreateVideoPort32 (FPO: [Uses EBP] [1,0,4])

01 fbb16d54 804df06b 06200001 0012ec98 0012ec7c dxg!DxDvpCreateVideoPort+0x16a (FPO: [Non-Fpo])

02 fbb16d54 7c90ebab 06200001 0012ec98 0012ec7c nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ fbb16d64)

03 0012ec64 77f50432 77f3d89c 06200001 0012ec98 ntdll!KiIntSystemCall+0x6 (FPO: [0,0,0])

04 0012ed58 5df8ea69 00195e70 00000000 0012ed84 GDI32!NtGdiDvpCreateVideoPort+0xc

05 0012ed58 5df8ea69 00195e70 00000000 0012ed84 qdvd!CAMVideoPort::CreateVideoPort+0x28c (FPO: [Non-Fpo])

06 0012edd0 5df8f805 00000000 00978b64 00978f08 qdvd!CAMVideoPort::CreateVideoPort+0x28c (FPO: [Non-Fpo])

07 0012ee50 5df8fb5e 00978b58 0012ee8c 5df97876 qdvd!CAMVideoPort::RecreateVideoPort+0x13f (FPO: [Non-Fpo])

DdVideoPortCreate

The DdVideoPortCreate callback function notifies the driver that DirectDraw has created a VPE object.

DWORD (APIENTRY *PDD_VPORTCB_CREATEVIDEOPORT)(PDD_CREATEVPORTDATA  lpCreateVideoPort );

 

typedef struct _DD_CREATEVPORTDATA {

  PDD_DIRECTDRAW_LOCAL  lpDD;

  LPDDVIDEOPORTDESC  lpDDVideoPortDesc;

  PDD_VIDEOPORT_LOCAL  lpVideoPort;

  HRESULT  ddRVal;

  VOID  *CreateVideoPort;

} DD_CREATEVPORTDATA;

 

lpVideoPortDesc:

DWORD dwSize

72

DWORD dwFieldWidth

720

DWORD dwVBIWidth

0

DWORD dwFieldHeight

262

DWORD dwMicrosecondsPerField

16683

DWORD dwMaxPixelsPerSecond

11340000

DWORD dwVideoPortID

0

 

DdVideoPortUpdate(... DDRAWI_VPORTSTOP...)

The DdVideoPortUpdate callback function starts and stops the VPE object, and modifies the VPE object data stream.

#define DDRAWI_VPORTSTART           0x0001
#define DDRAWI_VPORTSTOP            0x0002
#define DDRAWI_VPORTUPDATE          0x0003
 
DWORD (APIENTRY *PDD_VPORTCB_UPDATE)(PDD_UPDATEVPORTDATA  lpUpdate );

 

typedef struct _DD_UPDATEVPORTDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  PDD_SURFACE_INT  *lplpDDSurface;
  PDD_SURFACE_INT  *lplpDDVBISurface;
  PDD_VIDEOPORTINFO  lpVideoInfo;
  DWORD  dwFlags;                  = DDRAWI_VPORTSTOP
  DWORD  dwNumAutoflip;
  DWORD  dwNumVBIAutoflip;
  HRESULT  ddRVal;
  VOID  *UpdateVideoPort;
} DD_UPDATEVPORTDATA;

 

# ChildEBP RetAddr  Args to Child             

00 fbb16ca8 bf9cef0c fbb16cc0 00000000 e104e7b8 neo20xx_bff40000!UpdateVideoPort32 (FPO: [Uses EBP] [1,3,4])

01 fbb16cec bf9cfbe4 e104e7b8 bf933281 fbb16d64 dxg!vDdStopVideoPort+0x8a (FPO: [Non-Fpo])

02 fbb16d1c bf9cff3e 01800003 fbb16d38 fbb16d64 dxg!bDdDeleteVideoPortObject+0x38 (FPO: [Non-Fpo])

03 fbb16d54 804df06b 01800003 0012f03c 0012f024 dxg!DxDvpDestroyVideoPort+0x18 (FPO: [Non-Fpo])

04 fbb16d54 7c90ebab 01800003 0012f03c 0012f024 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ fbb16d64)

05 0012f010 77f50446 77f3d8c9 01800003 0012f03c ntdll!KiIntSystemCall+0x6 (FPO: [0,0,0])

06 0012f074 5df8da65 00195e90 0012f384 00978f08 GDI32!NtGdiDvpDestroyVideoPort+0xc

07 0012f074 5df8da65 00195e90 0012f384 00978f08 qdvd!CAMVideoPort::StopUsingVideoPort+0x65 (FPO: [Non-Fpo])

DdVideoPortCreate(PDD_CREATEVPORTDATA  lpCreateVideoPort)

typedef struct _DD_CREATEVPORTDATA {

  PDD_DIRECTDRAW_LOCAL  lpDD;

  LPDDVIDEOPORTDESC  lpDDVideoPortDesc;

  PDD_VIDEOPORT_LOCAL  lpVideoPort;

  HRESULT  ddRVal;

  VOID  *CreateVideoPort;

} DD_CREATEVPORTDATA;

 

lpVideoPortDesc:

DWORD  dwSize

72

DWORD  dwFieldWidth

720

DWORD  dwVBIWidth

0

DWORD  dwFieldHeight

262

DWORD  dwMicrosecondsPerField

16683

DWORD  dwMaxPixelsPerSecond

11340000

DWORD  dwVideoPortID

0

DWORD  dwReserved1

0

DdUpdateVideoPort(PDD_UPDATEVPORTDATA  lpUpdate)

PDD_DIRECTDRAW_LOCAL lpDD

e14ca724

PDD_VIDEOPORT_LOCAL lpVideoPort

e10507c8

PDD_SURFACE_INT *lplpDDSurface

fbb16670

PDD_SURFACE_INT *lplpDDVBISurface

00000000

PDD_VIDEOPORTINFO lpVideoInfo

fbb167ac

DWORD  dwFlags

00000001

DWORD  dwNumAutoflip

00000001

DWORD  dwNumVBIAutoflip

00000000

HRESULT  ddRVal

80004005

VOID  *UpdateVideoPort

00000000

 

lpVideoPort:

PDD_DIRECTDRAW_LOCAL lpDD
e14ca724
DDVIDEOPORTDESC ddvpDesc

dwSize

72

dwFieldWidth

720

dwVBIWidth

0

dwFieldHeight

262

dwMicrosecondsPerField

16683

dwMaxPixelsPerSecond

11340000

dwVideoPortID

0

dwReserved1

0

VideoPortType

DDVPTYPE_E_HREFL_VREFH

 

 

DDVIDEOPORTINFO ddvpInfo

 

PDD_SURFACE_INT lpSurface

 

PDD_SURFACE_INT lpVBISurface
 
DWORD dwNumAutoflip
 
DWORD dwNumVBIAutoflip
 

lpVideoInfo:

DWORD dwSize

64

 

DWORD dwOriginX

0

 

DWORD dwOriginY

0

 

DWORD dwVPFlags

324

 

RECT  rCrop
LONG left; 

0

vx

LONG top; 

14

vy

LONG right; 

720

vx+vw

LONG bottom;

254

vy+wh

DWORD dwPrescaleWidth

386

dw

DWORD dwPrescaleHeight

240

dy

LPDDPIXELFORMAT lpddpfInputFormat
 
 
LPDDPIXELFORMAT lpddpfVBIInputFormat
 
 
LPDDPIXELFORMAT lpddpfVBIOutputFormat
 
 
DWORD dwVBIHeight
 
 

DdUpdateOverlay(PDD_UPDATEOVERLAYDATA  lpUpdateOverlay)

The DdUpdateOverlay callback function repositions or modifies the visual attributes of an overlay surface.

PDD_DIRECTDRAW_GLOBAL lpDD
 
 
PDD_SURFACE_LOCAL lpDDDestSurface
 
 
RECTL  rDest;
LONG left

242

dx

LONG top

68

dy

LONG right

628

dx+dw

LONG bottom

358

dy+dh

PDD_SURFACE_LOCAL  lpDDSrcSurface
 
 
RECTL  rSrc;
LONG left

0

 

LONG top

0

 

LONG right

386

dw

LONG bottom

240

dh

DWORD  dwFlags
00084800
 
DDOVERLAYFX  overlayFX
 
 
HRESULT  ddRVal
 
 
VOID  *UpdateOverlay
 
 

int ProgramOverlayRegisters(struct NeoMagicHW *hpdev,
tOverlayData *p_OverlayData,t_ovl *p_TOvl)

p_OverlayData

 

OverlayWidthInBytes

1440

 

 

 

WidthRatio

4074

 

(4096*SrcWidth-4096)/(DestWidth+1)

 

HeighRatio

3364

 

(4096*SrcHeight-4096)/(DestHeight+1)

 

SrcWidth

386

628-242

rSrc.right  – rSrc.left

 

SrcHeight

240

358-68

rSrc.bottom – rSrc.top

 

DestWidth

386

386-0

rDest.right – rDest.left

 

DestHeigt

290

290-0

rDest.bottom– rDest.top

 

YUVBitCount

16

 

 

 

OverlaySize

768000

 

 

 

RECTL  rSrc

 

LONG left

0

 

 

 

LONG top 

0

 

 

 

LONG right 

386

 

 

 

LONG bottom

240

 

 

 

RECTL  rDest

LONG left

242

 

 

 

LONG top; 

68

 

 

 

LONG right; 

628

 

 

 

LONG bottom;

358

 

 

 

Overlay Xpos

0

 

 

 

Overlay Ypos

0

 

 

 

ScrWidth in lines

386

 

 

 

??

0

 

 

 

VideoPortID

1

 

 

 

p_TOvl

 

X1_left        

242

 

rDest.left

Y1_top         

68

 

rDest.top

X2_right       

628

 

rDest.right

Y2_bottom      

358

 

rDest.bottom

 

 


Resize to FULL SCREEN

neo20xx_bff40000!UpdateVideoPort32:

# ChildEBP RetAddr  Args to Child             

00 fbb16700 bf9cf6c8 fbb168c0 fbb16934 0012f764 neo20xx_bff40000!UpdateVideoPort32 (FPO: [Uses EBP] [1,3,4])

01 fbb1691c 804df06b 03800003 0012f764 0012f78c dxg!DxDvpUpdateVideoPort+0x36c (FPO: [Non-Fpo])

02 fbb1691c 7c90ebab 03800003 0012f764 0012f78c nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ fbb16934)

03 0012f748 77f5050e 77f3dac4 03800003 0012f764 ntdll!KiIntSystemCall+0x6 (FPO: [0,0,0])

 

 

PDD_DIRECTDRAW_LOCAL  lpDD;

e14ca724

 
 
PDD_VIDEOPORT_LOCAL  lpVideoPort;

e105d7c8

 
 
PDD_SURFACE_INT  *lplpDDSurface;

fbb16740

 
 
PDD_SURFACE_INT  *lplpDDVBISurface;

00000000

 
 
PDD_VIDEOPORTINFO  lpVideoInfo;

fbb1687c

 
 
DWORD  dwFlags;

00000001

 
 
DWORD  dwNumAutoflip;

00000001

 
 
DWORD  dwNumVBIAutoflip;

00000000

 
 
HRESULT  ddRVal;

80004005

 
 
VOID  *UpdateVideoPort;

00000000

 
 

 

lpVideoPort
 
  PDD_DIRECTDRAW_LOCAL  lpDD;
 
  DDVIDEOPORTDESC  ddvpDesc;

DWORD  dwSize;

72
 

DWORD  dwFieldWidth;

720
 

DWORD  dwVBIWidth;

0
 

DWORD  dwFieldHeight;

310
 

DWORD  dwMicrosecondsPerField;

16683
 

DWORD  dwMaxPixelsPerSecond;

12916800
 

DWORD  dwVideoPortID;

0
 

DWORD  dwReserved1;

0
 

DDVIDEOPORTCONNECT  VideoPortType;

DWORD  dwSize;
32
DWORD  dwPortWidth;
16
GUID  guidTypeID;
 

a07a02e0

11cfda60

a000069b

b8a303c9

DWORD  dwFlags;
32
ULONG_PTR  dwReserved1;
0
  DDVIDEOPORTINFO  ddvpInfo;
DWORD  dwSize;

64

DWORD  dwOriginX;

0

DWORD  dwOriginY;

0

DWORD  dwVPFlags;

324

RECT  rCrop;
  

0

17

720

305

DWORD  dwPrescaleWidth;

514

DWORD  dwPrescaleHeight;

288

LPDDPIXELFORMAT  lpddpfInputFormat;

e105d880

LPDDPIXELFORMAT  lpddpfVBIInputFormat;

00000000

LPDDPIXELFORMAT  lpddpfVBIOutputFormat;

00000000

DWORD  dwVBIHeight;

00000000

ULONG_PTR  dwReserved1;

00000000

ULONG_PTR  dwReserved2;

00000000

  PDD_SURFACE_INT  lpSurface;
 
  PDD_SURFACE_INT  lpVBISurface;
 
  DWORD  dwNumAutoflip;
 
  DWORD  dwNumVBIAutoflip;
 
  ULONG_PTR  dwReserved1;
 
  ULONG_PTR  dwReserved2;
 
  ULONG_PTR  dwReserved3;
 

 

lpVideoInfo;

 

 

 DWORD  dwSize;

64

 
 DWORD  dwOriginX;

0

 
 DWORD  dwOriginY;

0

 
 DWORD  dwVPFlags;

260

 
 RECT  rCrop;
LONG left; 

0

vx
LONG top; 

17

vy
LONG right; 

720

vx+vw

LONG bottom;

305

vy+vy
 DWORD  dwPrescaleWidth;

0

 
 DWORD  dwPrescaleHeight;

0

 
 LPDDPIXELFORMAT  lpddpfInputFormat;

-72259592

 
 LPDDPIXELFORMAT  lpddpfVBIInputFormat;

0

 
 LPDDPIXELFORMAT  lpddpfVBIOutputFormat;

0

 
 DWORD  dwVBIHeight;

0

 
 ULONG_PTR  dwReserved1;

0

 
 ULONG_PTR  dwReserved2;

0

 

 

 

DdUpdateOverlay(PDD_UPDATEOVERLAYDATA  lpUpdateOverlay)

 

# ChildEBP RetAddr  Args to Child             

00 fbb1682c bf8873a0 fbb16880 e109de00 e10a3ed8 neo20xx_bff40000!DdUpdateOverlay (FPO: [Uses EBP] [1,13,4])

01 fbb16864 bf9c6d64 fbb16880 fbb16934 0012f69c win32k!WatchdogDdUpdateOverlay+0x38 (FPO: [Non-Fpo])

02 fbb16920 804df06b 02400002 03400004 0012f6c4 dxg!DxDdUpdateOverlay+0x212 (FPO: [Non-Fpo])

03 fbb16920 7c90ebab 02400002 03400004 0012f6c4 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ fbb16934)

04 0012f684 77f28aa0 77f28a8b 02400002 03400004 ntdll!KiIntSystemCall+0x6 (FPO: [0,0,0])

05 0012f6f8 77f504d2 77f3d9e1 03800003 0012f724 GDI32!NtGdiDdUpdateOverlay+0xc

06 0012f7b8 5df92a1c 00180738 0012f82c 001969f8 GDI32!NtGdiDvpGetVideoPortOutputFormats+0xc

07 0012f854 5df9a6cf 00180738 0012f8cc 001969f8 qdvd!COMFilter::CallUpdateOverlay+0x220 (FPO: [Non-Fpo])

08 0012f878 5df8fd97 00978c38 00180738 0012f8cc qdvd!COMInputPin::CallUpdateOverlay+0x23 (FPO: [Non-Fpo])

 

lpUpdateOverlay
 
  PDD_DIRECTDRAW_GLOBAL  lpDD;

e14ca714

  PDD_SURFACE_LOCAL  lpDDDestSurface;

e109de10

  RECTL  rDest;
  LONG left; 

0

  LONG top; 

15

  LONG right; 

800

  LONG bottom;

465

  PDD_SURFACE_LOCAL  lpDDSrcSurface;
e10a3ee8
  RECTL  rSrc;
  LONG left; 

0

  LONG top; 

0

  LONG right; 

720

  LONG bottom;

288

  DWORD  dwFlags;

00084800

  DDOVERLAYFX  overlayFX;

 

  HRESULT  ddRVal;

 

  VOID  *UpdateOverlay;
 


 

int __stdcall ProgramOverlayRegisters(struct NeoMagicHW *hpdev,tOverlayData *p_OverlayData,t_ovl *p_TOvl)

 

# ChildEBP RetAddr  Args to Child             

00 fbb167d8 bff43feb e14dbcc8 bff4de60 fbb16810 neo20xx_bff40000!ProgramOverlayRegisters (FPO: [Uses EBP] [3,0,4])

01 fbb1682c bf8873a0 fbb16880 e109de00 e10a3ed8 neo20xx_bff40000!DdUpdateOverlay+0x6c1 (FPO: [Uses EBP] [1,13,4])

02 fbb16864 bf9c6d64 fbb16880 fbb16934 0012f69c win32k!WatchdogDdUpdateOverlay+0x38 (FPO: [Non-Fpo])

03 fbb16920 804df06b 02400002 03400004 0012f6c4 dxg!DxDdUpdateOverlay+0x212 (FPO: [Non-Fpo])

04 fbb16920 7c90ebab 02400002 03400004 0012f6c4 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ fbb16934)

05 0012f684 77f28aa0 77f28a8b 02400002 03400004 ntdll!KiIntSystemCall+0x6 (FPO: [0,0,0])

06 0012f6f8 77f504d2 77f3d9e1 03800003 0012f724 GDI32!NtGdiDdUpdateOverlay+0xc

07 0012f7b8 5df92a1c 00180738 0012f82c 001969f8 GDI32!NtGdiDvpGetVideoPortOutputFormats+0xc

08 0012f854 5df9a6cf 00180738 0012f8cc 001969f8 qdvd!COMFilter::CallUpdateOverlay+0x220 (FPO: [Non-Fpo])

 

p_OverlayData

 

OverlayWidthInBytes

1440

 

 

 

WidthRatio

3676

 

(4096*SrcWidth-4096)/(DestWidth+1)

 

HeighRatio

2606

 

(4096*SrcHeight-4096)/(DestHeight+1)

 

SrcWidth

720

720-0

rSrc.right  – rSrc.left

 

SrcHeight

288

288-0

rSrc.bottom – rSrc.top

 

DestWidth

800

800-0

rDest.right – rDest.left

 

DestHeigt

450

465-15

rDest.bottom– rDest.top

 

YUVBitCount

16

 

 

 

OverlaySize

768000

 

 

 

RECTL rSrc

 

LONG left 

0

 

 

 

LONG top 

0

 

 

 

LONG right 

720

 

 

 

LONG bottom

288

 

 

 

RECTL rDest

LONG left

0

 

 

 

LONG top 

15

 

 

 

LONG right 

800

 

 

 

LONG bottom

465

 

 

 

Overlay Xpos

0

 

 

 

Overlay Ypos

0

 

 

 

ScrWidth in lines

720

 

 

 

??

0

 

 

 

VideoPortID

1

 

 

 

 

 

 

 

 

 

p_TOvl

 

X1_left        

0

 

rDest.left

Y1_top         

15

 

rDest.top

X2_right       

799

 

rDest.right (-1) ?

Y2_bottom      

465

 

rDest.bottom

 



[1] dwFieldWidth is always 720.