home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Programming Black Book (Special Edition)
/
BlackBook.bin
/
disk1
/
source
/
l40-4.asm
next >
Wrap
Assembly Source File
|
1997-06-13
|
7KB
|
178 lines
; Demonstrates drawing solid text on the VGA, using The BitMan's write mode
; 3-based, one-pass technique.
CHAR_HEIGHT equ 8 ;# of scan lines per character (must be <256)
SCREEN_HEIGHT equ 480 ;# of scan lines per screen
SCREEN_SEGMENT equ 0a000h ;where screen memory is
FG_COLOR equ 14 ;text color
BG_COLOR equ 1 ;background box color
GC_INDEX equ 3ceh ;Graphics Controller (GC) Index reg I/O port
SET_RESET equ 0 ;Set/Reset register index in GC
G_MODE equ 5 ;Graphics Mode register index in GC
BIT_MASK equ 8 ;Bit Mask register index in GC
.model small
.stack 200h
.data
Line dw ? ;current line #
CharHeight dw ? ;# of scan lines in each character (must be <256)
MaxLines dw ? ;max # of scan lines of text that will fit on screen
LineWidthBytes dw ? ;offset from one scan line to the next
FontPtr dd ? ;pointer to font with which to draw
SampleString label byte
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'abcdefghijklmnopqrstuvwxyz'
db '0123456789!@#$%^&*(),<.>/?;:',0
.code
start:
mov ax,@data
mov ds,ax
mov ax,12h
int 10h ;select 640x480 16-color mode
mov ah,11h ;BIOS character generator function
mov al,30h ;BIOS get font pointer subfunction
mov bh,3 ;get 8x8 ROM font subsubfunction
int 10h ;get the pointer to the BIOS 8x8 font
mov word ptr [FontPtr],bp
mov word ptr [FontPtr+2],es
mov bx,CHAR_HEIGHT
mov [CharHeight],bx ;# of scan lines per character
mov ax,SCREEN_HEIGHT
sub dx,dx
div bx
mul bx ;max # of full scan lines of text that
mov [MaxLines],ax ; will fit on the screen
mov ah,0fh ;BIOS video status function
int 10h ;get # of columns (bytes) per row
mov al,ah ;convert byte columns variable in
sub ah,ah ; AH to word in AX
mov [LineWidthBytes],ax ;width of scan line in bytes
;now draw the text
sub bx,bx
mov [Line],bx ;start at scan line 0
LineLoop:
sub ax,ax ;start at column 0; must be a multiple of 8
mov ch,FG_COLOR ;color in which to draw text
mov cl,BG_COLOR ;color in which to draw background box
mov si,offset SampleString ;text to draw
call DrawTextString ;draw the sample text
mov bx,[Line]
add bx,[CharHeight] ;# of next scan line to draw on
mov [Line],bx
cmp bx,[MaxLines] ;done yet?
jb LineLoop ;not yet
mov ah,7
int 21h ;wait for a key press, without echo
mov ax,03h
int 10h ;back to text mode
mov ah,4ch
int 21h ;exit to DOS
; Draws a text string.
; Input: AX = X coordinate at which to draw upper left corner of first char
; BX = Y coordinate at which to draw upper left corner of first char
; CH = foreground (text) color
; CL = background (box) color
; DS:SI = pointer to string to draw, zero terminated
; CharHeight must be set to the height of each character
; FontPtr must be set to the font with which to draw
; LineWidthBytes must be set to the scan line width in bytes
; Don't count on any registers other than DS, SS, and SP being preserved.
; The X coordinate is truncated to a multiple of 8. Characters are
; assumed to be 8 pixels wide.
align 2
DrawTextString proc near
cld
shr ax,1 ;byte address of starting X within scan line
shr ax,1
shr ax,1
mov di,ax
mov ax,[LineWidthBytes]
mul bx ;start offset of initial scan line
add di,ax ;start offset of initial byte
mov ax,SCREEN_SEGMENT
mov es,ax ;ES:DI = offset of initial character's
; first scan line
;set up the VGA's hardware so that we can
; fill the latches with the background color
mov dx,GC_INDEX
mov ax,(0ffh SHL 8) + BIT_MASK
out dx,ax ;set Bit Mask register to 0xFF (that's the
; default, but I'm doing this just to make sure
; you understand that Bit Mask register and
; CPU data are ANDed in write mode 3)
mov ax,(003h SHL 8) + G_MODE
out dx,ax ;select write mode 3
mov ah,cl ;background color
mov al,SET_RESET
out dx,ax ;set the drawing color to background color
mov byte ptr es:[0ffffh],0ffh ;write 8 pixels of the background
; color to unused offscreen memory
mov cl,es:[0ffffh] ;read the background color back into the
; latches; the latches are now filled with
; the background color. The value in CL
; doesn't matter, we just needed a target
; for the read, so we could load the latches
mov ah,ch ;foreground color
out dx,ax ;set the Set/Reset (drawing) color to the
; foreground color
;we're ready to draw!
DrawTextLoop:
lodsb ;next character to draw
and al,al ;end of string?
jz DrawTextDone ;yes
push ds ;remember string's segment
push si ;remember offset of next character in string
push di ;remember drawing offset
;load these variables before we wipe out DS
mov dx,[LineWidthBytes] ;offset from one line to next
dec dx ;compensate for STOSB
mov cx,[CharHeight] ;
mul cl ;offset of character in font table
lds si,[FontPtr] ;point to font table
add si,ax ;point to start of character to draw
;the following loop should be unrolled for
; maximum performance!
DrawCharLoop: ;draw all lines of the character
movsb ;get the next byte of the character and draw
; character; data is ANDed with Bit Mask
; register to become bit mask, and selects
; between latch (containing the background
; color) and Set/Reset register (containing
; foreground color)
add di,dx ;point to next line of destination
loop DrawCharLoop
pop di ;retrieve initial drawing offset
inc di ;drawing offset for next char
pop si ;retrieve offset of next character in string
pop ds ;retrieve string's segment
jmp DrawTextLoop ;draw next character, if any
align 2
DrawTextDone: ;restore the Graphics Mode register to its
; default state of write mode 0
mov dx,GC_INDEX
mov ax,(000h SHL 8) + G_MODE
out dx,ax ;select write mode 0
ret
DrawTextString endp
end start
14
Abrash/ZEN OF GRAPHISC PROGRAMMING, Chapter 40 (DDJ 8/92) -- Edited