home *** CD-ROM | disk | FTP | other *** search
/ Graphics Programming Black Book (Special Edition) / BlackBook.bin / disk1 / source / chapter31 / l31-2.asm < prev    next >
Encoding:
Assembly Source File  |  1997-06-18  |  6.9 KB  |  265 lines

  1. ; *** Listing 9.2 ***
  2. ;
  3. ; Program to demonstrate the two pages available in 320x400
  4. ; 256-color modes on a VGA.  Draws diagonal color bars in all
  5. ; 256 colors in page 0, then does the same in page 1 (but with
  6. ; the bars tilted the other way), and finally draws vertical
  7. ; color bars in page 0.
  8. ;
  9. ; Assembled with TASM 4.0, linked with TLINK 6.10
  10. ; Checked by Jim Mischel 11/21/94
  11. ;
  12. VGA_SEGMENT    equ    0a000h
  13. SC_INDEX        equ    3c4h    ;Sequence Controller Index register
  14. GC_INDEX        equ    3ceh    ;Graphics Controller Index register
  15. CRTC_INDEX    equ    3d4h    ;CRT Controller Index register
  16. MAP_MASK        equ    2    ;Map Mask register index in SC
  17. MEMORY_MODE    equ    4    ;Memory Mode register index in SC
  18. MAX_SCAN_LINE    equ    9    ;Maximum Scan Line reg index in CRTC
  19. START_ADDRESS_HIGH equ    0ch    ;Start Address High reg index in CRTC
  20. UNDERLINE    equ    14h    ;Underline Location reg index in CRTC
  21. MODE_CONTROL    equ    17h    ;Mode Control register index in CRTC
  22. GRAPHICS_MODE    equ    5    ;Graphics Mode register index in GC
  23. MISCELLANEOUS    equ    6    ;Miscellaneous register index in GC
  24. SCREEN_WIDTH    equ    320    ;# of pixels across screen
  25. SCREEN_HEIGHT    equ    400    ;# of scan lines on screen
  26. WORD_OUTS_OK    equ    1    ;set to 0 to assemble for
  27.                 ; computers that can't handle
  28.                 ; word outs to indexed VGA registers
  29. ;
  30. stack    segment para stack 'STACK'
  31.     db    512 dup (?)
  32. stack    ends
  33. ;
  34. ; Macro to output a word value to a port.
  35. ;
  36. OUT_WORD    macro
  37. if WORD_OUTS_OK
  38.     out    dx,ax
  39. else
  40.     out    dx,al
  41.     inc    dx
  42.     xchg    ah,al
  43.     out    dx,al
  44.     dec    dx
  45.     xchg    ah,al
  46. endif
  47.     endm
  48. ;
  49. ; Macro to output a constant value to an indexed VGA register.
  50. ;
  51. CONSTANT_TO_INDEXED_REGISTER    macro    ADDRESS, INDEX, VALUE
  52.     mov    dx,ADDRESS
  53.     mov    ax,(VALUE shl 8) + INDEX
  54.     OUT_WORD
  55.     endm
  56. ;
  57. Code    segment
  58.     assume    cs:Code
  59. Start    proc    near
  60. ;
  61. ; Set 320x400 256-color mode.
  62. ;
  63.     call    Set320By400Mode
  64. ;
  65. ; We're in 320x400 256-color mode, with page 0 displayed.
  66. ; Let's fill page 0 with color bars slanting down and to the right.
  67. ;
  68.     sub    di,di        ;page 0 starts at address 0
  69.     mov    bl,1        ;make color bars slant down and
  70.                 ; to the right
  71.     call    ColorBarsUp    ;draw the color bars
  72. ;
  73. ; Now do the same for page 1, but with the color bars
  74. ; tilting the other way.
  75. ;
  76.     mov    di,8000h        ;page 1 starts at address 8000h
  77.     mov    bl,-1        ;make color bars slant down and
  78.                 ; to the left
  79.     call    ColorBarsUp    ;draw the color bars
  80. ;
  81. ; Wait for a key and flip to page 1 when one is pressed.
  82. ;
  83.     call    GetNextKey
  84.     CONSTANT_TO_INDEXED_REGISTER CRTC_INDEX,START_ADDRESS_HIGH,80h
  85.                 ;set the Start Address High register
  86.                 ; to 80h, for a start address of 8000h
  87. ;
  88. ; Draw vertical bars in page 0 while page 1 is displayed.
  89. ;
  90.     sub    di,di        ;page 0 starts at address 0
  91.     sub    bl,bl        ;make color bars vertical
  92.     call    ColorBarsUp    ;draw the color bars
  93. ;
  94. ; Wait for another key and flip back to page 0 when one is pressed.
  95. ;
  96.     call    GetNextKey
  97.     CONSTANT_TO_INDEXED_REGISTER CRTC_INDEX,START_ADDRESS_HIGH,00h
  98.                 ;set the Start Address High register
  99.                 ; to 00h, for a start address of 0000h
  100. ;
  101. ; Wait for yet another key and return to text mode and end when
  102. ; one is pressed.
  103. ;
  104.     call    GetNextKey
  105.     mov    ax,0003h
  106.     int    10h    ;text mode
  107.     mov    ah,4ch
  108.     int    21h    ;done
  109. ;
  110. Start    endp
  111. ;
  112. ; Sets up 320x400 256-color modes.
  113. ;
  114. ; Input: none
  115. ;
  116. ; Output: none
  117. ;
  118. Set320By400Mode    proc    near
  119. ;
  120. ; First, go to normal 320x200 256-color mode, which is really a
  121. ; 320x400 256-color mode with each line scanned twice.
  122. ;
  123.     mov    ax,0013h  ;AH = 0 means mode set, AL = 13h selects
  124.               ; 256-color graphics mode
  125.     int    10h      ;BIOS video interrupt
  126. ;
  127. ; Change CPU addressing of video memory to linear (not odd/even,
  128. ; chain, or chain 4), to allow us to access all 256K of display
  129. ; memory. When this is done, VGA memory will look just like memory
  130. ; in modes 10h and 12h, except that each byte of display memory will
  131. ; control one 256-color pixel, with 4 adjacent pixels at any given
  132. ; address, one pixel per plane.
  133. ;
  134.     mov    dx,SC_INDEX
  135.     mov    al,MEMORY_MODE
  136.     out    dx,al
  137.     inc    dx
  138.     in    al,dx
  139.     and    al,not 08h    ;turn off chain 4
  140.     or    al,04h        ;turn off odd/even
  141.     out    dx,al
  142.     mov    dx,GC_INDEX
  143.     mov    al,GRAPHICS_MODE
  144.     out    dx,al
  145.     inc    dx
  146.     in    al,dx
  147.     and    al,not 10h    ;turn off odd/even
  148.     out    dx,al
  149.     dec    dx
  150.     mov    al,MISCELLANEOUS
  151.     out    dx,al
  152.     inc    dx
  153.     in    al,dx
  154.     and    al,not 02h    ;turn off chain
  155.     out    dx,al
  156. ;
  157. ; Now clear the whole screen, since the mode 13h mode set only
  158. ; cleared 64K out of the 256K of display memory. Do this before
  159. ; we switch the CRTC out of mode 13h, so we don't see garbage
  160. ; on the screen when we make the switch.
  161. ;
  162.     CONSTANT_TO_INDEXED_REGISTER SC_INDEX,MAP_MASK,0fh
  163.                 ;enable writes to all planes, so
  164.                 ; we can clear 4 pixels at a time
  165.     mov    ax,VGA_SEGMENT
  166.     mov    es,ax
  167.     sub    di,di
  168.     mov    ax,di
  169.     mov    cx,8000h    ;# of words in 64K
  170.     cld
  171.     rep    stosw        ;clear all of display memory
  172. ;
  173. ; Tweak the mode to 320x400 256-color mode by not scanning each
  174. ; line twice.
  175. ;
  176.     mov    dx,CRTC_INDEX
  177.     mov    al,MAX_SCAN_LINE
  178.     out    dx,al
  179.     inc    dx
  180.     in    al,dx
  181.     and    al,not 1fh    ;set maximum scan line = 0
  182.     out    dx,al
  183.     dec    dx
  184. ;
  185. ; Change CRTC scanning from doubleword mode to byte mode, allowing
  186. ; the CRTC to scan more than 64K of video data.
  187. ;
  188.     mov    al,UNDERLINE
  189.     out    dx,al
  190.     inc    dx
  191.     in    al,dx
  192.     and    al,not 40h    ;turn off doubleword
  193.     out    dx,al
  194.     dec    dx
  195.     mov    al,MODE_CONTROL
  196.     out    dx,al
  197.     inc    dx
  198.     in    al,dx
  199.     or    al,40h    ;turn on the byte mode bit, so memory is
  200.             ; scanned for video data in a purely
  201.             ; linear way, just as in modes 10h and 12h
  202.     out    dx,al
  203.     ret
  204. Set320By400Mode    endp
  205. ;
  206. ; Draws a full screen of slanting color bars in the specified page.
  207. ;
  208. ; Input:
  209. ;    DI = page start address
  210. ;    BL = 1 to make the bars slant down and to the right, -1 to
  211. ;        make them slant down and to the left, 0 to make
  212. ;        them vertical.
  213. ;
  214. ColorBarsUp    proc    near
  215.     mov    ax,VGA_SEGMENT
  216.     mov    es,ax    ;point to display memory
  217.     sub    bh,bh    ;start with color 0
  218.     mov    si,SCREEN_HEIGHT ;# of rows to do
  219.     mov    dx,SC_INDEX
  220.     mov    al,MAP_MASK
  221.     out    dx,al    ;point the SC Index reg to the Map Mask reg
  222.     inc    dx    ;point DX to the SC Data register
  223. RowLoop:
  224.     mov    cx,SCREEN_WIDTH/4
  225.             ;there are 4 pixels at each address, so
  226.             ; each 320-pixel row is 80 bytes wide
  227.             ; in each plane
  228.     push    bx    ;save the row-start color
  229. ColumnLoop:
  230. MAP_SELECT = 1
  231.     rept    4    ;do all 4 pixels at this address with
  232.             ; in-line code
  233.     mov    al,MAP_SELECT
  234.     out    dx,al    ;select planes 0, 1, 2, and 3 in turn
  235.     mov    es:[di],bh ;write this plane's pixel
  236.     inc    bh    ;set the color for the next pixel
  237. MAP_SELECT = MAP_SELECT shl 1
  238.     endm
  239.     inc    di    ;point to the address containing the next
  240.             ; 4 pixels
  241.     loop    ColumnLoop ;do any remaining pixels on this line
  242.     pop    bx    ;get back the row-start color
  243.     add    bh,bl    ;select next row-start color (controls
  244.             ; slanting of color bars)
  245.     dec    si    ;count down lines on the screen
  246.     jnz    RowLoop
  247.     ret
  248. ColorBarsUp    endp
  249. ;
  250. ; Waits for the next key and returns it in AX.
  251. ;
  252. GetNextKey    proc    near
  253. WaitKey:
  254.     mov    ah,1
  255.     int    16h
  256.     jz    WaitKey    ;wait for a key to become available
  257.     sub    ah,ah
  258.     int    16h    ;read the key
  259.     ret
  260. GetNextKey    endp
  261. ;
  262. Code    ends
  263. ;
  264.     end    Start
  265.