home *** CD-ROM | disk | FTP | other *** search
/ Graphics Programming Black Book (Special Edition) / BlackBook.bin / disk1 / source / l40-4.asm next >
Assembly Source File  |  1997-06-13  |  7KB  |  178 lines

  1. ; Demonstrates drawing solid text on the VGA, using The BitMan's write mode 
  2. ; 3-based, one-pass technique.
  3.  
  4. CHAR_HEIGHT equ 8        ;# of scan lines per character (must be <256)
  5. SCREEN_HEIGHT   equ 480         ;# of scan lines per screen
  6. SCREEN_SEGMENT  equ 0a000h      ;where screen memory is
  7. FG_COLOR    equ 14          ;text color
  8. BG_COLOR    equ 1           ;background box color
  9. GC_INDEX    equ 3ceh            ;Graphics Controller (GC) Index reg I/O port
  10. SET_RESET   equ 0           ;Set/Reset register index in GC
  11. G_MODE      equ 5           ;Graphics Mode register index in GC
  12. BIT_MASK    equ 8           ;Bit Mask register index in GC
  13.  
  14.     .model  small
  15.     .stack  200h
  16.     .data
  17. Line            dw ?        ;current line #
  18. CharHeight     dw ?        ;# of scan lines in each character (must be <256)
  19. MaxLines     dw ?        ;max # of scan lines of text that will fit on screen
  20. LineWidthBytes     dw ?        ;offset from one scan line to the next
  21. FontPtr         dd ?           ;pointer to font with which to draw
  22. SampleString        label   byte
  23.     db  'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  24.     db  'abcdefghijklmnopqrstuvwxyz'
  25.     db  '0123456789!@#$%^&*(),<.>/?;:',0
  26.  
  27.     .code
  28. start:
  29.     mov ax,@data
  30.     mov ds,ax
  31.  
  32.     mov ax,12h
  33.     int 10h             ;select 640x480 16-color mode
  34.  
  35.     mov ah,11h              ;BIOS character generator function
  36.     mov al,30h              ;BIOS get font pointer subfunction
  37.     mov bh,3                ;get 8x8 ROM font subsubfunction
  38.     int 10h             ;get the pointer to the BIOS 8x8 font
  39.     mov word ptr [FontPtr],bp
  40.     mov word ptr [FontPtr+2],es
  41.  
  42.     mov bx,CHAR_HEIGHT
  43.     mov [CharHeight],bx ;# of scan lines per character
  44.     mov ax,SCREEN_HEIGHT
  45.     sub dx,dx
  46.     div bx
  47.     mul bx               ;max # of full scan lines of text that
  48.     mov [MaxLines],ax           ; will fit on the screen
  49.  
  50.     mov ah,0fh                  ;BIOS video status function
  51.     int 10h                         ;get # of columns (bytes) per row
  52.     mov al,ah                   ;convert byte columns variable in
  53.     sub ah,ah                   ; AH to word in AX
  54.     mov [LineWidthBytes],ax     ;width of scan line in bytes
  55.                                 ;now draw the text
  56.     sub     bx,bx
  57.     mov [Line],bx           ;start at scan line 0
  58. LineLoop:
  59.     sub ax,ax               ;start at column 0; must be a multiple of 8
  60.     mov ch,FG_COLOR         ;color in which to draw text
  61.     mov cl,BG_COLOR         ;color in which to draw background box
  62.     mov si,offset SampleString     ;text to draw
  63.     call    DrawTextString      ;draw the sample text
  64.     mov bx,[Line]
  65.     add bx,[CharHeight]         ;# of next scan line to draw on
  66.     mov [Line],bx
  67.     cmp bx,[MaxLines]           ;done yet?
  68.     jb  LineLoop            ;not yet
  69.  
  70.     mov ah,7
  71.     int 21h                 ;wait for a key press, without echo
  72.  
  73.     mov ax,03h
  74.     int 10h             ;back to text mode
  75.  
  76.     mov ah,4ch
  77.     int 21h             ;exit to DOS
  78.  
  79. ; Draws a text string.
  80. ; Input: AX = X coordinate at which to draw upper left corner of first char
  81. ;    BX = Y coordinate at which to draw upper left corner of first char
  82. ;    CH = foreground (text) color
  83. ;    CL = background (box) color
  84. ;    DS:SI = pointer to string to draw, zero terminated
  85. ;    CharHeight must be set to the height of each character
  86. ;    FontPtr must be set to the font with which to draw
  87. ;        LineWidthBytes must be set to the scan line width in bytes
  88. ; Don't count on any registers other than DS, SS, and SP being preserved.
  89. ; The X coordinate is truncated to a multiple of 8. Characters are
  90. ; assumed to be 8 pixels wide.
  91.     align   2
  92. DrawTextString  proc    near
  93.     cld
  94.     shr ax,1                ;byte address of starting X within scan line
  95.     shr ax,1
  96.     shr ax,1
  97.     mov di,ax
  98.     mov ax,[LineWidthBytes]
  99.     mul bx                  ;start offset of initial scan line
  100.     add di,ax               ;start offset of initial byte
  101.     mov ax,SCREEN_SEGMENT
  102.     mov es,ax               ;ES:DI = offset of initial character's
  103.                                     ; first scan line
  104.                             ;set up the VGA's hardware so that we can
  105.                             ; fill the latches with the background color
  106.     mov dx,GC_INDEX
  107.     mov ax,(0ffh SHL 8) + BIT_MASK
  108.     out dx,ax               ;set Bit Mask register to 0xFF (that's the
  109.                             ; default, but I'm doing this just to make sure
  110.                             ; you understand that Bit Mask register and
  111.                             ; CPU data are ANDed in write mode 3)
  112.     mov ax,(003h SHL 8) + G_MODE
  113.     out dx,ax               ;select write mode 3
  114.     mov ah,cl               ;background color
  115.     mov al,SET_RESET
  116.     out dx,ax               ;set the drawing color to background color
  117.     mov byte ptr es:[0ffffh],0ffh ;write 8 pixels of the background
  118.                               ; color to unused offscreen memory
  119.     mov cl,es:[0ffffh]          ;read the background color back into the
  120.                             ; latches; the latches are now filled with
  121.                             ; the background color. The value in CL
  122.                             ; doesn't matter, we just needed a target
  123.                             ; for the read, so we could load the latches
  124.     mov ah,ch               ;foreground color
  125.     out dx,ax               ;set the Set/Reset (drawing) color to the
  126.                             ; foreground color
  127.                             ;we're ready to draw!
  128. DrawTextLoop:
  129.     lodsb                   ;next character to draw
  130.     and al,al               ;end of string?
  131.     jz  DrawTextDone            ;yes
  132.     push    ds              ;remember string's segment
  133.     push    si              ;remember offset of next character in string
  134.     push    di              ;remember drawing offset
  135.                             ;load these variables before we wipe out DS
  136.     mov dx,[LineWidthBytes]     ;offset from one line to next
  137.     dec dx                  ;compensate for STOSB
  138.         mov     cx,[CharHeight]     ;
  139.         mul     cl                  ;offset of character in font table
  140.     lds si,[FontPtr]            ;point to font table
  141.     add si,ax               ;point to start of character to draw
  142.                                     ;the following loop should be unrolled for
  143.                                     ; maximum performance!
  144. DrawCharLoop:                   ;draw all lines of the character
  145.     movsb                   ;get the next byte of the character and draw
  146.                             ; character; data is ANDed with Bit Mask
  147.                             ; register to become bit mask, and selects
  148.                             ; between latch (containing the background 
  149.                                     ; color) and Set/Reset register (containing
  150.                             ; foreground color)
  151.     add di,dx               ;point to next line of destination
  152.     loop    DrawCharLoop
  153.  
  154.     pop di                  ;retrieve initial drawing offset
  155.     inc di                  ;drawing offset for next char
  156.     pop si                  ;retrieve offset of next character in string
  157.     pop ds                  ;retrieve string's segment
  158.     jmp DrawTextLoop            ;draw next character, if any
  159.  
  160.     align   2   
  161. DrawTextDone:                   ;restore the Graphics Mode register to its
  162.                             ; default state of write mode 0
  163.     mov dx,GC_INDEX
  164.     mov ax,(000h SHL 8) + G_MODE
  165.     out dx,ax               ;select write mode 0
  166.     ret
  167. DrawTextString  endp
  168.     end start
  169.  
  170.  
  171.  
  172.  
  173.  
  174. 14
  175. Abrash/ZEN OF GRAPHISC PROGRAMMING, Chapter 40 (DDJ 8/92) -- Edited    
  176.  
  177.  
  178.