;*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 = POLYSTYL.ASM
;*
;* DESCRIPTIVE NAME = Polyline styled line drawing device driver.
;*
;*
;* VERSION      V2.0
;*
;* DATE         03/30/87
;*
;* DESCRIPTION
;*
;*   This module contains all of the routines called by POLYLINE.ASM to draw
;*   styled polylines in memory bitmaps or the EGA.  The routines are basically
;*   broken into six different cases.  Lines are categorized as x major,
;*   y major or diagonal.  They are also broken down into simple and
;*   non-simple, or standard, cases; where simple means horizontal, vertical
;*   or on a diagonal.  These simple cases can be drawn much faster than
;*   the standard cases, and are therefore broken out from the rest.
;*
;*   There are similar routines in PLYSOLID.ASM for solid lines to the EGA,
;*   and POLYBITM.ASM for solid lines to memory bitmaps.  While these
;*   routines are all quite similar, they are separated purely for speed
;*   considerations.  POLYLINE.ASM is the dispatching module for all of
;*   these routines, and the run length slice algorithm DDA, which all of
;*   these routines are based on, is explained in that module.
;*
;*   At the end of this module are the *_pixel output routines:
;*   styled_dev_pixel draws the line portions of styled lines to the EGA
;*   styled_bm_pixel act similarly with bitmaps
;*   As needed, the address of one of these routines is loaded
;*   into StyledProc which is called to output each pixel.
;*
;*
;*
;* FUNCTIONS    setup_poly_frame_2
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*
;*****************************************************************************/


        .386

        .xlist

INCL_GPIPRIMITIVES      equ     1
INCL_DDIPATHS           equ     1
DINCL_ENABLE            equ     1
DINCL_BITMAP            equ     1

        .list

        include pmgre.inc
        include driver.inc
        include display.inc
        include polyline.inc
        include extern.inc
        include protos.inc
if SCAN_CNT EQ 768
        include oem_macs.inc
        include assert.mac
endif

        .list

        .MODEL FLAT

        ASSUME  CS:FLAT,SS:FLAT,DS:FLAT,ES:FLAT

        .DATA

        .CODE
_TUNE segment USE32 PUBLIC 'CODE'
        OPTION PROLOGUE:None

        OPTION EPILOGUE:None

;/***************************************************************************
;*
;* FUNCTION NAME = setup_poly_frame_2
;*
;* DESCRIPTION   = This function just encapsulates the following public
;*                 labels:
;*
;*                            dev_styled_horizontal
;*                            dev_styled_vertical
;*                            dev_styled_diagonal
;*
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

setup_poly_frame_2  PROC SYSCALL
 LOCAL   returnvalue:DWORD,
         dwStyleCounter:DWORD,
         Flags:DWORD,
         Count:DWORD,
         Points:DWORD
 LOCAL   npddc:DWORD,
         dwStyleMask:DWORD,
         npfnUnSetup:DWORD,
         CurLineColor:DWORD,
         DrawModeIndex:DWORD,
         cPlanes:DWORD
 LOCAL   cbNextPlane:DWORD,
         dwBitmapROP:DWORD,
         dwStyleStepHorz:DWORD,
         dwStyleStepVert:DWORD,
         dwStyleStepDiag:DWORD
 LOCAL   dwStyleStepHorzTmp:DWORD,
         dwStyleStepVertTmp:DWORD,
         offNextLine:DWORD,
         cbScanSize:DWORD,
         cbHugeScanWrap:DWORD,
         cySurface:DWORD
 LOCAL   cScansPerSegment:DWORD,
         pSurfaceStart:DWORD,
         anpfnRunRoutines:DWORD,
         LineStyle:DWORD,
         npfnPassSetup:DWORD,
         cPasses:DWORD,
         lsg:LINESEGMENT
 LOCAL   dwStyleStepRun:DWORD,
         dwStyleStepSide:DWORD,
         dwActiveStyleCounter:DWORD,
         dwActiveStyleMask:DWORD,
         yA:DWORD,
         cScans:DWORD,
         cA:DWORD,
         cB:DWORD,
         cm:DWORD
 LOCAL   npfnRunRoutine:DWORD,
         iWhichDDA:DWORD,
         dwError:DWORD,
         dwFracS:DWORD,
         dwRotBitMask:DWORD,
         cbScanAddressDelta:DWORD,
         cbSideStepAddressDelta:DWORD,
         cbHugeScanDelta:DWORD,
         selHugeDelta:DWORD,
         dwScan:DWORD
 LOCAL   pSurfaceAddress:DWORD,
         cTmpScans:DWORD,
         dwTmpError:DWORD,
         dwTmpScan:DWORD,
         dwTmpRotBitMask:DWORD,
         dwTmpActiveStyleCounter:DWORD,
         dwTmpActiveStyleMask:DWORD,
         cTmpPasses:DWORD,
         TmpCurLineColor:DWORD
if SCAN_CNT EQ 768
                        LOCAL   start_bank:DWORD
endif

        public  dev_styled_horizontal

;/***************************************************************************
;*
;* PUBLIC ROUTINE  dev_styled_horizontal
;*
;* DESCRIPTION   = Draws a styled horizontal line on the EGA.
;*
;*                 Registers Destroyed:
;*                       AX,CX,SI
;*                 Registers Preserved:
;*                       DX,BP,ES
;*
;* INPUT         = DS:DI = EGA address
;*                 BL = rotating bit mask
;*                 CX = number of bits to draw
;*                 DX = EGA_BASE + GRAF_DATA
;*
;* OUTPUT        = DS:DI = new EGA address
;*                 BL = new rotating bit mask
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

dev_styled_horizontal::

        DebugMsg <dev_styled_horizontal, polystyl, CLIFFL>


;/*
;** load all quantities into registers
;*/

        mov     al,bl                             ; AL = rotating bit mask
        mov     bl,BYTE PTR dwActiveStyleCounter ; BL = style error
        mov     ah,BYTE PTR dwActiveStyleMask  ; AH = style mask
        mov     esi,dwStyleStepHorz              ; SI = style step

