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

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