;*DDK*************************************************************************/
;
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
        page    ,132
;/*****************************************************************************
;*
;* SOURCE FILE NAME = ENUMCLIP.ASM
;*
;* DESCRIPTIVE NAME = Clipping region enumeration.
;*
;*
;* VERSION      V2.0
;*
;* DATE         03/12/87
;*
;* DESCRIPTION  Enumerates the clip region by calling the engine. 
;*             
;*
;* FUNCTIONS    do_exttextout
;*              do_bitblt
;*              do_drawbits
;*              do_stretchblt
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   03/12/87                     Charles Whitmer [chuckwh]
;*   05/08/89                     Lee A. Newberg [leen]
;*                                  - Allowed for non-visible (i.e.  INFO)
;*                                    DC's.  PTR HM377
;*   07/08/88                     Walt Moore [waltm]
;*                                  - Remove bitmap kludge.  Changed for
;*                                    new oem bitblt structure definition.
;*                                    Added return code from called routine                            
;*   11/05/87                     Walt Moore [waltm] - Temp bitmap kludge.
;*   06/23/87                     Hock Lee [hockl]   - Added exit condition.
;*   05/21/87                     Hock Lee [hockl]
;*                                  - Added internal enumerate clip rects.
;*   03/15/87                     Charles Whitmer [chuckwh]
;*                                  - Created enumerate_clip_rects.
;*   07/08/88                     Walt Moore [waltm] - Converted for RECTL.
;*   06/19/87                     Hock Lee [hockl] - Added opaque rectangle.
;*   03/17/87                     Charles Whitmer [chuckwh] 
;*                                  - Added correct coordinate flip.
;*   03/16/87                     Charles Whitmer [chuckwh]
;*                                  - Wrote  do_exttextout.
;*   08/14/90                     Viroon Touranachun [viroont]
;*                                  - Switched from Instance Data segment
;*                                    to CompileCode segment.
;*   07/08/88                     Walt Moore [waltm]
;*                                  - Modified for the new bitblt structure.
;*   03/17/87                     Charles Whitmer [chuckwh]
;*                                  - Added correct coordinate flip.
;*   03/15/87                     Charles Whitmer [chuckwh] - Wrote do_bitblt.
;*   05/09/90                     Viroon Touranachun [viroont]
;*                                  - Adapted from do_bitblt
;*   07/03/90                     Viroon Touranachun [viroont]
;*                                  - Wrote do_stretchblt
;*****************************************************************************/

        .286p
        .xlist
        include cmacros.inc
INCL_GRE_CLIP           equ                      1
INCL_FONTFILEFORMAT     equ                      1
INCL_DEV                equ                      1
INCL_GPIREGIONS         equ                      1
        include pmgre.inc
        include driver.inc
        include oemblt.inc
        include fontseg.inc
        include cmplcode.inc
        include assert.mac
        include profile.inc
        .list

        ??_out  enumclip

        externFP ExtTextOut
ifdef SPLITBLT
        externFP MemBlt
        externFP BoardBlt
else
        externFP OEMBitblt
endif ;SPLITBLT
        externFP OEMDrawBits
        externFP OEMStretchBlt

NRECTS  equ     NUM_CLIP_RECTS+1                  ;** Must be bigger than NUM_CLIP_RECTS
                                                  ;** so enum loop will terminate

sBegin  Data
        externW selCompileData
        externB fGrimReaper
        externD pfnDefGetClipRects
sEnd    Data

sBegin  Code
        assumes cs,Code

        externW CodeData
        externW MyCmplCodeData

;/***************************************************************************
;*
;* FUNCTION NAME = enumerate_clip_rects  
;*
;* DESCRIPTION   = Calls the given routine with a clip RECTS that intersect 
;*                 the given given RECTL.  Passes the given SI and DI to the 
;*                 routine. This routine will exit when there are no more 
;*                 clip rectangles or when the passed routine returns zero in AX.                             
;*
;*                 Registers Preserved:
;*                       SI,DI,DS,BP
;*                
;*                 Registers Destroyed:
;*                       BX,DX,ES
;*
;*                 Calls:
;*                       pfn with SS:BX = clip RECTS, SI and DI as passed in
;*                       pfnDefGetClipRects
;*
;* INPUT         = CX = rectangle enumeration direction - 1 
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = AX from called routine 
;*                 CX from called routine 
;* RETURN-ERROR  = AX = 0 
;*
;**************************************************************************/

        assumes ds,Data
        assumes es,nothing

