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

  1. ; Program to illustrate operation of write mode 3 of the VGA.
  2. ;  Draws 8x8 characters at arbitrary locations without disturbing
  3. ;  the background, using VGA's 8x8 ROM font.  Designed
  4. ;  for use with modes 0Dh, 0Eh, 0Fh, 10h, and 12h.
  5. ; Runs only on VGAs (in Models 50 & up and IBM Display Adapter
  6. ;  and 100% compatibles).
  7. ; Assembled with TASM 4.0, linked with TLINK 6.10
  8. ; Checked by Jim Mischel 11/21/94
  9. ;
  10. stack   segment para stack 'STACK'
  11.         db      512 dup(?)
  12. stack   ends
  13. ;
  14. VGA_VIDEO_SEGMENT       equ     0a000h  ;VGA display memory segment
  15. SCREEN_WIDTH_IN_BYTES   equ     044ah   ;offset of BIOS variable
  16. FONT_CHARACTER_SIZE     equ     8       ;# bytes in each font char
  17. ;
  18. ; VGA register equates.
  19. ;
  20. SC_INDEX        equ     3c4h    ;SC index register
  21. SC_MAP_MASK     equ     2       ;SC map mask register index
  22. GC_INDEX        equ     3ceh    ;GC index register
  23. GC_SET_RESET    equ     0       ;GC set/reset register index
  24. GC_ENABLE_SET_RESET equ 1       ;GC enable set/reset register index
  25. GC_ROTATE       equ     3       ;GC data rotate/logical function
  26.                                 ; register index
  27. GC_MODE         equ     5       ;GC Mode register
  28. GC_BIT_MASK     equ     8       ;GC bit mask register index
  29. ;
  30. dseg    segment para common 'DATA'
  31. TEST_TEXT_ROW   equ     69      ;row to display test text at
  32. TEST_TEXT_COL   equ     17      ;column to display test text at
  33. TEST_TEXT_WIDTH equ     8       ;width of a character in pixels
  34. TestString      label   byte
  35.         db      'Hello, world!',0       ;test string to print.
  36. FontPointer     dd      ?               ;font offset
  37. dseg    ends
  38. ;
  39. cseg    segment para public 'CODE'
  40.         assume  cs:cseg, ds:dseg
  41. start   proc    near
  42.         mov     ax,dseg
  43.         mov     ds,ax
  44. ;
  45. ; Select 640x480 graphics mode.
  46. ;
  47.         mov     ax,012h
  48.         int     10h
  49. ;
  50. ; Set the screen to all blue, using the readability of VGA registers
  51. ; to preserve reserved bits.
  52. ;
  53.         mov     dx,GC_INDEX
  54.         mov     al,GC_SET_RESET
  55.         out     dx,al
  56.         inc     dx
  57.         in      al,dx
  58.         and     al,0f0h
  59.         or      al,1                ;blue plane only set, others reset
  60.         out     dx,al
  61.         dec     dx
  62.         mov     al,GC_ENABLE_SET_RESET
  63.         out     dx,al
  64.         inc     dx
  65.         in      al,dx
  66.         and     al,0f0h
  67.         or      al,0fh              ;enable set/reset for all planes
  68.         out     dx,al
  69.         mov     dx,VGA_VIDEO_SEGMENT
  70.         mov     es,dx               ;point to display memory
  71.         mov     di,0
  72.         mov     cx,8000h            ;fill all 32k words
  73.         mov     ax,0ffffh           ;because of set/reset, the value
  74.                                     ; written actually doesn't matter
  75.         rep stosw                   ;fill with blue
  76. ;
  77. ; Set driver to use the 8x8 font.
  78. ;
  79.         mov     ah,11h          ;VGA BIOS character generator function,
  80.         mov     al,30h          ; return info subfunction
  81.         mov     bh,3            ;get 8x8 font pointer
  82.         int     10h
  83.         call    SelectFont
  84. ;
  85. ; Print the test string, cycling through colors.
  86. ;
  87.         mov     si,offset TestString
  88.         mov     bx,TEST_TEXT_ROW
  89.         mov     cx,TEST_TEXT_COL
  90.         mov     ah,0                ;start with color 0
  91. StringOutLoop:
  92.         lodsb
  93.         and     al,al
  94.         jz      StringOutDone
  95.         push    ax                  ;preserve color
  96.         call    DrawChar
  97.         pop     ax                  ;restore color
  98.         inc     ah                  ;next color
  99.         and     ah,0fh              ;colors range from 0 to 15
  100.         add     cx,TEST_TEXT_WIDTH
  101.         jmp     StringOutLoop
  102. StringOutDone:
  103. ;
  104. ; Wait for a key, then set to text mode & end.
  105. ;
  106.         mov     ah,1
  107.         int     21h             ;wait for a key
  108.         mov     ax,3
  109.         int     10h             ;restore text mode
  110. ;
  111. ; Exit to DOS.
  112. ;
  113.         mov     ah,4ch
  114.         int     21h
  115. Start   endp
  116. ;
  117. ; Subroutine to draw a text character in a linear graphics mode
  118. ;  (0Dh, 0Eh, 0Fh, 010h, 012h). Background around the pixels that
  119. ;  make up the character is preserved.
  120. ; Font used should be pointed to by FontPointer.
  121. ;
  122. ; Input:
  123. ;  AL = character to draw
  124. ;  AH = color to draw character in (0-15)
  125. ;  BX = row to draw text character at
  126. ;  CX = column to draw text character at
  127. ;
  128. ;  Forces ALU function to "move".
  129. ;  Forces write mode 3.
  130. ;
  131. DrawChar        proc    near
  132.         push    ax
  133.         push    bx
  134.         push    cx
  135.         push    dx
  136.         push    si
  137.         push    di
  138.         push    bp
  139.         push    ds
  140.  
  141.         push    ax      ;preserve character to draw in AL
  142. ;
  143. ; Set up set/reset to produce character color, using the readability
  144. ; of VGA register to preserve the setting of reserved bits 7-4.
  145. ;
  146.         mov     dx,GC_INDEX
  147.         mov     al,GC_SET_RESET
  148.         out     dx,al
  149.         inc     dx
  150.         in      al,dx
  151.         and     al,0f0h
  152.         and     ah,0fh
  153.         or      al,ah
  154.         out     dx,al
  155. ;
  156. ; Select write mode 3, using the readability of VGA registers
  157. ; to leave bits other than the write mode bits unchanged.
  158. ;
  159.         mov     dx,GC_INDEX
  160.         mov     al,GC_MODE
  161.         out     dx,al
  162.         inc     dx
  163.         in      al,dx
  164.         or      al,3
  165.         out     dx,al
  166. ;
  167. ; Set DS:SI to point to font and ES to point to display memory.
  168. ;
  169.         lds     si,[FontPointer]        ;point to font
  170.         mov     dx,VGA_VIDEO_SEGMENT
  171.         mov     es,dx                   ;point to display memory
  172. ;
  173. ; Calculate screen address of byte character starts in.
  174. ;
  175.         pop     ax              ;get back character to draw in AL
  176.  
  177.         push    ds              ;point to BIOS data segment
  178.         sub     dx,dx
  179.         mov     ds,dx
  180.         xchg    ax,bx
  181.         mov     di,ds:[SCREEN_WIDTH_IN_BYTES]   ;retrieve BIOS
  182.                                                 ; screen width
  183.         pop     ds
  184.         mul     di              ;calculate offset of start of row
  185.         push    di              ;set aside screen width
  186.         mov     di,cx           ;set aside the column
  187.         and     cl,0111b     ;keep only the column in-byte address
  188.         shr     di,1
  189.         shr     di,1
  190.         shr     di,1            ;divide column by 8 to make a byte address
  191.         add     di,ax           ;and point to byte
  192. ;
  193. ; Calculate font address of character.
  194. ;
  195.         sub     bh,bh
  196.         shl     bx,1            ;assumes 8 bytes per character; use
  197.         shl     bx,1            ; a multiply otherwise
  198.         shl     bx,1            ;offset in font of character
  199.         add     si,bx           ;offset in font segment of character
  200. ;
  201. ; Set up the GC rotation. In write mode 3, this is the rotation
  202. ; of CPU data before it is ANDed with the Bit Mask register to
  203. ; form the bit mask. Force the ALU function to "move". Uses the
  204. ; readability of VGA registers to leave reserved bits unchanged.
  205. ;
  206.         mov     dx,GC_INDEX
  207.         mov     al,GC_ROTATE
  208.         out     dx,al
  209.         inc     dx
  210.         in      al,dx
  211.         and     al,0e0h
  212.         or      al,cl
  213.         out     dx,al
  214. ;
  215. ; Set up BH as bit mask for left half, BL as rotation for right half.
  216. ;
  217.         mov     bx,0ffffh
  218.         shr     bh,cl
  219.         neg     cl
  220.         add     cl,8
  221.         shl     bl,cl
  222. ;
  223. ; Draw the character, left half first, then right half in the
  224. ; succeeding byte, using the data rotation to position the character
  225. ; across the byte boundary and then using write mode 3 to combine the
  226. ; character data with the bit mask to allow the set/reset value (the
  227. ; character color) through only for the proper portion (where the
  228. ; font bits for the character are 1) of the character for each byte.
  229. ; Wherever the font bits for the character are 0, the background
  230. ; color is preserved.
  231. ; Does not check for case where character is byte-aligned and
  232. ; no rotation and only one write is required.
  233. ;
  234.         mov     bp,FONT_CHARACTER_SIZE
  235.         mov     dx,GC_INDEX
  236.         pop     cx              ;get back screen width
  237.         dec     cx
  238.         dec     cx              ; -2 because do two bytes for each char
  239. CharacterLoop:
  240. ;
  241. ; Set the bit mask for the left half of the character.
  242. ;
  243.         mov     al,GC_BIT_MASK
  244.         mov     ah,bh
  245.         out     dx,ax
  246. ;
  247. ; Get the next character byte & write it to display memory.
  248. ; (Left half of character.)
  249. ;
  250.         mov     al,[si]         ;get character byte
  251.         mov     ah,es:[di]      ;load latches
  252.         stosb                   ;write character byte
  253. ;
  254. ; Set the bit mask for the right half of the character.
  255. ;
  256.         mov     al,GC_BIT_MASK
  257.         mov     ah,bl
  258.         out     dx,ax
  259. ;
  260. ; Get the character byte again & write it to display memory.
  261. ; (Right half of character.)
  262. ;
  263.         lodsb                   ;get character byte
  264.         mov     ah,es:[di]      ;load latches
  265.         stosb                   ;write character byte
  266. ;
  267. ; Point to next line of character in display memory.
  268. ;
  269.         add     di,cx
  270. ;
  271.         dec     bp
  272.         jnz     CharacterLoop
  273. ;
  274.         pop     ds
  275.         pop     bp
  276.         pop     di
  277.         pop     si
  278.         pop     dx
  279.         pop     cx
  280.         pop     bx
  281.         pop     ax
  282.         ret
  283. DrawChar        endp
  284. ;
  285. ; Set the pointer to the font to draw from to ES:BP.
  286. ;
  287. SelectFont      proc    near
  288.         mov     word ptr [FontPointer],bp       ;save pointer
  289.         mov     word ptr [FontPointer+2],es
  290.         ret
  291. SelectFont      endp
  292. ;  
  293. cseg    ends
  294.         end     start
  295.  
  296.