cgautils.asm

来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 792 行 · 第 1/3 页

ASM
792
字号
else
    PlotJmp dw BitReplace,BitXor,BitAnd,BitOr
endif

SetupAction:
ifdef __386__
        movzx   _ebx,word ptr ss:__PlotAct
        jmp     cs:PlotJmp[_ebx*4]
else
        mov     bx,ss:__PlotAct
        shl     bx,1
        jmp     cs:PlotJmp[bx]
endif

ifdef __386__
    FillJmp dd _CoRep_,_CoXor_,_CoAnd_,_CoOr_
else
    FillJmp dw _CoRep_,_CoXor_,_CoAnd_,_CoOr_
endif

;=========================================================================
;
;   Zap routines
;
;   Input       ES:_EDI,DH   screen memory
;               AL          colour (unmasked)
;               BX          not used
;               CX          number of pixels to fill
;
;=========================================================================
;
;   Fill routines
;
;   Input       ES:_EDI,DH   screen memory
;               AL          colour (unmasked)
;               BH,BL       mask offset, fill mask
;               CX          number of pixels to fill
;
;==========================================================================

_Pix1Zap_:                          ; zap fill ( 1 bit per pixel )
        push    _ebp
        push    _esi
        or      al,al               ; if given colour is zero
        _if     e
          xor     bl,bl             ; colour is zero
        _else
          mov     bl,0ffh           ; replicate 1 across byte
        _endif
        mov     bh,0ffh             ; mask is ff (affect all bits)
        jmp     short fill_1_common

_Pix1Fill_:                         ; fill with style ( 1 bit per pixel )
        push    _ebp
        push    _esi
        cmp     word ptr ss:__Transparent,0
        _if     e                   ; if _Transparent == 0
          mov     bh,0ffh           ; - bit mask is ff (affect all bits)
        _else                       ; else
          mov     bh,bl             ; - bit mask is fill mask (affect only the mask bits)
        _endif                      ; endif
        or      al,al               ; if colour is zero
        _if     e                   ; then
          mov     bl,al             ; - colour is zero
        _endif                      ; endif (else colour is fill mask)

fill_1_common:                      ; at this point bl = colour, bh = mask

ifdef __386__
        movzx   _esi,word ptr ss:__PlotAct
        mov     _esi,cs:FillJmp[_esi*4]
else                                ; load address of plot function
        mov     si,ss:__PlotAct
        shl     si,1
        mov     si,cs:FillJmp[si]