cProc   far_enumerate_clip_rects,<PUBLIC,FAR,NODATA,NONWIN>
        parmW   npddc
        parmD   prclClip
        parmW   pfn
cBegin
        cCall   enumerate_clip_rects,<npddc,prclClip,pfn>
cEnd

cProc   enumerate_clip_rects,<PUBLIC,NEAR>,<ds>

        parmW   npddc
        parmD   prclClip
        parmW   pfn

        localW  crcsClip
        localD  hdcTemp
        localW  SavedDI
        localW  SavedSI
        localW  usRetCode
        localV  arclBuf,%(NRECTS * size RECTL)
        localV  Control,%(size RGNRECT)
cBegin

ifdef FIREWALLS

;/*
;** Must only be called for ddcs that are not completely clipped away.
;** This is designed so that it will NOT catch ICs when we are doing
;** correlation.
;** We better not be here if dead and a display ddc.
;** The enumeration direction must be valid.
;*/

        push    bx
        mov     bx,npddc
        ddc?    bx
        cmp     [bx].ddc_crcsClip,0
        jnz     @F
        rip     text,<enum clip called with no clip rectangles>
@@:
        cmp     fGrimReaper,WE_BE_DEAD
        jne     @F
        test    [bx].ddc_fb,DDC_DEVICE
        jz      @F
        rip     text,<Enumerating clip rects for display while dead>
@@:
        assert  cx,LE,RECTDIR_RTLF_BOTTOP-1
        pop     bx
endif


;/*
;** If only one clip rectangle, or all rectangles are contained within
;** the ddc and the direction is correct, then we can use those rectangles
;** stored in the ddc.  Otherwise, we'll have to get them from the Engine.
;*/

        cld
        mov     SavedDI,di
        mov     SavedSI,si
        mov     ax,1
        mov     usRetCode,ax                      ;**Assume success incase nothing shows
        mov     si,npddc
        mov     dx,[si].ddc_crcsClip              ;**DX = num clip rects for ddc
        cmp     dx,ax
        je      use_our_rects                     ;**One rect doesn't require direction
        cmp     cx,RECTDIR_LFRT_BOTTOP-1          ;**Our rects are this direction only
        jne     cant_use_our_rects
        cmp     dx,NUM_CLIP_RECTS                 ;**Too many clip rects?
        jbe     use_our_rects
cant_use_our_rects:
        jmp     get_engine_rects

use_our_rects:
        lds     si,[si].ddc_prddc                 ;**DS:SI --> RDDC
        assumes ds,nothing
        lea     si,[si].rddc_arcsClip             ;**DS:SI --> source clip rects
        mov     cx,prclClip.sel
        jcxz    copy_first_rect                   ;**No rectangle given
        mov     es,cx                             ;**ES:DI --> bounding rectangle
        assumes es,nothing
        mov     di,prclClip.off
copy_first_rect:
        push    bp
        lea     bp,arclBuf                        ;**SS:BP --> buffer area
        .errnz  high NUM_CLIP_RECTS               ;**DH = Numer of clip rectangle copied
                                                  ;**DL = Number of rects in clip area

;/*
;** Copy and intersect our clip rectangles with the passed rectangle
;*/

copy_next_rect:
        push    dx
        lodsw
        .errnz  rcs_xLeft
        jcxz    @F
        mov     bx,es:[di].rcl_xLeft.lo
        cmp     ax,bx
        jge     @F
        xchg    ax,bx
@@:     mov     [bp].rcl_xLeft.lo,ax
        cwd
        mov     [bp].rcl_xLeft.hi,dx

        lodsw
        .errnz  rcs_yBottom-rcs_xLeft-2
        jcxz    @F
        mov     bx,es:[di].rcl_yBottom.lo
        cmp     ax,bx
        jg      @F
        xchg    ax,bx
@@:     mov     [bp].rcl_yBottom.lo,ax
        cwd
        mov     [bp].rcl_yBottom.hi,dx

        lodsw
        .errnz  rcs_xRight-rcs_yBottom-2
        jcxz    @F
        mov     bx,es:[di].rcl_xRight.lo
        cmp     ax,bx
        jl      @F
        xchg    ax,bx
