home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / video / 11 / 11_4.asm < prev    next >
Encoding:
Assembly Source File  |  1988-08-11  |  7.0 KB  |  276 lines

  1.         TITLE    'Listing 11-4'
  2.         NAME    StoreBitBlock10
  3.         PAGE    55,132
  4.  
  5. ;
  6. ; Name:        StoreBitBlock10
  7. ;
  8. ; Function:    Copy bit block from video buffer to system RAM
  9. ;         in native EGA and VGA graphics modes
  10. ;
  11. ; Caller:    Microsoft C:
  12. ;
  13. ;            void StoreBitBlock10(buf,x,y);
  14. ;
  15. ;                 char far *buf;   /* buffer */
  16. ;                 int x,y;    /* upper left corner of bit block */
  17. ;
  18.  
  19.  
  20. ADDRbuf        EQU    dword ptr [bp+4]
  21. ARGx        EQU    word ptr [bp+8]
  22. ARGy        EQU    word ptr [bp+10]
  23.  
  24. VARPixelRows    EQU    word ptr [bp-2]
  25. VARPixelRowLen    EQU    word ptr [bp-4]
  26. VARRowCounter    EQU    word ptr [bp-6]
  27. VARStartMask    EQU    word ptr [bp-8]
  28. VAREndMaskL    EQU    word ptr [bp-10]
  29. VAREndMaskR    EQU    word ptr [bp-12]
  30.  
  31. BytesPerRow    EQU    80        ; logical width of video buffer
  32. ByteOffsetShift    EQU    3        ; reflects number of pixels per byte
  33. RMWbits        EQU    18h        ; selects replace, XOR, AND, or OR
  34.  
  35. _TEXT        SEGMENT    byte public 'CODE'
  36.         ASSUME    cs:_TEXT
  37.  
  38.         EXTRN    PixelAddr10:near
  39.  
  40.         PUBLIC    _StoreBitBlock10
  41. _StoreBitBlock10    PROC    near
  42.  
  43.         push    bp        ; preserve caller registers
  44.         mov    bp,sp
  45.         sub    sp,12        ; establish stack frame
  46.         push    ds
  47.         push    si
  48.         push    di
  49.  
  50. ; establish addressing
  51.  
  52.         mov    ax,ARGy
  53.         mov    bx,ARGx
  54.         call    PixelAddr10    ; ES:BX -> byte offset of x,y
  55.         inc    cl
  56.         and    cl,7        ; CL := number of bits to shift left
  57.  
  58.         mov    di,bx        ; ES:DI -> x,y in video buffer
  59.         
  60.         lds    si,ADDRbuf    ; ES:DI -> buffer in system RAM
  61.  
  62. ; obtain dimensions of bit block from header
  63.  
  64.         lodsw            ; AX := number of pixel rows
  65.         mov    VARPixelRows,ax
  66.         lodsw            ; AX := bytes per pixel row
  67.         mov    VARPixelRowLen,ax
  68.         lodsb            ; AL := bit mask for last byte in row
  69.         mov    ch,al
  70.  
  71. ; set up Graphics Controller
  72.  
  73.         mov    dx,3CEh        ; DX := Graphics Controller I/O port
  74.  
  75.         mov    ah,RMWbits    ; AH := value for Data Rotate/Function
  76.         mov    al,3        ;  Select register
  77.         out    dx,ax        ; update this register
  78.  
  79.         mov    ax,0805h    ; AH := 8 (read mode 1, write mode 0)
  80.                     ; AL := 5 (Mode register number)
  81.         out    dx,ax        ; set up read mode 0
  82.  
  83.         mov    ax,0007        ; AH := 0 (don't care for all maps;
  84.                     ;  CPU reads always return 0FFH)
  85.                     ; AL := 7 (Color Don't Care reg number)
  86.         out    dx,ax        ; set up Color Don't Care reg
  87.  
  88.         mov    ax,0FF08h    ; AH := 0FFH (value for Bit Mask reg)
  89.         out    dx,ax        ; set up Bit Mask reg
  90.  
  91.         mov    dl,0C4h        ; DX := 3C4H (Sequencer I/O port)
  92.         mov    ax,0802h    ; AH := 1000B (value for Map Mask reg)
  93.                     ; AL := 2 (Map Mask register number)
  94.  
  95.         cmp    cx,0FF00h    ; if mask <> 0FFH or bits to shift <> 0
  96.         jne    L15        ;  jump if not byte-aligned
  97.  
  98. ; routine for byte-aligned bit blocks
  99.  
  100.         mov    cx,VARPixelRowLen
  101.  
  102. L10:        out    dx,ax        ; enable one bit plane for writes
  103.         push    ax        ; preserve Map Mask value
  104.         push    di        ; preserve video buffer offset of x,y
  105.         mov    bx,VARPixelRows
  106.  
  107. L11:        push    di        ; preserve DI and CX
  108.         push    cx
  109.  
  110. L12:        lodsb            ; AL := next byte of pixels
  111.         and    es:[di],al    ; update bit plane
  112.         inc    di
  113.         loop    L12
  114.         
  115.         pop    cx        ; restore DI and CX
  116.         pop    di    
  117.         add    di,BytesPerRow    ; ES:DI -> next pixel row in buffer
  118.         dec    bx
  119.         jnz    L11        ; loop down pixel rows
  120.  
  121.         pop    di        ; ES:DI -> video buffer offset of x,y
  122.         pop    ax        ; AH := current Map Mask reg value
  123.         shr    ah,1        ; AH := new Map Mask value
  124.         jnz    L10        ; loop across all bit planes
  125.  
  126.         jmp    Lexit
  127.  
  128. ; routine for non-aligned bit blocks
  129.  
  130. L15:        push    ax        ; preserve Map Mask reg values
  131.  
  132.         mov    bx,0FFh        ; BH := 0 (mask for first byte in row)
  133.                     ; BL := 0FFh
  134.         mov    al,ch        ; AL := mask for last byte in pixel row
  135.         cbw            ; AH := 0FFh (mask for last-1 byte)
  136.  
  137.         cmp    VARPixelRowLen,1
  138.         jne    L16        ; jump if more than one byte per row
  139.  
  140.         mov    bl,ch
  141.         mov    ah,ch        ; AH := mask for last-1 byte
  142.         xor    al,al        ; AL := 0 (mask for last byte)
  143.  
  144. L16:        shl    ax,cl        ; shift masks into position
  145.         shl    bx,cl
  146.  
  147.         mov    bl,al        ; save masks along with ..
  148.         mov    al,8        ; .. Bit Mask register number
  149.         mov    VAREndMaskL,ax
  150.         mov    ah,bl
  151.         mov    VAREndMaskR,ax
  152.         mov    ah,bh        
  153.         mov    VARStartMask,ax
  154.         
  155.         mov    bx,VARPixelRowLen
  156.         pop    ax        ; restore Map Mask reg values
  157.  
  158. ; set pixels row by row in the bit planes
  159.  
  160. L17:        out    dx,ax        ; enable one bit plane for writes
  161.         push    ax        ; preserve Map Mask value
  162.         push    di        ; preserve video buffer offset of x,y
  163.         mov    dl,0CEh        ; DX := 3CEH (Graphics Controller port)
  164.  
  165.         mov    ax,VARPixelRows
  166.         mov    VARRowCounter,ax  ; initialize loop counter
  167.  
  168. ; set pixels at start of row in currently enabled bit plane
  169.  
  170. L18:        push    di        ; preserve offset of start of pixel row
  171.         push    si        ; preserve offset of row in bit block 
  172.         push    bx        ; preserve bytes per pixel row
  173.  
  174.         mov    ax,VARStartMask
  175.         out    dx,ax        ; set Bit Mask reg for first byte of row
  176.  
  177.         lodsw            ; AH := 2nd byte of pixels
  178.                     ; AL := 1st byte of pixels
  179.         dec    si        ; DS:SI -> 2nd byte of pixels
  180.         test    cl,cl
  181.         jnz    L19        ; jump if not left-aligned
  182.  
  183.         dec    bx        ; BX := bytes per row - 1
  184.         jnz    L20        ; jump if at least 2 bytes per row
  185.         jmp    short L22    ; jump if only one byte per row
  186.  
  187. L19:        rol    ax,cl        ; AH := left part of 1st byte,
  188.                     ;     right part of 2nd byte
  189.                     ; AL := right part of 1st byte,
  190.                     ;     left part of 2nd byte
  191.         and    es:[di],ah    ; set pixels for left part of first byte
  192.         inc    di
  193.         dec    bx        ; BX := bytes per row - 2
  194.  
  195. L20:        push    ax        ; preserve pixels
  196.         mov    ax,0FF08h
  197.         out    dx,ax        ; set Bit Mask reg for succeeding bytes
  198.         pop    ax
  199.  
  200.         dec    bx
  201.         jng    L22        ; jump if only 1 or 2 bytes in pixel row
  202.  
  203. ; set pixels in middle of row
  204.  
  205. L21:        and    es:[di],al    ; set pixels in right part of current
  206.         inc    di        ;  byte and left part of next byte
  207.  
  208.         lodsw            ; AH := next+1 byte of pixels
  209.         dec    si        ; AL := next byte of pixels
  210.         rol    ax,cl        ; AH := left part of next byte, right
  211.                     ;     part of next+1 byte
  212.                     ; AL := right part of next byte, left
  213.                     ;     part of next+1 byte
  214.         dec    bx
  215.         jnz    L21        ; loop across pixel row
  216.  
  217. ; set pixels at end of row
  218.  
  219. L22:        mov    bx,ax        ; BH := right part of last byte, left
  220.                     ;     part of last-1 byte
  221.                     ; BL := left part of last byte, right
  222.                     ;     part of last-1 byte
  223.         mov    ax,VAREndMaskL    ; AH := mask for last-1 byte
  224.                     ; AL := Bit Mask reg number
  225.         out    dx,ax        ; set Bit Mask register
  226.         and    es:[di],bl    ; set pixels for last-1 byte
  227.  
  228.         mov    ax,VAREndMaskR    ; mask for last byte in pixel row
  229.         out    dx,ax        ; .. last byte in pixel row
  230.         and    es:[di+1],bh    ; set pixels for last byte
  231.  
  232.         pop    bx        ; BX := bytes per pixel row
  233.         pop    si
  234.         add    si,bx        ; DS:SI -> next row in bit block
  235.         pop    di
  236.         add    di,BytesPerRow    ; ES:DI -> next pixel row in buffer
  237.         dec    VARRowCounter
  238.         jnz    L18        ; loop down pixel rows
  239.  
  240.         pop    di        ; ES:DI -> video buffer offset of x,y
  241.         pop    ax        ; AX := current Map Mask value
  242.         mov    dl,0C4h        ; DX := 3C4H
  243.         shr    ah,1        ; AH := next Map Mask value
  244.         jnz    L17        ; loop across bit planes
  245.  
  246. ; restore Graphics Controller and Sequencer to their default states
  247.  
  248. Lexit:        mov    ax,0F02h    ; default Map Mask value
  249.         out    dx,ax
  250.  
  251.         mov    dl,0CEh        ; DX := 3CEh
  252.         mov    ax,0003        ; default Data Rotate/Function Select
  253.         out    dx,ax
  254.  
  255.         mov    ax,0005        ; default Mode value
  256.         out    dx,ax
  257.  
  258.         mov    ax,0F07h    ; default Color Compare value
  259.         out    dx,ax
  260.  
  261.         mov    ax,0FF08h    ; default Bit Mask value
  262.         out    dx,ax
  263.  
  264.         pop    di        ; restore registers and exit
  265.         pop    si
  266.         pop    ds
  267.         mov    sp,bp
  268.         pop    bp
  269.         ret
  270.  
  271. _StoreBitBlock10 ENDP
  272.  
  273. _TEXT        ENDS
  274.  
  275.         END
  276.