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