主题:[火星帖][华丽]突破256色限制, 24位真彩色闪亮登场!
昨天研究了一下SVGA模式, 居然被我研究出来了orz
首先, 这个SVGA模式, Pascal并没有相关函数, 所以我们只好自己动手, 丰衣足食:
procedure setsvga; assembler;{切换到SVGA模式}
asm
MOV AX, 4F02h
MOV BX, 10Fh
INT 16
end;
调用10h中断, 进入标准SVGA模式之一:320x200x24位真彩色.
然后就是画点, DOS下显存映射地址为mem[$A000:$0000]-mem[$AFFF:$000F]共计64KB区域, 然则, 320*200*4字节(虽然24位真彩色理论上只需要3字节存储)=250KB左右, 超了, 所以我们只能在屏幕上方约1/4大小的区域内显示.
当然, 社会是和谐的, 设计者早就考虑到这一点, 于是我们采用这样的方法: 将屏幕分成N个区, 如果你需要在第K个区画点, 那么就调用另外一个函数将显存映射地址切换到第K个区, 然后画点:
procedure svgasetbank(s:word); {切换到第s区}
begin
asm
MOV AX, 4F05h
MOV DX, s
INT 16
end;
curbank:=s;
end;
procedure svgapset(x, y, z:longint);{画点}
var
s, t:longint;
begin
t:=y*1280+x shl 2;
s:=t div $10000;
if curbank<>s then svgasetbank(s);
meml[$A000:t]:=z;
end;
function svgapoint(x, y:word):word;{取屏幕某点的值}
var
s, t:longint;
begin
t:=y*1280+x shl 2;
s:=t div $10000;
if curbank<>s then svgasetbank(s);
svgapoint:=mem[$A000:t];
end;
在你的程序运行完毕之后, 显然不能让它在SVGA模式继续呆着, 所以还要切换回文本模式:
procedure settext; assembler;
asm
mov ax, 3h
int 10h
end;
以上
首先, 这个SVGA模式, Pascal并没有相关函数, 所以我们只好自己动手, 丰衣足食:
procedure setsvga; assembler;{切换到SVGA模式}
asm
MOV AX, 4F02h
MOV BX, 10Fh
INT 16
end;
调用10h中断, 进入标准SVGA模式之一:320x200x24位真彩色.
然后就是画点, DOS下显存映射地址为mem[$A000:$0000]-mem[$AFFF:$000F]共计64KB区域, 然则, 320*200*4字节(虽然24位真彩色理论上只需要3字节存储)=250KB左右, 超了, 所以我们只能在屏幕上方约1/4大小的区域内显示.
当然, 社会是和谐的, 设计者早就考虑到这一点, 于是我们采用这样的方法: 将屏幕分成N个区, 如果你需要在第K个区画点, 那么就调用另外一个函数将显存映射地址切换到第K个区, 然后画点:
procedure svgasetbank(s:word); {切换到第s区}
begin
asm
MOV AX, 4F05h
MOV DX, s
INT 16
end;
curbank:=s;
end;
procedure svgapset(x, y, z:longint);{画点}
var
s, t:longint;
begin
t:=y*1280+x shl 2;
s:=t div $10000;
if curbank<>s then svgasetbank(s);
meml[$A000:t]:=z;
end;
function svgapoint(x, y:word):word;{取屏幕某点的值}
var
s, t:longint;
begin
t:=y*1280+x shl 2;
s:=t div $10000;
if curbank<>s then svgasetbank(s);
svgapoint:=mem[$A000:t];
end;
在你的程序运行完毕之后, 显然不能让它在SVGA模式继续呆着, 所以还要切换回文本模式:
procedure settext; assembler;
asm
mov ax, 3h
int 10h
end;
以上