301 lines
9.2 KiB
HTML
301 lines
9.2 KiB
HTML
<HTML>
|
|
<HEAD>
|
|
<META name=vsisbn content="1576101746">
|
|
<META name=vstitle content="Michael Abrash's Graphics Programming Black Book, Special Edition">
|
|
<META name=vsauthor content="Michael Abrash">
|
|
<META name=vspublisher content="The Coriolis Group">
|
|
<META name=vspubdate content="07/01/97">
|
|
<META name=vscategory content="Web and Software Development: Game Development,Web and Software Development: Graphics and Multimedia Development">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<TITLE>Michael Abrash's Graphics Programming Black Book Special Edition: VGA Data Machinery</TITLE>
|
|
|
|
<!-- HEADER -->
|
|
<!-- Empty Reference Subhead -->
|
|
|
|
<!--ISBN=1576101746//-->
|
|
<!--TITLE=Michael Abrash's Graphics Programming Black Book Special Edition//-->
|
|
<!--AUTHOR=Michael Abrash//-->
|
|
<!--PUBLISHER=The Coriolis Group, Inc.//-->
|
|
<!--CHAPTER=25//-->
|
|
<!--PAGES=466-470//-->
|
|
<!--UNASSIGNED1//-->
|
|
<!--UNASSIGNED2//--></HEAD><BODY LINK=#0000FF ALINK=#000099 VLINK=#0000FF BGCOLOR=#FFFFFF>
|
|
|
|
<CENTER>
|
|
<TABLE BORDER>
|
|
<TR>
|
|
<TD><A HREF="25-01.html">Previous</A></TD>
|
|
<TD><A HREF="index.html">Table of Contents</A></TD>
|
|
<TD><A HREF="25-03.html">Next</A></TD>
|
|
</TR>
|
|
</TABLE>
|
|
</CENTER>
|
|
<P><BR></P>
|
|
<P><B>LISTING 25.1 L25-1.ASM</B></P>
|
|
<!-- CODE //-->
|
|
<PRE>
|
|
; Program to illustrate operation of data rotate and bit mask
|
|
; features of Graphics Controller. Draws 8×8 character at
|
|
; specified location, using VGA’s 8×8 ROM font. Designed
|
|
; for use with modes 0Dh, 0Eh, 0Fh, 10h, and 12h.
|
|
; By Michael Abrash.
|
|
;
|
|
stack segment para stack ‘STACK’
|
|
db 512 dup(?)
|
|
stack ends
|
|
;
|
|
VGA_VIDEO_SEGMENT equ 0a000h ;VGA display memory segment
|
|
SCREEN_WIDTH_IN_BYTES equ 044ah ;offset of BIOS variable
|
|
FONT_CHARACTER_SIZE equ 8 ;# bytes in each font char
|
|
;
|
|
; VGA register equates.
|
|
;
|
|
GC_INDEX equ 3ceh ;GC index register
|
|
GC_ROTATE equ 3 ;GC data rotate/logical function
|
|
; register index
|
|
GC_BIT_MASK equ 8 ;GC bit mask register index
|
|
;
|
|
dseg segment para common ‘DATA’
|
|
TEST_TEXT_ROW equ 69 ;row to display test text at
|
|
TEST_TEXT_COL equ 17 ;column to display test text at
|
|
TEST_TEXT_WIDTH equ 8 ;width of a character in pixels
|
|
|
|
TestString label byte
|
|
db ‘Hello, world!’,0 ;test string to print.
|
|
FontPointer dd ? ;font offset
|
|
dseg ends
|
|
;
|
|
; Macro to set indexed register INDEX of GC chip to SETTING.
|
|
;
|
|
SETGC macro INDEX, SETTING
|
|
mov dx,GC_INDEX
|
|
mov ax,(SETTING SHL 8) OR INDEX
|
|
out dx,ax
|
|
endm
|
|
;
|
|
cseg segment para public ‘CODE’
|
|
assume cs:cseg, ds:dseg
|
|
start proc near
|
|
mov ax,dseg
|
|
mov ds,ax
|
|
;
|
|
; Select 640×480 graphics mode.
|
|
;
|
|
mov ax,012h
|
|
int 10h
|
|
;
|
|
; Set driver to use the 8×8 font.
|
|
;
|
|
mov ah,11h ;VGA BIOS character generator function,
|
|
mov al,30h ; return info subfunction
|
|
mov bh,3;get 8×8 font pointer
|
|
int 10h
|
|
call SelectFont
|
|
;
|
|
; Print the test string.
|
|
;
|
|
mov si,offset TestString
|
|
mov bx,TEST_TEXT_ROW
|
|
mov cx,TEST_TEXT_COL
|
|
StringOutLoop:
|
|
lodsb
|
|
and al,al
|
|
jz StringOutDone
|
|
call DrawChar
|
|
add cx,TEST_TEXT_WIDTH
|
|
jmp StringOutLoop
|
|
StringOutDone:
|
|
;
|
|
; Reset the data rotate and bit mask registers.
|
|
;
|
|
SETGC GC_ROTATE, 0
|
|
SETGC GC_BIT_MASK, 0ffh
|
|
;
|
|
; Wait for a keystroke.
|
|
;
|
|
mov ah,1
|
|
int 21h
|
|
;
|
|
; Return to text mode.
|
|
;
|
|
mov ax,03h
|
|
int 10h
|
|
;
|
|
; Exit to DOS.
|
|
;
|
|
mov ah,4ch
|
|
int 21h
|
|
Start endp
|
|
;
|
|
; Subroutine to draw a text character in a linear graphics mode
|
|
; (0Dh, 0Eh, 0Fh, 010h, 012h).
|
|
; Font used should be pointed to by FontPointer.
|
|
;
|
|
; Input:
|
|
; AL = character to draw
|
|
; BX = row to draw text character at
|
|
; CX = column to draw text character at
|
|
;
|
|
; Forces ALU function to “move”.
|
|
;
|
|
DrawChar proc near
|
|
push ax
|
|
push bx
|
|
push cx
|
|
push dx
|
|
push si
|
|
push di
|
|
push bp
|
|
push ds
|
|
;
|
|
; Set DS:SI to point to font and ES to point to display memory.
|
|
;
|
|
lds si,[FontPointer] ;point to font
|
|
mov dx,VGA_VIDEO_SEGMENT
|
|
mov es,dx ;point to display memory
|
|
;
|
|
; Calculate screen address of byte character starts in.
|
|
;
|
|
push ds ;point to BIOS data segment
|
|
sub dx,dx
|
|
mov ds,dx
|
|
xchg ax,bx
|
|
mov di,ds:[SCREEN_WIDTH_IN_BYTES] ;retrieve BIOS
|
|
; screen width
|
|
pop ds
|
|
mul di ;calculate offset of start of row
|
|
push di ;set aside screen width
|
|
mov di,cx ;set aside the column
|
|
and cl,0111b ;keep only the column in-byte address
|
|
shr di,1
|
|
shr di,1
|
|
shr di,1 ;divide column by 8 to make a byte address
|
|
add di,ax ;and point to byte
|
|
;
|
|
; Calculate font address of character.
|
|
;
|
|
sub bh,bh
|
|
shl bx,1 ;assumes 8 bytes per character; use
|
|
shl bx,1 ; a multiply otherwise
|
|
shl bx,1 ;offset in font of character
|
|
add si,bx ;offset in font segment of character
|
|
;
|
|
; Set up the GC rotation.
|
|
;
|
|
mov dx,GC_INDEX
|
|
mov al,GC_ROTATE
|
|
mov ah,cl
|
|
out dx,ax
|
|
;
|
|
; Set up BH as bit mask for left half,
|
|
; BL as rotation for right half.
|
|
;
|
|
mov bx,0ffffh
|
|
shr bh,cl
|
|
neg cl
|
|
add cl,8
|
|
shl bl,cl
|
|
;
|
|
; Draw the character, left half first, then right half in the
|
|
; succeeding byte, using the data rotation to position the character
|
|
; across the byte boundary and then using the bit mask to get the
|
|
; proper portion of the character into each byte.
|
|
; Does not check for case where character is byte-aligned and
|
|
; no rotation and only one write is required.
|
|
;
|
|
mov bp,FONT_CHARACTER_SIZE
|
|
mov dx,GC_INDEX
|
|
pop cx ;get back screen width
|
|
dec cx
|
|
dec cx ; -2 because do two bytes for each char
|
|
CharacterLoop:
|
|
;
|
|
; Set the bit mask for the left half of the character.
|
|
;
|
|
mov al,GC_BIT_MASK
|
|
mov ah,bh
|
|
out dx,ax
|
|
;
|
|
; Get the next character byte & write it to display memory.
|
|
; (Left half of character.)
|
|
;
|
|
mov al,[si] ;get character byte
|
|
mov ah,es:[di] ;load latches
|
|
stosb ;write character byte
|
|
;
|
|
; Set the bit mask for the right half of the character.
|
|
;
|
|
mov al,GC_BIT_MASK
|
|
mov ah,bl
|
|
out dx,ax
|
|
;
|
|
; Get the character byte again & write it to display memory.
|
|
; (Right half of character.)
|
|
;
|
|
lodsb ;get character byte
|
|
mov ah,es:[di] ;load latches
|
|
stosb ;write character byte
|
|
;
|
|
; Point to next line of character in display memory.
|
|
;
|
|
add di,cx
|
|
;
|
|
dec bp
|
|
jnz CharacterLoop
|
|
;
|
|
pop ds
|
|
pop bp
|
|
pop di
|
|
pop si
|
|
pop dx
|
|
pop cx
|
|
pop bx
|
|
pop ax
|
|
ret
|
|
DrawChar endp
|
|
;
|
|
; Set the pointer to the font to draw from to ES:BP.
|
|
;
|
|
SelectFont proc near
|
|
mov word ptr [FontPointer],bp ;save pointer
|
|
mov word ptr [FontPointer+2],es
|
|
ret
|
|
SelectFont endp
|
|
;
|
|
cseg ends
|
|
end start
|
|
</PRE>
|
|
<!-- END CODE //-->
|
|
<P>The bit mask can be used for much more than bit-aligned fonts. For example, the bit mask is useful for fast pixel drawing, such as that performed when drawing lines, as we’ll see in Chapter 35. It’s also useful for drawing the edges of primitives, such as filled polygons, that potentially involve modifying some but not all of the pixels controlled by a single byte of display memory.
|
|
</P>
|
|
<P>Basically, the bit mask is handy whenever only <I>some</I> of the eight pixels in a byte of display memory need to be changed, because it allows full use of the VGA’s four-way parallel processing capabilities for the pixels that are to be drawn, without interfering with the pixels that are to be left unchanged. The alternative would be plane-by-plane processing, which from a performance perspective would be undesirable indeed.</P><P><BR></P>
|
|
<CENTER>
|
|
<TABLE BORDER>
|
|
<TR>
|
|
<TD><A HREF="25-01.html">Previous</A></TD>
|
|
<TD><A HREF="index.html">Table of Contents</A></TD>
|
|
<TD><A HREF="25-03.html">Next</A></TD>
|
|
</TR>
|
|
</TABLE>
|
|
</CENTER>
|
|
|
|
<hr width="90%" size="1" noshade>
|
|
<div align="center">
|
|
<font face="Verdana,sans-serif" size="1">Graphics Programming Black Book © 2001 Michael Abrash</font>
|
|
</div>
|
|
<!-- all of the reference materials (books) have the footer and subfoot reveresed -->
|
|
<!-- reference_subfoot = footer -->
|
|
<!-- reference_footer = subfoot -->
|
|
|
|
<!-- BEGIN SUB FOOTER -->
|
|
</BODY>
|
|
</HTML>
|
|
|
|
<!-- END FOOTER -->
|
|
|
|
|