;/*
;** run the loop
;*/

        dec     ecx
        jz      dsh_last_byte

dsh_loop:

;/*
;** draw the pixel if the mask says so
;*/

        or      ah,ah
        jns     @F
        out     dx,al
        or      byte ptr [edi],0FFh
@@:

;/*
;** advance to the next pixel
;*/

        ror     al,1
        adc     edi,0

;/*
;** advance the style mask
;*/

        movzx   ebx,bl
        add     ebx,esi
        xchg    cl,bh
        rol     ah,cl
        mov     cl,bh
        loop    dsh_loop

;/*
;** draw the last pixel if the mask says so
;*/

dsh_last_byte:

        or      ah,ah
        jns     @F
        out     dx,al
        or      byte ptr [edi],0FFh
@@:

;/*
;** unload all registers
;*/

        mov     BYTE PTR dwActiveStyleCounter,bl
        mov     BYTE PTR dwActiveStyleMask,ah
        mov     bl,al
        ret

        public  dev_styled_vertical

;/***************************************************************************
;*
;* PUBLIC ROUTINE  dev_styled_vertical
;*
;* DESCRIPTION   = Draws a stlyed vertical line on the EGA.
;*
;*                 Registers Destroyed:
;*                       CX,SI
;*                 Registers Preserved:
;*                       DX,BP,ES
;*
;* INPUT         = DS:DI = EGA address
;*                 BL = rotating bit mask
;*                 CX = number of bits to draw
;*                 DX = EGA_BASE + GRAF_DATA
;*
;* OUTPUT        = DS:DI = new EGA address
;*                 BL = new rotating bit mask
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

dev_styled_vertical::

        DebugMsg <dev_styled_vertical, polystyl, CLIFFL>


;/*
;** load all quantities into registers
;*/

        mov     al,bl                             ; AL = rotating bit mask
        out     dx,al
        mov     bl,BYTE PTR dwActiveStyleCounter ; BL = style error
        mov     ah,BYTE PTR dwActiveStyleMask  ; AH = style mask
        mov     esi,cbScanAddressDelta           ; SI = scan delta

;/*
;** run the loop
;*/

        dec     ecx
        jz      dsv_last_byte

dsv_loop:

;/*
;** draw the pixel if the mask says so
;*/

        or      ah,ah
        jns     @F
        or      byte ptr [edi],0FFh
@@:

;/*
;** advance to the next pixel
;*/

        add     edi,esi

;/*
;** advance the style mask
;*/

        movzx   ebx,bl
        add     ebx,dwStyleStepVert
        xchg    cl,bh
        rol     ah,cl
        mov     cl,bh
if SCAN_CNT EQ 768
        dec     dwScan
        loopnz  dsv_loop
        jnz     dsv_last_byte

        ; there was a huge overflow

        push    eax
        push    edx

        mov     edx,start_bank
        add     edx,selHugeDelta
        mov     start_bank,edx
        SetBankRW
        assert  edi,NE,pVRAMInstance
        mov     eax,010000h
        cmp     edi,pVRAMInstance
        jb      @F
        neg     eax
@@:
        add     edi,eax
        mov     edx,cScansPerSegment
        mov     dwScan,edx

        pop     edx
        pop     eax
        or      ecx,ecx
        jnz     dsv_loop
else
        loop    dsv_loop
endif

;/*
;** draw the last pixel if the mask says so
;*/

dsv_last_byte:

        or      ah,ah
        jns     @F
        or      byte ptr [edi],0FFh
@@:

;/*
;** unload all registers
;*/

        mov     BYTE PTR dwActiveStyleCounter,bl
        mov     BYTE PTR dwActiveStyleMask,ah
        mov     bl,al
        ret

        public  dev_styled_diagonal

;/***************************************************************************
;*
;* PUBLIC ROUTINE  dev_styled_diagonal
;*
;* DESCRIPTION   = Draws a stlyed diagonal line on the EGA.
;*
;*                 Registers Destroyed:
;*                       CX,SI
;*                 Registers Preserved:
;*                       DX,BP,ES
;*
;* INPUT         = DS:DI = EGA address
;*                 BL = rotating bit mask
;*                 CX = number of bits to draw
;*                 DX = EGA_BASE + GRAF_DATA
;*
;* OUTPUT        = DS:DI = new EGA address
;*                 BL = new rotating bit mask
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

dev_styled_diagonal::

        DebugMsg <dev_styled_diagonal, polystyl, CLIFFL>


;/*
;** load all quantities into registers
;*/

        mov     al,bl                             ; AL = rotating bit mask
        mov     bl,BYTE PTR dwActiveStyleCounter ; BL = style error
        mov     ah,BYTE PTR dwActiveStyleMask  ; AH = style mask
        mov     esi,cbScanAddressDelta           ; SI = scan delta

;/*
;** run the loop
;*/

        dec     ecx
        jz      dsd_last_byte
dsd_loop:

;/*
;** draw the pixel if the mask says so
;*/

        or      ah,ah
        jns     @F
        out     dx,al
        or      byte ptr [edi],0FFh
@@:

;/*
;** advance to the next pixel
;*/

        ror     al,1
        adc     edi,esi

;/*
;** advance the style mask
;*/

        movzx   ebx,bl
        add     ebx,dwStyleStepDiag
        xchg    cl,bh
        rol     ah,cl
        mov     cl,bh
if SCAN_CNT EQ 768
        dec     dwScan
        loopnz  dsd_loop                          ; exit on huge overflow
        jnz     dsd_last_byte

;/*
;** there was a huge overflow
;*/

        push    eax
        push    edx

        mov     edx,start_bank
        add     edx,selHugeDelta
        mov     start_bank,edx
        SetBankRW

        assert  edi,NE,pVRAMInstance
        mov     eax,010000h
        cmp     edi,pVRAMInstance
        jb      @F
        neg     eax
@@:
        add     edi,eax
        mov     edx,cScansPerSegment
        mov     dwScan,edx

        pop     edx
        pop     eax
        or      ecx,ecx
        jnz     dsd_loop
else
        loop    dsd_loop
endif

;/*
;** draw the last pixel if the mask says so
;*/

dsd_last_byte:
        or      ah,ah
        jns     @F
        out     dx,al
        or      byte ptr [edi],0FFh
@@:

;/*
;** unload all registers
;*/

        mov     BYTE PTR dwActiveStyleCounter,bl
        mov     BYTE PTR dwActiveStyleMask,ah
        mov     bl,al
        ret

setup_poly_frame_2  ENDP
_TUNE ENDS
        end