@@:     mov     [bp].rcl_xRight.lo,ax
        cwd
        mov     [bp].rcl_xRight.hi,dx

        lodsw
        .errnz  rcs_yTop-rcs_xRight-2
        jcxz    @F
        mov     bx,es:[di].rcl_yTop.lo
        cmp     ax,bx
        jl      @F
        xchg    ax,bx
@@:     mov     [bp].rcl_yTop.lo,ax
        cwd
        mov     [bp].rcl_yTop.hi,dx
        pop     dx

        cmp     ax,[bp].rcl_yBottom.lo
        jle     skip_null_rect
        mov     ax,[bp].rcl_xRight.lo
        cmp     ax,[bp].rcl_xLeft.lo
        jle     skip_null_rect
        inc     dh
        add     bp,size RECTL
skip_null_rect:
        dec     dl
        jnz     copy_next_rect
        pop     bp
        xchg    dh,dl
        mov     Control.rgnrc_crcReturned,dx

        mov     ds,CodeData                       ;** retore DS
        assumes ds,Data

        jmp     short call_routine

;/*
;** We must get the rectangles from the Engine.  We will loop getting
;** as many as will fit within our buffer.
;*/

get_engine_rects:
        mov     ax,[si].ddc_hdc.lo
        mov     hdcTemp.lo,ax
        mov     ax,[si].ddc_hdc.hi
        mov     hdcTemp.hi,ax
        mov     Control.rgnrc_ircStart,1
        mov     Control.rgnrc_crc,NRECTS
        inc     cx
        mov     Control.rgnrc_usDirection,cx

;/*
;** Get the next bunch of rectangle from the Engine
;*/

get_more_loop:
        check   GetClipRects,<hdc,prclBounds,prgnrc,prclClip,hddc,ulFunN>
        farPtr  prgnrect,ss,bx
        farPtr  parcl,ss,ax
        farPtr  hddcNull,ax,ax
        lea     bx,Control
        lea     ax,arclBuf
        cCall   pfnDefGetClipRects,<hdcTemp,prclClip,prgnrect,parcl,hddcNull,GreGetClipRects>
ifdef FIREWALLS
        or      ax,ax
        jnz     @F
        rip     text,<GetClipRects returns error>
@@:
endif


;/*
;** Call routine for each rectangle in the buffer
;*/

call_routine:
        mov     cx,Control.rgnrc_crcReturned
        jcxz    enumerate_done
        mov     crcsClip,cx
        add     Control.rgnrc_ircStart,cx
        lea     bx,arclBuf                        ;**SS:BX --> first RECTL

call_loop:

ifdef FIREWALLS
        mov     cx,ss:[bx].rcl_yTop.lo
        cmp     cx,ss:[bx].rcl_yBottom.lo
        jg      @F
        rip     text,<Enumerated a null rectangle in Y>
@@:
        mov     cx,ss:[bx].rcl_xRight.lo
        cmp     cx,ss:[bx].rcl_xLeft.lo
        jg      @F
        rip     text,<Enumerated a null rectangle in X>
@@:
endif

        mov     si,SavedSI
        mov     di,SavedDI
        push    ds          ;** better to save ds.
        push    bx
        call    pfn
        pop     bx
        pop     ds
        mov     usRetCode,ax
        or      ax,ax
        jz      enumerate_done
        add     bx,size RECTL
        dec     crcsClip
        jnz     call_loop
        cmp     Control.rgnrc_crcReturned,NRECTS
        je      get_more_loop

enumerate_done:
        mov     si,SavedSI
        mov     di,SavedDI
        mov     ax,usRetCode
cEnd
page

;/***************************************************************************
;*
;* FUNCTION NAME = do_exttextout 
;*
;* DESCRIPTION   = This routine is called by enumerate_clip_rects to actually do 
;*                 the exttextouts.
;*
;*                 Registers Destroyed:
;*                       AX,BX,CX,DX,SI,DI,ES
;*
;* INPUT         = SS:BX = clip RECTL       
;*                 SS:DI -> exttextout_args 
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = AX = 1  
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

        assumes ds,Data
        assumes es,nothing

cProc   do_exttextout,<PUBLIC,NEAR>
cBegin  <nogen>

        profile entered

;/*
;** Make a copy of the arguments
;*/

        mov     si,di                             ;**SS:SI -> exttextout_args
        sub     sp,size eto_args
        mov     di,sp
        push    ss
        pop     es
        assumes es,nothing
        .errnz  (size eto_args) and 1
        mov     cx,(size eto_args) / 2
        cld
        rep     movs word ptr es:[di],word ptr ss:[si]
        sub     di,size eto_args

