264 lines
10 KiB
HTML
264 lines
10 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: Yet Another VGA Write Mode</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=27//-->
|
|
<!--PAGES=517-521//-->
|
|
<!--UNASSIGNED1//-->
|
|
<!--UNASSIGNED2//--></HEAD><BODY LINK=#0000FF ALINK=#000099 VLINK=#0000FF BGCOLOR=#FFFFFF>
|
|
|
|
<CENTER>
|
|
<TABLE BORDER>
|
|
<TR>
|
|
<TD><A HREF="27-04.html">Previous</A></TD>
|
|
<TD><A HREF="index.html">Table of Contents</A></TD>
|
|
<TD><A HREF="28-01.html">Next</A></TD>
|
|
</TR>
|
|
</TABLE>
|
|
</CENTER>
|
|
<P><BR></P>
|
|
<P>Another interesting point about flipping from graphics to text and back is that the standard mode 3 character/attribute map doesn’t actually take up every byte of the first 4000 bytes of planes 0 and 1. The standard mode 3 character/attribute map actually only takes up every even byte of the first 4000 in each plane; the odd bytes are left untouched. This means that only about 12K bytes actually have to be saved when going to text mode. The code in Listing 27.3 flips from graphics mode to text mode and back, saving only those 12K bytes that actually have to be saved. This code saves and restores the first 8K of plane 2 (the font area) while in graphics mode, but performs the save and restore of the 4000 bytes used for the character/attribute map while in text mode, because the characters and attributes, which are actually stored in the even bytes of planes 0 and 1, respectively, appear to be contiguous bytes in memory in text mode and so are easily saved as a single block.
|
|
</P>
|
|
<P>Explaining why only every other byte of planes 0 and 1 is used in text mode and why characters and attributes appear to be contiguous bytes when they are actually in different planes is a large part of the explanation I’m not going to go into now. One bit of fallout from this, however, is that if you flip to text mode and preserve the graphics bitmap using the mechanism illustrated in Listing 27.3, you shouldn’t write to any text page other than page 0 (that is, don’t write to any offset in display memory above 3999 in text mode) or alter the Page Select bit in the Miscellaneous Output register (3C2H) while in text mode. In order to allow completely unfettered access to text pages, it would be necessary to save every byte in the first 32K of each of planes 0 and 1. (On the other hand, this <I>would</I> allow up to 16 text screens to be stored simultaneously, with any one displayable instantly.) Moreover, if any fonts other than the default font are loaded, the portions of plane 2 that those particular fonts are loaded into would have to be saved, up to a maximum of all 64K of plane 2. In the worst case, a full 128K would have to be saved in order to preserve all the memory potentially used by text mode.</P>
|
|
<P>As I said, Phil Coleman’s question is an interesting one, and I’ve only touched on the intriguing possibilities arising from the various configurations of display memory in VGA graphics and text modes. Right now, though, we’ve still got the basics of the remarkably complex (but rewarding!) VGA to cover.</P>
|
|
<P><B>LISTING 27.3 L27-3.ASM</B></P>
|
|
<!-- CODE //-->
|
|
<PRE>
|
|
; Program to illustrate flipping from bit-mapped graphics mode to
|
|
; text mode and back without losing any of the graphics bit-map.
|
|
;
|
|
; Assemble with MASM or TASM
|
|
;
|
|
; By Michael Abrash
|
|
;
|
|
Stack segment para stack ‘STACK’
|
|
db 512 dup(0)
|
|
Stack ends
|
|
|
|
GRAPHICS_SEGMENT equ 0a000h ;mode 10 bit-map segment
|
|
TEXT_SEGMENT equ 0b800h ;mode 3 bit-map segment
|
|
SC_INDEX equ 3c4h ;Sequence Controller Index register
|
|
MAP_MASK equ 2 ;index of Map Mask register
|
|
GC_INDEX equ 3ceh ;Graphics Controller Index register
|
|
READ_MAP equ 4 ;index of Read Map register
|
|
|
|
Data segment para common ‘DATA’
|
|
|
|
GStrikeAnyKeyMsg0 label byte
|
|
db 0dh, 0ah, ‘Graphics mode’, 0dh, 0ah
|
|
db ‘Strike any key to continue...’, 0dh, 0ah, ‘$’
|
|
|
|
GStrikeAnyKeyMsg1 label byte
|
|
db 0dh, 0ah, ‘Graphics mode again’, 0dh, 0ah
|
|
db ‘Strike any key to continue...’, 0dh, 0ah, ‘$’
|
|
|
|
TStrikeAnyKeyMsg label byte
|
|
db 0dh, 0ah, ‘Text mode’, 0dh, 0ah
|
|
db ‘Strike any key to continue...’, 0dh, 0ah, ‘$’
|
|
|
|
Plane2Save db 2000h dup (?) ;save area for plane 2 data
|
|
; where font gets loaded
|
|
CharAttSave db 4000 dup (?) ;save area for memory wiped
|
|
; out by character/attribute
|
|
; data in text mode
|
|
Data ends
|
|
|
|
Code segment para public ‘CODE’
|
|
assume cs:Code, ds:Data
|
|
Start proc near
|
|
mov ax,10h
|
|
int 10h ;select video mode 10h (640×350)
|
|
;
|
|
; Fill the graphics bit-map with a colored pattern.
|
|
;
|
|
cld
|
|
mov ax,GRAPHICS_SEGMENT
|
|
mov es,ax
|
|
mov ah,3 ;initial fill pattern
|
|
mov cx,4 ;four planes to fill
|
|
mov dx,SC_INDEX
|
|
mov al,MAP_MASK
|
|
out dx,al ;leave the SC Index pointing to the
|
|
inc dx ; Map Mask register
|
|
|
|
FillBitMap:
|
|
mov al,10h
|
|
shr al,cl ;generate map mask for this plane
|
|
out dx,al ;set map mask for this plane
|
|
sub di,di ;start at offset 0
|
|
mov al,ah ;get the fill pattern
|
|
push cx ;preserve plane count
|
|
mov cx,8000h ;fill 32K words
|
|
rep stosw ;do fill for this plane
|
|
pop cx ;get back plane count
|
|
shl ah,1
|
|
shl ah,1
|
|
loop FillBitMap
|
|
;
|
|
; Put up “strike any key” message.
|
|
;
|
|
mov ax,Data
|
|
mov ds,ax
|
|
mov dx,offset GStrikeAnyKeyMsg0
|
|
mov ah,9
|
|
int 21h
|
|
;
|
|
; Wait for a key.
|
|
;
|
|
mov ah,01h
|
|
int 21h
|
|
;
|
|
; Save the 8K of plane 2 that will be used by the font.
|
|
;
|
|
mov dx,GC_INDEX
|
|
mov al,READ_MAP
|
|
out dx,al
|
|
inc dx
|
|
mov al,2
|
|
out dx,al ;set up to read from plane 2
|
|
mov ax,Data
|
|
mov es,ax
|
|
mov ax,GRAPHICS_SEGMENT
|
|
mov ds,ax
|
|
sub si,si
|
|
mov di,offset Plane2Save
|
|
mov cx,2000h/2 ;save 8K (length of default font)
|
|
rep movsw
|
|
;
|
|
; Go to text mode without clearing display memory.
|
|
;
|
|
mov ax,083h
|
|
int 10h
|
|
;
|
|
; Save the text mode bit-map.
|
|
;
|
|
mov ax,Data
|
|
mov es,ax
|
|
mov ax,TEXT_SEGMENT
|
|
mov ds,ax
|
|
sub si,si
|
|
mov di,offset CharAttSave
|
|
mov cx,4000/2 ;length of one text screen in words
|
|
rep movsw
|
|
;
|
|
; Fill the text mode screen with dots and put up “strike any key”
|
|
; message.
|
|
;
|
|
mov ax,TEXT_SEGMENT
|
|
mov es,ax
|
|
sub di,di
|
|
mov al,‘.’ ;fill character
|
|
mov ah,7 ;fill attribute
|
|
mov cx,4000/2 ;length of one text screen in words
|
|
rep stosw
|
|
mov ax,Data
|
|
mov ds,ax
|
|
mov dx,offset TStrikeAnyKeyMsg
|
|
mov ah,9
|
|
int 21h
|
|
;
|
|
; Wait for a key.
|
|
;
|
|
mov ah,01h
|
|
int 21h
|
|
;
|
|
; Restore the text mode screen to the state it was in on entering
|
|
; text mode.
|
|
;
|
|
mov ax,Data
|
|
mov ds,ax
|
|
mov ax,TEXT_SEGMENT
|
|
mov es,ax
|
|
mov si,offset CharAttSave
|
|
sub di,di
|
|
mov cx,4000/2 ;length of one text screen in words
|
|
rep movsw
|
|
;
|
|
; Return to mode 10h without clearing display memory.
|
|
;
|
|
mov ax,90h
|
|
int 10h
|
|
;
|
|
; Restore the portion of plane 2 that was wiped out by the font.
|
|
;
|
|
mov dx,SC_INDEX
|
|
mov al,MAP_MASK
|
|
out dx,al
|
|
inc dx
|
|
mov al,4
|
|
out dx,al ;set up to write to plane 2
|
|
mov ax,Data
|
|
mov ds,ax
|
|
mov ax,GRAPHICS_SEGMENT
|
|
mov es,ax
|
|
mov si,offset Plane2Save
|
|
sub di,di
|
|
mov cx,2000h/2 ;restore 8K (length of default font)
|
|
rep movsw
|
|
;
|
|
; Put up “strike any key” message.
|
|
;
|
|
mov ax,Data
|
|
mov ds,ax
|
|
mov dx,offset GStrikeAnyKeyMsg1
|
|
mov ah,9
|
|
int 21h
|
|
;
|
|
; Wait for a key before returning to text mode and ending.
|
|
;
|
|
mov ah,01h
|
|
int 21h
|
|
mov ax,03h
|
|
int 10h
|
|
mov ah,4ch
|
|
int 21h
|
|
Start endp
|
|
Code ends
|
|
end Start
|
|
</PRE>
|
|
<!-- END CODE //-->
|
|
<P><BR></P>
|
|
<CENTER>
|
|
<TABLE BORDER>
|
|
<TR>
|
|
<TD><A HREF="27-04.html">Previous</A></TD>
|
|
<TD><A HREF="index.html">Table of Contents</A></TD>
|
|
<TD><A HREF="28-01.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 -->
|
|
|
|
|