home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / C-ASM_VI.ARJ / PROGASM.ZIP / PROG087P.ASM < prev    next >
Assembly Source File  |  1988-05-25  |  10KB  |  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+18]            ;Formal parameters on the stack
  15. Y_Src    EQU    [BP+16]
  16. X_Dst    EQU    [BP+14]
  17. Y_Dst    EQU    [BP+12]
  18. BWidth    EQU    [BP+10]
  19. BHeight EQU    [BP+8]
  20. Fn    EQU    [BP+6]
  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    FAR
  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    14
  328. BitBlt ENDP
  329.