{ VGA Mode Set Functions:
Set the current video mode to mode 13h or mode 3 (text)
WITHOUT the BIOS call!
I learned some of this from an assembly file that I couldn't
assemble (wouldn't work in TASM or NASM).
I am recoding it for NASM right now, but popped it out with
Turbo Pascal just to see if it'd work. It did.
Feel free to use this code, but beware: It doesn't like
Windows '95 a whole lot unless the DOS window is already
full screen.
This is good for demos/games that use their own file system and
boot code, when by the time that the graphics function is called,
you are already in protected mode and don't wanna switch back just
to call a stupid 16bit real mode BIOS routine.
If you can expand it to other modes (ModeX) or even SVGA, PLEASE
drop me a line at
[email protected]
Enjoy the code!
Jeremy A. Mika
Genetic Fantasia
}
uses crt;
type
VGAMode = record
BIOSmode, BIOScols : byte;
VidSeg:word;
Misc,Feature:byte;
Seq:array[0..4] of byte;
Crtc:array[0..$18] of byte;
Gfx:array[0..$8] of byte;
Att:array[0..$14] of byte;
end;
procedure setmode(mode:VGAMode);
const
MISC = $3c2;
SEQ = $3c4;
CRTC = $3d4;
GRAPHICS = $3ce;
FEATURE = $3da;
ATTRIB = $3c0;
STATUS = $3da;
VREND = $11;
NOPROT = $7f;
ENABLEATTRIB = $20;
CURSORTOPDATA = 17;
CURSORBOTTOMDATA = 18;
BIOSMODE = $49;
COLUMNS = $4a;
procedure outw(ad:word;x,y:byte);assembler;
asm
mov ah,x
mov al,y
mov dx,ad
out dx,ax
end;
var x:byte;
begin
ASM
mov dx,3dah
@1: in al,dx
test al,8
jz @1
@2: in al,dx
test al,8
jnz @2
END;
mem[$40:BIOSMODE]:=mode.BIOSmode;
mem[$40:COLUMNS]:=mode.BIOScols;
mem[$40:$61]:=mode.crtc[$a];
mem[$40:$60]:=mode.crtc[$b];
port[MISC]:=mode.misc;
delay(0);
port[FEATURE]:=mode.feature;
delay(0);
for x:=0 to 4 do begin
outw(SEQ,mode.seq[x],x);
delay(0);
end;
port[CRTC]:=$11;
port[CRTC]:=mode.crtc[$11] and $7F; {No protection!}
for x:=0 to $18 do begin
outw(CRTC,mode.crtc[x],x);
delay(0);
end;
for x:=0 to $8 do begin
outw(GRAPHICS,mode.gfx[x],x);
delay(0);
end;
x:=port[$3da];
delay(0);
for x:=0 to $14 do begin
port[ATTRIB]:=x;
delay(0);
port[ATTRIB]:=mode.att[x];
delay(0);
end;
port[ATTRIB]:=$20;
delay(0);
end;
const
Mode13:VGAMode = (BIOSmode:$13; BIOScols:40;
VidSeg:$a000;
Misc:$63; Feature:$00;
Seq:($03,$01,$0f,$00,$0e);
Crtc:($5f,$4f,$50,$82,$54,$80,$bf,$1f,$00,$41,$00,$00,
$00,$00,$00,$00,$9c,$0e,$8f,$28,$40,$96,$b9,$a3,
$ff);
Gfx:($00,$00,$00,$00,$00,$50,$07,$0f,$ff);
Att:($00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,
$0d,$0e,$0f,
$41,$00,$0f,$00,$00)
);
Mode03:VGAMode = (BIOSmode:$03; BIOScols:80;
VidSeg:$b800;
Misc:$67; Feature:$00;
Seq:($03,$00,$03,$00,$02);
Crtc:($5f,$4f,$50,$82,$55,$81,$bf,$1f,$00,$4f,$0e,$0f,
$00,$00,$00,$00,$9c,$0e,$8f,$28,$1f,$96,$b9,$a3,
$ff);
Gfx:($00,$00,$00,$00,$00,$10,$0e,$00,$ff);
Att:($00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,
$0d,$0e,$0f,
$0c,$00,$0f,$08,$00)
);
var x:byte;
buf:array[1..2000] of char;
begin
readln;
move(mem[$b800:0],buf,2000);
setmode(Mode13);
for x:=0 to 255 do
mem[$a000:x]:=2;
repeat
until keypressed;
readkey;
for x:=0 to 255 do begin
setmode(Mode13);
setmode(Mode03);
move(buf,mem[$b800:0],2000);
end;
readln;
end.