egautils.asm

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

ASM
1,062
字号
;*****************************************************************************
;*
;*                            Open Watcom Project
;*
;*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;*  ========================================================================
;*
;*    This file contains Original Code and/or Modifications of Original
;*    Code as defined in and that are subject to the Sybase Open Watcom
;*    Public License version 1.0 (the 'License'). You may not use this file
;*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;*    provided with the Original Code and Modifications, and is also
;*    available at www.sybase.com/developer/opensource.
;*
;*    The Original Code and all software distributed under the License are
;*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;*    NON-INFRINGEMENT. Please see the License for the specific language
;*    governing rights and limitations under the License.
;*
;*  ========================================================================
;*
;* Description:  Graphics library EGA specific code.
;*
;*****************************************************************************


include graph.inc

        extrn   __PlotAct : word
        extrn   __Transparent : word

        modstart egautils,WORD

        xdefp   _EGAMoveUpHi_
        xdefp   _EGAMoveUpLo_
        xdefp   _EGAMoveDownHi_
        xdefp   _EGAMoveDownLo_
        xdefp   _EGAMoveLeft_
        xdefp   _EGAMoveRight_
        xdefp   _EGARep_
        xdefp   _EGAGetDot_
        xdefp   _EGAGetDotEO_
        xdefp   _EGAGetDotMono_
        xdefp   _EGAZap_
        xdefp   _EGAZapEO_
        xdefp   _EGAZapMono_
        xdefp   _EGAFill_
        xdefp   _EGAFillEO_
        xdefp   _EGAFillMono_
        xdefp   _EGAPixCopy_
        xdefp   _EGAPixCopyEO_
        xdefp   _EGAPixCopyMono_
        xdefp   _EGAReadRow_
        xdefp   _EGAReadRowEO_
        xdefp   _EGAReadRowMono_
        xdefp   _EGAScanLeft_
        xdefp   _EGAScanLeftEO_
        xdefp   _EGAScanLeftMono_
        xdefp   _EGAScanRight_
        xdefp   _EGAScanRightEO_
        xdefp   _EGAScanRightMono_

;=========================================================================
;
;   EGA constants
;
;=========================================================================

SEQADDR =       03C4h
GRADDR  =       03CEh

;   EGA sequence registers

MAPMASK =       02h

;   EGA control registers

SRREG   =       00h
ESRREG  =       01h
CMPREG  =       02h
ACTN    =       03h
RMSEL   =       04h
MODEREG =       05h
DONTCARE =      07h
EGAMASK =       08h

;   EGA mode values

WRITE_MODE_0    =       00h
WRITE_MODE_1    =       01h
WRITE_MODE_2    =       02h
READ_MODE_0     =       00h
READ_MODE_1     =       08h
EVEN_ODD_MODE   =       10h

MonoTab db      00000000B       ; black
        db      00000011B       ; video
        db      00001100B       ; blink
        db      00001111B       ; bright

;=========================================================================
;
;   Movement primitives
;
;   Input       ES:_EDI      screen memory
;               AL          colour
;               CH          mask
;
;   Output      same        altered as per move
;
;=========================================================================

        db      E_EGAMoveUpHi-_EGAMoveUpHi_
_EGAMoveUpHi_:
        sub     _edi,80          ; move up in 640 pixel wide mode
E_EGAMoveUpHi:
        ret

        db      E_EGAMoveDownHi-_EGAMoveDownHi_
_EGAMoveDownHi_:
        add     _edi,80          ; move down in 640 pixel wide mode
E_EGAMoveDownHi:
        ret

        db      E_EGAMoveUpLo-_EGAMoveUpLo_
_EGAMoveUpLo_:
        sub     _edi,40          ; move up in 320 pixel wide mode
E_EGAMoveUpLo:
        ret

        db      E_EGAMoveDownLo-_EGAMoveDownLo_
_EGAMoveDownLo_:
        add     _edi,40          ; move down in 320 pixel wide mode
E_EGAMoveDownLo:
        ret

        db      E_EGAMoveLeft-_EGAMoveLeft_
_EGAMoveLeft_:                  ; move left 1 pixel
        rol     ch,1
        sbb     _edi,0
E_EGAMoveLeft:
        ret

        db      E_EGAMoveRight-_EGAMoveRight_
_EGAMoveRight_:                 ; move right 1 pixel
        ror     ch,1
        adc     _edi,0
E_EGAMoveRight:
        ret

;=========================================================================
;
;   Plotting primitive
;
;   Input       ES:_EDI      screen memory
;               AL          colour
;               CH          mask
;
;=========================================================================

        db      E_EGARep-_EGARep_
_EGARep_:
        push    _edx
        mov     cl,al           ; copy colour
        mov     al,EGAMASK
        mov     _edx,GRADDR
        mov     ah,ch           ; mask
        out     dx,ax           ; set the set/reset register to colour
        mov     al,cl           ; get colour back
        xchg    cl,es:[_edi]     ; read to latch data, output data
        pop     _edx
E_EGARep:
        ret

;=========================================================================
;
;   GetDot routines
;
;   Input       ES:_EDI      screen memory
;               CL          bit position
;
;   Output      AX          colour of pixel at location
;
;=========================================================================

_EGAGetDotMono_:        ; for mono ega cards with > 64K
        push    _ebx
        mov     _ebx,0202h       ; bh = first bit plane, bl = increment
        jmp     GetDotCommon