;/*
;** Fill in the actual clip rectangle.  We will have to convert it into
;** a RECTS until exttextout is changed !!!!
;*/

        mov     ss:[di].eto_lpClipRect.sel,ss
        mov     ss:[di].eto_lpClipRect.off,bx
        mov     ax,ss:[bx].rcl_yBottom.lo
        mov     cx,ss:[bx].rcl_xRight.lo
        mov     dx,ss:[bx].rcl_yTop.lo
        mov     ss:[bx].rcs_yBottom,ax
        mov     ss:[bx].rcs_xRight,cx
        mov     ss:[bx].rcs_yTop,dx
        .errnz  rcs_xLeft-rcl_xLeft

;/*
;** Flip the coordinate system over for the old Window's way where 0,0 is
;** the upper left corner (you know, the way hardware works!)
;*/

        les     si,ss:[di].eto_lpDestDev          ;** ES:SI -> sd_
        assumes es,nothing
        mov     dx,es:[si].sd_cy
        mov     ax,dx                             ;**Flip clip rectangle
        sub     ax,ss:[bx].rcs_yBottom
        sub     dx,ss:[bx].rcs_yTop
        mov     ss:[bx].rcs_yTop,ax
        mov     ss:[bx].rcs_yBottom,dx

;/*
;** Make the exttextout call and exit
;*/

        call    ExtTextOut
        mov     ax,1                             ;** so we don't quit in enumerate_clip_rects

        profile exiting

        ret

cEnd    <nogen>
page

;/***************************************************************************
;*
;* FUNCTION NAME = do_bitblt
;*
;* DESCRIPTION   = This routine is called by enumerate_clip_rects to invoke the oem    
;*                 bitblt with the passed clipped rectangle.                           
;*
;*                 Registers Preserved:
;*                       DS,BP
;*                
;*                 Registers Destroyed:
;*                       AX,BX,CX,DX,SI,DI,ES
;*
;*                 Calls:
;*                       OEMBitblt
;*
;* INPUT         = SS:BX --> clip RECTL        
;*                 SS:DI --> OBB_ARGS structure
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = AX from called routine 
;* RETURN-ERROR  = AX = 0  
;*
;**************************************************************************/

        assumes ds,Data
        assumes es,nothing

cProc   do_bitblt,<PUBLIC,NEAR>
cBegin  <nogen>

        profile entered
;/*
;** Make the Compile Code Data Segment our current stack segment.  Since
;** parameters will have to be copied from the current stack onto the
;** new stack, we'll have to keep the old SS around
;*/

        push    ds                                ;**If we loose this, we're toast
        mov     cx,ss                             ;**Old SS will be saved in DS
        lea     si,proc_initial_sp                ;**This location will be the initial SP
        mov     ss,MyCmplCodeData
        assumes ss,nothing
        xchg    si,sp                             ;**SS:SP is the compile code data segment
        push    si                                ;**Save user's SP
        mov     ds,cx                             ;**Set DS = old SS
        assumes ds,nothing

;/*
;** Leave room for the arguments we'll copy to the stack
;*/

        mov     si,di                             ;**DS:SI --> OBB_ARGS
        sub     sp,size OBB_ARGS
        mov     di,sp

;/*
;** Get arguments onto our stack.  They are in our old stack segment.
;*/

        push    ss
        pop     es
        assumes es,nothing
        .errnz  (size OBB_ARGS) and 1
        mov     cx,(size OBB_ARGS) / 2
        cld
        rep     movsw
        sub     di,size OBB_ARGS


