home *** CD-ROM | disk | FTP | other *** search
/ Graphics Programming Black Book (Special Edition) / BlackBook.bin / disk1 / source / chapter49 / l49-3.asm < prev    next >
Assembly Source File  |  1997-06-18  |  9KB  |  177 lines

  1. ; Mode X (320x240, 256 colors) display memory to display memory copy
  2. ; routine. Left edge of source rectangle modulo 4 must equal left edge
  3. ; of destination rectangle modulo 4. Works on all VGAs. Uses approach
  4. ; of reading 4 pixels at a time from the source into the latches, then
  5. ; writing the latches to the destination. Copies up to but not
  6. ; including the column at SourceEndX and the row at SourceEndY. No
  7. ; clipping is performed. Results are not guaranteed if the source and
  8. ; destination overlap.
  9. ; Tested with TASM 4.0 by Jim Mischel 12/16/94.
  10. ; C near-callable as:
  11. ;
  12. ;    void CopyScreenToScreenX(int SourceStartX, int SourceStartY,
  13. ;       int SourceEndX, int SourceEndY, int DestStartX,
  14. ;       int DestStartY, unsigned int SourcePageBase,
  15. ;       unsigned int DestPageBase, int SourceBitmapWidth,
  16. ;       int DestBitmapWidth);
  17.  
  18. SC_INDEX equ    03c4h   ;Sequence Controller Index register port
  19. MAP_MASK equ    02h     ;index in SC of Map Mask register
  20. GC_INDEX equ    03ceh   ;Graphics Controller Index register port
  21. BIT_MASK equ    08h     ;index in GC of Bit Mask register
  22. SCREEN_SEG equ  0a000h  ;segment of display memory in Mode X
  23.  
  24. parms   struc
  25.         dw      2 dup (?) ;pushed BP and return address
  26. SourceStartX dw ?       ;X coordinate of upper left corner of source
  27. SourceStartY dw ?       ;Y coordinate of upper left corner of source
  28. SourceEndX   dw ?       ;X coordinate of lower right corner of source
  29.                         ; (the row at SourceEndX is not copied)
  30. SourceEndY   dw ?       ;Y coordinate of lower right corner of source
  31.                         ; (the column at SourceEndY is not copied)
  32. DestStartX   dw ?       ;X coordinate of upper left corner of dest
  33. DestStartY   dw ?       ;Y coordinate of upper left corner of dest
  34. SourcePageBase dw ?     ;base offset in display memory of page in
  35.                         ; which source resides
  36. DestPageBase dw ?       ;base offset in display memory of page in
  37.                         ; which dest resides
  38. SourceBitmapWidth dw ?  ;# of pixels across source bitmap
  39.                         ; (must be a multiple of 4)
  40. DestBitmapWidth   dw ?  ;# of pixels across dest bitmap
  41.                         ; (must be a multiple of 4)
  42. parms   ends
  43.  
  44. SourceNextScanOffset equ -2       ;local storage for distance from end of
  45.                                   ; one source scan line to start of next
  46. DestNextScanOffset   equ -4    ;local storage for distance from end of
  47.                                   ; one dest scan line to start of next
  48. RectAddrWidth         equ -6    ;local storage for address width of rectangle
  49. Height           equ -8    ;local storage for height of rectangle
  50. STACK_FRAME_SIZE     equ  8
  51.  
  52.         .model  small
  53.         .data
  54. ; Plane masks for clipping left and right edges of rectangle.
  55. LeftClipPlaneMask       db      00fh,00eh,00ch,008h
  56. RightClipPlaneMask      db      00fh,001h,003h,007h
  57.         .code
  58.         public  _CopyScreenToScreenX
  59. _CopyScreenToScreenX proc    near
  60.         push    bp                  ;preserve caller's stack frame
  61.         mov     bp,sp               ;point to local stack frame
  62.         sub     sp,STACK_FRAME_SIZE     ;allocate space for local vars
  63.         push    si                  ;preserve caller's register variables
  64.         push    di
  65.         push    ds
  66.  
  67.         cld
  68.         mov     dx,GC_INDEX             ;set the bit mask to select all bits
  69.         mov     ax,00000h+BIT_MASK     ; from the latches and none from
  70.         out     dx,ax                   ; the CPU, so that we can write the
  71.                                     ; latch contents directly to memory
  72.         mov     ax,SCREEN_SEG           ;point ES to display memory
  73.         mov     es,ax
  74.         mov     ax,[bp+DestBitmapWidth]
  75.         shr     ax,1                    ;convert to width in addresses
  76.         shr     ax,1
  77.         mul     [bp+DestStartY]         ;top dest rect scan line
  78.         mov     di,[bp+DestStartX]
  79.         shr     di,1                ;X/4 = offset of first dest rect pixel in
  80.         shr     di,1                ; scan line
  81.         add     di,ax               ;offset of first dest rect pixel in page
  82.         add     di,[bp+DestPageBase]     ;offset of first dest rect pixel
  83.                                     ; in display memory
  84.         mov     ax,[bp+SourceBitmapWidth]
  85.         shr     ax,1                    ;convert to width in addresses
  86.         shr     ax,1
  87.         mul     [bp+SourceStartY]        ;top source rect scan line
  88.         mov     si,[bp+SourceStartX]
  89.         mov     bx,si
  90.         shr     si,1                ;X/4 = offset of first source rect pixel in
  91.         shr     si,1                ; scan line
  92.         add     si,ax               ;offset of first source rect pixel in page
  93.         add     si,[bp+SourcePageBase]     ;offset of first source rect
  94.                                     ; pixel in display memory
  95.         and     bx,0003h                     ;look up left edge plane mask
  96.         mov     ah,LeftClipPlaneMask[bx]     ; to clip
  97.         mov     bx,[bp+SourceEndX]
  98.         and     bx,0003h                  ;look up right edge plane
  99.         mov     al,RightClipPlaneMask[bx] ; mask to clip
  100.         mov     bx,ax                    ;put the masks in BX
  101.         
  102.         mov     cx,[bp+SourceEndX]       ;calculate # of addresses across
  103.         mov     ax,[bp+SourceStartX]     ; rect
  104.         cmp     cx,ax
  105.         jle     CopyDone                ;skip if 0 or negative width
  106.         dec     cx
  107.         and     ax,not 011b
  108.         sub     cx,ax
  109.         shr     cx,1
  110.         shr     cx,1                ;# of addresses across rectangle to copy - 1
  111.         jnz     MasksSet         ;there's more than one address to draw
  112.         and     bh,bl               ;there's only one address, so combine the left
  113.                                     ; and right edge clip masks
  114. MasksSet:
  115.         mov     ax,[bp+SourceEndY]
  116.         sub     ax,[bp+SourceStartY]      ;AX = height of rectangle
  117.         jle     CopyDone                ;skip if 0 or negative height
  118.         mov     [bp+Height],ax
  119.         mov     ax,[bp+DestBitmapWidth]
  120.         shr     ax,1                    ;convert to width in addresses
  121.         shr     ax,1
  122.         sub     ax,cx               ;distance from end of one dest scan line to
  123.         dec     ax                  ; start of next
  124.         mov     [bp+DestNextScanOffset],ax
  125.         mov     ax,[bp+SourceBitmapWidth]
  126.         shr     ax,1                    ;convert to width in addresses
  127.         shr     ax,1
  128.         sub     ax,cx               ;distance from end of one source scan line to
  129.         dec     ax                  ; start of next
  130.         mov     [bp+SourceNextScanOffset],ax
  131.         mov     [bp+RectAddrWidth],cx     ;remember width in addresses - 1
  132. ;-----------------------BUG FIX
  133. mov     dx,SC_INDEX
  134.         mov     al,MAP_MASK
  135.         out     dx,al                   ;point SC Index reg to Map Mask
  136.         inc     dx                      ;point to SC Data reg
  137. ;-----------------------BUG FIX
  138.         mov     ax,es               ;DS=ES=screen segment for MOVS
  139.         mov     ds,ax
  140. CopyRowsLoop:
  141.         mov     cx,[bp+RectAddrWidth]     ;width across - 1
  142.         mov     al,bh               ;put left-edge clip mask in AL
  143.         out     dx,al               ;set the left-edge plane (clip) mask
  144.         movsb                       ;copy the left edge (pixels go through
  145.                                     ; latches)
  146.         dec     cx                  ;count off left edge address
  147.         js      CopyLoopBottom         ;that's the only address
  148.         jz      DoRightEdge         ;there are only two addresses
  149.         mov     al,00fh             ;middle addresses are drawn 4 pixels at a pop
  150.         out     dx,al               ;set the middle pixel mask to no clip
  151.         rep     movsb               ;draw the middle addresses four pixels apiece
  152.                                     ; (pixels copied through latches)
  153. DoRightEdge:
  154.         mov     al,bl               ;put right-edge clip mask in AL
  155.         out     dx,al               ;set the right-edge plane (clip) mask
  156.         movsb                       ;draw the right edge (pixels copied through
  157.                                     ; latches)
  158. CopyLoopBottom:
  159.         add     si,[bp+SourceNextScanOffset] ;point to the start of
  160.         add     di,[bp+DestNextScanOffset]   ; next source & dest lines
  161.         dec     word ptr [bp+Height]     ;count down scan lines
  162.         jnz     CopyRowsLoop
  163. CopyDone:
  164.         mov     dx,GC_INDEX+1         ;restore the bit mask to its default,
  165.         mov     al,0ffh                 ; which selects all bits from the CPU
  166.         out     dx,al                   ; and none from the latches (the GC
  167.                                         ; Index still points to Bit Mask)
  168.         pop     ds
  169.         pop     di                  ;restore caller's register variables
  170.         pop     si
  171.         mov     sp,bp               ;discard storage for local variables
  172.         pop     bp                  ;restore caller's stack frame
  173.         ret
  174. _CopyScreenToScreenX endp
  175.         end
  176.  
  177.