home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / C-ASM_VI.ARJ / PROGASM.ZIP / PROG087.ASM < prev    next >
Assembly Source File  |  1988-05-25  |  15KB  |  329 lines

  1.  
  2. ;************************************************************************
  3. ; Transfer Bit Aligned Block of dimensions Width x Height, from         *
  4. ; source, with upper left corner at (X_Src,Y_Src), to destination with  *
  5. ; upper left corner at (X_Dst,Y_Dst), using function fn.                *
  6. ; Entry:        X_Srs, Y_Src  - Source upper left                       *
  7. ;               X_Dst, Y_Dst  - Destination upper left                  *
  8. ;               BWidth,BHeight- Dimensions of the block                 *
  9. ;               Fn            - Logical function (Copy, AND, OR, XOR)   *
  10. ;************************************************************************
  11.  
  12. ;xxxx add later traversing x in reverse for overlapped src and dst
  13.  
  14. X_Src   EQU     [BP+4]                  ;Formal parameters on the stack
  15. Y_Src   EQU     [BP+6]
  16. X_Dst   EQU     [BP+8]
  17. Y_Dst   EQU     [BP+10]
  18. BWidth  EQU     [BP+12]
  19. BHeight EQU     [BP+14]
  20. Fn      EQU     [BP+16]
  21.  
  22. HBYTES  EQU     80                      ;Number of bytes per scanline
  23. GRF_SEG EQU     0A000H                  ;Segment for display buffer
  24.  
  25. Y_Incr          EQU     WORD PTR [BP-2] ;Local variables
  26. First_Mask      EQU     BYTE PTR [BP-4]
  27. InFirst         EQU     WORD PTR [BP-6]
  28. Last_Mask       EQU     BYTE PTR [BP-8]
  29. Read_Plane      EQU     BYTE PTR [BP-10]
  30. Lower_Mask      EQU     BYTE PTR [BP-12]
  31. Upper_Mask      EQU     BYTE PTR [BP-14]
  32. Src_Address     EQU     WORD PTR [BP-16]
  33. Dst_Address     EQU     WORD PTR [BP-18]
  34. Block_Dx        EQU     WORD PTR [BP-20]
  35. Block_Dy        EQU     WORD PTR [BP-22]
  36.  
  37.         PUBLIC  _BitBlt
  38.  
  39. _BitBlt PROC    NEAR
  40.         PUSH    BP
  41.         MOV     BP,SP
  42.  
  43.         SUB     SP,24                   ;Setup local variables
  44.  
  45.         PUSH    DS                      ;Presrve segment registers
  46.         PUSH    ES
  47.         PUSH    DI
  48.         PUSH    SI
  49.  
  50.         ;-------------------------------------------------------------
  51.         ;--- COMPUTE MASKS FOR FIRST AND LAST BYTE WITHIN A RASTER
  52.         ;    ROTATION FACTOR, AND MASKS FOR HI AND LOW BITS AFTER ROTATION
  53.         ;    ENABLE ROTATION AND LOGICAL FUNCTIONS IN GRAPHICS CONTROLLER
  54.         ;-------------------------------------------------------------
  55.  
  56.         MOV     CX,X_Dst                ; NUMBER OF CLEAR BITS IN FIRST BYTE
  57.         AND     CX,7
  58.         MOV     First_Mask,0FFH         ; COMPUTE MASK TO CLEAR LEADING BITS
  59.         SHR     First_Mask,CL
  60.         MOV     AX,8
  61.         SUB     AX,CX
  62.         MOV     InFirst,AX
  63.  
  64.         ;MASK TO KEEP BITS IN LAST BYTE (PARTIAL BYTE)
  65.  
  66.         MOV     CX,X_Dst                ; GET ADDRESS OF LAST BIT
  67.         ADD     CX,BWidth
  68.         AND     CX,7                    ; POSITION JUST AFTER LAST BIT
  69.         MOV     Last_Mask,0FFH          ; COMPUTE MASK TO KEEP BITS AFTER
  70.         SHR     Last_Mask,CL
  71.         NOT     Last_Mask               ; COMPLEMENT TO KEEP LEADING BITS
  72.  
  73.         ;BITS FROM SOURCE BYTE MUST BE ALLIGNED WITH BITS IN THE
  74.         ;DESTINATION BYTE.  HERE IS COMPUTED THE ROTATION AND THE
  75.         ;TWO MASKS NEEDED TO ISOLOTATE TWO HALVES OF THE BYTE
  76.  
  77.         ; COMPUTE ROTATION
  78.  
  79.         MOV     CX,X_Dst                ; COMPUTE BIT DISTANCE BETWEEN
  80.         SUB     CX,X_Src                ;... BIT POSITIONS IN FIRST BYTES
  81.         AND     CX,7                    ; ... OF SOURCE AND DESTINATION BYTES
  82.                                         ; ... AS (SRC-DST)&7
  83.         MOV     AX,00FFH                ;Compute masks for non-zero rotation
  84.         ROR     AX,CL
  85.         MOV     Lower_Mask,AL           ;Save the masks
  86.         MOV     Upper_Mask,AH
  87.  
  88.         MOV     DX,3CEH                 ;Address of GRAPHICS controller
  89.         MOV     AL,3                    ;Index for DATA ROTATE & FN SELECT
  90.         OUT     DX,AL                   ;Select DATA ROTATE & FN SELECT REG
  91.         INC     DX
  92.         MOV     AL,CL                   ;Fetch rotate count
  93.         MOV     AH,Fn                   ;Fetch logical function
  94.         AND     AH,3                    ;Move logical function into
  95.         SHL     AH,1                    ;bits 3 and 4
  96.         SHL     AH,1
  97.         SHL     AH,1
  98.         OR      AL,AH
  99.         OUT     DX,AL                   ;Write value into DATA ROTATE... reg
  100.  
  101.         ;-------------------------------------------------------------
  102.         ;--- COMPUTE ABSOLUTE ADDRESS OF SOURCE AND DESTINATION
  103.         ;-------------------------------------------------------------
  104.  
  105.         MOV     WORD PTR Y_Incr,HBYTES  ;Initialize y traversal as normal
  106.  
  107.         ;Because of possible overlap we must adjust direction of traversal
  108.         ;If source block is above the destination then reverse Y traversal
  109.         ;If source block is to the left, then reverse X traversal
  110.  
  111.         MOV     AX,Y_Src                ;Compare source and destination Y
  112.         MOV     BX,Y_Dst
  113.         CMP     AX,BX
  114.         JLE     Compute_Address         ;...Leave alone if src <= dst
  115.         ADD     AX,BHeight              ;Begin with last raster in block
  116.         DEC     AX
  117.         ADD     BX,BHeight
  118.         DEC     BX
  119.         MOV     Y_Src,AX
  120.         MOV     Y_Dst,BX
  121.         NEG     WORD PTR Y_Incr         ;And traverse backwards
  122. Compute_Address:
  123.         MOV     AX,Y_Src                ;Compute offset for source
  124.         MOV     BX,HBYTES               ;as offset = y * 80 + x/8
  125.         MUL     BX
  126.         MOV     SI,X_Src
  127.         SHR     SI,1
  128.         SHR     SI,1
  129.         SHR     SI,1
  130.         ADD     SI,AX
  131.         MOV     Src_Address,SI
  132.  
  133.         MOV     AX,Y_Dst                ;Compute offset for destination
  134.         MOV     BX,HBYTES               ;as offset = y * 80 + x/8
  135.         MUL     BX
  136.         MOV     DI,X_Dst
  137.         SHR     DI,1
  138.         SHR     DI,1
  139.         SHR     DI,1
  140.         ADD     DI,AX
  141.         MOV     Dst_Address,DI
  142.  
  143.         MOV     AX,GRF_SEG              ;Setup segment
  144.         MOV     ES,AX
  145.         MOV     DS,AX
  146.  
  147.         ;-------------------------------------------------------------
  148.         ;--- ENABLE NEXT PLANE FOR READ AND WRITE
  149.         ;-------------------------------------------------------------
  150.  
  151.         MOV     AL,3                    ;Initialize counter of planes
  152.         MOV     Read_Plane,AL
  153. Plane_Loop:
  154.         MOV     AX,BWidth               ;Copy dimensions of the block
  155.         MOV     Block_Dx,AX
  156.         MOV     AX,BHeight
  157.         MOV     Block_Dy,AX
  158.         MOV     SI,Src_Address          ;Fetch source address
  159.         MOV     DI,Dst_Address          ;Fetch destination address
  160.         MOV     CL,Read_Plane           ;Fetch next plane to do
  161.         MOV     AH,1                    ;Use plane number to setup value
  162.         SHL     AH,CL                   ;for WRITE PLANE SELECT register
  163.         MOV     DX,3C4H                 ;Fetch address of SEQUENCER
  164.         MOV     AL,2                    ;Index for WRITE PLANE SELECT register
  165.         OUT     DX,AL                   ;Select register
  166.         INC     DX
  167.         MOV     AL,AH                   ;Fetch value
  168.         OUT     DX,AL                   ;Write value into register
  169.         MOV     DX,3CEH                 ;Fetch address of GRAPHICS controller
  170.         MOV     AL,4                    ;Index for READ PLANE SELECT register
  171.         OUT     DX,AL                   ;Select register
  172.         INC     DX
  173.         MOV     AL,CL                   ;Fetch plane number
  174.         OUT     DX,AL                   ;Write plane number into register
  175.         DEC     DX
  176.         MOV     AL,8                    ;Index for BIT MASK register
  177.         OUT     DX,AL                   ;Select BIT MASK register
  178.         INC     DX
  179.  
  180.         ;-------------------------------------------------------------
  181.         ; RASTER LOOP IS DONE IN FOUR STEPS
  182.         ; (1) MASKS AND ROTATION FACTOR IS COMPUTED TO ALIGN SRC AND DEST
  183.         ; (2) LEADIING PARTIAL BYTE OF DESTINATION IS MODIFIED
  184.         ; (3) FULL BYTES OF DESTINATION ARE MODIFIED
  185.         ; (4) TRAILLING PARTIAL BYTE OF DESTINATION IS MODIFIED
  186.         ;-------------------------------------------------------------
  187.  
  188.         ;-------------------------------------------------------------
  189.         ;--- GET ENOUGH BITS FROM SOUCE TO CONSTRUCT FIRST PARTIAL BYTE OF DST
  190.         ;-------------------------------------------------------------
  191.  
  192. Raster_Loop:
  193.         MOV     CX,Block_Dx             ;Number of bits to copy
  194.         PUSH    SI                      ;Preserve addresses for next raster loo
  195.         PUSH    DI
  196.  
  197.         MOV     AX,X_Src                ;Check if need one or two bytes
  198.         AND     AX,7                    ;for first byte of destination
  199.         MOV     BX,X_Dst
  200.         AND     BX,7
  201.         CMP     AX,BX
  202.         JG      Get_2_Bytes
  203. Get_1_Byte:
  204.         MOV     AL,First_Mask           ;Fetch mask for first partial byte
  205.         AND     AL,Lower_Mask           ;Combine with 'lower mask'
  206.         OUT     DX,AL                   ;Write mask into BIT MASK register
  207.         LODSB                           ;Fetch first source byte
  208.         MOV     AH,[DI]                 ;Latch destination
  209.         STOSB                           ;Write first byte of destination
  210.         MOV     AH,AL                   ;Save AL since it will be trashed by OU
  211.         JMP     Leading_Done
  212.  
  213. Get_2_Bytes:
  214.         MOV     AL,First_Mask           ;Fetch mask for first partial byte
  215.         AND     AL,Upper_Mask           ;Combine with 'upper mask'
  216.         OUT     DX,AL                   ;Write mask into BIT MASK register
  217.         LODSB
  218.         MOV     AH,[DI]                 ;Latch destination bits
  219.         MOV     ES:[DI],AL              ;Write first byte
  220.  
  221.         MOV     AL,First_Mask           ;Fetch mask for first partial byte
  222.         AND     AL,Lower_Mask           ;Combine with 'lower mask'
  223.         OUT     DX,AL                   ;Write mask into BIT MASK register
  224.         LODSB
  225.         MOV     AH,[DI]                 ;Latch destination bits
  226.         STOSB                           ;Write first byte
  227.         MOV     AH,AL                   ;Save AL since it will be trashed by OU
  228.  
  229. Leading_Done:
  230.         SUB     CX,InFirst              ;Update number of bits to transfer
  231.         JLE     Raster_Done
  232.  
  233.         ;-------------------------------------------------------------
  234.         ;--- LOOP OVER COMPLETE BYTES WITHIN A SINGLE SOURCE RASTER
  235.         ;-------------------------------------------------------------
  236.  
  237. Full_Loop:
  238.         CMP     CX,8                    ;If less then 8 bits to do
  239.         JL      Full_Done               ;quit this loop
  240.  
  241.         MOV     AL,Upper_Mask           ;Fetch the 'upper mask'
  242.         OUT     DX,AL                   ;Write mask into BIT MASK register
  243.         MOV     AL,[DI]                 ;Latch destination bits
  244.         MOV     [DI],AH                 ;Write half 2 for src to half 1 of dst
  245.  
  246.         MOV     AL,Lower_Mask           ;Fetch the lower mask
  247.         OUT     DX,AL                   ;Write mask into BIT MASK register
  248.         LODSB                           ;Fetch next source byte
  249.         MOV     AH,[DI]                 ;Latch destination bits
  250.         STOSB                           ;Write half 1 of src to half 2 of dst
  251.         MOV     AH,AL                   ;Save AL since it will be trashed by OU
  252.  
  253.         SUB     CX,8                    ; DECREMENT WIDTH BY BITS TO BE DONE
  254.         JMP     Full_Loop
  255. Full_Done:
  256.  
  257.         ;-------------------------------------------------------------
  258.         ;--- TRANSFER THE LAST PARTIAL BYTE
  259.         ;-------------------------------------------------------------
  260.  
  261. Last_Partial:
  262.         CMP     CX,0                    ;Any more bits to transfer?
  263.         JLE     Raster_Done             ;...No, quit this raster
  264.  
  265.         MOV     AL,Last_Mask            ;Fetch mask for last partial byte
  266.         AND     AL,Upper_Mask           ;Combine with 'upper mask'
  267.         OUT     DX,AL                   ;Write mask into BIT MASK register
  268.         MOV     AL,[DI]                 ;Latch destination bits
  269.         MOV     [DI],AH                 ;Write half 2 for src to half 1 of dst
  270.  
  271.         MOV     AL,Last_Mask            ;Fetch mask for last partial byte
  272.         AND     AL,Lower_Mask           ;Combine with 'upper mask'
  273.         OUT     DX,AL                   ;Write mask into BIT MASK register
  274.         LODSB                           ;Fetch next source byte
  275.         MOV     AH,[DI]                 ;Latch destination bits
  276.         STOSB                           ;Write half 1 of src to half 2 of dst
  277.  
  278.         ;--- ADVANCE TO THE NEXT RASTER
  279.  
  280. Raster_Done:
  281.         POP     DI                      ;Pointers to current raster
  282.         POP     SI
  283.         ADD     SI,Y_Incr               ;Update pointer to point to the next
  284.         ADD     DI,Y_Incr               ;raster
  285.         DEC     WORD PTR Block_Dy       ;Update number of rasters to do
  286.         JLE     Test_Plane
  287.         JMP     Raster_Loop             ;And repeat if not all done
  288.  
  289. Test_Plane:
  290.         DEC     Read_Plane              ;Update number of planes to do
  291.         JL      Blit_Done
  292.         JMP     Plane_Loop              ;And do next plane if any left to do
  293.  
  294.         ;-------------------------------------------------------------
  295.         ;--- Clean up and exit
  296.         ;-------------------------------------------------------------
  297.  
  298. Blit_Done:
  299.         ;restore rotate value
  300.         MOV     DX,3CEH                 ;Address of GRAPHICS controller
  301.         MOV     AL,3                    ;Index for ROTATE & FN SELECT
  302.         OUT     DX,AL                   ;Select ROTATE & FN SELECT register
  303.         INC     DX
  304.         XOR     AL,AL                   ;Disable rotate and set fn=copy
  305.         OUT     DX,AL                   ;Write value into register
  306.         ;restore bit mask
  307.         DEC     DX
  308.         MOV     AL,8                    ;Index for BIT MASK register
  309.         OUT     DX,AL                   ;Select BIT MASK register
  310.         INC     DX
  311.         MOV     AL,0FFH                 ;Enable all 8 bits for write
  312.         OUT     DX,AL                   ;Write value into register
  313.         ;enable all four planes for write
  314.         MOV     DX,3C4H                 ;Address of SEQUENCER
  315.         MOV     AL,2                    ;Index for PLANE ENABLE register
  316.         OUT     DX,AL                   ;Select register
  317.         INC     DX
  318.         MOV     AL,0FH                  ;Value to enable all four planes
  319.         OUT     DX,AL                   ;Write value into register
  320.  
  321.         POP     SI                      ;Restore segment registers
  322.         POP     DI
  323.         POP     ES
  324.         POP     DS
  325.         MOV     SP,BP
  326.         POP     BP
  327.         RET
  328. _BitBlt ENDP
  329.