;/*
;** The arguments have been copied from our automatic data segment onto the
;** compile code data fake stack.  RECTL is on the old stack frame (references
;** off of [BX]).  obba_* is on the new stack frame (references off of [DI]).
;**
;** Compute the new rectangle
;*/

        mov     ax,ds:[bx].rcl_xLeft.lo
        mov     dx,ds:[bx].rcl_xRight.lo
        sub     dx,ax                             ;**New X extent
        mov     ss:[di].obba_cxExt,dx
        mov     cx,ax                             ;**Save a copy of new lhs
        xchg    ax,ss:[di].obba_xDst              ;**Set new dest lhs
        sub     cx,ax                             ;**How much we moved right
        add     ss:[di].obba_xSrc,cx              ;**New source lhs

        mov     ax,ds:[bx].rcl_yBottom.lo
        mov     dx,ds:[bx].rcl_yTop.lo
        sub     dx,ax                             ;**New Y extent
        mov     ss:[di].obba_cyExt,dx
        mov     cx,ax                             ;**Save a copy of new bottom
        xchg    ax,ss:[di].obba_yDst              ;**Set new dest bottom
        sub     cx,ax                             ;**How much we moved up
        add     ss:[di].obba_ySrc,cx              ;**New source bottom

;/*
;** Flip the coordinate system over for the old Window's way where 0,0 is
;** the upper left corner (you know, the way hardware works!)
;*/

        les     si,ss:[di].obba_pddcDst          ;**ES:SI --> DDC
        assumes es,nothing
        mov     si,es:[si].ddc_npsd              ;**Need surface definition part
        mov     ax,es:[si].sd_cy
        sub     ax,ss:[di].obba_yDst
        sub     ax,dx                             ;**DX = obba_cy
        mov     ss:[di].obba_yDst,ax

ifdef SPLITBLT
        mov     bl,es:[si].sd_fb                  ;** fetch dest device flags
endif  ;**SPLITBLT

        test    ss:[di].obba_fsBlt,BBF_HAVE_SOURCE
        jz      @F
        les     si,ss:[di].obba_psdSrc
        assumes es,nothing
        mov     ax,es:[si].sd_cy
        sub     ax,ss:[di].obba_ySrc
        sub     ax,dx                             ;**DX = obba_cy
        mov     ss:[di].obba_ySrc,ax
@@:

;/*
;** Make the Bitblt call and then restore the stack frame
;*/

ifdef SPLITBLT
        test    bl,SD_DEVICE                      ;** destination is the device ?
        jz      do_bitblt_compiled                ;** no -- use compiled blt...
        call    BoardBlt                          ;** yes -- do special board blt code
        jmp     @F
do_bitblt_compiled:
        call    MemBlt                            ;** memory blt specialist
@@:
else
        call    OEMBitblt
endif ;**SPLITBLT
        pop     cx                                ;**CX = old SP
        push    ds                                ;**DS is old SS
        pop     ss                                ;**Restore old SS
        mov     sp,cx                             ;**  and stack pointer
        assumes ss,nothing
        pop     ds                                ;**Restore caller's DS
        assumes ds,Data

        profile exiting

        ret

cEnd    <nogen>

;/***************************************************************************
;*
;* FUNCTION NAME = do_drawbits 
;*
;* DESCRIPTION   = This routine is called by enumerate_clip_rects to invoke the oem  
;*                 drawbits with the passed clipped rectangle.                       
;*
;*                 Registers Preserved:
;*                       DS,BP
;*                
;*                 Registers Destroyed:
;*                       AX,BX,CX,DX,SI,DI,ES
;*
;*                 Calls:
;*                       OEMDrawBits
;*
;* INPUT         = SS:BX --> clip RECTL         
;*                 SS:DI --> OBB_ARGS structure 
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = AX from called routine  
;* RETURN-ERROR  = AX = 0  
;*
;**************************************************************************/

        assumes ds,Data
        assumes es,nothing

cProc   do_drawbits,<PUBLIC,NEAR>
cBegin  <nogen>

        profile entered

;/*
;** Make a copy of the argument for the current rectangle.
;*/

        mov     si,di                             ;**SS:SI --> OBB_ARGS
        add     si,obba_cyExt                     ;**SS:SI --> OBB_ARGS
        sub     sp,size ODB_ARGS
        mov     di,sp
        push    ss
        pop     es
        assumes es,nothing
        .errnz  (size ODB_ARGS) and 1
        mov     cx,(size ODB_ARGS) / 2
        cld
        rep     movs word ptr es:[di],word ptr ss:[si]
        sub     di,size ODB_ARGS

