program Reverse;
{
Sample program demonstrating manipulation of the VGA (EGA?)
alphanumeric character set using the 80x25 character mode.
The only thing this program does is to copy the current character
set from the video adapter, and restore it in such a way that all
the characters appear upside-down. To restore the characters,
simply run the program again. Not that this is a terribly useful
thing to do, mind you...
NOTE: This has not been tested on monochrome monitors or in
other video modes.
Written using Borland Pascal 7.0.
For more information on character sets for other video modes and
a whole bunch of good stuff on the EGA & VGA in general, you will
want the following book:
Title - "Programmer's Guide to PC & PS/2 Video Systems"
Author - Richard Wilton, 1987
Publisher - Microsoft Press
16011 NE 36th Way
Box 97017
Redmond, Washington 98073-9717
}
var
I, J: integer;
CBuf: array [0..8191] of byte; { Buffer for original character map }
procedure CharGenModeOn;
{ I'm sorry that there is no explanation here, but I did this a while
ago and I don't have the reference with me right now. }
begin
asm
cli
mov dx,03C4h
mov ax,0100h
out dx,ax
mov ax,0402h
out dx,ax
mov ax,0704h
out dx,ax
mov ax,0300h
out dx,ax
sti
mov dl,0CEh
mov ax,0204h
out dx,ax
mov ax,0005h
out dx,ax
mov ax,0006h
out dx,ax
end;
end;
procedure CharGenModeOff;
begin
asm
cli
mov dx,03C4h
mov ax,0100h
out dx,ax
mov ax,0302h
out dx,ax
mov ax,0304h
out dx,ax
mov ax,0300h
out dx,ax
sti
mov dl,0CEh
mov ax,0004h
out dx,ax
mov ax,1005h
out dx,ax
mov ax,0E06h
out dx,ax
mov ah,0Fh
int 10h
cmp al,7
jne @skip
mov ax,0806h
out dx,ax
@skip:
end;
end;
begin
CharGenModeOn; { Get access to character map }
{ Copy the current character map into the buffer }
move( mem[$A000: 0], CBuf, 8192 );
{ Restore the map, inverting the top 16 scan lines.
Characters are stored in a 8x32 pixel matrix, allowing
for characters that are 32 scan lines high. Each byte
in the buffer represents one scan line of a single
character. In the 80x25 character mode only the first
16 scan lines are displayed, so we need to be a little
careful about what bytes are swapped. }
for I := 0 to 255 do { Each of the 256 characters }
for J := 0 to 15 do { Top 16 scan lines of each }
mem[$a000:((I*32) + J)] := CBuf[(I*32) + (15 - J)];
CharGenModeOff; { Restore normal video operations }
end.