endif
        mov     _ebp,_ecx             ; get count in bp

        or      dh,dh               ; if bit_pos != 0
        _if     ne                  ; (doesn't start on byte boundary)
          mov     cl,dh             ; - get bit_pos
          mov     ah,80h            ; - initial value of mask
          shr     ah,cl             ; - shift mask into position
          xor     ch,ch             ; - ch will be mask for wanted bits
          _loop                     ; - loop
            or      ch,ah           ; - - put bit in
            dec     _ebp             ; - - count--
            _quif   e               ; - - quif count == 0
            shr     ah,1            ; - - move to next bit
          _until    c               ; - until bit comes out
          mov     al,bl             ; - get colour
          and     al,ch             ; - keep bits of colour we want
          and     ch,bh             ; - keep only mask bits
          not     ch                ; - bit mask is complement
          call    _esi               ; - plot the pixels
          inc     _edi               ; - move to next byte
        _endif                      ; endif

        mov     _edx,_ebp             ; get count
        mov     cl,3                ; convert to byte count
        shr     _edx,cl              ; . . .
        _if     ne                  ; if byte count != 0
          mov     al,bl             ; - get colour
          mov     ch,bh             ; - get mask
          not     ch                ; - . . .
          _guess                    ; - guess (can use fast method)
            cmp     word ptr ss:__PlotAct,0
            _quif   ne              ; - - quif if its not replace mode
            or      ch,ch           ; - -
            _quif   ne              ; - - quif if the mask is not zero
            mov     _ecx,_edx         ; - - use fast fill
            cld                     ; - -
            rep     stosb           ; - - fill buffer until( --count == 0 )
          _admit                    ; - admit (use slow method)
            _loop                   ; - - loop
              call    _esi           ; - - - plot byte
              inc     _edi           ; - - - move to next byte
              dec     _edx           ; - - - count--
              _quif   e             ; - - - quif count == 0
            _endloop                ; - - endloop
          _endguess                 ; - endguess
        _endif                      ; endif

        and     _ebp,7               ; if bit count != 0
        _if     ne                  ; then
          mov     _ecx,8             ; - mask = ff << ( 8 - bit count )
          sub     _ecx,_ebp           ; - . . .
          mov     ch,0ffh           ; - ch will be mask for wanted bits
          shl     ch,cl             ; - . . .
          mov     al,bl             ; - get colour
          and     al,ch             ; - keep bits of colour we want
          and     ch,bh
          not     ch                ; - bit mask is complement
          call    _esi               ; - plot the pixels
        _endif                      ; endif

        pop     _esi
        pop     _ebp
        ret

TwoBitTab   db  00000000b
            db  01010101b
            db  10101010b
            db  11111111b

_Pix2Zap_:                          ; Zap fill routine ( 2 bits per pixel )
        push    _ebp
        push    _esi
        mov     _ebp,_ecx             ; move count to bp
        mov     ah,dh               ; move bit offset into ah

        mov     _ebx,offset TwoBitTab
        xlat    cs:TwoBitTab        ; get extended colour
        mov     dl,al               ; place colour into dx
        mov     dh,al
        mov     _ebx,0ffffh          ; bit mask is ffff (affect all bits)
        jmp     fill_2_common

_Pix2Fill_:                         ; fill style routine ( 2 bits per pixel)
        push    _ebp
        push    _esi
        mov     _ebp,_ecx             ; move count to bp
        mov     ah,dh               ; move bit offset into ah

        mov     _ecx,8               ; loop index
        xor     _esi,_esi             ; construct the extended fill mask
do_mask:                            ;   for 2 bpp
          shr     bl,1              ; check each bit in the fill mask
          _if     c
            or      _esi,11B         ; bit is set
          _endif
          ror     si,1              ; rotate the mask (16 bits only)
          ror     si,1
        loop    do_mask
        mov     cl,bh               ; save mask offset

        mov     _ebx,offset TwoBitTab
        xlat    cs:TwoBitTab        ; get extended colour
        mov     dl,al               ; place colour into dx
        mov     dh,al
        and     _edx,_esi             ; keep only bits in fill mask
        cmp     word ptr ss:__Transparent,0
        _if     e                   ; if _Transparent == 0
          mov     _ebx,0ffffh        ; - bit mask is ffff (affect all bits)
        _else                       ; else
          mov     _ebx,_esi           ; - bit mask is fill mask (affect only the mask bits)
       _endif                       ; endif

        cmp     cl,3                ; if mask offset > 3
        _if     g                   ; then
          xchg    dh,dl             ; - flip colour and mask
          xchg    bh,bl             ; - to use other half of byte
        _endif                      ; endif

fill_2_common:
        ; at this point we now
        ;   bp - count
        ;   ah - bit offset
        ;   bx - bit mask
        ;   dx - colour mask
        ;   cx - scratch register
        ;   si - will hold address of plot routine

ifdef __386__
        movzx   _esi,word ptr ss:__PlotAct
        mov     _esi,cs:FillJmp[_esi*4]
else                                ; load address of plot function
        mov     si,ss:__PlotAct
        shl     si,1
        mov     si,cs:FillJmp[si]
endif
        or      ah,ah               ; if bit_pos != 0
        _if     ne                  ; (doesn't start on byte boundary)
          mov     cl,ah             ; - get bit_pos
          mov     ah,11000000b      ; - initial value of mask
          shr     ah,cl             ; - shift mask into position
          xor     ch,ch             ; - ch will be mask for wanted bits
          _loop                     ; - loop
            or      ch,ah           ; - - put bit in
            dec     _ebp             ; - - count--
            _quif   e               ; - - quif count == 0
            shr     ah,1            ; - - move to next pixel
            shr     ah,1            ; - - . . .
          _until    c               ; - until bit comes out
          mov     al,dh             ; - get colour
          and     al,ch             ; - keep bits of colour we want
          and     ch,bh             ; - and with fill mask
          not     ch                ; - bit mask is complement
          call    _esi               ; - plot the pixels
          inc     _edi               ; - move to next byte
          xchg    dh,dl             ; - get ready for next byte
          xchg    bh,bl             ; - . . .
        _endif                      ; endif

        push    _ebp                 ; save count
        shr     _ebp,1               ; convert to byte count
        shr     _ebp,1               ; . . .
        _if     ne                  ; if byte count != 0
          mov     al,dh             ; - get colour
          mov     ch,bh             ; - get mask
          not     ch                ; - . . .
          _guess                    ; - guess (can use fast method)
            cmp     word ptr ss:__PlotAct,0
            _quif   ne              ; - - quif if its not replace mode
            cmp     _ebx,0ffffh      ; - -
            _quif   ne              ; - - quif if the mask is not ffff
            cmp     dl,dh           ; - -
            _quif   ne              ; - - quif if two parts of colour not same
            mov     _ecx,_ebp         ; - - use fast fill
            cld                     ; - -
            rep     stosb           ; - - fill buffer until( --count == 0 )
          _admit                    ; - admit (use slow method)
            _loop                   ; - - loop
              call    _esi           ; - - - plot byte
              inc     _edi           ; - - - move to next byte
              xchg    dh,dl         ; - - - get ready for next byte
              xchg    bh,bl         ; - - - . . .
              dec     _ebp           ; - - - count--
              _quif   e             ; - - - quif count == 0
              mov     al,dh         ; - - - get colour
              mov     ch,bh         ; - - - get mask
              not     ch            ; - - - . . .
            _endloop                ; - - endloop
          _endguess                 ; - endguess

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?