home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / program / asm / PJGRAPH.ZIP / CHAP05.1 < prev    next >
Encoding:
Text File  |  1989-09-26  |  9.8 KB  |  300 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 MASM 4.0, linked with LINK 3.51.
  8. ; By Michael Abrash, 9/1/87.
  9. ; Updated 6/25/89.
  10. ;
  11. stackseg        segment para stack 'STACK'
  12.         db      512 dup(?)
  13. stackseg        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     8       ;# 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_WIDTH equ     8       ;width of a character in pixels
  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 8x8 font.
  79. ;
  80.         call    Select8x8Font
  81. ;
  82. ; Print the test string, cycling through colors.
  83. ;
  84.         mov     si,offset TestString
  85.         mov     bx,TEST_TEXT_ROW
  86.         mov     cx,TEST_TEXT_COL
  87.         mov     ah,0            ;start with color 0
  88. StringOutLoop:
  89.         lodsb
  90.         and     al,al
  91.         jz      StringOutDone
  92.         push    ax              ;preserve color
  93.         call    DrawChar
  94.         pop     ax              ;restore color
  95.         inc     ah              ;next color
  96.         and     ah,0fh          ;colors range from 0 to 15
  97.         add     cx,TEST_TEXT_WIDTH
  98.         jmp     StringOutLoop
  99. StringOutDone:
  100. ;
  101. ; Wait for a key, then set to text mode & end.
  102. ;
  103.         mov     ah,1
  104.         int     21h     ;wait for a key
  105.         mov     ax,3
  106.         int     10h     ;restore text mode
  107. ;
  108. ; Exit to DOS.
  109. ;
  110.         mov     ah,4ch
  111.         int     21h
  112. Start   endp
  113. ;
  114. ; Subroutine to draw a text character in a linear graphics mode
  115. ;  (0Dh, 0Eh, 0Fh, 010h, 012h). Background around the pixels that
  116. ;  make up the character is preserved.
  117. ; Font used should be pointed to by FontPointer.
  118. ;
  119. ; Input:
  120. ;  AL = character to draw
  121. ;  AH = color to draw character in (0-15)
  122. ;  BX = row to draw text character at
  123. ;  CX = column to draw text character at
  124. ;
  125. ;  Forces ALU function to "move".
  126. ;  Forces write mode 3.
  127. ;
  128. DrawChar        proc    near
  129.         push    ax
  130.         push    bx
  131.         push    cx
  132.         push    dx
  133.         push    si
  134.         push    di
  135.         push    bp
  136.         push    ds
  137.  
  138.         push    ax      ;preserve character to draw in AL
  139. ;
  140. ; Set up set/reset to produce character color, using the readability
  141. ; of VGA register to preserve the setting of reserved bits 7-4.
  142. ;
  143.         mov     dx,GC_INDEX
  144.         mov     al,GC_SET_RESET
  145.         out     dx,al
  146.         inc     dx
  147.         in      al,dx
  148.         and     al,0f0h
  149.         and     ah,0fh
  150.         or      al,ah
  151.         out     dx,al
  152. ;
  153. ; Select write mode 3, using the readability of VGA registers
  154. ; to leave bits other than the write mode bits unchanged.
  155. ;
  156.         mov     dx,GC_INDEX
  157.         mov     al,GC_MODE
  158.         out     dx,al
  159.         inc     dx
  160.         in      al,dx
  161.         or      al,3
  162.         out     dx,al
  163. ;
  164. ; Set DS:SI to point to font and ES to point to display memory.
  165. ;
  166.         lds     si,[FontPointer]        ;point to font
  167.         mov     dx,VGA_VIDEO_SEGMENT
  168.         mov     es,dx                   ;point to display memory
  169. ;
  170. ; Calculate screen address of byte character starts in.
  171. ;
  172.         pop     ax      ;get back character to draw in AL
  173.  
  174.         push    ds      ;point to BIOS data segment
  175.         sub     dx,dx
  176.         mov     ds,dx
  177.         xchg    ax,bx
  178.         mov     di,ds:[SCREEN_WIDTH_IN_BYTES]   ;retrieve BIOS
  179.                                                 ; screen width
  180.         pop     ds
  181.         mul     di      ;calculate offset of start of row
  182.         push    di      ;set aside screen width
  183.         mov     di,cx   ;set aside the column
  184.         and     cl,0111b ;keep only the column in-byte address
  185.         shr     di,1
  186.         shr     di,1
  187.         shr     di,1    ;divide column by 8 to make a byte address
  188.         add     di,ax   ;and point to byte
  189. ;
  190. ; Calculate font address of character.
  191. ;
  192.         sub     bh,bh
  193.         shl     bx,1    ;assumes 8 bytes per character; use
  194.         shl     bx,1    ; a multiply otherwise
  195.         shl     bx,1    ;offset in font of character
  196.         add     si,bx   ;offset in font segment of character
  197. ;
  198. ; Set up the GC rotation. In write mode 3, this is the rotation
  199. ; of CPU data before it is ANDed with the Bit Mask register to
  200. ; form the bit mask. Force the ALU function to "move". Uses the
  201. ; readability of VGA registers to leave reserved bits unchanged.
  202. ;
  203.         mov     dx,GC_INDEX
  204.         mov     al,GC_ROTATE
  205.         out     dx,al
  206.         inc     dx
  207.         in      al,dx
  208.         and     al,0e0h
  209.         or      al,cl
  210.         out     dx,al
  211. ;
  212. ; Set up BH as bit mask for part of character in left byte,
  213. ; BL as bit mask for part of character in right byte.
  214. ;
  215.         mov     bx,0ff00h
  216.         shr     bx,cl
  217. ;
  218. ; Draw the character, the part in left byte first, then the part in
  219. ; right byte next, using the data rotation to position the character
  220. ; across the byte boundary and then using write mode 3 to combine the
  221. ; character data with the bit mask to allow the set/reset value (the
  222. ; character color) through only for the proper portion (where the
  223. ; font bits for the character are 1) of the character for each byte.
  224. ; Wherever the font bits for the character are 0, the background
  225. ; color is preserved.
  226. ;
  227. ; Does not check for the case where the character is byte-aligned,
  228. ; so no rotation (and hence only one write) is required; special
  229. ; code would speed that case considerably.
  230. ;
  231.         mov     bp,FONT_CHARACTER_SIZE
  232.         mov     dx,GC_INDEX
  233.         pop     cx      ;get back screen width
  234.         dec     cx
  235.         dec     cx      ;-2 because do two bytes for each char
  236. ; Point the GC Index register to the Bit Mask register for the
  237. ; duration of the loop.
  238.         mov     al,GC_BIT_MASK
  239.         out     dx,al
  240.         inc     dx      ;point to GC Data register
  241. CharacterLoop:
  242. ;
  243. ; Set the bit mask for the part of the character in the left byte.
  244. ;
  245.         mov     al,bh
  246.         out     dx,al
  247. ;
  248. ; Get the next character byte & write it to display memory.
  249. ; (This draws the part of the character in the left byte.)
  250. ;
  251.         mov     al,es:[di]      ;load latches from left byte
  252.         lodsb                   ;get character byte
  253.         stosb                   ;write left part of character byte
  254. ;
  255. ; Set the bit mask for the part of the character in the right byte.
  256. ;
  257.         xchg    ax,bx           ;get right-byte bit mask in AL
  258.                                 ; and save the font byte
  259.         out     dx,al           ;set the right-byte bit mask
  260.         xchg    ax,bx           ;put the font byte back in AL
  261.                                 ; and the bit masks back in BX
  262. ;
  263. ; Write the character byte to display memory again.
  264. ; (Right part of character.)
  265. ;
  266.         mov     ah,es:[di]      ;load latches from right byte
  267.         stosb                   ;write character byte
  268. ;
  269. ; Point to next line of character in display memory.
  270. ;
  271.         add     di,cx
  272. ;
  273.         dec     bp
  274.         jnz     CharacterLoop
  275. ;
  276.         pop     ds
  277.         pop     bp
  278.         pop     di
  279.         pop     si
  280.         pop     dx
  281.         pop     cx
  282.         pop     bx
  283.         pop     ax
  284.         ret
  285. DrawChar        endp
  286. ;
  287. ; Set the pointer to the 8x8 font.
  288. ;
  289. Select8x8Font   proc    near
  290.         mov     ah,11h  ;EGA BIOS character generator function,
  291.         mov     al,30h  ; return info subfunction
  292.         mov     bh,3    ;get 8x8 font pointer
  293.         int     10h
  294.         mov     word ptr [FontPointer],bp       ;save pointer
  295.         mov     word ptr [FontPointer+2],es
  296.         ret
  297. Select8x8Font   endp
  298. ;  
  299. cseg    ends
  300.         end     start