home *** CD-ROM | disk | FTP | other *** search
-
- ;************************************************************************
- ; Transfer Bit Aligned Block of dimensions Width x Height, from *
- ; source, with upper left corner at (X_Src,Y_Src), to destination with *
- ; upper left corner at (X_Dst,Y_Dst), using function fn. *
- ; Entry: X_Srs, Y_Src - Source upper left *
- ; X_Dst, Y_Dst - Destination upper left *
- ; BWidth,BHeight- Dimensions of the block *
- ; Fn - Logical function (Copy, AND, OR, XOR) *
- ;************************************************************************
-
- ;xxxx add later traversing x in reverse for overlapped src and dst
-
- X_Src EQU [BP+4] ;Formal parameters on the stack
- Y_Src EQU [BP+6]
- X_Dst EQU [BP+8]
- Y_Dst EQU [BP+10]
- BWidth EQU [BP+12]
- BHeight EQU [BP+14]
- Fn EQU [BP+16]
-
- HBYTES EQU 80 ;Number of bytes per scanline
- GRF_SEG EQU 0A000H ;Segment for display buffer
-
- Y_Incr EQU WORD PTR [BP-2] ;Local variables
- First_Mask EQU BYTE PTR [BP-4]
- InFirst EQU WORD PTR [BP-6]
- Last_Mask EQU BYTE PTR [BP-8]
- Read_Plane EQU BYTE PTR [BP-10]
- Lower_Mask EQU BYTE PTR [BP-12]
- Upper_Mask EQU BYTE PTR [BP-14]
- Src_Address EQU WORD PTR [BP-16]
- Dst_Address EQU WORD PTR [BP-18]
- Block_Dx EQU WORD PTR [BP-20]
- Block_Dy EQU WORD PTR [BP-22]
-
- PUBLIC _BitBlt
-
- _BitBlt PROC NEAR
- PUSH BP
- MOV BP,SP
-
- SUB SP,24 ;Setup local variables
-
- PUSH DS ;Presrve segment registers
- PUSH ES
- PUSH DI
- PUSH SI
-
- ;-------------------------------------------------------------
- ;--- COMPUTE MASKS FOR FIRST AND LAST BYTE WITHIN A RASTER
- ; ROTATION FACTOR, AND MASKS FOR HI AND LOW BITS AFTER ROTATION
- ; ENABLE ROTATION AND LOGICAL FUNCTIONS IN GRAPHICS CONTROLLER
- ;-------------------------------------------------------------
-
- MOV CX,X_Dst ; NUMBER OF CLEAR BITS IN FIRST BYTE
- AND CX,7
- MOV First_Mask,0FFH ; COMPUTE MASK TO CLEAR LEADING BITS
- SHR First_Mask,CL
- MOV AX,8
- SUB AX,CX
- MOV InFirst,AX
-
- ;MASK TO KEEP BITS IN LAST BYTE (PARTIAL BYTE)
-
- MOV CX,X_Dst ; GET ADDRESS OF LAST BIT
- ADD CX,BWidth
- AND CX,7 ; POSITION JUST AFTER LAST BIT
- MOV Last_Mask,0FFH ; COMPUTE MASK TO KEEP BITS AFTER
- SHR Last_Mask,CL
- NOT Last_Mask ; COMPLEMENT TO KEEP LEADING BITS
-
- ;BITS FROM SOURCE BYTE MUST BE ALLIGNED WITH BITS IN THE
- ;DESTINATION BYTE. HERE IS COMPUTED THE ROTATION AND THE
- ;TWO MASKS NEEDED TO ISOLOTATE TWO HALVES OF THE BYTE
-
- ; COMPUTE ROTATION
-
- MOV CX,X_Dst ; COMPUTE BIT DISTANCE BETWEEN
- SUB CX,X_Src ;... BIT POSITIONS IN FIRST BYTES
- AND CX,7 ; ... OF SOURCE AND DESTINATION BYTES
- ; ... AS (SRC-DST)&7
- MOV AX,00FFH ;Compute masks for non-zero rotation
- ROR AX,CL
- MOV Lower_Mask,AL ;Save the masks
- MOV Upper_Mask,AH
-
- MOV DX,3CEH ;Address of GRAPHICS controller
- MOV AL,3 ;Index for DATA ROTATE & FN SELECT
- OUT DX,AL ;Select DATA ROTATE & FN SELECT REG
- INC DX
- MOV AL,CL ;Fetch rotate count
- MOV AH,Fn ;Fetch logical function
- AND AH,3 ;Move logical function into
- SHL AH,1 ;bits 3 and 4
- SHL AH,1
- SHL AH,1
- OR AL,AH
- OUT DX,AL ;Write value into DATA ROTATE... reg
-
- ;-------------------------------------------------------------
- ;--- COMPUTE ABSOLUTE ADDRESS OF SOURCE AND DESTINATION
- ;-------------------------------------------------------------
-
- MOV WORD PTR Y_Incr,HBYTES ;Initialize y traversal as normal
-
- ;Because of possible overlap we must adjust direction of traversal
- ;If source block is above the destination then reverse Y traversal
- ;If source block is to the left, then reverse X traversal
-
- MOV AX,Y_Src ;Compare source and destination Y
- MOV BX,Y_Dst
- CMP AX,BX
- JLE Compute_Address ;...Leave alone if src <= dst
- ADD AX,BHeight ;Begin with last raster in block
- DEC AX
- ADD BX,BHeight
- DEC BX
- MOV Y_Src,AX
- MOV Y_Dst,BX
- NEG WORD PTR Y_Incr ;And traverse backwards
- Compute_Address:
- MOV AX,Y_Src ;Compute offset for source
- MOV BX,HBYTES ;as offset = y * 80 + x/8
- MUL BX
- MOV SI,X_Src
- SHR SI,1
- SHR SI,1
- SHR SI,1
- ADD SI,AX
- MOV Src_Address,SI
-
- MOV AX,Y_Dst ;Compute offset for destination
- MOV BX,HBYTES ;as offset = y * 80 + x/8
- MUL BX
- MOV DI,X_Dst
- SHR DI,1
- SHR DI,1
- SHR DI,1
- ADD DI,AX
- MOV Dst_Address,DI
-
- MOV AX,GRF_SEG ;Setup segment
- MOV ES,AX
- MOV DS,AX
-
- ;-------------------------------------------------------------
- ;--- ENABLE NEXT PLANE FOR READ AND WRITE
- ;-------------------------------------------------------------
-
- MOV AL,3 ;Initialize counter of planes
- MOV Read_Plane,AL
- Plane_Loop:
- MOV AX,BWidth ;Copy dimensions of the block
- MOV Block_Dx,AX
- MOV AX,BHeight
- MOV Block_Dy,AX
- MOV SI,Src_Address ;Fetch source address
- MOV DI,Dst_Address ;Fetch destination address
- MOV CL,Read_Plane ;Fetch next plane to do
- MOV AH,1 ;Use plane number to setup value
- SHL AH,CL ;for WRITE PLANE SELECT register
- MOV DX,3C4H ;Fetch address of SEQUENCER
- MOV AL,2 ;Index for WRITE PLANE SELECT register
- OUT DX,AL ;Select register
- INC DX
- MOV AL,AH ;Fetch value
- OUT DX,AL ;Write value into register
- MOV DX,3CEH ;Fetch address of GRAPHICS controller
- MOV AL,4 ;Index for READ PLANE SELECT register
- OUT DX,AL ;Select register
- INC DX
- MOV AL,CL ;Fetch plane number
- OUT DX,AL ;Write plane number into register
- DEC DX
- MOV AL,8 ;Index for BIT MASK register
- OUT DX,AL ;Select BIT MASK register
- INC DX
-
- ;-------------------------------------------------------------
- ; RASTER LOOP IS DONE IN FOUR STEPS
- ; (1) MASKS AND ROTATION FACTOR IS COMPUTED TO ALIGN SRC AND DEST
- ; (2) LEADIING PARTIAL BYTE OF DESTINATION IS MODIFIED
- ; (3) FULL BYTES OF DESTINATION ARE MODIFIED
- ; (4) TRAILLING PARTIAL BYTE OF DESTINATION IS MODIFIED
- ;-------------------------------------------------------------
-
- ;-------------------------------------------------------------
- ;--- GET ENOUGH BITS FROM SOUCE TO CONSTRUCT FIRST PARTIAL BYTE OF DST
- ;-------------------------------------------------------------
-
- Raster_Loop:
- MOV CX,Block_Dx ;Number of bits to copy
- PUSH SI ;Preserve addresses for next raster loo
- PUSH DI
-
- MOV AX,X_Src ;Check if need one or two bytes
- AND AX,7 ;for first byte of destination
- MOV BX,X_Dst
- AND BX,7
- CMP AX,BX
- JG Get_2_Bytes
- Get_1_Byte:
- MOV AL,First_Mask ;Fetch mask for first partial byte
- AND AL,Lower_Mask ;Combine with 'lower mask'
- OUT DX,AL ;Write mask into BIT MASK register
- LODSB ;Fetch first source byte
- MOV AH,[DI] ;Latch destination
- STOSB ;Write first byte of destination
- MOV AH,AL ;Save AL since it will be trashed by OU
- JMP Leading_Done
-
- Get_2_Bytes:
- MOV AL,First_Mask ;Fetch mask for first partial byte
- AND AL,Upper_Mask ;Combine with 'upper mask'
- OUT DX,AL ;Write mask into BIT MASK register
- LODSB
- MOV AH,[DI] ;Latch destination bits
- MOV ES:[DI],AL ;Write first byte
-
- MOV AL,First_Mask ;Fetch mask for first partial byte
- AND AL,Lower_Mask ;Combine with 'lower mask'
- OUT DX,AL ;Write mask into BIT MASK register
- LODSB
- MOV AH,[DI] ;Latch destination bits
- STOSB ;Write first byte
- MOV AH,AL ;Save AL since it will be trashed by OU
-
- Leading_Done:
- SUB CX,InFirst ;Update number of bits to transfer
- JLE Raster_Done
-
- ;-------------------------------------------------------------
- ;--- LOOP OVER COMPLETE BYTES WITHIN A SINGLE SOURCE RASTER
- ;-------------------------------------------------------------
-
- Full_Loop:
- CMP CX,8 ;If less then 8 bits to do
- JL Full_Done ;quit this loop
-
- MOV AL,Upper_Mask ;Fetch the 'upper mask'
- OUT DX,AL ;Write mask into BIT MASK register
- MOV AL,[DI] ;Latch destination bits
- MOV [DI],AH ;Write half 2 for src to half 1 of dst
-
- MOV AL,Lower_Mask ;Fetch the lower mask
- OUT DX,AL ;Write mask into BIT MASK register
- LODSB ;Fetch next source byte
- MOV AH,[DI] ;Latch destination bits
- STOSB ;Write half 1 of src to half 2 of dst
- MOV AH,AL ;Save AL since it will be trashed by OU
-
- SUB CX,8 ; DECREMENT WIDTH BY BITS TO BE DONE
- JMP Full_Loop
- Full_Done:
-
- ;-------------------------------------------------------------
- ;--- TRANSFER THE LAST PARTIAL BYTE
- ;-------------------------------------------------------------
-
- Last_Partial:
- CMP CX,0 ;Any more bits to transfer?
- JLE Raster_Done ;...No, quit this raster
-
- MOV AL,Last_Mask ;Fetch mask for last partial byte
- AND AL,Upper_Mask ;Combine with 'upper mask'
- OUT DX,AL ;Write mask into BIT MASK register
- MOV AL,[DI] ;Latch destination bits
- MOV [DI],AH ;Write half 2 for src to half 1 of dst
-
- MOV AL,Last_Mask ;Fetch mask for last partial byte
- AND AL,Lower_Mask ;Combine with 'upper mask'
- OUT DX,AL ;Write mask into BIT MASK register
- LODSB ;Fetch next source byte
- MOV AH,[DI] ;Latch destination bits
- STOSB ;Write half 1 of src to half 2 of dst
-
- ;--- ADVANCE TO THE NEXT RASTER
-
- Raster_Done:
- POP DI ;Pointers to current raster
- POP SI
- ADD SI,Y_Incr ;Update pointer to point to the next
- ADD DI,Y_Incr ;raster
- DEC WORD PTR Block_Dy ;Update number of rasters to do
- JLE Test_Plane
- JMP Raster_Loop ;And repeat if not all done
-
- Test_Plane:
- DEC Read_Plane ;Update number of planes to do
- JL Blit_Done
- JMP Plane_Loop ;And do next plane if any left to do
-
- ;-------------------------------------------------------------
- ;--- Clean up and exit
- ;-------------------------------------------------------------
-
- Blit_Done:
- ;restore rotate value
- MOV DX,3CEH ;Address of GRAPHICS controller
- MOV AL,3 ;Index for ROTATE & FN SELECT
- OUT DX,AL ;Select ROTATE & FN SELECT register
- INC DX
- XOR AL,AL ;Disable rotate and set fn=copy
- OUT DX,AL ;Write value into register
- ;restore bit mask
- DEC DX
- MOV AL,8 ;Index for BIT MASK register
- OUT DX,AL ;Select BIT MASK register
- INC DX
- MOV AL,0FFH ;Enable all 8 bits for write
- OUT DX,AL ;Write value into register
- ;enable all four planes for write
- MOV DX,3C4H ;Address of SEQUENCER
- MOV AL,2 ;Index for PLANE ENABLE register
- OUT DX,AL ;Select register
- INC DX
- MOV AL,0FH ;Value to enable all four planes
- OUT DX,AL ;Write value into register
-
- POP SI ;Restore segment registers
- POP DI
- POP ES
- POP DS
- MOV SP,BP
- POP BP
- RET
- _BitBlt ENDP