;/*
;** Compute the new rectangle
;*/

        mov     ax,ss:[bx].rcl_xLeft.lo
        mov     dx,ss:[bx].rcl_xRight.lo
        sub     dx,ax                             ;**New X extent
        mov     ss:[di].odba_cxExt,dx
        mov     cx,ax                             ;**Save a copy of new lhs
        xchg    ax,ss:[di].odba_xDst              ;**Set new dest lhs
        sub     cx,ax                             ;**How much we moved right
        add     ss:[di].odba_xSrc,cx              ;**New source lhs

        mov     ax,ss:[bx].rcl_yBottom.lo
        mov     dx,ss:[bx].rcl_yTop.lo
        sub     dx,ax                             ;**New Y extent
        mov     ss:[di].odba_cyExt,dx
        mov     cx,ax                             ;**Save a copy of new bottom
        xchg    ax,ss:[di].odba_yDst              ;**Set new dest bottom
        sub     cx,ax                             ;**How much we moved up
        add     ss:[di].odba_ySrc,cx              ;**New source bottom


;/*
;** Flip the coordinate system over for the old Window's way where 0,0 is
;** the upper left corner (you know, the way hardware works!). Only the
;** destination need to be flipped, the source already have the starting
;** pel at the lowest byte(s).
;*/

        les     si,ss:[di].odba_pddcDst          ;**ES:SI --> DDC
        assumes es,nothing
        mov     si,es:[si].ddc_npsd              ;**Need surface definition part
        mov     ax,es:[si].sd_cy
        sub     ax,ss:[di].odba_yDst
        sub     ax,dx                             ;**DX = obba_cyExt
        mov     ss:[di].odba_yDst,ax

;/*
;**  Make the DrawBits call.
;*/

        call    OEMDrawBits

        profile exiting

        ret

cEnd    <nogen>

;/***************************************************************************
;*
;* FUNCTION NAME = do_stretchblt
;*
;* DESCRIPTION   = This routine is called by enumerate_clip_rects to invoke the oem 
;*                 stretchblt with the passed clipped rectangle.                    
;*
;*                 Registers Preserved:
;*                       DS,BP
;*                 
;*                 Registers Destroyed:
;*                       AX,BX,CX,DX,SI,DI,ES
;*
;*                 Calls:
;*                       OEMBitblt
;*                 
;* INPUT         = SS:BX --> clip RECTL        
;*                 SS:DI --> OBB_ARGS structure
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = AX from called routine
;* RETURN-ERROR  = AX = 0  
;*
;**************************************************************************/
        assumes ds,Data
        assumes es,nothing

cProc   do_stretchblt,<PUBLIC,NEAR>
cBegin  <nogen>

        profile entered

;/*
;** Make a copy of the argument for the current rectangle.
;*/

        mov     si,di                             ;**SS:SI --> OBB_ARGS
        sub     sp,size OSB_ARGS
        mov     di,sp
        push    ss
        pop     es
        assumes es,nothing

ifdef   PALMGR
        .errnz  obba_fsBlt - obba_pmappal - 4

        CPUMode 386

        movs    dword ptr es:[di],dword ptr ss:[si]

        CPUMode 286

        add     si,obba_cyExt - 4                ;**SS:SI --> obba_cyExt
        .errnz  (size OSB_ARGS - 4) and 1
        mov     cx,(size OSB_ARGS - 4) / 2
else
        add     si,obba_cyExt                    ;**SS:SI --> obba_cyExt
        .errnz  (size OSB_ARGS) and 1
        mov     cx,(size OSB_ARGS) / 2
endif   ;**  PALMGR

        cld
        rep     movs word ptr es:[di],word ptr ss:[si]
        sub     di,size OSB_ARGS

;/*
;** Compute the new rectangle
;*/

        mov     ax,ss:[bx].rcl_xLeft.lo
        mov     dx,ss:[bx].rcl_xRight.lo
        sub     dx,ax                             ;**New X extent
        mov     ss:[di].osba_cxExt,dx
        mov     ss:[di].osba_xDst,ax              ;**Set new dest lhs

        mov     ax,ss:[bx].rcl_yBottom.lo
        mov     dx,ss:[bx].rcl_yTop.lo
        sub     dx,ax                             ;**New Y extent
        mov     ss:[di].osba_cyExt,dx
        mov     ss:[di].osba_yDst,ax             ;**Set new dest bottom

;/*
;** Make the Bitblt call and then restore the stack frame
;*/

        cCall   OEMStretchBlt

        profile exiting

        ret

cEnd    <nogen>

sEnd    Code

end
