home *** CD-ROM | disk | FTP | other *** search
/ Graphics Programming Black Book (Special Edition) / BlackBook.bin / disk1 / source / chapter27 / l27-1.asm next >
Assembly Source File  |  1997-06-18  |  8KB  |  221 lines

  1. ;
  2. ; *** Listing 5.1 ***
  3. ;
  4. ; Program to illustrate one use of write mode 2 of the VGA and EGA by
  5. ; animating the image of an "A" drawn by copying it from a chunky
  6. ; bit-map in system memory to a planar bit-map in VGA or EGA memory.
  7. ;
  8. ; Assembled with TASM 4.0, linked with TLINK 6.10
  9. ; Checked by Jim Mischel 11/21/94
  10. ;
  11. Stack   segment para stack 'STACK'
  12.         db      512 dup(0)
  13. Stack   ends
  14.  
  15. SCREEN_WIDTH_IN_BYTES       equ     80
  16. DISPLAY_MEMORY_SEGMENT      equ     0a000h
  17. SC_INDEX                equ     3c4h    ;Sequence Controller Index register
  18. MAP_MASK                equ     2       ;index of Map Mask register
  19. GC_INDEX                equ     03ceh   ;Graphics Controller Index reg
  20. GRAPHICS_MODE           equ     5       ;index of Graphics Mode reg
  21. BIT_MASK            equ     8       ;index of Bit Mask reg
  22.  
  23. Data    segment para common 'DATA'
  24. ;
  25. ; Current location of "A" as it is animated across the screen.
  26. ;
  27. CurrentX        dw      ?
  28. CurrentY        dw      ?
  29. RemainingLength dw      ?
  30. ;
  31. ; Chunky bit-map image of a yellow "A" on a bright blue background
  32. ;
  33. AImage          label   byte
  34.                 dw      13, 13          ;width, height in pixels
  35.                 db      000h, 000h, 000h, 000h, 000h, 000h, 000h
  36.                 db      009h, 099h, 099h, 099h, 099h, 099h, 000h
  37.                 db      009h, 099h, 099h, 099h, 099h, 099h, 000h
  38.                 db      009h, 099h, 099h, 0e9h, 099h, 099h, 000h
  39.                 db      009h, 099h, 09eh, 0eeh, 099h, 099h, 000h
  40.                 db      009h, 099h, 0eeh, 09eh, 0e9h, 099h, 000h
  41.                 db      009h, 09eh, 0e9h, 099h, 0eeh, 099h, 000h
  42.                 db      009h, 09eh, 0eeh, 0eeh, 0eeh, 099h, 000h
  43.                 db      009h, 09eh, 0e9h, 099h, 0eeh, 099h, 000h
  44.                 db      009h, 09eh, 0e9h, 099h, 0eeh, 099h, 000h
  45.                 db      009h, 099h, 099h, 099h, 099h, 099h, 000h
  46.                 db      009h, 099h, 099h, 099h, 099h, 099h, 000h
  47.                 db      000h, 000h, 000h, 000h, 000h, 000h, 000h
  48. Data    ends
  49.  
  50. Code    segment para public 'CODE'
  51.         assume  cs:Code, ds:Data
  52. Start   proc    near
  53.         mov     ax,Data
  54.         mov     ds,ax
  55.         mov     ax,10h
  56.         int     10h                     ;select video mode 10h (640x350)
  57. ;
  58. ; Prepare for animation.
  59. ;
  60.         mov     [CurrentX],0
  61.         mov     [CurrentY],200
  62.         mov     [RemainingLength],600       ;move 600 times
  63. ;
  64. ; Animate, repeating RemainingLength times. It's unnecessary to erase
  65. ; the old image, since the one pixel of blank fringe around the image
  66. ; erases the part of the old image not overlapped by the new image.
  67. ;
  68. AnimationLoop:
  69.         mov     bx,[CurrentX]
  70.         mov     cx,[CurrentY]
  71.         mov     si,offset AImage
  72.         call    DrawFromChunkyBitmap        ;draw the "A" image
  73.         inc     [CurrentX]                  ;move one pixel to the right
  74.  
  75.         mov     cx,0                        ;delay so we don't move the
  76. DelayLoop:                                  ; image too fast; adjust as
  77.                                             ; needed
  78.         loop    DelayLoop
  79.  
  80.         dec     [RemainingLength]
  81.         jnz     AnimationLoop
  82. ;
  83. ; Wait for a key before returning to text mode and ending.
  84. ;
  85.         mov     ah,01h
  86.         int     21h
  87.         mov     ax,03h
  88.         int     10h
  89.         mov     ah,4ch
  90.         int     21h
  91. Start   endp
  92. ;
  93. ; Draw an image stored in a chunky-bit map into planar VGA/EGA memory
  94. ; at the specified location.
  95. ;
  96. ; Input:
  97. ;       BX = X screen location at which to draw the upper left corner
  98. ;               of the image
  99. ;       CX = Y screen location at which to draw the upper left corner
  100. ;               of the image
  101. ;       DS:SI = pointer to chunky image to draw, as follows:
  102. ;               word at 0: width of image, in pixels
  103. ;               word at 2: height of image, in pixels
  104. ;               byte at 4: msb/lsb = first & second chunky pixels,
  105. ;                       repeating for the remainder of the scan line
  106. ;                       of the image, then for all scan lines. Images
  107. ;                       with odd widths have an unused null nibble
  108. ;                       padding each scan line out to a byte width
  109. ;
  110. ; AX, BX, CX, DX, SI, DI, ES destroyed.
  111. ;
  112. DrawFromChunkyBitmap    proc    near
  113.         cld
  114. ;
  115. ; Select write mode 2.
  116. ;
  117.         mov     dx,GC_INDEX
  118.         mov     al,GRAPHICS_MODE
  119.         out     dx,al
  120.         inc     dx
  121.         mov     al,02h
  122.         out     dx,al
  123. ;
  124. ; Enable writes to all 4 planes.
  125. ;
  126.         mov     dx,SC_INDEX
  127.         mov     al,MAP_MASK
  128.         out     dx,al
  129.         inc     dx
  130.         mov     al,0fh
  131.         out     dx,al
  132. ;
  133. ; Point ES:DI to the display memory byte in which the first pixel
  134. ; of the image goes, with AH set up as the bit mask to access that
  135. ; pixel within the addressed byte.
  136. ;
  137.         mov     ax,SCREEN_WIDTH_IN_BYTES        
  138.         mul     cx                      ;offset of start of top scan line
  139.         mov     di,ax
  140.         mov     cl,bl
  141.         and     cl,111b
  142.         mov     ah,80h                  ;set AH to the bit mask for the
  143.         shr     ah,cl                   ; initial pixel
  144.         shr     bx,1
  145.         shr     bx,1
  146.         shr     bx,1                    ;X in bytes
  147.         add     di,bx                   ;offset of upper left byte of image
  148.         mov     bx,DISPLAY_MEMORY_SEGMENT
  149.         mov     es,bx                   ;ES:DI points to the byte at which the
  150.                                         ; upper left of the image goes
  151. ;
  152. ; Get the width and height of the image.
  153. ;
  154.         mov     cx,[si]             ;get the width
  155.         inc     si
  156.         inc     si
  157.         mov     bx,[si]          ;get the height
  158.         inc     si
  159.         inc     si
  160.         mov     dx,GC_INDEX
  161.         mov     al,BIT_MASK
  162.         out     dx,al               ;leave the GC Index register pointing
  163.         inc     dx                  ; to the Bit Mask register
  164. RowLoop:
  165.  
  166.         push    ax                  ;preserve the left column's bit mask
  167.         push    cx                  ;preserve the width
  168.         push    di                  ;preserve the destination offset
  169.  
  170. ColumnLoop:
  171.         mov     al,ah
  172.         out     dx,al               ;set the bit mask to draw this pixel
  173.         mov     al,es:[di]          ;load the latches
  174.         mov     al,[si]             ;get the next two chunky pixels
  175.         shr     al,1
  176.         shr     al,1
  177.         shr     al,1
  178.         shr     al,1                ;move the first pixel into the lsb
  179.         stosb                       ;draw the first pixel
  180.         ror     ah,1                ;move mask to next pixel position
  181.         jc      CheckMorePixels     ;is next pixel in the adjacent byte?
  182.         dec     di                  ;no
  183.  
  184. CheckMorePixels:
  185.         dec     cx                  ;see if there are any more pixels
  186.         jz      AdvanceToNextScanLine ; across in image
  187.         mov     al,ah
  188.         out     dx,al               ;set the bit mask to draw this pixel
  189.         mov     al,es:[di]          ;load the latches
  190.         lodsb                       ;get the same two chunky pixels again
  191.                                     ; and advance pointer to the next
  192.                                     ; two pixels
  193.         stosb                       ;draw the second of the two pixels
  194.         ror     ah,1                ;move mask to next pixel position
  195.         jc      CheckMorePixels2 ;is next pixel in the adjacent byte?
  196.         dec     di                  ;no
  197.  
  198. CheckMorePixels2:
  199.         loop    ColumnLoop          ;see if there are any more pixels
  200.                                     ; across in the image
  201.         jmp     short CheckMoreScanLines
  202.  
  203. AdvanceToNextScanLine:
  204.         inc     si              ;advance to the start of the next
  205.                                 ; scan line in the image
  206.  
  207. CheckMoreScanLines:
  208.         pop     di              ;get back the destination offset
  209.         pop     cx              ;get back the width
  210.         pop     ax              ;get back the left column's bit mask
  211.         add     di,SCREEN_WIDTH_IN_BYTES
  212.                                 ;point to the start of the next scan
  213.                                 ; line of the image
  214.         dec     bx              ;see if there are any more scan lines
  215.         jnz     RowLoop         ; in the image
  216.         ret
  217. DrawFromChunkyBitmap    endp
  218. Code    ends
  219.         end     Start
  220.  
  221.