_EGAGetDotEO_:          ; even/odd modes
        push    _ebx
        mov     _ebx,0202h       ; bh = first bit plane, bl = increment
        test    _edi,1           ; if odd plane
        _if     ne              ; then
          inc     bh            ; - use planes 3 & 1 instead of 2 & 0
        _endif                  ; endif
        jmp     GetDotCommon

_EGAGetDot_:
        push    _ebx
        mov     _ebx,0301h       ; bh = first bit plane, bl = increment
GetDotCommon:
        push    _edx             ; save dx
        mov     _edx,GRADDR      ; load graphics register
        mov     ch,80h          ; prepare bit mask
        shr     ch,cl           ; . . .
        mov     al,RMSEL        ; select read map select register
        out     dx,al           ; . . .
        inc     _edx             ; point to data register

        xor     cl,cl           ; colour = 0
        mov     al,bh           ; plane = first bit plane
        _loop                   ; loop
          shl     cl,1          ; - move colour bit over
          out     dx,al         ; - select plane
          test    ch,es:[_edi]   ; - if bit is on in byte
          _if     ne            ; - then
            or      cl,1        ; - - set bit in pixel
          _endif                ; - endif
          sub     al,bl         ; - plane -= plane increment
        _until  l               ; until( plane < 0 )

        mov     al,cl           ; get colour in AX
        xor     ah,ah           ; clear high byte
        pop     _edx             ; restore dx
        pop     _ebx             ; and bx
        ret

;=========================================================================
;
;   PixCopy routines
;
;   Input       ES:_EDI,DH   screen memory
;               SI:_EAX,DL   buffer to copy from
;               CX          number of pixels to copy
;
;=========================================================================

_EGAPixCopyEO_:
        push    _ebp             ; save registers
        push    ds
        docall  pcopy_common
        mov     ah,0100B        ; plane mask
        _loop
          mov     al,ah
          test    _edi,1         ; if odd address, shift mask left 1
          _if     ne
            shl     al,1
          _endif
          push    _ecx           ; save offsets
          push    _ebp           ; put count on stack
          push    _edi           ; put dest addr on stack
          push    _esi           ; put scr addr on stack
          docall  start_put
          mov     ch,dh
          _loop                 ; main loop transferring full bytes
            mov     al,ah       ; get mask
            test    _edi,1       ; if odd address, shift mask over 1
            _if     ne
              shl     al,1
            _endif
            mov     _edx,SEQADDR+1
            out     dx,al       ; set bit mask reg
            mov     dh,ch
            mov     dl,[_esi]    ; get next byte
            inc     _esi         ; increment through source buffer
            mov     ch,dl
            shl     _edx,cl      ; do bit offset
            sub     _ebp,8       ; 8 pixels/byte
            cmp     _ebp,8
            _quif   l
            xchg    dh,es:[_edi] ; write out byte (need to xchg to load latches)
            inc     _edi         ; increment through screen memory
          _endloop
          docall  finish_put
          pop     _esi           ; restore src
          add     _esi,_ebx       ; add offset to next plane
          pop     _edi           ; restore destination
          pop     _ebp           ; restore count
          pop     _ecx           ; restore offsets
          shr     ah,1          ; next bit plane
          shr     ah,1
        _until  e
done_pixcopy:
        mov     _edx,SEQADDR     ; set map mask register to all planes
        mov     ah,0Fh
        mov     al,MAPMASK
        out     dx,ax
        pop     ds
        pop     _ebp
        ret

_EGAPixCopyMono_:
        push    _ebp             ; save registers
        push    ds
        docall  pcopy_common
        mov     al,0100B        ; set map mask to start at bit plane 2
        docall  put_bitplane
        mov     al,0001B        ; then do bit plane 0
        docall  put_bitplane
        jmp     done_pixcopy

_EGAPixCopy_:
        push    _ebp             ; save registers
        push    ds
        docall  pcopy_common
        mov     ah,1000B        ; set map mask to start at bit plane 3
        _loop
          mov     al,ah
          docall  put_bitplane
          shr     ah,1          ; next bit plane
        _until  c
        jmp     done_pixcopy

pcopy_common:
        mov     ds,si           ; get source in ds:si
        mov     _esi,_eax
        mov     _ebp,_ecx         ; save count
        mov     cl,dh           ; move dest bit offset
        mov     ch,dl           ; move src bit offset
        mov     _edx,GRADDR      ; get graphics address
        mov     al,MODEREG      ; set write mode
        mov     ah,READ_MODE_0+WRITE_MODE_0
        out     dx,ax
        mov     al,EGAMASK
        out     dx,al           ; select mask register
        mov     _edx,SEQADDR
        mov     al,MAPMASK      ; select sequencer map mask register
        out     dx,al
        ret

put_bitplane:
        push    _ecx             ; save offsets
        push    _ebp             ; put count on stack
        push    _edi             ; put dest addr on stack
        push    _esi             ; put scr addr on stack
        docall  start_put
        cmp     cl,0
        _if     e
          mov     _ecx,_ebp
          and     _ebp,111B      ; bp mod 8
          shr     _ecx,1         ; divide count by 8 pixels per byte
          shr     _ecx,1
          shr     _ecx,1
          dec     _ecx
          jle     short finished ; quit if count is zero
          dec     _esi           ; back up 1
          cmp     word ptr ss:__PlotAct,0

⌨️ 快捷键说明

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