4469 lines
128 KiB
ObjectPascal
4469 lines
128 KiB
ObjectPascal
unit idvga;
|
|
interface
|
|
procedure DumpRegisters;
|
|
|
|
procedure AnalyseMode;
|
|
|
|
procedure CalcRegisters;
|
|
|
|
function dumpVGAregs:word;
|
|
|
|
procedure dumpVGAregfile;
|
|
|
|
procedure loadmodes;
|
|
|
|
function FormatRgs(var b:byte):word; {Format registers for dump}
|
|
|
|
{Weitek W5x86 Enable function
|
|
Sets the Extention & Bank enable flags in SEQ index $11}
|
|
function WeitekEnable(flag:word):word;
|
|
|
|
{Check for PCI devices}
|
|
procedure findPCI;
|
|
|
|
{Checks for a PCI card with ID=sign, returns index in PCIrec, 0 if not found
|
|
start is the PCI device to start at (0 first time, last ID next time)}
|
|
function CheckPCI(start,vendor,device:word):integer;
|
|
|
|
procedure findvideo;
|
|
|
|
procedure testdac;
|
|
|
|
function dacis8bit:boolean;
|
|
|
|
function DACflags:word;
|
|
|
|
procedure wPCIbyte(index,val:word);
|
|
procedure wPCIword(index,val:word);
|
|
procedure wPCIlong(index:word;val:longint);
|
|
function rPCIbyte(index:word):word;
|
|
function rPCIword(index:word):word;
|
|
function rPCIlong(index:word):longint;
|
|
|
|
|
|
|
|
const
|
|
PCIdevs:word=0; {Number of PCI video devices}
|
|
var
|
|
PCItype:word;
|
|
PCIrec:array[1..10] of record
|
|
PCIbase:word;
|
|
case integer of
|
|
0:(l:array[0..63] of longint);
|
|
1:(vendor,device,command,status:word;
|
|
rev,prog:byte;class:word;
|
|
cache,latency,header,bist:byte;
|
|
base0,base1,base2,base3,base4,base5
|
|
,xx0,xx1,rom,xx2,xx3:longint;
|
|
iline,ipin,mingnt,maxlat:byte);
|
|
end;
|
|
|
|
|
|
{$i idvga2.pas} {Holds all the Chipset, mode etc definitions.}
|
|
|
|
|
|
function DACflags:word;
|
|
var flag:word;
|
|
begin
|
|
flag:=0;
|
|
case cv.dactype of
|
|
_dac0,_dac8,_dacCEG:;
|
|
|
|
_dacInt:;
|
|
_dac15,_dac16,_dacADAC1,_dacSC486,_dacUMC188:
|
|
flag:=DFL_CmdReg;
|
|
|
|
_dacALG1101:;
|
|
_dacALG1201,_dacALG1301:
|
|
flag:=DFL_CmdReg;
|
|
|
|
_dacATI68860,_dacATI68880:
|
|
flag:=DFL_8bit;
|
|
|
|
_dacATT490,_dacATT491:
|
|
flag:=DFL_CmdReg+DFL_8bit;
|
|
_dacATT492,_dacATT493:
|
|
flag:=DFL_CmdReg;
|
|
_dacATT498,_dacATT1498,_dacATT2498:
|
|
flag:=DFL_CmdReg+DFL_8bit;
|
|
|
|
_dacBt477:
|
|
flag:=DFL_8bit;
|
|
_dacBt481,_dacBt482:
|
|
flag:=DFL_CmdReg+DFL_8bit+DFL_cursor;
|
|
_dacBt484,_dacBt485,_dacATT504,_dacATT505:
|
|
flag:=DFL_8bit+DFL_cursor;
|
|
|
|
_dacCH8391,
|
|
_dacCH8398:
|
|
flag:=DFL_CmdReg+DFL_8bit+DFL_Clock;
|
|
|
|
_dacCL5200:
|
|
flag:=DFL_CmdReg;
|
|
|
|
_dacIBM514,_dacIBM524,_dacIBM525,_dacIBM528:
|
|
flag:=DFL_cursor+DFL_8bit+DFL_Clock;
|
|
|
|
_dacICS5301:
|
|
flag:=DFL_CmdReg;
|
|
|
|
_dacICW498,_dacICW516:
|
|
flag:=DFL_CmdReg+DFL_8bit;
|
|
|
|
_dacMU1880,_dacMU4870:
|
|
flag:=DFL_CmdReg;
|
|
_dacMU4910:
|
|
flag:=DFL_CmdReg+DFL_8bit;
|
|
_dacMU9910:
|
|
flag:=DFL_CmdReg+DFL_8bit+DFL_Clock;
|
|
|
|
_dacS3_716,_dacS3_708:
|
|
flag:=DFL_CmdReg+DFL_8bit+DFL_Clock;
|
|
_dacSC15021,_dacSC15025:
|
|
flag:=DFL_CmdReg+DFL_8bit;
|
|
_dacSTG1700,_dacSTG1702:
|
|
flag:=DFL_CmdReg+DFL_8bit;
|
|
_dacSTG1703:
|
|
flag:=DFL_CmdReg+DFL_8bit+DFL_Clock;
|
|
_dacTLC34075,_dacTLC34076:
|
|
flag:=DFL_8bit; {8bit DACs from input pin}
|
|
_dacTR8001:
|
|
flag:=DFL_CmdReg+DFL_8bit;
|
|
_dacTVP3010,_dacTVP3020:
|
|
flag:=DFL_8bit+DFL_Cursor;
|
|
_dacTVP3025,_dacTVP3026:
|
|
flag:=DFL_8bit+DFL_Cursor+DFL_Clock;
|
|
end;
|
|
DACflags:=flag;
|
|
end;
|
|
|
|
procedure loadmodes; {Load extended modes for this chip}
|
|
var
|
|
t:text;
|
|
s,pat:string;
|
|
md,x,xres,yres,err,mreq,byt:word;
|
|
vbe0:_vbe0;
|
|
vbe1:_vbe1;
|
|
xbe1:_xbe1;
|
|
xbe2:_xbe2;
|
|
ok:boolean;
|
|
|
|
function VESAmemmode(model,bits,redinf,grninf,bluinf,resinf:word):integer;
|
|
const
|
|
mode6s=8;
|
|
mode:array[1..mode6s] of byte=(
|
|
_p15,_p16,_p24 ,_p24b,_p32 ,_p32b,_p32c,_p32d);
|
|
blui:array[1..mode6s] of word =(
|
|
5, 5, 8,$1008, 8,$1008, $808,$1808);
|
|
grni:array[1..mode6s] of word =(
|
|
$505,$506, $808, $808, $808, $808,$1008,$1008);
|
|
redi:array[1..mode6s] of word =(
|
|
$A05,$B05,$1008, 8,$1008, 8,$1808, $808);
|
|
resi:array[1..mode6s] of word =(
|
|
$F01, 0, 0, 0,$1808,$1808, 8, 8);
|
|
var x:word;
|
|
begin
|
|
VESAmemmode:=_text; {catch weird modes}
|
|
if (bits=15) and (resinf=0) then resinf:=$F01; {Bloody ATI Vesa driver @#$}
|
|
if (bits=15) and (bluinf=5) and (grninf=$405) then grninf:=$505;
|
|
{@#$ Mach64 VESA driver}
|
|
case model of
|
|
0:VESAmemmode:=_text;
|
|
1:case bits of
|
|
1:VESAmemmode:=_cga1;
|
|
2:VESAmemmode:=_cga2;
|
|
end;
|
|
2:VESAmemmode:=_herc;
|
|
3:case bits of
|
|
2:VESAmemmode:=_pl2;
|
|
4:VESAmemmode:=_pl4;
|
|
end;
|
|
4:case bits of
|
|
4:VESAmemmode:=_pk4;
|
|
8:VESAmemmode:=_p8;
|
|
15:VESAmemmode:=_p15;
|
|
16:VESAmemmode:=_p16;
|
|
24:VESAmemmode:=_p24;
|
|
end;
|
|
5:; {YUV coding}
|
|
6:for x:=1 to mode6s do
|
|
if (redinf=redi[x]) and (grninf=grni[x]) and (bluinf=blui[x])
|
|
and (resinf=resi[x]) then VESAmemmode:=mode[x];
|
|
7:;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure addmode(md,xres,yres,bytes:word;memmode:integer);
|
|
begin
|
|
inc(nomodes);
|
|
modetbl[nomodes].md :=md;
|
|
modetbl[nomodes].xres :=xres;
|
|
modetbl[nomodes].yres :=yres;
|
|
modetbl[nomodes].bytes :=bytes;
|
|
modetbl[nomodes].memmode:=memmode;
|
|
modetbl[nomodes].flags :=MFL_enabled;
|
|
if memmode>=_PL4 then
|
|
modetbl[nomodes].flags:=modetbl[nomodes].flags OR MFL_graphics;
|
|
end;
|
|
|
|
begin
|
|
nomodes:=0;
|
|
|
|
if (cv.flags and FLG_StdVGA)>0 then
|
|
begin
|
|
move(stdmodetbl,modetbl,novgamodes*sizeof(modetype));
|
|
nomodes:=novgamodes;
|
|
end;
|
|
|
|
case cv.chip of
|
|
__vesa:begin
|
|
vbe0.sign:=$41534556; (* VESA *)
|
|
viop($4F00,0,0,0,@vbe0);
|
|
|
|
{S3 VESA driver can return wrong segment if run with QEMM}
|
|
IF seg(vbe0.model^)=$E000 then
|
|
vbe0.model:=ptr($C000,ofs(vbe0.model^));
|
|
x:=1;
|
|
while vbe0.model^[x]<>$FFFF do
|
|
begin
|
|
vesamodeinfo(vbe0.model^[x],vbe1);
|
|
if (vbe1.attr and 1)<>0 then
|
|
begin
|
|
memmode:=VESAmemmode(vbe1.model,vbe1.bits,vbe1.redinf
|
|
,vbe1.grninf,vbe1.bluinf,vbe1.resinf);
|
|
addmode(vbe0.model^[x],vbe1.width,vbe1.height,vbe1.bytes,memmode);
|
|
end;
|
|
inc(x);
|
|
end;
|
|
end;
|
|
__xbe:begin
|
|
viop($4E01,0,0,cv.id,@xbe1);
|
|
x:=1;
|
|
while xbe1.modep^[x]<>$FFFF do
|
|
begin
|
|
viop($4E02,0,xbe1.modep^[x],cv.id,@xbe2);
|
|
if (rp.ax=$4E) and ((xbe2.attrib and 1)>0) then
|
|
begin
|
|
memmode:=VESAmemmode(xbe2.model,xbe2.bits,xbe2.redinf
|
|
,xbe2.grninf,xbe2.bluinf,xbe2.resinf);
|
|
if xbe2.bits=4 then memmode:=_pk4;
|
|
addmode(xbe1.modep^[x],xbe2.pixels,xbe2.lins,xbe2.bytes,memmode);
|
|
end;
|
|
inc(x);
|
|
end;
|
|
|
|
end;
|
|
else
|
|
for x:=1 to NBRMODES do
|
|
if MODELIST[x].chp=cv.chip then
|
|
begin
|
|
ok:=true;
|
|
md :=MODELIST[x].md;
|
|
memmode:=MODELIST[x].mode;
|
|
xres :=MODELIST[x].xres;
|
|
yres :=MODELIST[x].yres;
|
|
planes:=1;
|
|
if memmode<_herc then bytes:=xres*2
|
|
else bytes:=(xres*usebits[memmode]) shr 3;
|
|
if memmode=_pl4 then
|
|
begin
|
|
bytes:=xres shr 3;
|
|
planes:=4;
|
|
end;
|
|
|
|
case cv.dactype of
|
|
_dacCEG,
|
|
_dac8:if memmode>_p8 then ok:=false;
|
|
_dac15:if memmode>_p15 then ok:=false;
|
|
_dac16,_dacMU4870:
|
|
if memmode>_p16 then ok:=false;
|
|
_dacALG1101:if (memmode=_p15) or (memmode>_p16) then ok:=false;
|
|
end;
|
|
case cv.chip of
|
|
__ALG:if (md=$48) and (cv.Version=ALG_2228) then bytes:=2048;
|
|
__ARK:if (memmode=_P24) and (cv.Version>=ARK_2000PV) then
|
|
begin
|
|
memmode:=_P32;
|
|
bytes:=xres*4;
|
|
end;
|
|
__ATI:begin
|
|
if (md<$100) and (cv.Version<ATI_M64_GX) then
|
|
begin
|
|
rp.bx:=$5506;
|
|
rp.bp:=$FFFF;
|
|
rp.si:=0;
|
|
vio($1200+md);
|
|
if rp.bp=$FFFF then ok:=false;
|
|
end;
|
|
{The VGA chip can't handle the ATI dac yet}
|
|
if (cv.dactype=_dacATI68860) and (memmode>_P8) then ok:=false;
|
|
end;
|
|
__Compaq:if (cv.Version<CPQ_QV) and (md>$2E) then ok:=false;
|
|
__Cir54:if (cv.Version<CL_GD5430) and ((memmode=_p32) or (xres>1280)) then ok:=false;
|
|
|
|
__S3:if (cv.version<=S3_924) then
|
|
begin
|
|
if ((md>$105) and (md<$200)) or (md=$212) or (md=$211) then ok:=false;
|
|
end
|
|
else begin
|
|
if md>$210 then ok:=false;
|
|
if (cv.version<S3_928) and (memmode=_p32) then memmode:=_p24;
|
|
if (cv.version=S3_928) and (memmode=_PK4a) then ok:=false;
|
|
end;
|
|
__Trid:if cv.version=TR_IITAGX then
|
|
if (md>=$60) then ok:=false;
|
|
__Tseng:case cv.version of
|
|
ET_3000:if md=$2F then ok:=false;
|
|
ET_4000:case cv.subvers of
|
|
TS_SpeedStar:if (hi(md)=2) or (md=$53E) then ok:=false;
|
|
TS_Genoa7900:if (hi(md)=1) or (hi(md)=2) then ok:=false;
|
|
else
|
|
if (md=$53E) or (hi(md)=1) then ok:=false;
|
|
end;
|
|
else if (md=$53E) or (hi(md)=1) then ok:=false;
|
|
end;
|
|
end;
|
|
byt :=MODELIST[x].size;
|
|
if (byt>0) then bytes:=byt;
|
|
mreq:=(longint(bytes*planes)*yres+1023) div 1024;
|
|
if ok and (cv.mm>=mreq) then
|
|
addmode(md,xres,yres,bytes,memmode);
|
|
end;
|
|
for x:=1 to noumodes do {User overrides (.CFG)}
|
|
if usermodes[x].flags=cv.chip then
|
|
if usermodes[x].memmode=__None then
|
|
begin
|
|
for xres:=1 to nomodes do
|
|
if modetbl[xres].md=usermodes[x].md then
|
|
modetbl[xres].flags:=0; {Disable}
|
|
end
|
|
else addmode(usermodes[x].md,usermodes[x].xres,usermodes[x].yres
|
|
,usermodes[x].bytes,usermodes[x].memmode);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure findPCI;
|
|
const ROMs:array[0..3] of string[4]=(' 32K',' 64K','128K','256K');
|
|
var
|
|
i,j:word;
|
|
PCIid:longint;
|
|
tmp:longint;
|
|
|
|
procedure wrPCI(txt:string;base:longint);
|
|
begin
|
|
write(' '+txt+': '+hex8(base)+' at ');
|
|
if (base and 1)>0 then write('I/O: '+hex4(base and $FF00)+'h')
|
|
else write('Mem: '+hex8(base and $FFFFFF00)+'h (',base shr 20,'M)');
|
|
if (base and 8)>0 then write(' Cachable');
|
|
writeln;
|
|
end;
|
|
|
|
begin
|
|
PCItype:=0;
|
|
outp($CF8,0);
|
|
outp($CFA,0);
|
|
if (inp($CF8)=0) and (inp($CFA)=0) then PCItype:=2
|
|
else begin
|
|
tmp:=inplong($CF8);
|
|
for i:=1 to 10 do; {delay}
|
|
outplong($CF8,$80000000);
|
|
for i:=1 to 10 do;
|
|
if inplong($CF8)=$80000000 then PCItype:=1;
|
|
for i:=1 to 10 do;
|
|
outplong($CF8,tmp);
|
|
end;
|
|
if PCItype>0 then
|
|
begin
|
|
clrscr;
|
|
Writeln('PCI bus type ',PCItype,' Devices:');
|
|
writeln(' Bus: Vendor: Device:');
|
|
case PCItype of
|
|
1:begin {PCI type 1}
|
|
for i:=0 to 127{511} do
|
|
begin
|
|
outplong($CF8,$80000000+i*longint(2048));
|
|
tmp:=inplong($CFC);
|
|
if (word(tmp)<>$FFFF) and ((tmp shr 16)<>$FFFF) then
|
|
begin
|
|
inc(PCIdevs);
|
|
PCIrec[PCIdevs].PCIbase:=i;
|
|
PCIrec[PCIdevs].l[0]:=tmp;
|
|
for j:=1 to 63 do
|
|
begin
|
|
outplong($CF8,$80000000+i*longint(2048)+j*4);
|
|
PCIrec[PCIdevs].l[j]:=inplong($CFC);
|
|
end;
|
|
if PCIrec[PCIdevs].class<>$300 then dec(PCIdevs);
|
|
end;
|
|
end;
|
|
end;
|
|
2:begin {PCI type 2}
|
|
outp($CF8,$80);
|
|
outp($CFA,0); {Bus select?}
|
|
for i:=0 to 15 do
|
|
begin
|
|
tmp:=inplong($C000+i*256);
|
|
if (word(tmp)<>$FFFF) and ((tmp shr 16)<>$FFFF) then
|
|
begin
|
|
inc(PCIdevs);
|
|
PCIrec[PCIdevs].PCIbase:=i;
|
|
PCIrec[PCIdevs].l[0]:=tmp;
|
|
for j:=1 to 63 do PCIrec[PCIdevs].l[j]:=inplong($C000+i*256+j*4);
|
|
if PCIrec[PCIdevs].class<>$300 then dec(PCIdevs);
|
|
end;
|
|
end;
|
|
outp($CF8,0);
|
|
end;
|
|
end;
|
|
if PCIdevs>0 then
|
|
begin
|
|
settextmode;
|
|
for i:=1 to PCIdevs do
|
|
begin
|
|
writeln(' Vendor: '+hex4(PCIrec[i].vendor)+' Device: '+hex4(PCIrec[i].device));
|
|
if PCIrec[i].base0<>0 then wrPCI('Base0',PCIrec[i].base0);
|
|
if PCIrec[i].base1<>0 then wrPCI('Base1',PCIrec[i].base1);
|
|
if PCIrec[i].base2<>0 then wrPCI('Base2',PCIrec[i].base2);
|
|
if PCIrec[i].base3<>0 then wrPCI('Base3',PCIrec[i].base3);
|
|
if PCIrec[i].base4<>0 then wrPCI('Base4',PCIrec[i].base4);
|
|
if PCIrec[i].base5<>0 then wrPCI('Base5',PCIrec[i].base5);
|
|
if PCIrec[i].rom<>0 then wrPCI('ROM ',PCIrec[i].rom);
|
|
|
|
writeln;
|
|
end;
|
|
if readkey='' then;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
{Checks for a PCI card with ID=sign, returns index in PCIrec, 0 if not found
|
|
START is the }
|
|
function CheckPCI(start,vendor,device:word):integer;
|
|
var i:integer;
|
|
begin
|
|
i:=start;
|
|
repeat inc(i);
|
|
until (i>PCIdevs) or ((PCIrec[i].vendor=vendor) and
|
|
((PCIrec[i].device=device) or (device=$FFFF)));
|
|
if i<=PCidevs then CheckPCI:=i
|
|
else CheckPCI:=0; {Default: None found}
|
|
end;
|
|
|
|
procedure wPCIbyte(index,val:word);
|
|
begin
|
|
case PCItype of
|
|
1:begin
|
|
outplong($CF8,$80000000+PCIrec[cv.PCIid].PCIbase*longint(2048)+index);
|
|
outp($CFC,val);
|
|
end;
|
|
2:begin
|
|
outp($CF8,$80);
|
|
outp($CFA,0); {Bus select?}
|
|
outp($C000+PCIrec[cv.PCIid].PCIbase*256+index,val);
|
|
outp($CF8,0);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure wPCIword(index,val:word);
|
|
begin
|
|
case PCItype of
|
|
1:begin
|
|
outplong($CF8,$80000000+PCIrec[cv.PCIid].PCIbase*longint(2048)+index);
|
|
outpw($CFC,val);
|
|
end;
|
|
2:begin
|
|
outp($CF8,$80);
|
|
outp($CFA,0); {Bus select?}
|
|
outpw($C000+PCIrec[cv.PCIid].PCIbase*256+index,val);
|
|
outp($CF8,0);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure wPCIlong(index:word;val:longint);
|
|
begin
|
|
case PCItype of
|
|
1:begin
|
|
outplong($CF8,$80000000+PCIrec[cv.PCIid].PCIbase*longint(2048)+index);
|
|
outpl($CFC,val);
|
|
end;
|
|
2:begin
|
|
outp($CF8,$80);
|
|
outp($CFA,0); {Bus select?}
|
|
outpl($C000+PCIrec[cv.PCIid].PCIbase*256+index,val);
|
|
outp($CF8,0);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function rPCIbyte(index:word):word;
|
|
begin
|
|
case PCItype of
|
|
1:begin
|
|
outplong($CF8,$80000000+PCIrec[cv.PCIid].PCIbase*longint(2048)+index);
|
|
rPCIbyte:=inp($CFC);
|
|
end;
|
|
2:begin
|
|
outp($CF8,$80);
|
|
outp($CFA,0); {Bus select?}
|
|
rPCIbyte:=inp($C000+PCIrec[cv.PCIid].PCIbase*256+index);
|
|
outp($CF8,0);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function rPCIword(index:word):word;
|
|
begin
|
|
case PCItype of
|
|
1:begin
|
|
outplong($CF8,$80000000+PCIrec[cv.PCIid].PCIbase*longint(2048)+index);
|
|
rPCIword:=inpw($CFC);
|
|
end;
|
|
2:begin
|
|
outp($CF8,$80);
|
|
outp($CFA,0); {Bus select?}
|
|
rPCIword:=inpw($C000+PCIrec[cv.PCIid].PCIbase*256+index);
|
|
outp($CF8,0);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function rPCIlong(index:word):longint;
|
|
begin
|
|
case PCItype of
|
|
1:begin
|
|
outplong($CF8,$80000000+PCIrec[cv.PCIid].PCIbase*longint(2048)+index);
|
|
rPCIlong:=inpl($CFC);
|
|
end;
|
|
2:begin
|
|
outp($CF8,$80);
|
|
outp($CFA,0); {Bus select?}
|
|
rPCIlong:=inpl($C000+PCIrec[cv.PCIid].PCIbase*256+index);
|
|
outp($CF8,0);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
(* Analyse the current mode *)
|
|
|
|
var
|
|
oldreg:boolean;
|
|
|
|
function getbios(offs,lnn:word):string;
|
|
var s:string;
|
|
begin
|
|
s[0]:=chr(lnn);
|
|
move(mem[biosseg:offs],s[1],lnn);
|
|
getbios:=s;
|
|
end;
|
|
|
|
|
|
procedure checkmem(mx:word);
|
|
var
|
|
fail:boolean;
|
|
ma:array[0..99] of byte;
|
|
x:word;
|
|
begin
|
|
memmode:=_p8;
|
|
|
|
fail:=true;
|
|
while (mx>1) and fail do
|
|
begin
|
|
setbank(mx-1);
|
|
move(mem[SegA000:0],ma,100);
|
|
for x:=0 to 99 do
|
|
mem[SegA000:x]:=ma[x] xor $aa;
|
|
setbank(mx-1);
|
|
fail:=false;
|
|
for x:=0 to 99 do
|
|
if mem[SegA000:x]<>ma[x] xor $aa then fail:=true;
|
|
move(ma,mem[SegA000:0],100);
|
|
if not fail then
|
|
begin
|
|
setbank((mx shr 1)-1);
|
|
for x:=0 to 99 do
|
|
mem[SegA000:x]:=ma[x] xor $55;
|
|
setbank(mx-1);
|
|
fail:=true;
|
|
for x:=0 to 99 do
|
|
if mem[SegA000:x]<>ma[x] xor $55 then fail:=false;
|
|
move(ma,mem[SegA000:0],100);
|
|
end;
|
|
mx:=mx shr 1;
|
|
end;
|
|
cv.mm:=mx*128;
|
|
end;
|
|
|
|
|
|
procedure DumpRegisters;
|
|
|
|
procedure dumprg(base,start,ende:word;var rg:regblk);
|
|
var six,ix:word;
|
|
same:boolean;
|
|
begin
|
|
rg.base:=base;
|
|
six:=inp(base);
|
|
outp(base,0);
|
|
ix:=inp(base) xor 255;
|
|
outp(base,255);
|
|
ix:=ix and inp(base);
|
|
|
|
if ende=0 then
|
|
if ix>127 then ende:=255
|
|
else if ix>63 then ende:=127
|
|
else if ix>31 then ende:=63
|
|
else if ix>15 then ende:=31
|
|
else if ix>7 then ende:=15
|
|
else ende:=7;
|
|
for ix:=start to ende do
|
|
rg.x[ix]:=rdinx(base,ix);
|
|
rg.nbr:=ende;
|
|
outp(base,six);
|
|
same:=true;
|
|
while (rg.nbr>7) and same do {Check for doubles}
|
|
begin
|
|
six:=succ(rg.nbr) div 2;
|
|
for ix:=0 to six-1 do
|
|
if rg.x[ix]<>rg.x[ix+six] then same:=false;
|
|
if same then rg.nbr:=rg.nbr div 2;
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure DumpTridOldRegs;
|
|
begin
|
|
wrinx(SEQ,$B,0);
|
|
rgs.tridold0d:=rdinx(SEQ,$D);
|
|
rgs.tridold0e:=rdinx(SEQ,$E);
|
|
if rdinx(SEQ,$B)=0 then; {New mode}
|
|
oldreg:=true;
|
|
end;
|
|
|
|
procedure DumpXGAregs;
|
|
var x:word;
|
|
begin
|
|
dumprg(cv.IOadr+10,0,0,rgs.xxregs);
|
|
for x:=0 to 15 do
|
|
rgs.xgaregs[x]:=inp(cv.IOadr+x);
|
|
end;
|
|
|
|
var x,y,m:word;
|
|
VESAcheat:boolean;
|
|
begin
|
|
if cv.chip=__VESA then
|
|
begin
|
|
cv.chip:=__Alli;
|
|
cv.ioadr:=$1ce;
|
|
cv.dactype:=_dacSTG1703;
|
|
VESAcheat:=true;
|
|
end
|
|
else VESAcheat:=false;
|
|
case cv.chip of { Enable ext }
|
|
__S3:begin
|
|
wrinx(crtc,$38,$48);
|
|
wrinx(crtc,$39,$A5);
|
|
if (cv.version=S3_732) or (cv.Version=S3_764) then wrinx(SEQ,8,6);
|
|
end;
|
|
__Trid:begin
|
|
outpw(SEQ,$B);
|
|
if inp(SEQ+1)=0 then;
|
|
x:=rdinx(SEQ,$E) XOR 2;
|
|
outp(SEQ+1,x OR $80); {Enable extended registers}
|
|
end;
|
|
__Compaq:wrinx(GRC,$F,5);
|
|
{__Video7:wrinx(SEQ,6,$EA); }
|
|
end;
|
|
fillchar(rgs,sizeof(rgs),0);
|
|
oldreg:=false;
|
|
vclk:=0;
|
|
for x:=$3C2 to $3DF do rgs.stdregs[x]:=inp(x);
|
|
rgs.stdregs[$3DA]:=inp(CRTC+6);
|
|
rgs.stdregs[$3C0]:=inp($3C0);
|
|
for x:=0 to 31 do rgs.attregs[x]:=rdinx($3C0,x);
|
|
x:=rdinx($3C0,$30);
|
|
rgs.mode:=curmode;
|
|
dumprg(CRTC,0,0,rgs.crtcregs);
|
|
dumprg(SEQ,0,0,rgs.seqregs);
|
|
dumprg(GRC,0,0,rgs.grcregs);
|
|
case cv.chip of
|
|
__Alli:begin
|
|
if mem[SegA000:$D8]=0 then;
|
|
outpw(SEQ,$1210);
|
|
setinx(SEQ,$1C,8);
|
|
modinx(SEQ,$1B,7,1);
|
|
|
|
rgs.xxregs.nbr:=255;
|
|
rgs.xxregs.base:=1;
|
|
move(mem[SegA000:0],rgs.xxregs.x,256);
|
|
clrinx(SEQ,$1B,7);
|
|
clrinx(SEQ,$1C,8);
|
|
end;
|
|
__ati:begin
|
|
dumprg(cv.IOadr,$A0,$BF,rgs.xxregs);
|
|
rgs.xxregs.x[0]:=inp($6AEC);
|
|
rgs.xxregs.x[1]:=inp($6AED);
|
|
rgs.xxregs.x[2]:=inp($6AEE);
|
|
rgs.xxregs.x[3]:=inp($6AEF);
|
|
rgs.xxregs.x[4]:=inp($72EC);
|
|
rgs.xxregs.x[5]:=inp($72ED);
|
|
rgs.xxregs.x[6]:=inp($72EE);
|
|
rgs.xxregs.x[7]:=inp($72EF);
|
|
rgs.xxregs.x[8]:=inp($62EC);
|
|
rgs.xxregs.x[9]:=inp($62ED);
|
|
rgs.xxregs.x[10]:=inp($62EE);
|
|
rgs.xxregs.x[11]:=inp($62EF);
|
|
rgs.xxregs.x[12]:=inp($1EEC);
|
|
rgs.xxregs.x[13]:=inp($1EED);
|
|
rgs.xxregs.x[14]:=inp($1EEE);
|
|
rgs.xxregs.x[15]:=inp($1EEF);
|
|
end;
|
|
__chips:dumprg(cv.IOadr,0,0,rgs.xxregs);
|
|
__VESA,
|
|
__compaq:begin
|
|
for x:=1 to 15 do
|
|
for m:=0 to 15 do
|
|
rgs.xxregs.x[(x-1)*16+m]:=inp(x*$1000+$3C0+m);
|
|
rgs.xxregs.base:=$3C;
|
|
rgs.xxregs.nbr:=240;
|
|
end;
|
|
__WD:if cv.Version=WD_90c24 then
|
|
begin
|
|
wrinx(SEQ,$35,$50); {Unlock clock regs}
|
|
rgs.seqregs.x[$31]:=rdinx(SEQ,$31);
|
|
wrinx(crtc,$34,$A6);
|
|
wrinx(crtc,$35,$30);
|
|
for x:=$31 to $3F do
|
|
rgs.crtcregs.x[x]:=rdinx(crtc,x);
|
|
wrinx(crtc,$34,0);
|
|
wrinx(crtc,$35,0);
|
|
end;
|
|
__Mach64:begin
|
|
move(mem[cv.Xseg:0],rgs.xxregs.x,256);
|
|
rgs.xxregs.x[$D4]:=inp($6AEC);
|
|
rgs.xxregs.x[$D5]:=inp($6AED);
|
|
rgs.xxregs.x[$D6]:=inp($6AEE);
|
|
rgs.xxregs.x[$D7]:=inp($6AEF);
|
|
rgs.xxregs.base:=$2EC;
|
|
rgs.xxregs.nbr:=256;
|
|
end;
|
|
__Mach32:begin
|
|
rgs.xxregs.base:=$2E8;
|
|
rgs.xxregs.nbr:=128;
|
|
for x:=0 to 63 do {Mach8 & 32}
|
|
begin
|
|
m:=inpw($2E8+(x shl 10));
|
|
rgs.xxregs.x[x*2]:=lo(m);
|
|
rgs.xxregs.x[x*2+1]:=hi(m);
|
|
end;
|
|
if cv.Version>=ATI_GUP_3 then {Mach32}
|
|
begin
|
|
for x:=0 to 63 do
|
|
begin
|
|
m:=inpw($2EE+(x shl 10));
|
|
rgs.xxregs.x[x*2+128]:=lo(m);
|
|
rgs.xxregs.x[x*2+129]:=hi(m);
|
|
end;
|
|
rgs.xxregs.nbr:=256;
|
|
end;
|
|
end;
|
|
__Tseng:if cv.version>=ET_4W32 then dumprg($217A,0,0,rgs.xxregs);
|
|
__hmc:dumprg(SEQ,$0,$FF,rgs.xxregs);
|
|
__Matrox,
|
|
__oak:dumprg($3DE,0,0,rgs.xxregs);
|
|
__trid:DumpTridOldRegs;
|
|
(* __agx:if (inp(cv.IOadr) and 4)=0 then DumpTridOldRegs
|
|
else DumpXGAregs; *)
|
|
__AGX,__xbe,__xga:
|
|
DumpXGAregs;
|
|
else rgs.xxregs.base:=0;
|
|
end;
|
|
|
|
for x:=0 to 15 do
|
|
rgs.dacregs[x]:=rdDACreg(x);
|
|
if (DACflags and DFL_CmdReg)>0 then
|
|
begin
|
|
dac2comm;
|
|
rgs.dacregs[16]:=inp($3C6);
|
|
dac2pel;
|
|
end;
|
|
rgs.dacinxd.nbr :=0;
|
|
rgs.dacinxd.base:=0;
|
|
case cv.dactype of
|
|
_dacCL5200:begin
|
|
outp($3C6,0);
|
|
dac2comm;
|
|
rgs.dacregs[6]:=inp($3C6);
|
|
dac2pel;
|
|
outp($3C6,rgs.dacregs[2]);
|
|
end;
|
|
_dacMU1880:begin
|
|
dac2comm;
|
|
dac2comm;
|
|
x:=8;
|
|
while (x>0) and (inp($3C6)<>$8E) do dec(x);
|
|
rgs.dacinxd.x[6]:=inp($3C6);
|
|
rgs.dacinxd.x[6]:=inp($3C6);
|
|
dac2pel;
|
|
|
|
end;
|
|
_dacSC15021,_dacSc15025:
|
|
begin {Sierra SC15025 24bit DAC}
|
|
y:=inp(SetDACpage(dacHIcmd));
|
|
outp(SetDACpage(dacHIcmd),y or 16);
|
|
dumprg($3C7,0,31,rgs.dacinxd);
|
|
outp(SetDACpage(dacHIcmd),y);
|
|
end;
|
|
_dacSTG1700,_dacSTG1702,_dacSTG1703:
|
|
begin
|
|
rgs.dacinxd.base:=$3C6;
|
|
rgs.dacinxd.nbr:=7;
|
|
y:=inp(SetDACpage(dacHIcmd));
|
|
outp(SetDACpage(dacHIcmd),y or 16);
|
|
dac2comm;
|
|
m:=inp($3C6);
|
|
outp($3C6,0);
|
|
outp($3C6,0);
|
|
for x:=0 to 7 do
|
|
rgs.dacinxd.x[x]:=inp($3C6);
|
|
if cv.dactype=_dacSTG1703 then
|
|
begin
|
|
for x:=8 to $5F do
|
|
rgs.dacinxd.x[x]:=inp($3C6);
|
|
rgs.dacinxd.nbr:=$5F;
|
|
end;
|
|
wrDACreg(dacHIcmd,y);
|
|
end;
|
|
_dacBt481,_dacBt482:
|
|
begin
|
|
if cv.chip=__AGX then outp(cv.IOadr,1);
|
|
(* outp(SetDACpage(dacBT1cmdA),1);
|
|
for x:=0 to 15 do {This screws up the DAC, so we drop it for now}
|
|
begin
|
|
outp($3C8,x);
|
|
rgs.dacinxd.x[x]:=inp($3C6);
|
|
end;
|
|
rgs.dacinxd.base:=$3C6;
|
|
rgs.dacinxd.nbr:=15;
|
|
outp(SetDACpage(dacBT1cmdA),rgs.dacregs[dacBT1cmdA]); *)
|
|
if cv.chip=__AGX then outp(cv.IOadr,4);
|
|
end;
|
|
_dacBt484,_dacBt485,_dacATT504,_dacATT505:
|
|
begin {BrookTree Bt484/5 or ATT20c504/5 DAC}
|
|
outp(SetDACpage(dacBTcmd0),rgs.dacregs[dacBTcmd0] or $80);
|
|
outp(SetDACpage(0),0);
|
|
rgs.dacregs[dacBTstat]:=inp(SetDACpage(dacBTstat));
|
|
outp(SetDACpage(0),1);
|
|
rgs.dacregs[16]:=inp(SetDACpage(dacBTstat));
|
|
outp(SetDACpage(dacBTcmd0),rgs.dacregs[dacBTcmd0]);
|
|
end;
|
|
_dacCH8391,
|
|
_dacCH8398:begin
|
|
outp(SetDACpage(7),0);
|
|
for x:=1 to 4 do y:=inp(SetDACpage(4));
|
|
rgs.dacregs[16]:=inp(SetDACpage(4));
|
|
outp(SetDACpage(7),0);
|
|
for x:=0 to 47 do rgs.dacinxd.x[x]:=inp(SetDACpage(5));
|
|
rgs.dacinxd.base:=$3C8;
|
|
rgs.dacinxd.nbr :=47;
|
|
end;
|
|
_dacS3_708,_dacS3_716:
|
|
begin {S3 SDAC and GenDAC}
|
|
outp(SetDACpage(7),0);
|
|
for x:=0 to 31 do {There are 16 16bit registers}
|
|
begin
|
|
{outp(SetDACpage(7),x);}
|
|
rgs.dacinxd.x[x]:=inp(SetDACpage(5));
|
|
end;
|
|
rgs.dacinxd.base:=$3C6;
|
|
rgs.dacinxd.nbr:=31;
|
|
end;
|
|
_dacTVP3010,_dacTVP3020,_dacTVP3025:
|
|
begin {TI TVP 302x DAC}
|
|
y:=rdDACreg(dacTVPindex);
|
|
for y:=0 to $3F do
|
|
begin
|
|
wrDACreg(dacTVPindex,y);
|
|
rgs.dacinxd.x[y]:=rdDACreg(dacTVPdata);
|
|
end;
|
|
|
|
wrDACreg(dacTVPindex,$2C);
|
|
wrDACreg(dacTVPdata,0); {PLL 1st byte}
|
|
wrDACreg(dacTVPindex,$2D);
|
|
rgs.dacinxd.x[$40]:=rdDACreg(dacTVPdata);
|
|
wrDACreg(dacTVP6index,$2E);
|
|
rgs.dacinxd.x[$43]:=rdDACreg(dacTVPdata);
|
|
wrDACreg(dacTVPindex,$2F);
|
|
rgs.dacinxd.x[$46]:=rdDACreg(dacTVPdata);
|
|
wrDACreg(dacTVPindex,$2C);
|
|
wrDACreg(dacTVPdata,1); {PLL 2nd byte}
|
|
wrDACreg(dacTVPindex,$2D);
|
|
rgs.dacinxd.x[$41]:=rdDACreg(dacTVPdata);
|
|
wrDACreg(dacTVPindex,$2E);
|
|
rgs.dacinxd.x[$44]:=rdDACreg(dacTVPdata);
|
|
wrDACreg(dacTVPindex,$2F);
|
|
rgs.dacinxd.x[$47]:=rdDACreg(dacTVPdata);
|
|
wrDACreg(dacTVPindex,$2C);
|
|
wrDACreg(dacTVPdata,2); {PLL 3rd byte}
|
|
wrDACreg(dacTVPindex,$2D);
|
|
rgs.dacinxd.x[$42]:=rdDACreg(dacTVPdata);
|
|
wrDACreg(dacTVPindex,$2E);
|
|
rgs.dacinxd.x[$45]:=rdDACreg(dacTVPdata);
|
|
wrDACreg(dacTVPindex,$2F);
|
|
rgs.dacinxd.x[$48]:=rdDACreg(dacTVPdata);
|
|
rgs.dacinxd.nbr:=$48;
|
|
rgs.dacinxd.base:=$3C6;
|
|
wrDACreg(dacTVP6index,y);
|
|
end;
|
|
_dacTVP3026:
|
|
begin {TI TVP 3026 DAC}
|
|
y:=rdDACreg(dacTVP6index);
|
|
for y:=0 to $3F do
|
|
begin
|
|
wrDACreg(dacTVP6index,y);
|
|
rgs.dacinxd.x[y]:=rdDACreg(dacTVP6data);
|
|
end;
|
|
|
|
wrDACreg(dacTVP6index,$2C);
|
|
wrDACreg(dacTVP6data,0); {PLL 1st byte}
|
|
wrDACreg(dacTVP6index,$2D);
|
|
rgs.dacinxd.x[$40]:=rdDACreg(dacTVP6data);
|
|
wrDACreg(dacTVP6index,$2E);
|
|
rgs.dacinxd.x[$43]:=rdDACreg(dacTVP6data);
|
|
wrDACreg(dacTVP6index,$2F);
|
|
rgs.dacinxd.x[$46]:=rdDACreg(dacTVP6data);
|
|
wrDACreg(dacTVP6index,$2C);
|
|
wrDACreg(dacTVP6data,1); {PLL 2nd byte}
|
|
wrDACreg(dacTVP6index,$2D);
|
|
rgs.dacinxd.x[$41]:=rdDACreg(dacTVP6data);
|
|
wrDACreg(dacTVP6index,$2E);
|
|
rgs.dacinxd.x[$44]:=rdDACreg(dacTVP6data);
|
|
wrDACreg(dacTVP6index,$2F);
|
|
rgs.dacinxd.x[$47]:=rdDACreg(dacTVP6data);
|
|
wrDACreg(dacTVP6index,$2C);
|
|
wrDACreg(dacTVP6data,2); {PLL 3rd byte}
|
|
wrDACreg(dacTVP6index,$2D);
|
|
rgs.dacinxd.x[$42]:=rdDACreg(dacTVP6data);
|
|
wrDACreg(dacTVP6index,$2E);
|
|
rgs.dacinxd.x[$45]:=rdDACreg(dacTVP6data);
|
|
wrDACreg(dacTVP6index,$2F);
|
|
rgs.dacinxd.x[$48]:=rdDACreg(dacTVP6data);
|
|
rgs.dacinxd.nbr:=$48;
|
|
rgs.dacinxd.base:=$3C6;
|
|
wrDACreg(dacTVP6index,y);
|
|
end;
|
|
_dacMU9910:begin
|
|
rgs.dacinxd.base:=$83C9;
|
|
rgs.dacinxd.nbr:=$1F;
|
|
outp(SetDACpage(7),0);
|
|
for y:=0 to $1F do
|
|
rgs.dacinxd.x[y]:=inp(SetDACpage(5));
|
|
end;
|
|
_dacIBM514,_dacIBM524,_dacIBM525,_dacIBM528:
|
|
begin
|
|
rgs.dacinxd.base:=$3C6;
|
|
rgs.dacinxd.nbr:=255;
|
|
|
|
(* wrDACreg(dacIBMind1,0);
|
|
for x:=0 to 255 do
|
|
begin
|
|
wrDACreg(dacIBMind0,x);
|
|
rgs.dacinxd.x[x]:=rdDACreg(dacIBMdata);
|
|
end;
|
|
wrDACreg(dacIBMind0,rgs.dacregs[dacIBMind0]); *)
|
|
end;
|
|
end;
|
|
clearDACpage;
|
|
case cv.chip of { Disable ext }
|
|
__S3:begin
|
|
if (cv.version=S3_732) or (cv.Version=S3_764) then
|
|
wrinx(SEQ,8,rgs.seqregs.x[8]);
|
|
wrinx(crtc,$38,0);
|
|
wrinx(crtc,$39,$5A);
|
|
end;
|
|
__Trid:if cv.version>=TR_GUI9440 then
|
|
begin
|
|
setinx(SEQ,$C,$60);
|
|
rgs.dacregs[ 8]:=inp($43C8);
|
|
rgs.dacregs[ 9]:=inp($43C9);
|
|
rgs.dacregs[10]:=inp($43C6);
|
|
rgs.dacregs[11]:=inp($43C7);
|
|
wrinx(SEQ,$C,rgs.seqregs.x[$C]);
|
|
end;
|
|
end;
|
|
if VESAcheat then cv.chip:=__VESA;
|
|
end;
|
|
|
|
procedure CalcRegisters;
|
|
{const
|
|
wd24clk:array[0..15] of real=(29.979,77.408,0,80.092,25.175,28.322
|
|
,65,36,39.822,50.114,42.060,44.297,31.5,35.501,75.166,50.114); }
|
|
var x,m,wid,wordadr,pixwid,clksel,vclkdiv:word;
|
|
force256,graph,isilace:boolean;
|
|
hfreqfact:word;
|
|
|
|
VESAcheat,
|
|
SerialDAC:boolean; {If set the DAC takes one byte at a time}
|
|
begin
|
|
if cv.chip=__VESA then
|
|
begin
|
|
cv.chip:=__Alli;
|
|
VESAcheat:=true;
|
|
end
|
|
else VESAcheat:=false;
|
|
SerialDAC:=true;
|
|
m:=rgs.grcregs.x[6];
|
|
case (m shr 2) and 3 of
|
|
0,1:calcvseg:=SegA000;
|
|
2:calcvseg:=SegB000;
|
|
3:calcvseg:=SegB800;
|
|
end;
|
|
clksel:=(rgs.stdregs[$3CC] shr 2) and 3;
|
|
vclkdiv:=12; {Base 12.}
|
|
begin
|
|
ilace:=false;
|
|
isilace:=false; {Interlaced, but do not double lines!!}
|
|
extpixfact:=1;
|
|
extlinfact:=1;
|
|
|
|
hfreqfact:=1;
|
|
calclines:=rgs.crtcregs.x[$12]+1;
|
|
pixwid:=8;
|
|
calcpixels:=rgs.crtcregs.x[1]+1;
|
|
force256:=false;
|
|
calchtot:=rgs.crtcregs.x[0]+5;
|
|
calcvtot:=rgs.crtcregs.x[6]+2;
|
|
|
|
calchblks:=rgs.crtcregs.x[2];
|
|
calchrtrs:=rgs.crtcregs.x[4];
|
|
calchblke:=rgs.crtcregs.x[3] and 31;
|
|
calchrtre:=rgs.crtcregs.x[5] and 31;
|
|
hrtrmask:=$1F; {Retrace and blanking masks (valid bits)}
|
|
hblkmask:=$3F;
|
|
calcvblks:=rgs.crtcregs.x[$15];
|
|
calcvrtrs:=rgs.crtcregs.x[$10];
|
|
calcvblke:=rgs.crtcregs.x[$16] and 127;
|
|
calcvrtre:=rgs.crtcregs.x[$11] and 15;
|
|
vblkmask:=$7F;
|
|
vrtrmask:=$F;
|
|
|
|
if (rgs.crtcregs.x[7] and 1)>0 then inc(calcvtot, 256);
|
|
if (rgs.crtcregs.x[7] and 2)>0 then inc(calclines,256);
|
|
if (rgs.crtcregs.x[7] and 4)>0 then inc(calcvrtrs,256);
|
|
if (rgs.crtcregs.x[7] and 8)>0 then inc(calcvblks,256);
|
|
if (rgs.crtcregs.x[7] and $20)>0 then inc(calcvtot, 512);
|
|
if (rgs.crtcregs.x[7] and $40)>0 then inc(calclines,512);
|
|
if (rgs.crtcregs.x[7] and $80)>0 then inc(calcvrtrs,512);
|
|
if (rgs.crtcregs.x[5] and $80)>0 then inc(calchblke, 32);
|
|
if (rgs.crtcregs.x[9] and $20)>0 then inc(calcvblks,512);
|
|
|
|
if (rgs.seqregs.x[1] and 8)>0 then vclkdiv:=vclkdiv*2;
|
|
|
|
graph:=(rgs.attregs[$10] and 1)>0;
|
|
if graph then
|
|
begin
|
|
extlinfact:=(rgs.crtcregs.x[9] and $1F)+1;
|
|
if (rgs.crtcregs.x[9] and $80)>0 then extlinfact:=extlinfact*2;
|
|
end
|
|
else begin
|
|
if {((rgs.attregs[$10] and 4)>0) or} ((rgs.seqregs.x[1] and 1)=0) then charwid:=9 else charwid:=8;
|
|
charhigh:=(rgs.crtcregs.x[9] and $1f)+1;
|
|
end;
|
|
|
|
wid:=rgs.crtcregs.x[$13];
|
|
wordadr:=2;
|
|
if (rgs.crtcregs.x[$14] and 64)<>0 then wordadr:=8
|
|
else if (rgs.crtcregs.x[$17] and 64)=0 then wordadr:=4;
|
|
case cv.chip of
|
|
__Acer:wid:=wid+(rgs.crtcregs.x[$81] and 3) shl 8;
|
|
__AGX:begin
|
|
calcpixels:=rgs.xxregs.x[$13]*256+rgs.xxregs.x[$12]+1;
|
|
calchtot:=rgs.xxregs.x[$11]*256+rgs.xxregs.x[$10]+1;
|
|
pixwid:=8;
|
|
calclines :=rgs.xxregs.x[$23]*256+rgs.xxregs.x[$22]+1;
|
|
calcvtot:=rgs.xxregs.x[$21]*256+rgs.xxregs.x[$20]+1;
|
|
wid :=rgs.xxregs.x[$44]*256+rgs.xxregs.x[$43];
|
|
wordadr:=8;
|
|
vclkdiv:=12; {Nominal}
|
|
if (rgs.xxregs.x[$50] and 8)>0 then ilace:=true;
|
|
end;
|
|
__ahead:begin
|
|
if (rgs.grcregs.x[$1c] and 12)=12 then ilace:=true;
|
|
if (rgs.seqregs.x[4] and 8)<>0 then wordadr:=16;
|
|
end;
|
|
__ALG:begin
|
|
if (rgs.grcregs.x[$C] and $10)>0 then wordadr:=wordadr shl 1
|
|
else if (rgs.crtcregs.x[$14] and 64)>0 then {Packed mode}
|
|
begin
|
|
pixwid:=4;
|
|
vclkdiv:=vclkdiv*2;
|
|
end;
|
|
if (rgs.crtcregs.x[$19] and 1)>0 then
|
|
begin
|
|
ilace:=true;
|
|
wordadr:=wordadr shr 1;
|
|
end;
|
|
if (cv.version>ALG_2101) and ((rgs.crtcregs.x[$19] and $80)>0) then
|
|
begin
|
|
if (rdinx(crtc,$2A) and 1)>0 then inc(calchtot,256);
|
|
if (rdinx(crtc,$28) and $80)>0 then inc(wid,256);
|
|
end;
|
|
end;
|
|
__Alli:begin
|
|
if (rgs.grcregs.x[5] and $40)>0 then
|
|
begin
|
|
force256:=true;
|
|
wordadr:=8;
|
|
end;
|
|
inc(wid,(rgs.crtcregs.x[$1C] shr 4)*256);
|
|
if (rgs.crtcregs.x[$1A] and 1)>0 then inc(calcvtot,1024);
|
|
if (rgs.crtcregs.x[$1A] and 2)>0 then inc(calclines,1024);
|
|
if (rgs.crtcregs.x[$1A] and 4)>0 then inc(calcvrtrs,1024);
|
|
if (rgs.crtcregs.x[$1A] and 8)>0 then inc(calcvblks,1024);
|
|
if (rgs.crtcregs.x[$1B] and 1)>0 then inc(calchtot,256);
|
|
if (rgs.crtcregs.x[$1B] and 4)>0 then inc(calchblks,256);
|
|
if (rgs.crtcregs.x[$1B] and 8)>0 then inc(calchrtrs,256);
|
|
end;
|
|
__ARK:begin
|
|
if (rgs.crtcregs.x[$44] and 4)>0 then ilace:=true;
|
|
if (rgs.crtcregs.x[$41] and 128)>0 then inc(calchtot,256);
|
|
if (rgs.crtcregs.x[$41] and 64)>0 then inc(calcpixels,256);
|
|
if (rgs.crtcregs.x[$41] and 32)>0 then inc(calchblks,256);
|
|
if (rgs.crtcregs.x[$41] and 16)>0 then inc(calchrtrs,256);
|
|
if (rgs.crtcregs.x[$41] and 8)>0 then inc(wid,256);
|
|
if (rgs.crtcregs.x[$40] and 128)>0 then inc(calcvtot,1024);
|
|
if (rgs.crtcregs.x[$40] and 64)>0 then inc(calclines,1024);
|
|
if (rgs.crtcregs.x[$40] and 32)>0 then inc(calcvblks,1024);
|
|
if (rgs.crtcregs.x[$40] and 16)>0 then inc(calcvrtrs,1024);
|
|
end;
|
|
__ati:begin
|
|
if cv.Version=ATI_18800 then
|
|
begin
|
|
if (rgs.xxregs.x[$B2] and 1)<>0 then ilace:=true;
|
|
end
|
|
else if (rgs.xxregs.x[$BE] and 2)<>0 then ilace:=true;
|
|
if (rgs.xxregs.x[$B0] and $20)>0 then
|
|
begin
|
|
force256:=true;
|
|
if cv.Version=ATI_18800 then wordadr:=8
|
|
else wordadr:=16;
|
|
end;
|
|
if ((rgs.xxregs.x[$B3] and $40)>0) and (cv.Version>ATI_18800) then
|
|
begin
|
|
pixwid:=pixwid*2;
|
|
wordadr:=wordadr*2;
|
|
end;
|
|
if ((rgs.xxregs.x[$B6] and $10)>0) and ((cv.version<ATI_GUP_3)
|
|
or (cv.Version>=ATI_M64_GX)) then
|
|
begin
|
|
force256:=false;
|
|
end;
|
|
if ((rgs.xxregs.x[$B1] and $40)>0) then
|
|
begin
|
|
calclines:=calclines div 2;
|
|
calcvtot:=calcvtot div 2;
|
|
end;
|
|
if ((rgs.seqregs.x[4] and 8)>0) and not force256 then
|
|
pixwid:=pixwid*2; {Mode 65h (PK4) fix}
|
|
|
|
|
|
if (cv.Version=ATI_28800_6) and ((rgs.xxregs.x[$AD] and 8)>0) then
|
|
begin
|
|
if (rgs.xxregs.x[$AD] and 1)>0 then inc(calchtot,256);
|
|
if (rgs.xxregs.x[$AD] and 2)>0 then inc(calchblks,256);
|
|
if (rgs.xxregs.x[$AD] and 4)>0 then inc(calchrtrs,256);
|
|
end;
|
|
end;
|
|
__chips:begin
|
|
if (rgs.xxregs.x[$D] and 1)<>0 then inc(wid,256);
|
|
if (rgs.xxregs.x[$17] and 1)>0 then inc(calchtot,256);
|
|
if (rgs.xxregs.x[$D] and 4)>0 then inc(wid,256);
|
|
if (rgs.xxregs.x[$B] and 4)>0 then
|
|
begin
|
|
force256:=true;
|
|
wordadr:=8;
|
|
if cv.version<CT_65520 then
|
|
begin
|
|
pixwid:=4;
|
|
vclkdiv:=vclkdiv*2;
|
|
end;
|
|
end;
|
|
if (rgs.xxregs.x[$28] and $20)>0 then ilace:=true;
|
|
end;
|
|
__cir54:begin
|
|
if (rgs.seqregs.x[4] and 8)>0 then wordadr:=8;
|
|
if (rgs.crtcregs.x[$1B] and 16)>0 then inc(wid,256);
|
|
if (rgs.crtcregs.x[$1A] and 1)>0 then ilace:=true;
|
|
if (rgs.crtcregs.x[$1B] and $80)>0 then
|
|
begin
|
|
inc(calchblke,(rgs.crtcregs.x[$1A] and $30) shl 2);
|
|
hblkmask:=$FF;
|
|
calcvblke:=rgs.crtcregs.x[$16]+((rgs.crtcregs.x[$1A] and $C0) shl 2);
|
|
vblkmask:=$3FF;
|
|
end;
|
|
end;
|
|
__cir64:begin
|
|
if (rgs.seqregs.x[4] and 8)<>0 then wordadr:=8;
|
|
if (rgs.grcregs.x[$82] and 7)=2 then pixwid:=4;
|
|
if (rgs.grcregs.x[$79] and 1)>0 then inc(calchtot,1024);
|
|
if (rgs.grcregs.x[$79] and 2)>0 then inc(calclines,1024);
|
|
if (rgs.grcregs.x[$79] and 16)>0 then inc(calchrtrs,1024);
|
|
inc(calchblks,(rgs.grcregs.x[$79] and $C) shl 7);
|
|
end;
|
|
__compaq:begin
|
|
if (rgs.grcregs.x[$F] and $F0)=0 then wordadr:=8;
|
|
inc(wid,(rgs.grcregs.x[$42] and 3)*256);
|
|
if (rgs.crtcregs.x[$14] and 64)>0 then pixwid:=4;
|
|
if (rgs.grcregs.x[$51] and $40)>0 then inc(calcvtot,1024);
|
|
if (rgs.grcregs.x[$51] and $80)>0 then inc(calcvrtrs,1024);
|
|
{ if (rgs.grcregs.x[$51] and $20)>0 then inc(calchrtre,32);
|
|
hrtrmask:=$3F; }
|
|
if cv.version>CPQ_QV then
|
|
begin
|
|
SerialDAC:=false; {Dirty Hack!!}
|
|
if memmode>=_PK4 then pixwid:=pixwid shr 2;
|
|
end;
|
|
end;
|
|
__genoa:begin
|
|
if (rgs.crtcregs.x[$2F] and 1)<>0 then ilace:=true;
|
|
if (rgs.crtcregs.x[$2F] and 2)<>0 then wordadr:=16;
|
|
if (rgs.seqregs.x[4] and 8)>0 then pixwid:=4;
|
|
end;
|
|
__hmc:begin
|
|
IF (rgs.xxregs.x[$E7] and 1)>0 then ilace:=true;
|
|
if (rgs.xxregs.x[$E7] and 2)>0 then force256:=true;
|
|
{ if (rgs.xxregs.x[$E7] and 64)>0 then inc(clksel,4);
|
|
vclk:=HMCclk[clksel]; }
|
|
end;
|
|
__Mach32:begin
|
|
calcpixels:=rgs.xxregs.x[$D8]+1; {B2EE}
|
|
calchtot :=rgs.xxregs.x[$D9]+1; {B2EF}
|
|
calcvtot :=(rgs.xxregs.x[$E0]+rgs.xxregs.x[$E1]*256)+1; {C2EE}
|
|
calclines :=(rgs.xxregs.x[$E2]+rgs.xxregs.x[$E3]*256)+1; {C6EE}
|
|
calchrtrs :=rgs.xxregs.x[$DA]; {B6EE}
|
|
calchrtre :=calchrtrs+(rgs.xxregs.x[$DC] and $1F); {BAEE}
|
|
calcvrtrs :=(rgs.xxregs.x[$E4]+rgs.xxregs.x[$E5]*256)+1; {CAEE}
|
|
calcvrtre :=calcvrtrs+(rgs.xxregs.x[$E8] and $1F); {D2EE}
|
|
pixwid:=8;
|
|
case rgs.xxregs.x[$C6] and $30 of {8EEE}
|
|
0:calcmmode:=_pk4;
|
|
$10:calcmmode:=_p8;
|
|
$20:case rgs.xxregs.x[$C6] and $C0 of
|
|
0:calcmmode:=_p15;
|
|
$40:calcmmode:=_p16;
|
|
end;
|
|
$30:case rgs.xxregs.x[$C7] and 6 of
|
|
0:calcmmode:=_p24;
|
|
2:calcmmode:=_p32c;
|
|
4:calcmmode:=_p24b;
|
|
6:calcmmode:=_p32b;
|
|
end;
|
|
end;
|
|
{There is no way to determine the bytes/scanline (Write only)}
|
|
end;
|
|
__Mach64:begin
|
|
calchtot :=(rgs.xxregs.x[$0]+rgs.xxregs.x[$1]*256)+1;
|
|
calcpixels:=(rgs.xxregs.x[$2]+rgs.xxregs.x[$3]*256)+1;
|
|
calcvtot :=(rgs.xxregs.x[$8]+rgs.xxregs.x[$9]*256)+1;
|
|
calclines :=(rgs.xxregs.x[$A]+rgs.xxregs.x[$B]*256)+1;
|
|
wid :=(rgs.xxregs.x[$16]+rgs.xxregs.x[$17]*256) shr 6;
|
|
calchrtrs :=rgs.xxregs.x[$4];
|
|
calchrtre :=calchrtrs+(rgs.xxregs.x[$6] and $1F);
|
|
calcvrtrs :=(rgs.xxregs.x[$C]+rgs.xxregs.x[$D]*256)+1;
|
|
calcvrtre :=calcvrtrs+(rgs.xxregs.x[$E] and $1F);
|
|
pixwid:=8;
|
|
calcmmode:=_P8;
|
|
if (rgs.xxregs.x[$1C] and 2)>0 then ilace:=true;
|
|
case rgs.xxregs.x[$1D] and 7 of
|
|
1:calcmmode:=_PK4;
|
|
2:calcmmode:=_P8;
|
|
3:calcmmode:=_P15;
|
|
4:calcmmode:=_P16;
|
|
5:calcmmode:=_P24;
|
|
6:calcmmode:=_P32;
|
|
end;
|
|
wordadr:=usebits[calcmmode];
|
|
SerialDAC:=false;
|
|
end;
|
|
__Matrox:begin
|
|
if (rgs.xxregs.x[$D] and $40)>0 then
|
|
begin
|
|
ilace:=true;
|
|
if (rgs.xxregs.x[1] and 8)=0 then {not Ext 256c}
|
|
wordadr:=wordadr shr 1;
|
|
end;
|
|
if (rgs.xxregs.x[1] and 8)>0 then {Ext 256c}
|
|
wordadr:=wordadr shl 2;
|
|
|
|
end;
|
|
__mxic:if (rgs.seqregs.x[$F0] and 3)=3 then ilace:=true;
|
|
__NCR:begin
|
|
if (rgs.seqregs.x[$20] and 2)<>0 then
|
|
begin
|
|
force256:=true;
|
|
wordadr:=8;
|
|
end;
|
|
if (rgs.seqregs.x[$1F] and $10)<>0 then
|
|
case rgs.seqregs.x[$1F] and 15 of
|
|
0:pixwid:=4;
|
|
11:pixwid:=16;
|
|
else pixwid:=(rgs.seqregs.x[$1F] and 15)+6;
|
|
end;
|
|
if (rgs.crtcregs.x[$30] and $10)<>0 then
|
|
begin
|
|
ilace:=true;
|
|
extlinfact:=1;
|
|
end;
|
|
if (rgs.crtcregs.x[$30] and 1)>0 then inc(calchtot,256);
|
|
if (rgs.crtcregs.x[$30] and 2)>0 then inc(calcpixels,256);
|
|
if (rgs.crtcregs.x[$30] and 4)>0 then inc(calchblks,256);
|
|
if (rgs.crtcregs.x[$30] and 8)>0 then inc(calchrtrs,256);
|
|
if (rgs.crtcregs.x[$31] and 16)>0 then inc(wid,256);
|
|
if cv.version>=NCR_77c22Ep then
|
|
begin
|
|
if (rgs.crtcregs.x[$32] and 1)>0 then inc(calchtot,512);
|
|
if (rgs.crtcregs.x[$32] and 2)>0 then inc(calcpixels,512);
|
|
if (rgs.crtcregs.x[$32] and 4)>0 then inc(calchblks,512);
|
|
if (rgs.crtcregs.x[$32] and 8)>0 then inc(calchrtrs,512);
|
|
if (rgs.crtcregs.x[$33] and 1)>0 then inc(calcvtot,1024);
|
|
if (rgs.crtcregs.x[$33] and 2)>0 then inc(calclines,1024);
|
|
if (rgs.crtcregs.x[$33] and 4)>0 then inc(calcvblks,1024);
|
|
if (rgs.crtcregs.x[$33] and 8)>0 then inc(calcvrtrs,1024);
|
|
if (rgs.crtcregs.x[$30] and 32)>0 then
|
|
begin
|
|
inc(calchblke,(rgs.crtcregs.x[$32] and $30) shl 2);
|
|
hblkmask:=$FF;
|
|
inc(calchrtre,(rgs.crtcregs.x[$32] and $C0) shr 1);
|
|
hrtrmask:=$7F;
|
|
calcvblke:=rgs.crtcregs.x[$16]+((rgs.crtcregs.x[$33] and $60) shl 3);
|
|
vblkmask:=$3FF;
|
|
inc(calchrtre,(rgs.crtcregs.x[$33] and $80) shr 3);
|
|
vrtrmask:=$1F;
|
|
end;
|
|
end;
|
|
end;
|
|
__oak:if cv.version<>OAK_037 then
|
|
begin
|
|
if (rgs.xxregs.x[$14] and 128)<>0 then ilace:=true;
|
|
if (rgs.xxregs.x[$14] and 1)>0 then inc(calcvtot,1024);
|
|
if (rgs.xxregs.x[$14] and 2)>0 then inc(calclines,1024);
|
|
if (rgs.xxregs.x[$14] and 4)>0 then inc(calcvrtrs,1024);
|
|
if cv.Version<=OAK_083 then
|
|
begin
|
|
if (rgs.seqregs.x[4] and 8)<>0 then wordadr:=16;
|
|
{Cheat for 256 color mode}
|
|
end
|
|
else begin
|
|
if (rgs.seqregs.x[4] and 8)<>0 then
|
|
if (rgs.xxregs.x[$21] and 4)>0 then wordadr:=16
|
|
else pixwid:=4;
|
|
end;
|
|
end;
|
|
__p2000:begin
|
|
if (rgs.grcregs.x[$13] and $40)<>0 then
|
|
begin
|
|
wordadr:=wordadr shr 1;
|
|
ilace:=true;
|
|
end;
|
|
if (rgs.grcregs.x[$21] and $20)<>0 then inc(wid,256);
|
|
end;
|
|
__WD:begin
|
|
if (cv.version>=WD_90c00) then
|
|
if (rgs.crtcregs.x[$2D] and $20)>0 then ilace:=true;
|
|
if (cv.version>=WD_90c30) then
|
|
begin
|
|
if (rgs.crtcregs.x[$3D] and 1)>0 then inc(calcvtot,1024);
|
|
if (rgs.crtcregs.x[$3D] and 2)>0 then inc(calclines,1024);
|
|
if (rgs.crtcregs.x[$3D] and 4)>0 then inc(calcvrtrs,1024);
|
|
if (rgs.crtcregs.x[$3D] and 8)>0 then inc(calcvblks,1024);
|
|
end;
|
|
if (rgs.seqregs.x[4] and 8)>0 then wordadr:=8;
|
|
{Cheat for 256 color mode}
|
|
{ if (rgs.grcregs.x[$C] and 2)>0 then inc(clksel,4);
|
|
vclk:=WDclk[clksel]; }
|
|
if (cv.version>=WD_90c33) and ((rgs.crtcregs.x[$3E] and $20)>0) then inc(calchtot,256);
|
|
end;
|
|
__realtek:begin
|
|
if (rgs.seqregs.x[4] and 8)<>0 then
|
|
begin
|
|
pixwid:=4;
|
|
hfreqfact:=2;
|
|
end;
|
|
if (rgs.grcregs.x[$C] and $10)<>0 then
|
|
begin
|
|
pixwid:=pixwid*2;
|
|
wid:=wid*2;
|
|
end;
|
|
if (rgs.crtcregs.x[$19] and 1)<>0 then
|
|
begin
|
|
ilace:=true;
|
|
wid:=wid div 2;
|
|
end;
|
|
end;
|
|
__s3:begin
|
|
if (rgs.crtcregs.x[$42] and $20)<>0 then ilace:=true;
|
|
if (rgs.crtcregs.x[$43] and 4)<>0 then inc(wid,256);
|
|
if (rgs.crtcregs.x[$43] and $80)<>0 then pixwid:=pixwid*2;
|
|
if (rgs.seqregs.x[4] and 8)<>0 then wordadr:=8 else wordadr:=2;
|
|
if (rgs.attregs[$10] and 1)=0 then wid:=wid*2;
|
|
if (rgs.crtcregs.x[$3A] and $10)>0 then force256:=true;
|
|
if (cv.Version>S3_924) then
|
|
begin
|
|
if (rgs.crtcregs.x[$5D] and 1)>0 then inc(calchtot,256);
|
|
if (rgs.crtcregs.x[$5D] and 2)>0 then inc(calcpixels,256);
|
|
if (rgs.crtcregs.x[$5D] and 4)>0 then inc(calchblks,256);
|
|
if (rgs.crtcregs.x[$5D] and 16)>0 then inc(calchrtrs,256);
|
|
if (rgs.crtcregs.x[$5E] and 1)>0 then inc(calcvtot,1024);
|
|
if (rgs.crtcregs.x[$5E] and 2)>0 then inc(calclines,1024);
|
|
if (rgs.crtcregs.x[$5E] and 4)>0 then inc(calcvblks,1024);
|
|
if (rgs.crtcregs.x[$5E] and 16)>0 then inc(calcvrtrs,1024);
|
|
if (rgs.crtcregs.x[$51] and $30)>0 then
|
|
wid:=(wid and $FF)+(rgs.crtcregs.x[$51] and $30) shl 4;
|
|
end;
|
|
end;
|
|
__SC:wid:=wid+(rgs.crtcregs.x[$1E] and $30) shl 4;
|
|
__SiS:begin
|
|
wid:=wid+(rgs.seqregs.x[$A] and $F0) shl 4;
|
|
if (rgs.seqregs.x[6] and $20)>0 then
|
|
begin
|
|
ilace:=true;
|
|
wid:=wid shr 1;
|
|
end;
|
|
end;
|
|
__trid:begin
|
|
if memmode>=_P8 then wordadr:=8; {Req'd for 9440 800x600 16bit}
|
|
if (rgs.tridold0d and 16)<>0 then wordadr:=wordadr*2
|
|
else if cv.version<TR_GUI9440 then
|
|
begin
|
|
if (rgs.seqregs.x[4] and 8)>0 then pixwid:=pixwid div 2;
|
|
if memmode>=_p8 then vclkdiv:=vclkdiv*2;
|
|
end;
|
|
if (rgs.crtcregs.x[$1e] and 4)<>0 then
|
|
if cv.version=TR_IITAGX then isilace:=true
|
|
else begin
|
|
ilace:=true;
|
|
if cv.version<TR_GUI9440 then wordadr:=wordadr div 2;
|
|
end;
|
|
if (cv.mm=512) and (memmode>=_p8) and
|
|
(cv.version<TR_IITAGX) then hfreqfact:=2;
|
|
if (rgs.grcregs.x[$F] and 8)>0 then pixwid:=pixwid*2;
|
|
if (rgs.crtcregs.x[$29] and $10)>0 then inc(wid,256);
|
|
end;
|
|
__Tseng:if cv.version=ET_3000 then
|
|
begin
|
|
if (rgs.crtcregs.x[$25] and $80)>0 then ilace:=true;
|
|
if (rgs.crtcregs.x[$25] and 1)>0 then inc(calcvblks,1024);
|
|
if (rgs.crtcregs.x[$25] and 2)>0 then inc(calcvtot,1024);
|
|
if (rgs.crtcregs.x[$25] and 4)>0 then inc(calclines,1024);
|
|
if (rgs.crtcregs.x[$25] and 8)>0 then inc(calcvrtrs,1024);
|
|
if (rgs.grcregs.x[5] and $40)>0 then wordadr:=16;
|
|
if (rgs.seqregs.x[7] and $40)>0 then
|
|
begin
|
|
pixwid:=pixwid*2;
|
|
wordadr:=wordadr*2;
|
|
end;
|
|
end
|
|
else begin
|
|
if (rgs.crtcregs.x[$3F] and $80)>0 then inc(wid,256);
|
|
if (rgs.crtcregs.x[$3F] and 1)>0 then inc(calchtot,256);
|
|
if (rgs.crtcregs.x[$3F] and 4)>0 then inc(calchblks,256);
|
|
if (rgs.crtcregs.x[$3F] and 16)>0 then inc(calchrtrs,256);
|
|
if (rgs.crtcregs.x[$35] and 1)>0 then inc(calcvblks,1024);
|
|
if (rgs.crtcregs.x[$35] and 2)>0 then inc(calcvtot,1024);
|
|
if (rgs.crtcregs.x[$35] and 4)>0 then inc(calclines,1024);
|
|
if (rgs.crtcregs.x[$35] and 8)>0 then inc(calcvrtrs,1024);
|
|
if (rgs.crtcregs.x[$35] and $80)>0 then isilace:=true;
|
|
if (rgs.attregs[$10] and $40)>0 then pixwid:=4;
|
|
{ if ((rgs.attregs[$16] and $20)>0) and (cv.version>=ET_4W32P) then pixwid:=pixwid*2; }
|
|
end;
|
|
__UMC:begin
|
|
if (rgs.crtcregs.x[$33] and $10)>0 then wordadr:=16
|
|
else if ((rgs.attregs[$10] and 64)>0) then
|
|
begin
|
|
pixwid:=4;
|
|
hfreqfact:=2;
|
|
end;
|
|
if (rgs.crtcregs.x[$2F] and 1)>0 then
|
|
begin
|
|
ilace:=true;
|
|
wordadr:=wordadr div 2;
|
|
dec(calclines);
|
|
end;
|
|
end;
|
|
__video7:begin
|
|
if (rgs.seqregs.x[$E0] and 1)<>0 then ilace:=true;
|
|
if (rgs.attregs[$10] and $40)>0 then
|
|
begin
|
|
pixwid:=4;
|
|
wordadr:=8;
|
|
hfreqfact:=2;
|
|
end;
|
|
if (rgs.seqregs.x[$C8] and $10)>0 then
|
|
begin
|
|
force256:=true;
|
|
wordadr:=8;
|
|
end;
|
|
end;
|
|
__Weitek:begin
|
|
if (rgs.grcregs.x[$C] and 4)>0 then
|
|
begin
|
|
wordadr:=8;
|
|
force256:=true;
|
|
end;
|
|
end;
|
|
__xbe,__xga:begin
|
|
calchtot :=rgs.xxregs.x[$11]*256+rgs.xxregs.x[$10]+1;
|
|
calcpixels:=rgs.xxregs.x[$13]*256+rgs.xxregs.x[$12]+1;
|
|
calchblks :=rgs.xxregs.x[$15]*256+rgs.xxregs.x[$14]+1;
|
|
calchblke :=rgs.xxregs.x[$17]*256+rgs.xxregs.x[$16]+1;
|
|
calchrtrs :=rgs.xxregs.x[$19]*256+rgs.xxregs.x[$18]+1;
|
|
calchrtre :=rgs.xxregs.x[$1B]*256+rgs.xxregs.x[$1A]+1;
|
|
pixwid:=8;
|
|
calclines :=rgs.xxregs.x[$23]*256+rgs.xxregs.x[$22]+1;
|
|
calcvtot :=rgs.xxregs.x[$21]*256+rgs.xxregs.x[$20]+1;
|
|
calcvblks :=rgs.xxregs.x[$25]*256+rgs.xxregs.x[$24]+1;
|
|
calcvblke :=rgs.xxregs.x[$27]*256+rgs.xxregs.x[$26]+1;
|
|
calcvrtrs :=rgs.xxregs.x[$29]*256+rgs.xxregs.x[$28]+1;
|
|
calcvrtre :=rgs.xxregs.x[$2B]*256+rgs.xxregs.x[$2A]+1; {Hm!!}
|
|
wid :=rgs.xxregs.x[$44]*256+rgs.xxregs.x[$43];
|
|
wordadr:=8;
|
|
case rgs.xxregs.x[$51] and 7 of
|
|
2:calcmmode:=_pk4;
|
|
3:calcmmode:=_p8;
|
|
4:calcmmode:=_p16; {or _p15}
|
|
5:calcmmode:=_p24;
|
|
end;
|
|
if (rgs.xxregs.x[$50] and 8)>0 then isilace:=true;
|
|
end;
|
|
end;
|
|
|
|
if (cv.flags and FLG_StdVGA)>0 then
|
|
begin
|
|
calchblke:=(calchblks and (not hblkmask))+calchblke;
|
|
if calchblke<=calchblks then inc(calchblke,hblkmask+1);
|
|
if calchblke>calchtot then calchblke:=calchtot+(hblkmask and calchblke);
|
|
calchrtre:=(calchrtrs and (not hrtrmask))+calchrtre;
|
|
if calchrtre<=calchrtrs then inc(calchrtre,hrtrmask+1);
|
|
if calchrtre>calchtot then calchrtre:=calchtot+(hrtrmask and calchrtre);
|
|
calcvblke:=(calcvblks and (not vblkmask))+calcvblke;
|
|
if calcvblke<=calcvblks then inc(calcvblke,vblkmask+1);
|
|
calcvrtre:=(calcvrtrs and (not vrtrmask))+calcvrtre;
|
|
if calcvrtre<=calcvrtrs then inc(calcvrtre,vrtrmask+1);
|
|
|
|
if (rgs.crtcregs.x[$17] and 4)>0 then
|
|
begin
|
|
calclines:=calclines*2;
|
|
calcvtot:=calcvtot*2;
|
|
end;
|
|
if ilace then calclines:=calclines*2;
|
|
if isilace then ilace:=true;
|
|
if (rgs.attregs[$10] and 1)=0 then {Text}
|
|
begin
|
|
calclines:=calclines div ((rgs.crtcregs.x[9] and $1F)+1);
|
|
if (rgs.attregs[$10] and 2)=0 then calcmmode:=_TEXT
|
|
else calcmmode:=_TXT4;
|
|
pixwid:=charwid;
|
|
end
|
|
else begin
|
|
if ((rgs.crtcregs.x[$17] and 1)=0)
|
|
and ((rgs.attregs[$10] and 64)=0) then {CGA}
|
|
begin
|
|
if (rgs.crtcregs.x[$17] and $40)>0 then calcmmode:=_cga1
|
|
else calcmmode:=_cga2;
|
|
extlinfact:=extlinfact shr 1;
|
|
end
|
|
else if ((rgs.attregs[$10] and 64)=0) and ((rgs.grcregs.x[5] and 64)=0)
|
|
and not force256 then {16 color}
|
|
begin
|
|
if ((rgs.attregs[$10] and 2)>0) then calcmmode:=_pl1
|
|
else if (rgs.attregs[$12]=5) then
|
|
begin
|
|
calcmmode:=_pl2;
|
|
pixwid:=pixwid*2;
|
|
end
|
|
else if (rgs.seqregs.x[4] and 8)>0 then calcmmode:=_pk4
|
|
else calcmmode:=_pl4;
|
|
end
|
|
else calcmmode:=_p8;
|
|
end;
|
|
end;
|
|
|
|
|
|
if (calcmmode>=_PK4) and (cv.dactype>_dac8) then
|
|
begin
|
|
x:=rgs.dacregs[6]{getdaccomm};
|
|
|
|
case cv.dactype of
|
|
_dac15:if x>127 then calcmmode:=_p15;
|
|
_dac16:case (x and $c0) of
|
|
$80:calcmmode:=_p15;
|
|
$c0:calcmmode:=_p16;
|
|
end;
|
|
_dacALG1101:
|
|
if (cv.chip=__ALG) and ((rgs.crtcregs.x[$19] and 16)>0) then
|
|
calcmmode:=_p16; {Only used on ALG chips ??}
|
|
_dacMU1880:
|
|
begin
|
|
outp($3C8,0);
|
|
for m:=1 to 4 do x:=inp($3C6);
|
|
while x<>$8e do x:=inp($3C6);
|
|
x:=inp($3C6);
|
|
rgs.stdregs[$3c1]:=x;
|
|
case x of
|
|
$A6:calcmmode:=_p16;
|
|
$A0:calcmmode:=_p15;
|
|
$9E:calcmmode:=_p24b;
|
|
end;
|
|
end;
|
|
_dacICS5301,_dacMU4910,_dacMU9910,_dacATT490,_dacATT491,_dacATT492,
|
|
_dacATT493,_dacCH8391:
|
|
case (x and $E0) of
|
|
$80,$A0:calcmmode:=_p15;
|
|
$C0:calcmmode:=_p16;
|
|
$E0:calcmmode:=_p24;
|
|
end;
|
|
_dacATT498,_dacATT1498,_dacATT2498:
|
|
case x shr 4 of
|
|
1:begin
|
|
calcmmode:=_p15;
|
|
pixwid:=pixwid*2;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
2:begin
|
|
pixwid:=pixwid*2;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
3:begin
|
|
calcmmode:=_p16;
|
|
pixwid:=pixwid*2;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
5:begin
|
|
calcmmode:=_p32;
|
|
pixwid:=pixwid*2;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
6:calcmmode:=_p16;
|
|
10:calcmmode:=_p15;
|
|
end;
|
|
_dacALG1201,_dacALG1301:
|
|
case (x and $E0) of
|
|
$A0:calcmmode:=_p15;
|
|
$C0:calcmmode:=_p16;
|
|
$E0:calcmmode:=_p24;
|
|
end;
|
|
_dacADAC1:
|
|
case (x and $C7) of
|
|
$C1:calcmmode:=_p16;
|
|
$C5:calcmmode:=_p24;
|
|
$80:calcmmode:=_p15;
|
|
end;
|
|
_dacSC15021,_dacSC15025:
|
|
begin
|
|
case (x and $E1) of
|
|
$41:calcmmode:=_p32b;
|
|
$40:calcmmode:=_p32;
|
|
$61:calcmmode:=_p24b;
|
|
$60:calcmmode:=_p24;
|
|
$80,$81,$A0,$A1:calcmmode:=_p15;
|
|
$C0,$E0:calcmmode:=_p16;
|
|
end;
|
|
if rgs.dacinxd.x[$10]>0 then
|
|
begin
|
|
pixwid:=pixwid*2;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
end;
|
|
_dacTR8001:case x and $E0 of
|
|
$A0:calcmmode:=_p15;
|
|
$E0:calcmmode:=_p16;
|
|
$C0:calcmmode:=_p24;
|
|
end;
|
|
_dacUMC188:case (x and $D0) of
|
|
$80:calcmmode:=_p15;
|
|
$C0:calcmmode:=_p16;
|
|
$10,$50,$90,$D0:calcmmode:=_p24;
|
|
end;
|
|
_dacSTG1700,_dacSTG1702,_dacSTG1703:
|
|
if (x and 8)>0 then
|
|
case rgs.dacinxd.x[3] of
|
|
1:begin
|
|
calcmmode:=_P15;
|
|
pixwid:=pixwid*2;
|
|
end;
|
|
2:begin
|
|
calcmmode:=_p15;
|
|
pixwid:=pixwid*2;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
3:begin
|
|
calcmmode:=_p16;
|
|
pixwid:=pixwid*2;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
4:begin
|
|
calcmmode:=_P32;
|
|
pixwid:=pixwid*2;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
5:begin {P8 - two pixels/clock}
|
|
calcmmode:=_P8;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
6:begin
|
|
calcmmode:=_P16;
|
|
pixwid:=pixwid*2;
|
|
end;
|
|
9:begin
|
|
calcmmode:=_p24;
|
|
pixwid:=pixwid*2;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
end
|
|
else
|
|
case x and $E0 of
|
|
$A0:calcmmode:=_p15;
|
|
$C0:calcmmode:=_p16;
|
|
$E0:calcmmode:=_p24;
|
|
end;
|
|
_dacCH8398:case rgs.dacregs[dacHIcmd] shr 4 of
|
|
6:calcmmode:=_p16;
|
|
3:begin
|
|
calcmmode:=_p16;
|
|
pixwid:=pixwid*2;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
7:calcmmode:=_p24; {24bpp = 2pixels/3VCLKs}
|
|
$B:begin {24bpp = 2pixels/3VCLKs}
|
|
calcmmode:=_p24;
|
|
pixwid:=pixwid*2;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
$C:calcmmode:=_p15;
|
|
1:begin {15bit 1VCLK/pixel}
|
|
calcmmode:=_p15;
|
|
pixwid:=pixwid*2;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
end;
|
|
_dacS3_708,_dacS3_716:
|
|
case rgs.dacregs[dacHIcmd] and $F0 of
|
|
(* $10:begin {2 8bpp pixels/VCLK}
|
|
vclkdiv:=vclkdiv div 2;
|
|
end; *)
|
|
$20:calcmmode:=_p15;
|
|
$30:begin
|
|
calcmmode:=_p15;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
$50:begin
|
|
calcmmode:=_p16;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
$60:calcmmode:=_p16;
|
|
$70:begin {32bpp = 2 VCLKs}
|
|
calcmmode:=_p32;
|
|
vclkdiv:=vclkdiv div 2;
|
|
end;
|
|
$E0:calcmmode:=_p24;
|
|
end;
|
|
_dacBt481,_dacBt482:
|
|
case rgs.dacregs[6] and $F0 of
|
|
$A0:calcmmode:=_P15;
|
|
$E0:calcmmode:=_P16;
|
|
$F0:calcmmode:=_P24;
|
|
end;
|
|
_dacBt484,_dacBt485,_dacATT504,_dacATT505:
|
|
if (rgs.dacregs[9] and $20)>0 then
|
|
begin
|
|
case rgs.dacregs[8] and $78 of
|
|
$10:calcmmode:=_p32;
|
|
$30:calcmmode:=_p15;
|
|
$38:calcmmode:=_p16;
|
|
$60:calcmmode:=_pk4;
|
|
end;
|
|
pixwid:=pixwid*4;
|
|
if (cv.dactype=_dacBt485) or (cv.dactype=_dacATT505) then
|
|
if (rgs.dacregs[16] and 8)>0 then vclkdiv:=vclkdiv div 2; {clk*2}
|
|
end;
|
|
_dacTVP3010,_dacTVP3020,_dacTVP3025,_dacTVP3026:
|
|
begin
|
|
case rgs.dacinxd.x[$18] and $CF of
|
|
$C:calcmmode:=_P15;
|
|
$D:calcmmode:=_P16;
|
|
6,$E:calcmmode:=_P32;
|
|
end;
|
|
if (rgs.dacinxd.x[$1A] and $10)>0 then
|
|
begin
|
|
vclkdiv:=vclkdiv div 2;
|
|
pixwid:=pixwid*2;
|
|
end;
|
|
SerialDAC:=false;
|
|
end;
|
|
_dacTLC34075:
|
|
begin {TLC34075}
|
|
if (rgs.dacregs[9]=1) then {On the ATI Mach32 the VCLK is
|
|
looped back to CLK1, really should
|
|
test explicitly for such loops }
|
|
case (rgs.dacregs[10] shr 3) and 7 of
|
|
1:vclkdiv:=vclkdiv*2;
|
|
2:vclkdiv:=vclkdiv*4;
|
|
3:vclkdiv:=vclkdiv*8;
|
|
4:vclkdiv:=vclkdiv*16;
|
|
5:vclkdiv:=vclkdiv*32;
|
|
end;
|
|
SerialDAC:=false;
|
|
end;
|
|
_dacInt:case cv.chip of
|
|
__chips:case rdinx(cv.IOadr,6) and $C of
|
|
0:if (cv.Version=CT_64300) and
|
|
((rgs.xxregs.x[$28] and $10)=0) then calcmmode:=_pk4;
|
|
4:calcmmode:=_p15;
|
|
8:calcmmode:=_p24;
|
|
$C:calcmmode:=_p16;
|
|
end;
|
|
__cir54:begin
|
|
case x and $CF of
|
|
$80,$C0:calcmmode:=_p15;
|
|
$C1:calcmmode:=_p16;
|
|
$C5:if (cv.Version>=CL_GD5430) and
|
|
((rgs.seqregs.x[7] and 8)>0) then calcmmode:=_p32
|
|
else calcmmode:=_p24;
|
|
$C8:; {8bit Grey scale}
|
|
$C9:; {3-3-2 RGB}
|
|
end;
|
|
SerialDAC:=false;
|
|
end;
|
|
__WD:case rdinx(SEQ,$26) and $C of
|
|
4:calcmmode:=_P16;
|
|
{ 8:calcmmode:=_p16b; }
|
|
$C:calcmmode:=_P15;
|
|
end;
|
|
__S3:case rgs.crtcregs.x[$67] shr 4 of
|
|
{ 1:vclkdiv:=vclkdiv div 2; {2px/VCLK}
|
|
3:begin
|
|
calcmmode:=_P15;
|
|
vclkdiv:=vclkdiv div 2; {1px/VCLK}
|
|
end;
|
|
5:begin
|
|
calcmmode:=_P16;
|
|
vclkdiv:=vclkdiv div 2; {1px/VCLK}
|
|
end;
|
|
7:begin
|
|
calcmmode:=_P32;
|
|
vclkdiv:=vclkdiv div 2; {1px/2VCLK}
|
|
end;
|
|
13:begin
|
|
calcmmode:=_P32; {1px/VCLK}
|
|
SerialDAC:=false;
|
|
end;
|
|
end;
|
|
__SiS:begin
|
|
case rgs.seqregs.x[6] and $1C of
|
|
4:calcmmode:=_P15;
|
|
8:calcmmode:=_P16;
|
|
16:calcmmode:=_P24;
|
|
end;
|
|
SerialDAC:=false;
|
|
end;
|
|
__Trid:if cv.version<TR_GUI9440 then
|
|
case rgs.dacregs[6] shr 5 of
|
|
5:calcmmode:=_p15;
|
|
7:calcmmode:=_p16;
|
|
6:calcmmode:=_p24;
|
|
end
|
|
else begin
|
|
case rgs.dacregs[6] shr 4 of
|
|
1:calcmmode:=_p15;
|
|
3:calcmmode:=_p16;
|
|
13:begin
|
|
calcmmode:=_p24;
|
|
SerialDAC:=false;
|
|
vclkdiv:=vclkdiv*3;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
if SerialDAC then
|
|
case calcmmode of {Adjust for HiColor}
|
|
_p15,_p16:begin
|
|
pixwid:=pixwid div 2;
|
|
vclkdiv:=vclkdiv*2;
|
|
end;
|
|
_P24,_P24b:begin
|
|
calcpixels:=calcpixels div 3;
|
|
calchtot:=calchtot div 3;
|
|
calchblks:=calchblks div 3;
|
|
calchblke:=calchblke div 3;
|
|
calchrtrs:=calchrtrs div 3;
|
|
calchrtre:=calchrtre div 3;
|
|
vclkdiv:=vclkdiv*3;
|
|
end;
|
|
_p32:begin
|
|
pixwid:=pixwid div 4;
|
|
vclkdiv:=vclkdiv*4;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
if calcmmode>=_herc then calcpixels:=calcpixels*pixwid;
|
|
calcbytes:=wid*wordadr;
|
|
|
|
vclk:=GetClockFreq;
|
|
|
|
|
|
calchtot :=calchtot*pixwid;
|
|
calchblks:=calchblks*pixwid;
|
|
calchblke:=calchblke*pixwid;
|
|
calchrtrs:=calchrtrs*pixwid;
|
|
calchrtre:=calchrtre*pixwid;
|
|
vclk:=(vclk*12) div vclkdiv;
|
|
if vclk>0 then
|
|
begin
|
|
hclk:=(vclk*1000) div (calchtot*hfreqfact);
|
|
fclk:=(hclk*1000) div calcvtot;
|
|
end;
|
|
if extlinfact>0 then calclines:=calclines div extlinfact;
|
|
BWlow :=hclk;
|
|
case memmode of
|
|
_PL4,_PK4,_PK4a:BWlow:=BWlow div 2;
|
|
_P15,_P16:BWlow:=BWlow*2;
|
|
_P24,_P24b:BWlow:=BWlow*3;
|
|
_P32.._P32d:BWlow:=BWlow*4;
|
|
end;
|
|
|
|
BWhigh:=(BWlow*calchtot) div 1000;
|
|
BWlow :=(BWlow*calcpixels) div 1000;
|
|
|
|
if memmode<=_TXT4 then
|
|
begin
|
|
BWlow :=BWlow*3;
|
|
BWhigh:=(BWhigh*3) div 8;
|
|
end;
|
|
|
|
if VESAcheat then cv.chip:=__VESA;
|
|
rgs.bytes :=calcbytes;
|
|
rgs.pixels:=calcpixels;
|
|
rgs.lins :=calclines;
|
|
rgs.mmode :=calcmmode;
|
|
rgs.chip :=cv.chip;
|
|
end;
|
|
|
|
|
|
procedure AnalyseMode;
|
|
begin
|
|
DumpRegisters;
|
|
CalcRegisters;
|
|
end;
|
|
|
|
procedure wrregs(var rg:regblk);
|
|
var x:word;
|
|
begin
|
|
write(hex4(rg.base)+':');
|
|
for x:=0 to rg.nbr do
|
|
begin
|
|
if (x mod 25=0) and (x>0) then
|
|
write('('+hex2(x)+'):');
|
|
|
|
write(' '+hex2(rg.x[x]));
|
|
end;
|
|
writeln;
|
|
end;
|
|
|
|
function dumpVGAregs:word;
|
|
var x,y:word;
|
|
begin
|
|
settextmode; {Set 43/50 line text mode}
|
|
writeln('Mode: '+hex2(rgs.mode)+'h Pixels: '+istr(rgs.pixels)+' lines: '+istr(rgs.lins)
|
|
+' bytes: '+istr(rgs.bytes)+' colors: '+istr(modecols[rgs.mmode]));
|
|
writeln;
|
|
if oldreg then writeln('SEQ (OLD): 0Dh: ',hex2(rgs.tridold0d)
|
|
,' 0Eh: ',hex2(rgs.tridold0e));
|
|
|
|
for x:=$3C0 to $3CF do write(' '+hex2(rgs.stdregs[x]));
|
|
writeln;
|
|
for x:=$3D0 to $3DF do write(' '+hex2(rgs.stdregs[x]));
|
|
writeln;
|
|
write('03C0:');
|
|
for x:=0 to 31 do
|
|
begin
|
|
if x=25 then write('(19):');
|
|
write(' '+hex2(rgs.attregs[x]));
|
|
end;
|
|
writeln;
|
|
wrregs(rgs.seqregs);
|
|
wrregs(rgs.grcregs);
|
|
wrregs(rgs.crtcregs);
|
|
if rgs.xxregs.base<>0 then
|
|
begin
|
|
if (rgs.xxregs.base and $ff8f)=$210A then
|
|
begin
|
|
write(hex4(rgs.xxregs.base and $fff0)+':');
|
|
for x:=0 to 15 do write(' '+hex2(rgs.xgaregs[x]));
|
|
writeln;
|
|
end;
|
|
wrregs(rgs.xxregs);
|
|
end;
|
|
writeln;
|
|
write('DAC: ');
|
|
for x:=0 to 16 do
|
|
write(' '+hex2(rgs.dacregs[x]));
|
|
writeln;
|
|
if rgs.dacinxd.base<>0 then wrregs(rgs.dacinxd);
|
|
dumpVGAregs:=getkey;
|
|
end;
|
|
|
|
function FormatRgs(var b:byte):word; {Format registers for dump}
|
|
type
|
|
barr=array[1..2000] of byte;
|
|
var
|
|
blk:^barr;
|
|
bts,x:word;
|
|
|
|
procedure appb(b:byte);
|
|
begin
|
|
inc(bts);
|
|
blk^[bts]:=b;
|
|
end;
|
|
|
|
procedure appw(w:word);
|
|
begin
|
|
appb(lo(w));
|
|
appb(hi(w));
|
|
end;
|
|
|
|
procedure apprgs(var r:regblk);
|
|
var x:word;
|
|
begin
|
|
appw(1);
|
|
appw(r.base);
|
|
appb(0);
|
|
appb(r.nbr);
|
|
for x:=0 to r.nbr do appb(r.x[x]);
|
|
end;
|
|
|
|
begin
|
|
blk:=@b;
|
|
bts:=0;
|
|
appw(1);
|
|
appw($3C0);
|
|
appb(0);
|
|
appb(31);
|
|
for x:=0 to 31 do appb(rgs.attregs[x]);
|
|
apprgs(rgs.seqregs);
|
|
apprgs(rgs.grcregs);
|
|
apprgs(rgs.crtcregs);
|
|
if rgs.xxregs.base<>0 then apprgs(rgs.xxregs);
|
|
if oldreg then
|
|
begin
|
|
appw($FF);
|
|
appw(0);
|
|
appb(rgs.tridold0d);
|
|
appw($FF);
|
|
appw(1);
|
|
appb(rgs.tridold0e);
|
|
end;
|
|
for x:=0 to 16 do {DAC registers 0-10h}
|
|
begin
|
|
appw($FF);
|
|
appw($F000+x);
|
|
appb(rgs.dacregs[x]);
|
|
end;
|
|
if rgs.dacinxd.nbr>0 then apprgs(rgs.dacinxd);
|
|
if (rgs.xxregs.base and $FF8F)=$210A then
|
|
begin
|
|
appw(16);
|
|
appw(rgs.xxregs.base-$A);
|
|
for x:=0 to 15 do appb(rgs.xgaregs[x]);
|
|
end;
|
|
appw($3C2);
|
|
appb(rgs.stdregs[$3C2]);
|
|
appw(4);
|
|
appw($3CA);
|
|
for x:=$3CA to $3CD do appb(rgs.stdregs[x]);
|
|
appw(8);
|
|
appw(crtc+4);
|
|
for x:=$3D8 to $3DF do appb(rgs.stdregs[x]);
|
|
appw(0);
|
|
FormatRgs:=bts;
|
|
end;
|
|
|
|
|
|
procedure dumpVGAregfile;
|
|
var
|
|
f:file of regtype;
|
|
begin
|
|
assign(f,'register.vga');
|
|
{$i-}
|
|
reset(f);
|
|
{$i+}
|
|
if ioresult=0 then seek(f,filesize(f)) else rewrite(f);
|
|
write(f,rgs);
|
|
close(f);
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
function tstrg(pt,msk:word):boolean; {Returns true if the bits in MSK
|
|
of register PT are read/writable}
|
|
var old,nw1,nw2:word;
|
|
begin
|
|
old:=inp(pt);
|
|
outp(pt,old and not msk);
|
|
nw1:=inp(pt) and msk;
|
|
outp(pt,old or msk);
|
|
nw2:=inp(pt) and msk;
|
|
outp(pt,old);
|
|
tstrg:=(nw1=0) and (nw2=msk);
|
|
end;
|
|
|
|
function testinx2(pt,rg,msk:word):boolean; {Returns true if the bits in MSK
|
|
of register PT index RG are
|
|
read/writable}
|
|
var old,nw1,nw2:word;
|
|
begin
|
|
old:=rdinx(pt,rg);
|
|
wrinx(pt,rg,old and not msk);
|
|
nw1:=rdinx(pt,rg) and msk;
|
|
wrinx(pt,rg,old or msk);
|
|
nw2:=rdinx(pt,rg) and msk;
|
|
wrinx(pt,rg,old);
|
|
testinx2:=(nw1=0) and (nw2=msk);
|
|
end;
|
|
|
|
function testinx(pt,rg:word):boolean; {Returns true if all bits of
|
|
register PT index RG are
|
|
read/writable.}
|
|
var old,nw1,nw2:word;
|
|
begin
|
|
testinx:=testinx2(pt,rg,$ff);
|
|
end;
|
|
|
|
procedure UNK(vers,code:word);
|
|
begin
|
|
cv.version:=vers;
|
|
cv.subvers:=code;
|
|
end;
|
|
|
|
procedure SetVersion(vers:word;nam:string);
|
|
begin
|
|
cv.Version:=vers;
|
|
cv.name:=nam;
|
|
end;
|
|
|
|
|
|
procedure SetDAC(typ:word;Name:string);
|
|
begin
|
|
cv.dactype:=typ;
|
|
cv.dacname:=name;
|
|
end;
|
|
|
|
|
|
procedure addvideo;
|
|
var nam,s:string;
|
|
x,nr,err:word;
|
|
ok:boolean;
|
|
begin
|
|
nam:='';
|
|
if force_version<>0 then cv.version:=force_version;
|
|
if cv.version<>0 then
|
|
begin
|
|
for x:=1 to NBRCHIPS do
|
|
begin
|
|
if cv.version=CHIPSLIST[x].nbr then
|
|
begin
|
|
nam:=CHIPSLIST[x].nam;
|
|
if nam[length(nam)]='(' then nam:=nam+hex4(cv.subvers)+')';
|
|
end;
|
|
end;
|
|
end;
|
|
if cv.Version=ET_4000 then
|
|
case cv.Subvers of
|
|
TS_SpeedStar:nam:=nam+' (SpeedStar)';
|
|
TS_Genoa7900:nam:=nam+' (Genoa7900)';
|
|
end;
|
|
cv.flags:=cv.flags or FLG_ExtDAC; {Allow Ext DAC addressing}
|
|
if (cv.flags and FLG_StdVGA)>0 then ok:=setmode($12,false); {Set std mode}
|
|
if cv.dactype=_dac0 then testdac;
|
|
if (cv.chip=__ALG) and (cv.dactype=_dac8) then SetDAC(_dacALG1101,'ALG1101');
|
|
|
|
if (DACflags and DFL_CmdReg)>0 then {Must have CMD register}
|
|
begin
|
|
x:=inp(SetDACpage(dacHIcmd)); {test if RS2/3 works}
|
|
clearDACpage;
|
|
if x<>getdaccomm then cv.flags:=cv.flags and (not FLG_ExtDAC);
|
|
end;
|
|
|
|
if cv.dactype=_dacInt then cv.dacname:='Internal';
|
|
if force_mm<>0 then cv.mm:=force_mm;
|
|
fillchar(cv.clks,sizeof(cv.clks),0);
|
|
if (cv.chip<>__vesa) and clocktest then findclocks;
|
|
inc(vids);
|
|
vid[vids]:=cv;
|
|
vid[vids].name :=nam+' '+cv.name;
|
|
vid[vids].sname:=chipnam[cv.chip];
|
|
SetTextMode; {Reset any special bits}
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
(* Tests for various adapters *)
|
|
|
|
|
|
procedure _Acer;
|
|
var old:word;
|
|
begin
|
|
old:=rdinx(GRC,$FF);
|
|
clrinx(GRC,$FF,7);
|
|
if not testinx2(GRC,$10,$9F) then
|
|
begin
|
|
clrinx(GRC,$FF,7);
|
|
if testinx2(GRC,$10,$9F) then
|
|
begin
|
|
cv.chip:=__Acer;
|
|
case rdinx(GRC,$E) and $C of
|
|
0:cv.mm:=256;
|
|
1:cv.mm:=512;
|
|
2:cv.mm:=1024;
|
|
3:cv.mm:=2048;
|
|
end;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
wrinx(GRC,$FF,old);
|
|
end;
|
|
|
|
procedure _ahead;
|
|
var old:word;
|
|
begin
|
|
old:=rdinx(GRC,$F);
|
|
wrinx(GRC,$F,0);
|
|
if not testinx2(GRC,$C,$FB) then
|
|
begin
|
|
wrinx(GRC,$F,$20);
|
|
if testinx2(GRC,$C,$FB) then
|
|
begin
|
|
cv.chip:=__ahead;
|
|
case rdinx(GRC,$F) and 15 of
|
|
0:cv.Version:=AH_A;
|
|
1:begin
|
|
cv.Version:=AH_B;
|
|
cv.features:=ft_rwbank;
|
|
cv.clktype:=clk_ext4;
|
|
end;
|
|
end;
|
|
case rdinx(GRC,$1F) and 3 of
|
|
0:cv.mm:=256;
|
|
1:cv.mm:=512;
|
|
2:;
|
|
3:cv.mm:=1024;
|
|
end;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
wrinx(GRC,$F,old);
|
|
end;
|
|
|
|
procedure _ALG;
|
|
var old:integer;
|
|
begin
|
|
old:=rdinx(crtc,$1A);
|
|
clrinx(crtc,$1A,$10);
|
|
if not testinx2(crtc,$19,$CF) then
|
|
begin
|
|
setinx(crtc,$1A,$10);
|
|
if testinx2(crtc,$19,$CF) and testinx2(crtc,$1A,$3F) then
|
|
begin
|
|
cv.chip:=__ALG;
|
|
cv.subvers:=rdinx(crtc,$1A);
|
|
case cv.subvers shr 6 of
|
|
3:begin
|
|
cv.Version:=ALG_2101;
|
|
{SetDAC(_dacalg,'ALG1101');}
|
|
end;
|
|
2:if (rdinx(crtc,$1B) and 4)>0 then cv.Version:=ALG_2228
|
|
else cv.Version:=ALG_2301;
|
|
{The 2228/2301/230x should probably be ID'd from the PCI ID ?}
|
|
1:cv.version:=ALG_2201;
|
|
else cv.Version:=ALG_Unknown;
|
|
end;
|
|
cv.clktype:=clk_ext4;
|
|
cv.features:=ft_rwbank+ft_blit+ft_cursor+ft_line;
|
|
if cv.version>ALG_2101 then cv.features:=ft_rwbank; {CBL don't work yet!}
|
|
case rdinx(crtc,$1E) and 3 of
|
|
0:cv.mm:=256;
|
|
1:cv.mm:=512;
|
|
2:cv.mm:=1024;
|
|
3:cv.mm:=2048;
|
|
end;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
wrinx(crtc,$1A,old);
|
|
end;
|
|
|
|
procedure _Alliance;
|
|
begin
|
|
if (rdinx(SEQ,$11)=$41) and (rdinx(SEQ,$12)=$53) then
|
|
begin
|
|
cv.chip:=__Alli;
|
|
cv.version:=ALi_3210;
|
|
|
|
if mem[SegA000:$D8]=0 then;
|
|
outpw(SEQ,$1210);
|
|
setinx(SEQ,$1C,8);
|
|
modinx(SEQ,$1B,7,1);
|
|
cv.mm:=mem[SegA000:$F0]*64; {Video Memory}
|
|
clrinx(SEQ,$1B,7);
|
|
clrinx(SEQ,$1C,8);
|
|
addvideo;
|
|
end;
|
|
end;
|
|
|
|
procedure _ARK;
|
|
var old:word;
|
|
begin
|
|
old:=rdinx(SEQ,$1D);
|
|
wrinx(SEQ,$1D,0); {Lock the ext registers}
|
|
if not (testinx(SEQ,$11) and testinx(SEQ,$12)) then
|
|
begin
|
|
wrinx(SEQ,$1D,old);
|
|
if testinx(SEQ,$11) and testinx(SEQ,$12) then
|
|
begin
|
|
cv.chip:=__ARK;
|
|
cv.SubVers:=rdinx(crtc,$50);
|
|
case cv.SubVers and $F8 of
|
|
$88:cv.Version:=ARK_1000VL;
|
|
$90:cv.Version:=ARK_1000PV;
|
|
$98:cv.Version:=ARK_2000PV;
|
|
else cv.version:=ARK_Unknown;
|
|
end;
|
|
cv.clktype:=clk_ext4;
|
|
cv.features:=ft_rwbank+ft_cursor;
|
|
if cv.Version=ARK_2000PV then
|
|
case rdinx(SEQ,$10) shr 6 of
|
|
0:cv.mm:=1024;
|
|
1:cv.mm:=2048;
|
|
2:cv.mm:=4096;
|
|
3:cv.mm:=8192;
|
|
end
|
|
else
|
|
if (rdinx(SEQ,$10) and $40)>0 then cv.mm:=2048
|
|
else cv.mm:=1024;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
wrinx(SEQ,$1D,old);
|
|
end;
|
|
|
|
|
|
procedure _ati;
|
|
var w,mall,mvga:word;
|
|
l:longint;
|
|
begin
|
|
if getbios($31,9)='761295520' then
|
|
begin
|
|
case memw[biosseg:$40] of
|
|
$3133:begin
|
|
cv.IOadr:={memw[biosseg:$10]}$1CE;
|
|
w:=rdinx(cv.IOadr,$BB);
|
|
case w and 15 of
|
|
0:_crt:='EGA';
|
|
1:_crt:='Analog Monochrome';
|
|
2:_crt:='Monochrome';
|
|
3:_crt:='Analog Color';
|
|
4:_crt:='CGA';
|
|
6:_crt:='';
|
|
7:_crt:='IBM 8514/A';
|
|
else _crt:='Multisync';
|
|
end;
|
|
cv.chip:=__ati;
|
|
cv.SubVers:=mem[biosseg:$43];
|
|
case cv.SubVers of
|
|
$31:cv.Version:=ATI_18800;
|
|
$32:cv.Version:=ATI_18800_1;
|
|
$33:cv.Version:=ATI_28800_2;
|
|
$34:cv.Version:=ATI_28800_4;
|
|
$35,$36:if (rdinx(cv.IOadr,$AA) and 15)=6 then
|
|
cv.Version:=ATI_28800_6
|
|
else cv.Version:=ATI_28800_5;
|
|
$20:begin
|
|
cv.SubVers:=inpw($6EEC);
|
|
case cv.Subvers of
|
|
$57:cv.Version:=ATI_M64_CX;
|
|
$D7:cv.Version:=ATI_M64_GX;
|
|
else cv.Version:=ATI_M64_Unk;
|
|
end;
|
|
cv.Xseg:=$BFC0; {Memory mapped regs at BFC00h}
|
|
if (inpw($72EC) and $E00)=$A00 then
|
|
SetDAC(_dacATI68860,'ATI 68860'); {Hack!}
|
|
end;
|
|
$61..$63:begin {Mach32}
|
|
cv.SubVers:=inpw($FAEE);
|
|
case cv.SubVers and $3FF of
|
|
$2F7:cv.Version:=ATI_GUP_6;
|
|
$177:cv.Version:=ATI_GUP_LX;
|
|
$017:cv.Version:=ATI_GUP_AX;
|
|
0:cv.Version:=ATI_GUP_3;
|
|
else cv.Version:=ATI_M32_Unk;
|
|
end;
|
|
end;
|
|
else cv.Version:=ATI_Unknown;
|
|
end;
|
|
if cv.Version=ATI_18800 then cv.clktype:=clk_ext3
|
|
else cv.clktype:=clk_ext4;
|
|
if cv.Version>=ATI_18800_1 then cv.features:=ft_rwbank;
|
|
case cv.Version of
|
|
ATI_18800,ATI_18800_1:
|
|
if (rdinx(cv.IOadr,$BB) and $20)<>0 then cv.mm:=512;
|
|
ATI_28800_2:if (rdinx(cv.IOadr,$B0) and $10)<>0 then cv.mm:=512;
|
|
ATI_28800_4,ATI_28800_5,ATI_28800_6:
|
|
case rdinx(cv.IOadr,$B0) and $18 of
|
|
0:cv.mm:=256;
|
|
$10:cv.mm:=512;
|
|
8,$18:cv.mm:=1024;
|
|
end;
|
|
ATI_GUP_3..ATI_GUP_LX:
|
|
begin
|
|
case inp($36EE) and $C of
|
|
0:mall:=512;
|
|
4:mall:=1024;
|
|
8:mall:=2048;
|
|
12:mall:=4096;
|
|
end;
|
|
mvga:=mall;
|
|
if (inp($42EE) and $10)>0 then {Split VGA/Mach mem}
|
|
begin
|
|
mvga:=(inp($42EE) and $F)*256;
|
|
if mvga>mall then mvga:=mall;
|
|
end;
|
|
cv.mm:=mvga;
|
|
end;
|
|
ATI_M64_GX:begin
|
|
l:=inpl($52EC);
|
|
case l and 7 of
|
|
0:mall:=512;
|
|
1:mall:=1024;
|
|
2:mall:=2048;
|
|
3:mall:=4096;
|
|
4:mall:=6144;
|
|
5:mall:=8192;
|
|
end;
|
|
mvga:=mall;
|
|
if (l and $40000)>0 then
|
|
begin
|
|
case (l shr 16) and 3 of
|
|
0:mvga:=0;
|
|
1:mvga:=256;
|
|
2:mvga:=512;
|
|
3:mvga:=1024;
|
|
end;
|
|
if mvga>mall then mvga:=mall;
|
|
end;
|
|
cv.mm:=mvga;
|
|
if cv.mm>1024 then cv.mm:=1024;
|
|
end;
|
|
end;
|
|
end;
|
|
$3233:begin
|
|
cv.Version:=ATI_EGA;
|
|
video:='EGA';
|
|
cv.chip:=__ega;
|
|
end;
|
|
end;
|
|
addvideo;
|
|
if cv.version>=ATI_GUP_3 then {Now add the VGA part}
|
|
begin
|
|
if cv.Version>=ATI_M64_GX then cv.chip:=__Mach64
|
|
else cv.chip:=__Mach32;
|
|
cv.flags:=cv.flags and (not FLG_StdVGA);
|
|
cv.mm:=mall;
|
|
if mvga<mall then cv.mm:=mall-mvga;
|
|
cv.features:=cv.features or ft_cursor or ft_line or ft_blit;
|
|
if (inpw($72EC) and $E00)=$A00 then
|
|
SetDAC(_dacATI68860,'ATI 68860'); {Hack!}
|
|
addvideo;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure _chipstech;
|
|
var prt,old,x:word;
|
|
begin
|
|
vio($5F00);
|
|
if rp.al=$5F then
|
|
begin
|
|
cv.subvers:=rp.bl;
|
|
case cv.SubVers shr 4 of
|
|
0:cv.Version:=CT_451;
|
|
1:cv.Version:=CT_452;
|
|
2:cv.Version:=CT_455;
|
|
3:cv.Version:=CT_453;
|
|
4:cv.Version:=CT_450;
|
|
5:cv.Version:=CT_456;
|
|
6:cv.Version:=CT_457;
|
|
7:cv.Version:=CT_65520;
|
|
8:cv.Version:=CT_65530;
|
|
9:cv.Version:=CT_65510;
|
|
10:cv.Version:=CT_64200;
|
|
11:if cv.subvers>=$B8 then cv.Version:=CT_64310
|
|
else cv.Version:=CT_64300;
|
|
12:cv.Version:=CT_65535;
|
|
13:if cv.subvers>=$D8 then cv.Version:=CT_65545
|
|
else cv.Version:=CT_65540;
|
|
else cv.Version:=CT_Unknown;
|
|
end;
|
|
cv.clktype:=clk_ext3;
|
|
if cv.version<CT_450 then
|
|
begin
|
|
prt:=$46E8; {Should be $94 for MCA systems}
|
|
outp(prt,$1E); {Setup mode}
|
|
|
|
x:=inp($103);
|
|
outp($103,x or $80); {Enable extensions}
|
|
outp(prt,$E);
|
|
if (x and $40)=0 then cv.IOadr:=$3D6 else cv.IOadr:=$3B6;
|
|
end
|
|
else begin
|
|
cv.IOadr:=$3D6;
|
|
if cv.version=CT_64300 then
|
|
begin
|
|
cv.clktype:=clk_internal;
|
|
setDAC(_dacInt,'CT 24bit DAC');
|
|
end
|
|
else setDAC(_dacInt,'CT 15/16bit DAC');
|
|
end;
|
|
cv.SubVers:=rdinx(cv.IOadr,0);
|
|
cv.chip:=__chips;
|
|
if cv.version=CT_452 then cv.features:=ft_cursor;
|
|
case rdinx(cv.IOadr,4) and 3 of
|
|
1:cv.mm:=512;
|
|
2,3:begin
|
|
cv.mm:=1024;
|
|
if (cv.Version>=CT_64300) and ((rdinx(cv.IOadr,$F) and 3)=3) then
|
|
cv.mm:=2048
|
|
end;
|
|
end;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
|
|
procedure _cirrus;
|
|
var old,old6:word;
|
|
begin
|
|
old6:=rdinx(SEQ,6);
|
|
old:=rdinx(crtc,$C);
|
|
outp(crtc+1,0);
|
|
cv.SubVers:=rdinx(crtc,$1F);
|
|
wrinx(SEQ,6,lo(cv.Subvers shr 4) or lo(cv.Subvers shl 4));
|
|
{The SubVers value is rotated by 4}
|
|
if inp(SEQ+1)=0 then
|
|
begin
|
|
outp($3c5,cv.SubVers);
|
|
if inp($3c5)=1 then
|
|
begin
|
|
case cv.SubVers of
|
|
$EC:cv.Version:=CL_GD5x0;
|
|
$CA:cv.Version:=CL_GD6x0;
|
|
$EA:cv.Version:=CL_V7_OEM;
|
|
else cv.Version:=CL_old_unk;
|
|
end;
|
|
cv.chip:=__cirrus;
|
|
cv.features:=ft_cursor;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
wrinx(crtc,$C,old);
|
|
wrinx(SEQ,6,old6);
|
|
end;
|
|
|
|
|
|
procedure _cirrus54;
|
|
var x,old:word;
|
|
begin
|
|
old:=rdinx(SEQ,6);
|
|
wrinx(SEQ,6,0);
|
|
if (rdinx(SEQ,6)=$F) then
|
|
begin
|
|
wrinx(SEQ,6,$12);
|
|
if (rdinx(SEQ,6)=$12) and testinx2(SEQ,$1E,$3F) {and testinx2(crtc,$1B,$ff)} then
|
|
begin
|
|
case rdinx(SEQ,$A) and $18 of {Alternate method:}
|
|
0:cv.mm:=256; { case rdinx(SEQ,$F) and $18}
|
|
8:cv.mm:=512; { $10: cv.mm:=1024; }
|
|
16:cv.mm:=1024; { $18: cv.mm:=2048; May not work}
|
|
24:cv.mm:=2048; { else cv.mm:=512}
|
|
end;
|
|
cv.SubVers:=rdinx(crtc,$27);
|
|
if testinx(GRC,9) then
|
|
begin
|
|
cv.features:=ft_cursor;
|
|
case cv.SubVers of
|
|
$18:cv.Version:=CL_AVGA2;
|
|
$88:cv.Version:=CL_GD5402;
|
|
$89:cv.Version:=CL_GD5402r1;
|
|
$8A:cv.Version:=CL_GD5420;
|
|
$8B:cv.Version:=CL_GD5420r1;
|
|
$8C..$8F:cv.Version:=CL_GD5422;
|
|
$90..$93:cv.Version:=CL_GD5426;
|
|
$94..$97:cv.Version:=CL_GD5424;
|
|
$98..$9B:cv.Version:=CL_GD5428;
|
|
$9C..$9F:cv.Version:=CL_GD5429; {Might not get here ??}
|
|
$A0..$A3:cv.Version:=CL_GD5430;
|
|
{ $A4..$A7:cv.Version:=CL_GD543x; Probably does not exist}
|
|
$A8..$AB:cv.version:=CL_GD5434;
|
|
$2C..$2F:cv.version:=CL_GD7542; {Nordic}
|
|
$30..$33:cv.version:=CL_GD7543; {Viking}
|
|
$34..$37:cv.version:=CL_GD7541; {Nordic Lite}
|
|
else cv.Version:=CL_Unk54;
|
|
end;
|
|
SetDAC(_dacInt,'Cirrus Internal');
|
|
if cv.Version>=CL_GD5426 then
|
|
cv.features:=ft_cursor+ft_blit;
|
|
if cv.Version>=CL_GD7541 then
|
|
case rdinx(SEQ,$A) and 15 of
|
|
0:cv.mm:=256;
|
|
1:cv.mm:=512;
|
|
2:cv.mm:=1024;
|
|
3:cv.mm:=2048;
|
|
4:cv.mm:=4096;
|
|
end;
|
|
if cv.Version>=CL_GD5430 then
|
|
case rdinx(SEQ,$15) and 15 of {Alternate method:}
|
|
0:cv.mm:=256; { case rdinx(SEQ,$F) and $18}
|
|
1:cv.mm:=512; { $10: cv.mm:=1024; }
|
|
2:cv.mm:=1024; { $18: cv.mm:=2048; }
|
|
3:cv.mm:=2048; { else cv.mm:=512; }
|
|
4:cv.mm:=4096; { end; }
|
|
end; { if (rdinx(SEQ,$F) and $80)>0 then }
|
|
end { cv.mm:=cv.mm*2; }
|
|
else if testinx(SEQ,$19) then
|
|
begin
|
|
case cv.SubVers shr 6 of
|
|
0:cv.Version:=CL_GD6205;
|
|
1:cv.Version:=CL_GD6235;
|
|
2:cv.Version:=CL_GD6215;
|
|
3:cv.Version:=CL_GD6225;
|
|
end;
|
|
cv.mm:=512;
|
|
cv.features:=0;
|
|
end
|
|
else begin
|
|
cv.Version:=CL_AVGA2;
|
|
cv.features:=ft_cursor;
|
|
case rdinx(SEQ,$A) and 3 of
|
|
0:cv.mm:=256;
|
|
1:cv.mm:=512;
|
|
2:cv.mm:=1024;
|
|
end;
|
|
end;
|
|
cv.chip:=__cir54;
|
|
cv.clktype:=clk_internal;
|
|
addvideo;
|
|
end;
|
|
end
|
|
else wrinx(SEQ,6,old);
|
|
end;
|
|
|
|
procedure _cirrus64;
|
|
var x,old:word;
|
|
begin
|
|
old:=rdinx(GRC,$A);
|
|
wrinx(GRC,$A,$CE); {Lock}
|
|
if (rdinx(GRC,$A)=0) then
|
|
begin
|
|
wrinx(GRC,$A,$EC); {unlock}
|
|
if (rdinx(GRC,$A)=1) then
|
|
begin
|
|
cv.SubVers:=rdinx(GRC,$AA);
|
|
case cv.SubVers shr 4 of
|
|
4:cv.Version:=CL_GD6440;
|
|
5:cv.Version:=CL_GD6412;
|
|
6:cv.Version:=CL_GD5410;
|
|
7:if testinx2(GRC,$87,$90) then cv.Version:=CL_GD6420B
|
|
else cv.Version:=CL_GD6420A;
|
|
8:cv.Version:=CL_GD6410;
|
|
else cv.Version:=CL_Unk64;
|
|
end;
|
|
case rdinx(GRC,$BB) shr 6 of
|
|
0:cv.mm:=256;
|
|
1:cv.mm:=512;
|
|
2:cv.mm:=768;
|
|
3:cv.mm:=1024;
|
|
end;
|
|
cv.chip:=__cir64;
|
|
cv.clktype:=clk_internal;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
wrinx(GRC,$A,old);
|
|
end;
|
|
|
|
|
|
procedure _compaq;
|
|
var old,x:word;
|
|
begin
|
|
old:=rdinx(GRC,$F);
|
|
wrinx(GRC,$F,0);
|
|
if not testinx(GRC,$45) then
|
|
begin
|
|
wrinx(GRC,$F,5);
|
|
if testinx(GRC,$45) then
|
|
begin
|
|
cv.chip:=__compaq;
|
|
cv.features:=ft_blit;
|
|
cv.SubVers:=rdinx(GRC,$C) shr 3;
|
|
case cv.SubVers of
|
|
3:cv.Version:=CPQ_IVGS;
|
|
5:cv.Version:=CPQ_AVGA;
|
|
6:cv.Version:=CPQ_QV1024;
|
|
$E:if (rdinx(GRC,$56) and 4)<>0 then cv.Version:=CPQ_QV1280
|
|
else cv.Version:=CPQ_QV1024;
|
|
$10:cv.Version:=CPQ_AVPort; {What is this ?}
|
|
else cv.Version:=CPQ_Unknown;
|
|
end;
|
|
if (rdinx(GRC,$C) and $B8)=$30 then {QVision}
|
|
begin
|
|
cv.features:=cv.features + ft_cursor;
|
|
wrinx(GRC,$F,5);
|
|
case rdinx(GRC,$54) of
|
|
0:cv.mm:=1024; {old QV1024 fix}
|
|
2:cv.mm:=512;
|
|
4:cv.mm:=1024;
|
|
8:cv.mm:=2048;
|
|
end;
|
|
cv.clktype:=clk_ext4;
|
|
end
|
|
else begin
|
|
rp.bx:=0;
|
|
rp.cx:=0;
|
|
vio($BF03);
|
|
if (rp.ch and 64)=0 then cv.mm:=512;
|
|
cv.clktype:=clk_ext3;
|
|
end;
|
|
addvideo;
|
|
end
|
|
end;
|
|
wrinx(GRC,$F,old);
|
|
end;
|
|
|
|
procedure _everex;
|
|
var x:word;
|
|
begin
|
|
rp.bx:=0;
|
|
vio($7000);
|
|
if rp.al=$70 then
|
|
begin
|
|
x:=rp.dx shr 4;
|
|
if (x<>$678) and (x<>$236)
|
|
and (x<>$620) and (x<>$673) then {Some Everex boards use Trident chips.}
|
|
begin
|
|
case rp.ch shr 6 of
|
|
0:cv.mm:=256;
|
|
1:cv.mm:=512;
|
|
2:cv.mm:=1024;
|
|
3:cv.mm:=2048;
|
|
end;
|
|
cv.name:='Everex Ev'+hx[x shr 8]+hx[(x shr 4) and 15]+hx[x and 15];
|
|
cv.chip:=__everex;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure _genoa;
|
|
var ad:word;
|
|
begin
|
|
ad:=memw[biosseg:$37];
|
|
if (memw[biosseg:ad+2]=$6699) and (mem[biosseg:ad]=$77) then
|
|
begin
|
|
case mem[biosseg:ad+1] of
|
|
0:cv.Version:=GE_6200;
|
|
$11:begin
|
|
cv.Version:=GE_6400;
|
|
cv.mm:=512;
|
|
end;
|
|
$22:cv.Version:=GE_6100;
|
|
$33:cv.Version:=GE_5100; {Do we need to detect the Tseng versions ??}
|
|
$55:begin
|
|
cv.Version:=GE_5300;
|
|
cv.mm:=512;
|
|
end;
|
|
end;
|
|
cv.clktype:=clk_ext3;
|
|
if mem[biosseg:ad+1]<$33 then cv.chip:=__genoa {else cv.chip:=__ET3000};
|
|
addvideo;
|
|
end
|
|
end;
|
|
|
|
procedure _hmc;
|
|
begin
|
|
(* if testinx(SEQ,$E7) and testinx(SEQ,$EE) then *)
|
|
|
|
if testinx2(SEQ,$E7,$7F) and testinx2(SEQ,$EE,$F1) then
|
|
begin
|
|
if (rdinx(SEQ,$E7) and $10)>0 then cv.mm:=512;
|
|
cv.chip:=__HMC;
|
|
cv.clktype:=clk_ext4;
|
|
if testinx(SEQ,$E7) and testinx(SEQ,$EE) then cv.Version:=HMC_304
|
|
else cv.Version:=HMC_314;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
|
|
procedure _Imagine;
|
|
var inx:integer;
|
|
begin
|
|
inx:=CheckPCI(0,$105D,$2309);
|
|
if inx>0 then
|
|
begin
|
|
cv.IOadr:=PCIrec[inx].base5 and $FFFE;
|
|
case inp(cv.IOadr+$18) and $C0 of
|
|
0:cv.mm:=4096;
|
|
$40:cv.mm:=8192;
|
|
$80:cv.mm:=16384;
|
|
$C0:cv.mm:=32768;
|
|
end;
|
|
cv.version:=IMG_128;
|
|
cv.chip:=__IMAG;
|
|
cv.name:='';
|
|
addvideo;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure _matrox;
|
|
const
|
|
segm:array[1..7] of word=($AC00,$C800,$CC00,$D000,$D400,$D800,$DC00);
|
|
|
|
procedure addMGA(sgm:word);
|
|
var l:longint;
|
|
begin
|
|
cv.mm:=2048; {Still have to figure out memory, 2048 for now}
|
|
cv.Xseg:=sgm;
|
|
cv.chip:=__MGA;
|
|
cv.subvers:=memw[sgm:$1E48];
|
|
case cv.subvers of
|
|
$1700:cv.version:=MGA_Titan;
|
|
$1702:cv.version:=MGA_Helena;
|
|
else cv.Version:=MGA_Unknown;
|
|
end;
|
|
cv.flags:=cv.flags and (not FLG_StdVGA);
|
|
addvideo;
|
|
end;
|
|
|
|
var i,j,inx:word;
|
|
begin {First check for the Matrox VGA}
|
|
if testinx(crtc,$E1) and testinx($3DE,0) then
|
|
begin
|
|
cv.chip:=__Matrox;
|
|
cv.version:=MGA_VGA; {Hm}
|
|
cv.mm:=1024;
|
|
addvideo;
|
|
end;
|
|
|
|
cv.dactype:=_dac0; {Force DAC test}
|
|
j:=0;
|
|
for i:=1 to 7 do {Check for MGA-II (Ultima)}
|
|
if memw[segm[i]:$1E4A]=$A268 then
|
|
addMGA(segm[i]);
|
|
if getbios($78,3)='_VB' then
|
|
addMGA($AC00);
|
|
|
|
inx:=0;
|
|
repeat
|
|
inx:=CheckPCI(inx,$102B,$FFFF); {Look for any Matrox}
|
|
if (inx>0) and ((PCIrec[inx].device=$518) or (PCIrec[inx].device=$D10)) then
|
|
begin
|
|
cv.PCIid:=inx;
|
|
wPCIlong($10,$AC000); {MAP Matrox regs at AC000h}
|
|
addMGA($AC00);
|
|
wPCIlong($10,PCIrec[inx].l[4]); {remap}
|
|
end;
|
|
until inx=0;
|
|
end;
|
|
|
|
procedure _MediaVis; {MediaVision}
|
|
const
|
|
IObase:array[0..4] of word=($538,$E88,$F48,$60C,$148);
|
|
var
|
|
i,j,w:integer;
|
|
begin
|
|
j:=0;i:=0;
|
|
while (i<5) do
|
|
if inp(IObase[i])=$38 then i:=i+100 {found one, now stop}
|
|
else inc(i);
|
|
(* - While this will detect an uninitialised PG1024, it will also falsely
|
|
claim that about every second VGA card is a PG!!
|
|
if i<100 then
|
|
begin
|
|
i:=0;
|
|
while (i<5) do
|
|
if (inp(IObase[i])=$FF) and (inp(IObase[i]+1)=$FF) then
|
|
i:=i+100 {found one, now stop}
|
|
else inc(i);
|
|
end; *)
|
|
if i>=100 then {Found a PG1024}
|
|
begin
|
|
cv.IOadr :=IObase[i-100];
|
|
cv.chip :=__MV;
|
|
cv.mm :=2304; {2.25Mb = 9*256K}
|
|
cv.version:=MV_PG1024;
|
|
addvideo;
|
|
end
|
|
|
|
(* The 1280 detection does not work yet!
|
|
else begin {Now try for a 1280}
|
|
|
|
if (inp($539) and $CF)=$0A then outp($539,0);
|
|
if (inp($E89) and $CF)=$4A then outp($E89,0);
|
|
if (inp($F49) and $CF)=$8A then outp($F49,0);
|
|
if (inp($60D) and $CF)=$CA then outp($60D,0);
|
|
for i:=0 to 3 do
|
|
begin
|
|
w:=IObase[i]+1;
|
|
if inp(w)=$FF then
|
|
begin
|
|
outp(w,$8A);
|
|
for j:=1 to 100 do;
|
|
if inp(w)=$FF then
|
|
begin
|
|
for j:=1 to 100 do;
|
|
outp(w,$54);
|
|
for j:=1 to 100 do;
|
|
if inp(w)=$FF then
|
|
begin
|
|
outp(w,1);
|
|
if inp(w)=$0A then;
|
|
|
|
i:=999; {Stop the loop}
|
|
end;
|
|
end;
|
|
outp(w,$FF);
|
|
end;
|
|
end;
|
|
end; *)
|
|
end;
|
|
|
|
procedure _mxic;
|
|
var old:integer;
|
|
begin
|
|
old:=rdinx(SEQ,$A7);
|
|
wrinx(SEQ,$A7,0); {disable extensions}
|
|
if not testinx(SEQ,$C5) then
|
|
begin
|
|
wrinx(SEQ,$A7,$87); {enable extensions}
|
|
if testinx(SEQ,$C5) then
|
|
begin
|
|
cv.chip:=__mxic;
|
|
cv.clktype:=clk_ext3;
|
|
if (rdinx(SEQ,$26) and 1)=0 then cv.Version:=MX_86010
|
|
else cv.Version:=MX_86000; {Does this work, else test 85h bit 1 ??}
|
|
case (rdinx(SEQ,$C2) shr 2) and 3 of
|
|
0:cv.mm:=256;
|
|
1:cv.mm:=512;
|
|
2:cv.mm:=1024;
|
|
end;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
wrinx(SEQ,$A7,old);
|
|
end;
|
|
|
|
procedure _ncr;
|
|
var x:word;
|
|
begin
|
|
if testinx2(SEQ,5,5) then
|
|
begin
|
|
wrinx(SEQ,5,0); {Disable extended registers}
|
|
if not testinx(SEQ,$10) then
|
|
begin
|
|
wrinx(SEQ,5,1); {Enable extended registers}
|
|
if testinx(SEQ,$10) then
|
|
begin
|
|
cv.chip:=__ncr;
|
|
cv.clktype:=clk_ext3;
|
|
cv.SubVers:=rdinx(SEQ,8);
|
|
case cv.SubVers shr 4 of
|
|
0:cv.Version:=NCR_77C22;
|
|
1:cv.Version:=NCR_77C21;
|
|
2:if (cv.SubVers and 15)<8 then cv.Version:=NCR_77C22E
|
|
else cv.Version:=NCR_77C22Ep;
|
|
3:cv.Version:=NCR_77c32BLT;
|
|
else cv.Version:=NCR_Unknown;
|
|
end;
|
|
cv.features:=ft_rwbank+ft_cursor;
|
|
if cv.Version>=NCR_77c32BLT then cv.features:=cv.features+ft_blit;
|
|
cv.name:=cv.name+' Rev. '+istr(rdinx(SEQ,8) and 15);
|
|
memmode:=_P8;
|
|
if setmode($13,false) then;
|
|
checkmem(64);
|
|
addvideo;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure _oak;
|
|
var old:word;
|
|
|
|
begin
|
|
if testinx($3DE,9) or testinx2($3DE,$D,$38) then
|
|
begin
|
|
cv.chip:=__oak;
|
|
cv.features:=ft_rwbank;
|
|
if testinx2($3DE,$23,$1F) then
|
|
begin
|
|
case rdinx($3DE,2) and 6 of
|
|
0:cv.mm:=256;
|
|
2:cv.mm:=512;
|
|
4:cv.mm:=1024;
|
|
6:cv.mm:=2048;
|
|
end;
|
|
if (rdinx($3DE,0) and 2)=0 then cv.Version:=OAK_087
|
|
else cv.version:=OAK_083;
|
|
{SetDAC(_dac16,'OAK OTI-066HC'); {Cheat}
|
|
cv.clktype:=clk_ext4;
|
|
end
|
|
else begin
|
|
cv.clktype:=clk_ext3;
|
|
cv.SubVers:=inp($3DE) shr 5;
|
|
case cv.SubVers of
|
|
0:cv.Version:=OAK_037;
|
|
2:cv.Version:=OAK_067;
|
|
5:cv.Version:=OAK_077;
|
|
7:cv.Version:=OAK_057;
|
|
else cv.Version:=OAK_Unknown;
|
|
end;
|
|
|
|
case rdinx($3DE,$D) shr 6 of
|
|
2:cv.mm:=512;
|
|
1,3:cv.mm:=1024; {1 might not give 1M??}
|
|
end;
|
|
end;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
|
|
procedure _p2000;
|
|
begin
|
|
if testinx2(GRC,$3D,$3F) and tstrg($3D6,$1F) and tstrg($3D7,$1F) then
|
|
begin
|
|
cv.Version:=PR_2000;
|
|
cv.chip:=__p2000;
|
|
cv.features:=ft_rwbank+ft_blit;
|
|
memmode:=_P8;
|
|
if setmode($13,false) then;
|
|
checkmem(32);
|
|
cv.clktype:=clk_ext4;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
|
|
procedure _paradise;
|
|
var old,old2:word;
|
|
begin
|
|
old:=rdinx(GRC,$F);
|
|
setinx(GRC,$F,$17); {Lock registers}
|
|
|
|
if not testinx2(GRC,9,$7F) then
|
|
begin
|
|
wrinx(GRC,$F,5); {Unlock them again}
|
|
if testinx2(GRC,9,$7F) then
|
|
begin
|
|
cv.clktype:=clk_ext3;
|
|
old2:=rdinx(crtc,$29);
|
|
modinx(crtc,$29,$8F,$85); {Unlock WD90Cxx registers}
|
|
if not testinx(crtc,$2B) then cv.Version:=WD_PVGA1A
|
|
else begin
|
|
wrinx(SEQ,6,$48); {Enable C1x extensions}
|
|
if not testinx2(SEQ,7,$F0) then cv.Version:=WD_90C00
|
|
else if not testinx(SEQ,$10) then
|
|
begin
|
|
if testinx2(crtc,$31,$68) then cv.Version:=WD_90c22
|
|
else if testinx2(crtc,$31,$90) then cv.Version:=WD_90c20A
|
|
else cv.Version:=WD_90C20;
|
|
wrinx(crtc,$34,$A6);
|
|
if (rdinx(crtc,$32) and $20)<>0 then wrinx(crtc,$34,0);
|
|
end
|
|
else begin
|
|
cv.clktype:=clk_ext4;
|
|
cv.features:=ft_rwbank;
|
|
if testinx2(SEQ,$14,$F) then
|
|
begin
|
|
wrinx(crtc,$34,0); {Disable c2x registers}
|
|
wrinx(crtc,$35,0); {Disable c2x registers}
|
|
cv.SubVers:=(rdinx(crtc,$36) shl 8)+rdinx(crtc,$37);
|
|
case cv.SubVers of
|
|
$3234:begin
|
|
cv.Version:=WD_90c24;
|
|
cv.features:=cv.features+ft_cursor+ft_blit;
|
|
cv.clktype:=clk_internal;
|
|
SetDAC(_dacInt,'WD 16bit');
|
|
end;
|
|
$3236:cv.Version:=WD_90C26;
|
|
$3330:cv.Version:=WD_90c30;
|
|
$3331:begin
|
|
cv.Version:=WD_90C31;
|
|
cv.features:=cv.features+ft_cursor+ft_blit;
|
|
end;
|
|
$3333:begin
|
|
cv.Version:=WD_90C33;
|
|
cv.features:=cv.features+ft_cursor+ft_blit+ft_line;
|
|
end;
|
|
end;
|
|
end
|
|
else if not testinx2(SEQ,$10,4) then cv.Version:=WD_90C10
|
|
else cv.Version:=WD_90C11;
|
|
end;
|
|
end;
|
|
wrinx(GRC,$F,5); {Unlock them again}
|
|
case rdinx(GRC,$B) shr 6 of
|
|
2:cv.mm:=512;
|
|
3:cv.mm:=1024;
|
|
end;
|
|
if (cv.Version>=WD_90c33) and ((rdinx(crtc,$3E) and $80)>0) then cv.mm:=2048;
|
|
wrinx(crtc,$29,old2);
|
|
cv.chip:=__WD;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
wrinx(GRC,$F,old);
|
|
end;
|
|
|
|
procedure _realtek;
|
|
begin
|
|
if testinx2(crtc,$1F,$3F) and tstrg($3D6,$F) and tstrg($3D7,$F) then
|
|
begin
|
|
cv.chip:=__realtek;
|
|
cv.clktype:=clk_ext3;
|
|
cv.SubVers:=rdinx(crtc,$1A) shr 6;
|
|
case cv.SubVers of
|
|
0:cv.Version:=RT_3103;
|
|
1:cv.Version:=RT_3105;
|
|
2:cv.Version:=RT_3106;
|
|
else cv.Version:=RT_unknown;
|
|
end;
|
|
case rdinx(crtc,$1E) and 15 of
|
|
0:cv.mm:=256;
|
|
1:cv.mm:=512;
|
|
2:if cv.SubVers=0 then cv.mm:=768 else cv.mm:=1024;
|
|
3:if cv.SubVers=0 then cv.mm:=1024 else cv.mm:=2048;
|
|
end;
|
|
cv.features:=ft_rwbank;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
|
|
procedure _s3;
|
|
begin
|
|
wrinx(crtc,$38,0);
|
|
if not testinx2(crtc,$35,$F) then
|
|
begin
|
|
wrinx(crtc,$38,$48);
|
|
if testinx2(crtc,$35,$F) then
|
|
begin
|
|
cv.features:=ft_blit+ft_line+ft_cursor;
|
|
cv.SubVers:=rdinx(crtc,$30);
|
|
cv.clktype:=clk_ext4;
|
|
case cv.SubVers of
|
|
$81:cv.Version:=S3_911;
|
|
$82:cv.Version:=S3_924; {Also known as 911A}
|
|
$90:cv.Version:=S3_928;
|
|
$91:cv.Version:=S3_928C;
|
|
$94:cv.Version:=S3_928D;
|
|
$95:cv.Version:=S3_928E;
|
|
$A0:if (rdinx(crtc,$36) and 2)>0 then cv.Version:=S3_801AB
|
|
else cv.Version:=S3_805AB;
|
|
$A2..$A4:if (rdinx(crtc,$36) and 2)>0 then cv.Version:=S3_801C
|
|
else cv.Version:=S3_805C;
|
|
$A5,$A7:if (rdinx(crtc,$36) and 2)>0 then cv.Version:=S3_801D
|
|
else cv.Version:=S3_805D;
|
|
$A6:if (rdinx(crtc,$36) and 2)>0 then cv.Version:=S3_801P
|
|
else cv.Version:=S3_805P;
|
|
$A8:if (rdinx(crtc,$36) and 2)>0 then cv.Version:=S3_801I
|
|
else cv.Version:=S3_805I;
|
|
$B0:cv.Version:=S3_928PCI;
|
|
$C0:cv.Version:=S3_864;
|
|
$C1:cv.Version:=S3_864P;
|
|
$D0:cv.Version:=S3_964;
|
|
$E0,$E1:case rdinx(crtc,$2E) of {Not sure of this yet}
|
|
$10:cv.Version:=S3_732;
|
|
$11:cv.Version:=S3_764;
|
|
$80:cv.Version:=S3_866;
|
|
$90:cv.Version:=S3_868;
|
|
$B0,$F0:cv.Version:=S3_968;
|
|
end;
|
|
else cv.Version:=S3_Unknown;
|
|
end;
|
|
if (cv.Version=S3_732) or (cv.Version=S3_764) then
|
|
begin
|
|
cv.clktype:=clk_internal;
|
|
SetDAC(_dacInt,'S3 Trio');
|
|
end;
|
|
cv.mm:=512;
|
|
if (rdinx(crtc,$36) and $20)=0 then
|
|
if (cv.subvers<$90) then cv.mm:=1024 {911 and 924}
|
|
else case rdinx(crtc,$36) shr 6 of
|
|
0:cv.mm:=4096;
|
|
1:cv.mm:=3072;
|
|
2:cv.mm:=2048;
|
|
3:cv.mm:=1024;
|
|
end;
|
|
cv.chip:=__S3;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure _Sierra;
|
|
var old,i:word;
|
|
begin
|
|
old:=rdinx(SEQ,$11);
|
|
setinx(SEQ,$11,$20);
|
|
if not testinx(SEQ,$15) then
|
|
begin
|
|
i:=rdinx(SEQ,$11);
|
|
outp(SEQ+1,i);
|
|
outp(SEQ+1,i);
|
|
outp(SEQ+1,i and $DF);
|
|
if testinx(SEQ,$15) then
|
|
begin
|
|
setinx(SEQ,$11,$20);
|
|
cv.chip:=__Acer;
|
|
case rdinx(SEQ,7) shr 5 of
|
|
4:cv.version:=SC_15064;
|
|
else cv.version:=SC_Unknown;
|
|
end;
|
|
if setmode($13,false) then;
|
|
checkmem(64);
|
|
addvideo;
|
|
end;
|
|
end;
|
|
wrinx(SEQ,$11,old);
|
|
end;
|
|
|
|
procedure _SiS;
|
|
var old:word;
|
|
begin
|
|
old:=rdinx(SEQ,5);
|
|
wrinx(SEQ,5,0);
|
|
if rdinx(SEQ,5)=$21 then
|
|
begin
|
|
wrinx(SEQ,5,$86);
|
|
if rdinx(SEQ,5)=$A1 then
|
|
begin
|
|
cv.chip:=__SiS;
|
|
cv.Version:=SIS_201;
|
|
case rdinx(SEQ,$F) and 3 of
|
|
0:cv.mm:=1024;
|
|
1:cv.mm:=2048;
|
|
2:cv.mm:=4096;
|
|
end;
|
|
cv.dactype:=_dacInt;
|
|
cv.clktype:=clk_ext4;
|
|
cv.features:=ft_cursor+ft_rwbank;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
wrinx(SEQ,5,old);
|
|
end;
|
|
|
|
procedure _trident;
|
|
var old,val,Xseg,x:word;
|
|
Phadr:longint;
|
|
begin
|
|
wrinx(SEQ,$B,0); {Force old mode}
|
|
cv.SubVers:=inp(SEQ+1); { --- new mode}
|
|
old:=rdinx(SEQ,$E);
|
|
outp(SEQ+1,old xor $55);
|
|
val:=inp(SEQ+1);
|
|
outp(SEQ+1,old);
|
|
if ((val xor old) and 15)=7 then {Check for inverting bit 1}
|
|
begin
|
|
outp($3c5,old xor 2); (* Trident should restore bit 1 reversed *)
|
|
case cv.SubVers of
|
|
1:cv.Version:=TR_8800BR; {This'll never happen - no new mode}
|
|
2:cv.Version:=TR_8800CS;
|
|
3:cv.Version:=TR_8900B;
|
|
4,$13:cv.Version:=TR_8900C;
|
|
$23:cv.Version:=TR_9000;
|
|
$33:if (rdinx(crtc,$28) and $80)>0 then cv.Version:=TR_8900CL
|
|
{Does this work?} else cv.Version:=TR_9000C;
|
|
$43:cv.Version:=TR_9000i;
|
|
$53:cv.Version:=TR_9200CXr;
|
|
$63:cv.Version:=TR_LCD9100B;
|
|
$73:cv.Version:=TR_GUI9420; {Haven't seen this yet ?}
|
|
$83:cv.Version:=TR_LX8200;
|
|
$93:cv.Version:=TR_9400CXi;
|
|
$A3:cv.Version:=TR_LCD9320;
|
|
$C3:cv.Version:=TR_GUI9420;
|
|
$D3:cv.Version:=TR_GUI9660;
|
|
$E3:cv.Version:=TR_GUI9440;
|
|
$F3:cv.Version:=TR_GUI9430; {not quite sure}
|
|
{The $63, $73, $83, $A3 entries are still in doubt}
|
|
else cv.Version:=TR_Unknown;
|
|
end;
|
|
case cv.version of
|
|
TR_8800BR,
|
|
TR_8800CS,
|
|
TR_8900B:cv.clktype:=clk_ext3;
|
|
TR_9200CXr,TR_9400CXi,TR_GUI9420,TR_GUI9430
|
|
:begin
|
|
cv.clktype:=clk_ext4;
|
|
cv.dactype:=_dacInt;
|
|
end;
|
|
TR_GUI9440:begin
|
|
cv.clktype:=clk_internal;
|
|
cv.dactype:=_dacInt;
|
|
end;
|
|
else cv.clktype:=clk_ext4;
|
|
end;
|
|
if (cv.version>=TR_9000C) then cv.features:=cv.features+ft_rwbank;
|
|
if (cv.version>=TR_GUI9440) then cv.features:=cv.features+ft_cursor;
|
|
if cv.version=TR_9000i then setDAC(_dac16,'Trident 9000i');
|
|
cv.chip:=__trid;
|
|
if (pos('Zymos Poach 51',getbios(0,255))>0) or
|
|
(pos('Zymos Poach 51',getbios(230,255))>0) then
|
|
begin
|
|
cv.name:=cv.name+' (Zymos Poach)';
|
|
cv.chip:=__poach;
|
|
end;
|
|
case rdinx(crtc,$1F) and 3 of
|
|
0:cv.mm:=256;
|
|
1:cv.mm:=512;
|
|
2:cv.mm:=768;
|
|
3:if (cv.Version>=TR_8900CL) and ((rdinx(crtc,$1F) and 4)>0) then
|
|
cv.mm:=2048
|
|
else cv.mm:=1024;
|
|
end;
|
|
if (cv.SubVers=2) and (tstrg($2168,$F)) then
|
|
begin
|
|
cv.clktype:=clk_ext2;
|
|
cv.Version:=TR_IITAGX;
|
|
cv.mm:=512; {Might be able to address 1Mb, but scroll etc only works}
|
|
addvideo; {in the first 512K anyhow !}
|
|
|
|
cv.IOadr:=$2160;
|
|
cv.chip:=__AGX;
|
|
old:=inp(cv.IOadr);
|
|
modreg(cv.IOadr,7,4); {Enable XGA mode}
|
|
if testinx2(cv.IOadr+10,$7F,$30) then cv.version:=IIT_AGX1x
|
|
else if testinx2(cv.IOadr+10,$71,$F) then cv.version:=IIT_AGX16
|
|
else if (rdinx(cv.IOadr+10,$6C) and 1)>0 then cv.version:=IIT_AGX15
|
|
else cv.Version:=IIT_AGX14;
|
|
if (rdinx(cv.IOadr+10,$6D) and 1)>0 then cv.Xseg:=$B1F0 else cv.Xseg:=$D1F0;
|
|
outp(cv.IOadr,old);
|
|
if cv.Version>=IIT_AGX14 then cv.clktype:=clk_ext5
|
|
else cv.clktype:=clk_ext4;
|
|
memmode:=_p8;
|
|
if setmode($65,false) then;
|
|
checkmem(32);
|
|
cv.features:=ft_blit+ft_line+ft_cursor;
|
|
Phadr:=$FF800000;
|
|
cv.flags:=cv.flags and (not FLG_StdVGA);
|
|
end;
|
|
addvideo;
|
|
end
|
|
else begin {Trident 8800BR tests}
|
|
if (cv.subvers=1) and testinx2(SEQ,$E,6) then
|
|
begin
|
|
cv.Version:=TR_8800BR;
|
|
cv.chip:=__trid;
|
|
if (rdinx(crtc,$1F) and 2)>0 then cv.mm:=512;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure _tseng;
|
|
var x,vs:word;
|
|
s:string;
|
|
begin
|
|
outp($3BF,3);
|
|
outp(crtc+4,$A0); {Enable Tseng 4000 extensions}
|
|
if tstrg($3CD,$3F) then
|
|
begin
|
|
cv.chip:=__Tseng;
|
|
cv.features:=ft_rwbank;
|
|
cv.clktype:=clk_ext5;
|
|
if testinx2(crtc,$33,$F) then
|
|
begin
|
|
if tstrg($3CB,$33) then
|
|
begin
|
|
cv.features:=cv.features+ft_cursor+ft_blit;
|
|
cv.SubVers:=rdinx($217A,$EC);
|
|
case cv.SubVers shr 4 of
|
|
0:cv.Version:=ET_4W32;
|
|
1:cv.Version:=ET_4W32i_a;
|
|
2:cv.Version:=ET_4W32p_a;
|
|
3:cv.Version:=ET_4W32i_b;
|
|
5:cv.Version:=ET_4W32p_b;
|
|
6:cv.Version:=ET_4W32p_d;
|
|
7:cv.Version:=ET_4W32p_c;
|
|
11:cv.Version:=ET_4W32i_c;
|
|
else Unk(ET_4Unk,cv.SubVers);
|
|
end;
|
|
case rdinx(crtc,$37) and $9 of
|
|
0:cv.mm:=2048;
|
|
1:cv.mm:=4096;
|
|
{ 9:mm:=256;}
|
|
8:cv.mm:=512;
|
|
9:cv.mm:=1024;
|
|
end;
|
|
if cv.version>=ET_4W32p_a then cv.features:=cv.features or ft_line;
|
|
if (cv.Version<>ET_4W32) and ((rdinx(crtc,$32) and $80)>0) then
|
|
cv.mm:=cv.mm*2;
|
|
end
|
|
else begin
|
|
cv.Version:=ET_4000;
|
|
case rdinx(crtc,$37) and $B of
|
|
3,9:cv.mm:=256;
|
|
10:cv.mm:=512;
|
|
11:cv.mm:=1024;
|
|
end;
|
|
cv.subvers:=0;
|
|
for x:=0 to 10 do
|
|
begin
|
|
s:=getbios(x*230,255);
|
|
if pos('Genoa Systems',s)>0 then cv.subvers:=TS_Genoa7900
|
|
else if pos('SpeedSTAR',s)>0 then cv.subvers:=TS_SpeedStar;
|
|
end;
|
|
end;
|
|
end
|
|
else begin
|
|
cv.Version:=ET_3000;
|
|
if setmode($13,false) then;
|
|
x:=inp(CRTC+6);
|
|
x:=rdinx($3C0,$36);
|
|
outp($3C0,x or $10);
|
|
case (rdinx(GRC,6) shr 2) and 3 of
|
|
0,1:vs:=SegA000;
|
|
2:vs:=SegB000;
|
|
3:vs:=SegB800;
|
|
end;
|
|
|
|
meml[vs:1]:=$12345678;
|
|
if memw[vs:2]=$3456 then cv.mm:=512;
|
|
|
|
wrinx($3C0,$36,x); {reset value and reenable DAC}
|
|
end;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
|
|
procedure _UMC;
|
|
var old:integer;
|
|
begin
|
|
old:=inp($3BF);
|
|
outp($3BF,3);
|
|
if not testinx(SEQ,6) then
|
|
begin
|
|
outp($3BF,$AC);
|
|
if testinx(SEQ,6) then
|
|
begin
|
|
cv.chip:=__UMC;
|
|
cv.clktype:=clk_ext3;
|
|
case rdinx(SEQ,7) shr 6 of
|
|
1:cv.mm:=512;
|
|
2,3:cv.mm:=1024;
|
|
end;
|
|
if testinx2(crtc,$35,$F) then
|
|
begin
|
|
cv.version:=UMC_418;
|
|
if ((rdinx(GRC,$B) and $7F)=$2A) then cv.mm:=1024;
|
|
end
|
|
else cv.version:=UMC_408;
|
|
cv.features:=ft_rwbank;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
outp($3BF,old);
|
|
end;
|
|
|
|
|
|
procedure _video7;
|
|
var ram:string[10];
|
|
old:integer;
|
|
begin
|
|
vio($6f00);
|
|
if rp.bx=$5637 then
|
|
begin
|
|
vio($6f07);
|
|
if rp.ah<128 then ram:='VRAM' else ram:='FASTWRITE';
|
|
|
|
(* old:=rdinx(crtc,$C);
|
|
wrinx(crtc,$C,old);
|
|
wrinx($3C4,6,$EA); {Enable Extensions}
|
|
if rdinx(crtc,$1F)=(old XOR $EA) then
|
|
begin
|
|
wrinx(crtc,$C,old XOR $FF);
|
|
if rdinx(crtc,$1F)=(old XOR $15) then
|
|
begin
|
|
cv.SubVers:=(rdinx($3C4,$8F) shl 8)+rdinx($3C4,$8E);
|
|
|
|
wrinx(crtc,$C,old); *)
|
|
|
|
wrinx(SEQ,6,$EA); {Enable extensions}
|
|
cv.Subvers:=(rdinx(SEQ,$8F) shl 8)+rdinx(SEQ,$8E);
|
|
case cv.Subvers of
|
|
$8000..$FFFF:cv.Version:=V7_VEGA;
|
|
$7000..$70FF:cv.Version:=V7_208_13; {Fastwrite}
|
|
$7140..$714F:cv.Version:=V7_208A; {1024i}
|
|
$7151:cv.Version:=V7_208B; {VRAm II b}
|
|
$7152:cv.Version:=V7_208CD; {VRAm II c}
|
|
$7760:cv.Version:=V7_216BC;
|
|
$7763:cv.Version:=V7_216D;
|
|
$7764:cv.Version:=V7_216E;
|
|
$7765:cv.Version:=V7_216F;
|
|
else cv.Version:=V7_Unknown;
|
|
end;
|
|
case rp.ah and 127 of
|
|
2:cv.mm:=512;
|
|
4:cv.mm:=1024;
|
|
end;
|
|
cv.chip:=__video7;
|
|
cv.features:=ft_cursor;
|
|
if cv.Version>=V7_208A then
|
|
begin
|
|
{ cv.Features:=cv.features+ft_rwbank; {Don't work }
|
|
cv.clktype:=clk_ext4;
|
|
end;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
|
|
|
|
{Sets the Extention & Bank enable flags in SEQ index $11}
|
|
function WeitekEnable(flag:word):word;
|
|
var x,y:word;
|
|
begin
|
|
disable;
|
|
x:=rdinx(SEQ,$11);
|
|
for y:=1 to 10 do; {delay}
|
|
outp(SEQ+1,x);
|
|
for y:=1 to 10 do;
|
|
outp(SEQ+1,x);
|
|
for y:=1 to 10 do;
|
|
WeitekEnable:=x;
|
|
x:=inp(SEQ+1);
|
|
for y:=1 to 10 do;
|
|
outp(SEQ+1,(x and $9F) or flag);
|
|
WeitekEnable:=x;
|
|
enable;
|
|
end;
|
|
|
|
|
|
procedure _Weitek;
|
|
var old,x,y,z:word;
|
|
rr:array[0..$1FF] of byte;
|
|
begin
|
|
old:=WeitekEnable($60); {Disable}
|
|
if not testinx(SEQ,$12) then
|
|
begin
|
|
x:=WeitekEnable(0); {Enable}
|
|
if testinx(SEQ,$12) and tstrg($3CD,$FF) then
|
|
begin
|
|
cv.chip:=__Weitek;
|
|
cv.features:=ft_rwbank;
|
|
cv.SubVers:=rdinx(SEQ,7);
|
|
cv.clktype:=clk_ext3;
|
|
case cv.subvers shr 5 of
|
|
1:begin
|
|
cv.Version:=WT_5186; {Should check for version and memory}
|
|
(* if (rdinx(SEQ,$12) and $80)>0 then
|
|
cv.mm:=512; {Untested} *)
|
|
end;
|
|
2:begin
|
|
outp($9100,0);
|
|
z:=inp($9104);
|
|
outp($9100,1);
|
|
z:=(inp($9104) shl 8)+z;
|
|
if (z=$100E) then
|
|
begin
|
|
cv.Version:=WT_P9100;
|
|
cv.mm:=1024; {Hm}
|
|
end
|
|
else begin
|
|
cv.Version:=WT_5286;
|
|
case rdinx(SEQ,$12) shr 6 of
|
|
0:cv.mm:=256;
|
|
1:cv.mm:=512;
|
|
2:cv.mm:=1024;
|
|
end;
|
|
end;
|
|
end;
|
|
else cv.Version:=WT_Unk;
|
|
end;
|
|
addvideo;
|
|
x:=WeitekEnable($60); {dis. VGA}
|
|
z:=rdinx(SEQ,$12);
|
|
clrinx(SEQ,$12,$80);
|
|
setinx(SEQ,$12,$10);
|
|
outp($3CD,$10);
|
|
|
|
move(mem[SegA000:0],rr,$200);
|
|
wrinx(SEQ,$12,z);
|
|
end;
|
|
end;
|
|
wrinx(SEQ,$11,old);
|
|
end;
|
|
|
|
procedure _XGA;
|
|
var p:pointer;
|
|
posbase,cardid,xga_base,x,cx:word;
|
|
temp0,temp1,temp2,temp3:byte;
|
|
begin
|
|
getintvec($15,p);
|
|
if (seg(p^)<>0) then
|
|
begin
|
|
rp.ax:=$C400;
|
|
rp.dx:=$ffff;
|
|
intr($15,rp);
|
|
if not odd(rp.flags) and (rp.dx<>$ffff) then
|
|
begin
|
|
posbase:=rp.dx;
|
|
for cx:=0 to 9 do
|
|
begin
|
|
disable; (* CLI - Disable interrupts *)
|
|
if cx=0 then outp($94,$DF)
|
|
else begin
|
|
rp.ax:=$C401;
|
|
rp.bx:=cx;
|
|
intr($15,rp);
|
|
end;
|
|
cardid:=inpw(posbase);
|
|
temp0:=inp(posbase+2);
|
|
temp1:=inp(posbase+3);
|
|
temp2:=inp(posbase+4);
|
|
temp3:=inp(posbase+5);
|
|
if cx=0 then outp($94,$FF)
|
|
else begin
|
|
rp.ax:=$C402;
|
|
rp.bx:=cx;
|
|
intr($15,rp);
|
|
end;
|
|
enable; (* STI - Enable interrupts *)
|
|
if (cardid>=$8FD8) and (cardid<=$8FDB) then
|
|
begin
|
|
cv.IOadr:=$2100+(temp0 and $E)*8;
|
|
x:=rdinx(cv.IOadr+10,$52) and 15;
|
|
if (x<>0) and (x<>15) then
|
|
begin
|
|
cv.chip:=__XGA;
|
|
outp(cv.IOadr+4,0);
|
|
{ outp(cv.IOadr,4);
|
|
checkmem(16); }
|
|
cv.mm:=1024;
|
|
case cardid of
|
|
$8FDA:cv.Version:=XGA_NI;
|
|
$8FDB:cv.Version:=XGA_org;
|
|
end;
|
|
|
|
cv.Xseg:=(temp0 shr 4)*$2000+$C1C0+(temp0 and $E)*4;
|
|
cv.Phadr:=((temp2 and $FE)*word(8)+(temp0 and $E))*longint($200000);
|
|
addvideo;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure _yamaha;
|
|
begin
|
|
if testinx2(crtc,$7C,$7C) then
|
|
begin
|
|
cv.Version:=YA_6388;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
|
|
procedure _xbe;
|
|
var
|
|
x:word;
|
|
xbe0:_xbe0;
|
|
xbe1:_xbe1;
|
|
|
|
begin
|
|
viop($4E00,0,0,0,@xbe0);
|
|
if (rp.ax=$4E) and (xbe0.sign=$41534556) then
|
|
begin
|
|
for x:=0 to xbe0.xgas-1 do
|
|
begin
|
|
viop($4E01,0,0,x,@xbe1);
|
|
if (rp.ax=$4E) then
|
|
begin
|
|
cv.chip:=__xbe;
|
|
cv.features:=ft_blit+ft_line;
|
|
cv.mm:=xbe1.memory*longint(64);
|
|
cv.id:=x;
|
|
cv.IOadr :=xbe1.iobase;
|
|
cv.Xseg :=xbe1.memreg shr 16;
|
|
cv.Phadr :=xbe1.vidadr;
|
|
cv.name :=gtstr(xbe1.oemadr^);
|
|
UNK(VS_XBE,xbe0.vers);
|
|
addvideo;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure _vesa;
|
|
var
|
|
vesarec:_vbe0;
|
|
x:word;
|
|
begin
|
|
viop($4f00,0,0,0,@vesarec);
|
|
if (rp.ax=$4f) and (vesarec.sign=$41534556) then
|
|
begin
|
|
cv.chip:=__vesa;
|
|
cv.mm:=vesarec.mem*longint(64);
|
|
cv.name:=gtstr(vesarec.oemadr^);
|
|
UNK(VS_VBE,vesarec.vers);
|
|
cv.dactype:=_dac8; {Dummy, to keep Cirrus 542x out of trouble}
|
|
addvideo;
|
|
end;
|
|
end;
|
|
|
|
|
|
type
|
|
pel=record
|
|
index,red,green,blue:byte;
|
|
end;
|
|
|
|
procedure readpelreg(index:word;var p:pel);
|
|
begin
|
|
p.index:=index;
|
|
disable;
|
|
outp($3C7,index);
|
|
p.red :=inp($3C9);
|
|
p.blue :=inp($3C9);
|
|
p.green:=inp($3C9);
|
|
enable;
|
|
end;
|
|
|
|
procedure writepelreg(var p:pel);
|
|
begin
|
|
disable;
|
|
outp($3C8,p.index);
|
|
outp($3C9,p.red);
|
|
outp($3C9,p.blue);
|
|
outp($3C9,p.green);
|
|
enable;
|
|
end;
|
|
|
|
function setcomm(cmd:word):word;
|
|
begin
|
|
dac2comm;
|
|
outp($3c6,cmd);
|
|
dac2comm;
|
|
setcomm:=inp($3c6);
|
|
end;
|
|
|
|
function dacis8bit:boolean;
|
|
var
|
|
pel2,x,y,z,v:word;
|
|
pel1:pel;
|
|
begin
|
|
pel2:=inp($3C8);
|
|
readpelreg(255,pel1);
|
|
v:=pel1.red;
|
|
pel1.red:=255;
|
|
writepelreg(pel1);
|
|
readpelreg(255,pel1);
|
|
x:=pel1.red;
|
|
pel1.red:=v;
|
|
writepelreg(pel1);
|
|
outp($3C8,pel2);
|
|
dacis8bit:=(x=255);
|
|
end;
|
|
|
|
procedure testdac; {Test for type of DAC}
|
|
var
|
|
x,y,z,v,oldcomm,oldpel,notcomm:word;
|
|
dac8,dac8now:boolean;
|
|
data:array[9..12] of byte;
|
|
|
|
procedure waitforretrace;
|
|
begin
|
|
repeat until (inp(CRTC+6) and 8)=0;
|
|
repeat until (inp(CRTC+6) and 8)>0; {Wait until we're in retrace}
|
|
end;
|
|
|
|
procedure SetDACCmd(cmd:integer);
|
|
begin
|
|
dac2comm;
|
|
outp($3C6,cmd);
|
|
dac2pel;
|
|
end;
|
|
|
|
|
|
function testdacbit(bit:word):boolean;
|
|
var v:word;
|
|
begin
|
|
dac2pel;
|
|
outp($3C6,oldpel and (bit xor $FF));
|
|
dac2comm;
|
|
disable;
|
|
outp($3C6,oldcomm or bit);
|
|
dac2comm;
|
|
v:=inp($3C6);
|
|
outp($3C6,v and (bit xor $FF));
|
|
enable;
|
|
testdacbit:=(v and bit)<>0;
|
|
end;
|
|
|
|
function rdSCdac(Inx:word):word;
|
|
begin
|
|
dac2comm;
|
|
outp($3C6,inp($3C6) or $10);
|
|
rdSCdac:=rdinx($3C7,inx);
|
|
dac2comm;
|
|
outp($3C6,inp($3C6) and $EF);
|
|
dac2pel;
|
|
end;
|
|
|
|
procedure wrBTinx(inx,val:word);
|
|
var x:word;
|
|
begin
|
|
dac2comm;
|
|
x:=daccomm;
|
|
outp($3C6,1);
|
|
{ dac2pel;}
|
|
outp($3C8,Inx);
|
|
outp($3C6,val);
|
|
dac2comm;
|
|
outp($3C6,x and $FE);
|
|
dac2pel;
|
|
end;
|
|
|
|
function rdBTinx(Inx:word):word;
|
|
var x:word;
|
|
begin
|
|
dac2comm;
|
|
x:=daccomm;
|
|
outp($3C6,1);
|
|
{ dac2pel;}
|
|
outp($3C8,Inx);
|
|
rdBTinx:=inp($3C6);
|
|
dac2comm;
|
|
outp($3C6,x and $FE);
|
|
dac2pel;
|
|
end;
|
|
|
|
|
|
var zz:integer;
|
|
t:text;
|
|
begin
|
|
setDAC(_dac8,'Normal');
|
|
dac2comm;
|
|
oldcomm:=inp($3c6);
|
|
dac2pel;
|
|
oldpel:=inp($3c6);
|
|
|
|
if cv.dactype=_dac8 then
|
|
begin
|
|
dac2comm;
|
|
outp($3C6,0);
|
|
dac8:=dacis8bit;
|
|
dac2pel;
|
|
|
|
notcomm:=oldcomm xor 255;
|
|
outp($3C6,notcomm);
|
|
dac2comm;
|
|
v:=inp($3C6);
|
|
if v<>notcomm then {We have a "Hidden Command" register}
|
|
begin
|
|
dac2pel;
|
|
dac2comm;
|
|
x:=inp($3C6);
|
|
x:=inp($3C6);
|
|
y:=inp($3C6);
|
|
z:=inp($3C6);
|
|
dac2pel;
|
|
if (x=$84) and (y=$98) then
|
|
begin
|
|
if z=$4F then setDAC(_dacICW516,'IC Works W30c516')
|
|
else if setcomm($A)=0 then setDAC(_dacATT2498,'ATT 22c498')
|
|
else setDAC(_dacATT1498,'ATT 21c498');
|
|
end
|
|
else begin
|
|
setDACcmd($10);
|
|
if rdinx($3C7,9)=$53 then
|
|
begin
|
|
x:=rdinx($3C7,10);
|
|
x:=x*256+rdinx($3C7,11);
|
|
case x of {Looks like the 15021 & 25 are the only values}
|
|
15021:setDAC(_dacSC15021,'SC15021');
|
|
15025:setDAC(_dacSC15025,'SC15025');
|
|
else setDAC(_dacSC15021,'Unknown SC 15xxx');
|
|
end;
|
|
end;
|
|
setDACcmd(oldcomm);
|
|
end;
|
|
if cv.dactype=_dac8 then
|
|
begin
|
|
setDACcmd($10);
|
|
dac2comm;
|
|
x:=inp($3C6);
|
|
outp($3C6,0);
|
|
outp($3C6,0);
|
|
if inp($3C6)=$44 then
|
|
case inp($3C6) of
|
|
0:setDAC(_dacSTG1700,'STG1700');
|
|
2:setDAC(_dacSTG1702,'STG1702');
|
|
3:begin
|
|
setDAC(_dacSTG1703,'STG1703');
|
|
cv.clktype:=clk_STG;
|
|
end;
|
|
else setDAC(_dacSTG1700,'Unknown STG');
|
|
end;
|
|
setDACcmd(oldcomm);
|
|
end;
|
|
if cv.dactype=_dac8 then
|
|
begin
|
|
dac2pel;
|
|
x:=inp($3C6);
|
|
x:=inp($3C6);
|
|
x:=inp($3C6);
|
|
x:=inp($3C6);
|
|
if (x and $F0)=$70 then
|
|
begin
|
|
setDAC(_dacS3_716,'S3 86c716 (SDAC)');
|
|
cv.clktype:=clk_sdac;
|
|
end;
|
|
dac2pel;
|
|
end;
|
|
if cv.dactype=_dac8 then
|
|
begin
|
|
dac2comm;
|
|
if daccomm=$31 then setDAC(_dacALG1301,'ALG1301');
|
|
dac2pel;
|
|
end;
|
|
if cv.dactype=_dac8 then
|
|
if (setcomm($E0) and $E0)<>$E0 then
|
|
begin
|
|
dac2pel;
|
|
x:=inp($3C6);
|
|
repeat
|
|
y:=x; {wait for the same value twice}
|
|
x:=inp($3C6);
|
|
until (x=y);
|
|
z:=x;
|
|
dac2comm;
|
|
if daccomm<>$8E then
|
|
begin {If command register=$8e, we've got an SS24}
|
|
y:=8;
|
|
repeat
|
|
x:=inp($3C6);
|
|
dec(y);
|
|
until (x=$8E) or (y=0);
|
|
end
|
|
else x:=daccomm;
|
|
if x=$8e then setDAC(_dacMU1880,'SS24')
|
|
else setDAC(_dacSC486,'Sierra SC11486');
|
|
dac2pel;
|
|
end
|
|
else begin
|
|
if (setcomm($60) and $E0)=0 then
|
|
begin
|
|
if (setcomm(2) and 2)>0 then setDAC(_dacATT490,'ATT 20c490')
|
|
else setDAC(_dacATT493,'ATT 20c493');
|
|
end
|
|
else begin {Bit 5-7 fully r/w}
|
|
dac2pel;
|
|
outp($3C6,notcomm); {PEL register}
|
|
x:=setcomm(oldcomm);
|
|
if inp($3C6)=notcomm then {Falls back to PEL register}
|
|
begin {after 1st read}
|
|
x:=setcomm($FC);
|
|
if x<>$FC then
|
|
case x of
|
|
$E2:setDAC(_dacALG1201,'ALG1201');
|
|
$E0:setDAC(_dacICS5301,'ICS 5301');
|
|
$F4:setDAC(_dacS3_708,'S3/ICS 86c708 GenDAC');
|
|
else
|
|
if testdacbit($F0) then setDAC(_dacUMC188,'UMC UM70c188')
|
|
else setDAC(_dacADAC1,'Acumos ADAC1');
|
|
end
|
|
else begin {All 8 bits fully r/w}
|
|
dac8now:=dacis8bit;
|
|
dac2comm;
|
|
outp($3C6,(oldcomm or 2) and $FE);
|
|
dac8now:=dacis8bit;
|
|
if dac8now then
|
|
begin
|
|
if dacis8bit then
|
|
begin
|
|
x:=setcomm(oldcomm or $10);
|
|
dac2comm;
|
|
x:=inp($3C6);
|
|
outp($3C6,1);
|
|
x:=x; {delay}
|
|
outp($3C6,0);
|
|
if inp($3C6)=0 then setDAC(_dacATT491,'ATT 20c491')
|
|
end
|
|
end
|
|
{ else setDAC(_dacCL24,'Cirrus 24bit DAC')}
|
|
else
|
|
if trigdac=$B3 then
|
|
begin
|
|
setDAC(_dacCH8391,'CHRONTEL CH8391');
|
|
cv.clktype:=clk_CHRON;
|
|
end
|
|
else setDAC(_dacATT492,'ATT 20c492');
|
|
end;
|
|
end
|
|
else begin
|
|
{if trigdac=notcomm then setDAC(_dacCL24,'Cirrus 24bit DAC')
|
|
else} begin
|
|
dac2pel;
|
|
outp($3C6,$FF);
|
|
case trigdac of
|
|
$44:begin
|
|
setDAC(_dacMU9910,'MUSIC MU9C9910');
|
|
cv.clktype:=CLK_MUSIC;
|
|
end;
|
|
$82:setDAC(_dacMU4910,'MUSIC MU9C4910');
|
|
$8E:setDAC(_dacMU1880,'MUSIC MU9C1880 (SS2410)');
|
|
else begin
|
|
if setcomm(1)=$AA then setDAC(_dacALG1201,'ALG1201')
|
|
else begin
|
|
dac2comm;
|
|
if daccomm=$C0 then
|
|
begin
|
|
setDAC(_dacCH8398,'CH8398');
|
|
cv.clktype:=clk_CHRON;
|
|
end
|
|
else
|
|
if testdacbit($10) then
|
|
begin
|
|
outp($3C8,2);
|
|
SetDACcmd(oldcomm or 2);
|
|
dac8now:=dacis8bit;
|
|
SetDACcmd(oldcomm and $FD);
|
|
if dac8now then {The Bt481 ends here too}
|
|
begin
|
|
outp($3C8,0);
|
|
SetDACcmd(oldcomm or 2);
|
|
dac8now:=dacis8bit;
|
|
SetDACcmd(oldcomm and $FD);
|
|
if dac8now then setDAC(_dacTR8001,'Trident TKD8001')
|
|
else setDAC(_dacBt481,'Bt481');
|
|
end
|
|
else setDAC(_dac16,'OAK 66HC');
|
|
end
|
|
else begin
|
|
dac2pel;
|
|
outp($3C6,$FF);
|
|
dac2comm;
|
|
outp($3C6,0);
|
|
dac2pel;
|
|
dac2comm;
|
|
outp($3C6,$7F);
|
|
dac2comm;
|
|
x:=inp($3C6);
|
|
dac2comm;
|
|
dac2comm;
|
|
outp($3C6,$FF);
|
|
dac2comm;
|
|
v:=inp($3C6);
|
|
dac2comm;
|
|
outp($3C6,oldcomm);
|
|
dac2pel;
|
|
if (x=$60) and (v=$E0) then setDAC(_dac16,'UMC 70c178')
|
|
else if (x=$7F) and (v=$FE) then setDAC(_dac16,'Sierra SC11487')
|
|
else setDAC(_dac15,'Sierra Sc11483');
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
dac2comm;
|
|
outp($3c6,oldcomm);
|
|
end;
|
|
dac2pel;
|
|
outp($3c6,oldpel);
|
|
|
|
end;
|
|
|
|
if (cv.dactype=_dac8) then
|
|
begin
|
|
oldpel :=rdDACreg(dacSTDpelMask) xor $FF;
|
|
oldcomm:=rdDACreg(dacSTDpelMask+4);
|
|
x :=rdDACreg(dacSTDpelMask+8);
|
|
wrDACreg(dacSTDpelMask,oldpel);
|
|
y :=rdDACreg(dacSTDpelMask+4);
|
|
z :=rdDACreg(dacSTDpelMask+8);
|
|
zz:=rdDACreg(dacSTDpelMask);
|
|
if (zz=oldpel) and (y<>oldpel) or (z<>oldpel) then
|
|
begin { Either RS2 or RS3 finds a register <> $3C6,
|
|
We have an advanced DAC and access to it! }
|
|
wrDACreg(dacSTDpelMask,0);
|
|
wrDACreg(dacTLCtest,3);
|
|
case rdDACreg(dacTLCtest) of
|
|
$75:setDAC(_dacTLC34075,'TLC34075');
|
|
$76:setDAC(_dacTLC34076,'TLC34076');
|
|
else
|
|
if cv.chip=__S3 then
|
|
begin
|
|
outpw(crtc,$A539);
|
|
y:=rdinx(crtc,$5C); {Force TI mode}
|
|
clrinx(crtc,$5C,$20);
|
|
wrDACreg(dacTVPindex,6);
|
|
z:=rdDACreg(dacTVPdata);
|
|
wrDACreg(dacTVPdata,z and $7F);
|
|
end;
|
|
x:=rdDACreg(dacTVPindex);
|
|
wrDACreg(dacTVPindex,$3F);
|
|
y:=rdDACreg(dacTVPdata);
|
|
wrDACreg(dacTVPdata,y xor $FF);
|
|
z:=rdDACreg(dacTVPdata);
|
|
if z<>y then {Must be read-only for TVP}
|
|
wrDACreg(dacTVPdata,y)
|
|
else
|
|
case y of
|
|
$10:setDAC(_dacTVP3010,'TVP 3010');
|
|
$20:setDAC(_dacTVP3020,'TVP 3020');
|
|
$25:begin
|
|
setDAC(_dacTVP3025,'TVP 3025');
|
|
cv.clktype:=clk_TVP302x;
|
|
end;
|
|
end;
|
|
wrDACreg(dacTVPindex,x);
|
|
if cv.dactype=_dac8 then
|
|
begin
|
|
x:=rdDACreg(dacTVP6index);
|
|
wrDACreg(dacTVP6index,$3F);
|
|
y:=rdDACreg(dacTVP6data);
|
|
wrDACreg(dacTVP6data,y xor $FF);
|
|
z:=rdDACreg(dacTVP6data);
|
|
if z<>y then {Must be read-only for TVP}
|
|
wrDACreg(dacTVP6data,y)
|
|
else
|
|
case y of
|
|
$26:begin
|
|
setDAC(_dacTVP3026,'TVP 3026');
|
|
cv.clktype:=clk_TVP302x;
|
|
end;
|
|
end;
|
|
wrDACreg(dacTVP6index,x);
|
|
end;
|
|
if cv.chip=__S3 then
|
|
begin
|
|
wrDACreg(dacTVPindex,6);
|
|
wrDACreg(dacTVPdata,z);
|
|
outpw(crtc,$A539);
|
|
wrinx(crtc,$5C,y);
|
|
end;
|
|
if (cv.dactype=_dac8) then
|
|
begin
|
|
x:=rdDACreg(dacHIcmd);
|
|
wrDACreg(dacHIcmd,x and $FE);
|
|
y:=rdDACreg(dacSTDpelMask);
|
|
wrDACreg(dacHIcmd,x or 1); {Switch to Bt481 Indexed}
|
|
wrDACreg(dacSTDwrInx,dacBTIipixm);
|
|
wrDACreg(dacSTDpelMask,y xor $55);
|
|
z:=rdDACreg(dacSTDpelMask);
|
|
wrDACreg(dacSTDwrInx,dacBTIcurX);
|
|
wrDACreg(dacSTDpelMask,y xor $AA);
|
|
v:=rdDACreg(dacSTDpelMask);
|
|
wrDACreg(dacSTDwrInx,dacBTIipixm);
|
|
zz:=rdDACreg(dacSTDpelMask);
|
|
wrDACreg(dacHIcmd,x and $FE); {Back to std regs}
|
|
if (y=rdDACreg(dacSTDpelMask)) and (z=(y xor $55)) then
|
|
begin
|
|
if v=(y xor $AA) then setDAC(_dacBt481,'Bt482')
|
|
else setDAC(_dacBt482,'Bt481');
|
|
end
|
|
else begin
|
|
x:=rdDACreg(dacIBMind0);
|
|
wrDACreg(dacIBMind1,0);
|
|
wrDACreg(dacIBMind0,dacIBMiRev);
|
|
y:=rdDACreg(dacIBMdata);
|
|
wrDACreg(dacIBMind0,dacIBMiId);
|
|
y:=y+256*rdDACreg(dacIBMdata);
|
|
if (y>$FF) and (y<$2FF) then {Range ??}
|
|
begin
|
|
wrDACreg(dacIBMind0,dacIBMiRev);
|
|
wrDACreg(dacIBMdata,y xor $FF);
|
|
wrDACreg(dacIBMind0,dacIBMiId);
|
|
wrDACreg(dacIBMdata,hi(y) xor $FF);
|
|
wrDACreg(dacIBMind0,dacIBMiRev);
|
|
z:=rdDACreg(dacIBMdata);
|
|
wrDACreg(dacIBMind0,dacIBMiId);
|
|
z:=z+256*rdDACreg(dacIBMdata);
|
|
if (y=z) then
|
|
begin
|
|
case y of
|
|
$2F0:SetDAC(_dacIBM524,'IBM RGB524');
|
|
else SetDAC(_dacIBM524,'Unknown IBM RGB');
|
|
end;
|
|
cv.clktype:=clk_IBM52x;
|
|
end
|
|
else begin
|
|
wrDACreg(dacIBMind0,dacIBMiRev);
|
|
wrDACreg(dacIBMdata,y);
|
|
wrDACreg(dacIBMind0,dacIBMiId);
|
|
wrDACreg(dacIBMdata,hi(y));
|
|
end;
|
|
end
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if cv.dactype=_dac8 then
|
|
begin
|
|
wrDACreg(dacSTDwrInx,0); {Force the Bt485 status register}
|
|
wrDACreg(dacBTcmd0,rdDACreg(dacBTcmd0) and $7F);
|
|
x:=rdDACreg(dacBTstat);
|
|
case x and $F0 of
|
|
$40:setDAC(_dacATT504,'AT&T20c504');
|
|
$D0:setDAC(_dacATT505,'AT&T20c505');
|
|
$80..$B0:begin
|
|
y:=rdDACreg(dacBTcmd0);
|
|
wrDACreg(dacBTcmd0,y or $80); {Enable STat/Cmd3}
|
|
wrDACreg(dacSTDwrInx,1); {Force the cmd3 reg}
|
|
z:=rdDACreg(dacBTstat);
|
|
if z=x then
|
|
begin
|
|
wrDACreg(dacBTstat,x xor $55);
|
|
wrDACreg(dacSTDwrInx,0); {Force the stat reg}
|
|
v:=rdDACreg(dacBTstat);
|
|
wrDACreg(dacSTDwrInx,1); {Force the stat reg}
|
|
wrDACreg(dacBTstat,z);
|
|
if v=x then z:=x+1; {Ie. Bt485}
|
|
end;
|
|
wrDACreg(dacBTcmd0,y);
|
|
if x=z then setDAC(_dacBT484,'Bt484')
|
|
else setDAC(_dacBT485,'Bt485');
|
|
end;
|
|
else
|
|
x:=rdDACreg(0);
|
|
y:=rdDACreg(4);
|
|
wrDACreg(0,x XOR $FF);
|
|
if rdDACreg(4)<>y then setDAC(_dacBT477,'Bt477');
|
|
{else setDAC(_dacIBM525,'IBM RGB525')}
|
|
|
|
end;
|
|
end;
|
|
end;
|
|
wrDACreg(dacSTDpelMask,oldpel);
|
|
end;
|
|
clearDACpage;
|
|
|
|
|
|
|
|
if cv.dactype=_dac8 then
|
|
begin
|
|
WaitforRetrace;
|
|
outp($3C8,222);
|
|
outp($3C9,$43);
|
|
outp($3C9,$45);
|
|
outp($3C9,$47); {Write 'CEGEDSUN' + mode to DAC index 222}
|
|
outp($3C8,222);
|
|
outp($3C9,$45);
|
|
outp($3C9,$44);
|
|
outp($3C9,$53);
|
|
outp($3C8,222);
|
|
outp($3C9,$55);
|
|
outp($3C9,$4E);
|
|
outp($3C9,13); {Should be in CEG mode now}
|
|
outp($3C6,255);
|
|
x:=(inp($3c6) shr 4) and 7;
|
|
if x<7 then
|
|
begin
|
|
setDAC(_dacCEG,'Edsun CEG rev. '+chr(x+48));
|
|
WaitforRetrace;
|
|
outp($3C8,223);
|
|
outp($3C9,0); {Back in normal dac mode}
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure findbios; {Finds the most likely BIOS segment}
|
|
var
|
|
score:array[0..7] of byte;
|
|
x,y:word;
|
|
begin
|
|
biosseg:=$c000;
|
|
for x:=0 to 6 do score[x]:=1;
|
|
for x:=0 to 7 do
|
|
begin
|
|
rp.bh:=x;
|
|
vio($1130);
|
|
if (rp.es>=$c000) and ((rp.es and $7ff)=0) then
|
|
inc(score[(rp.es-$c000) shr 11]);
|
|
end;
|
|
|
|
for x:=0 to 6 do
|
|
begin
|
|
y:=$c000+(x shl 11);
|
|
if (memw[y:0]<>$aa55) or (mem[y:2]<48) then
|
|
score[x]:=0; {fail if no rom}
|
|
end;
|
|
for x:=6 downto 0 do
|
|
if score[x]>0 then
|
|
biosseg:=$c000+(x shl 11);
|
|
end;
|
|
|
|
type
|
|
fnctyp=procedure;
|
|
|
|
const
|
|
chps=30;
|
|
chptype:array[1..chps] of byte=(__chips,__WD,__Video7
|
|
,__Everex,__Trid,__ati,__Ahead,__NCR,__S3,__ALG,__ARK
|
|
,__Cir54,__Cir64,__MXIC,__UMC,__Genoa,__Weitek,__SIS
|
|
,__Tseng,__Realtek,__P2000,__Acer,__SC,__Alli
|
|
,__Yamaha ,__Matrox,__Oak,__Cirrus,__Compaq,__HMC);
|
|
|
|
(* Known test ordering requirements:
|
|
|
|
UMC before Genoa, otherwise the UMC will be ID'd as Genoa 6400
|
|
C&T before HMC, as HMC test disturbs C&T
|
|
MXIC before Tseng, as Tseng test disturbs MXIC
|
|
SiS before Tseng, as the SiS will be ID'd as a Tseng
|
|
*)
|
|
|
|
|
|
procedure findvideo;
|
|
var old,chp,vid1:word;
|
|
|
|
begin
|
|
vids:=0;
|
|
cv.dactype:=_dac0;
|
|
cv.features:=0;
|
|
cv.flags:=0;
|
|
if odd(inp($3CC)) then CRTC:=$3D4 else CRTC:=$3B4;
|
|
if dotest[__VESA] then _vesa;
|
|
if dotest[__XBE] then _xbe;
|
|
if dotest[__XGA] then _XGA;
|
|
_Imagine;
|
|
|
|
_crt:='';
|
|
cv.chip:=__none;
|
|
secondary:='';
|
|
cv.name:='';
|
|
video:='none';
|
|
rp.bx:=$1010;
|
|
vio($1200);
|
|
if rp.bh<=1 then
|
|
begin
|
|
video:='EGA';
|
|
cv.chip:=__ega;
|
|
|
|
cv.mm:=rp.bl;
|
|
vio($1a00);
|
|
if rp.al=$1a then
|
|
begin
|
|
if (rp.bl<4) and (rp.bh>3) then
|
|
begin
|
|
old:=rp.bl;
|
|
rp.bl:=rp.bh;
|
|
rp.bh:=old;
|
|
end;
|
|
video:='MCGA';
|
|
case rp.bl of
|
|
2,4,6,10:_crt:='TTL Color';
|
|
1,5,7,11:_crt:='Monochrome';
|
|
8,12:_crt:='Analog Color';
|
|
end;
|
|
case rp.bh of
|
|
1:secondary:='Monochrome';
|
|
2:secondary:='CGA';
|
|
end;
|
|
findbios;
|
|
if (getbios($31,9)='') and (getbios($40,2)='22') then
|
|
begin
|
|
video:='EGA'; {@#%@ lying ATI EGA Wonder !}
|
|
cv.name:='ATI EGA Wonder';
|
|
addvideo;
|
|
end else
|
|
if (rp.bl<10) or (rp.bl>12) then
|
|
begin
|
|
_MediaVis;
|
|
chp:=0;vid1:=vids;
|
|
while (vids=vid1) and (chp<chps) do
|
|
begin
|
|
inc(chp);
|
|
|
|
video:='VGA';
|
|
cv.chip:=__vga;
|
|
cv.mm:=256;
|
|
cv.features:=0;
|
|
cv.dactype:=_dac0;
|
|
cv.version:=0;
|
|
cv.subvers:=0;
|
|
cv.clktype:=clk_ext2;
|
|
cv.flags:=FLG_StdVGA;
|
|
if debug then
|
|
begin
|
|
writeln('Testing: '+header[chptype[chp]]);
|
|
if readkey='' then;
|
|
end;
|
|
if dotest[chptype[chp]] then
|
|
case chptype[chp] of
|
|
__Acer:_Acer;
|
|
__Ahead:_Ahead;
|
|
__ALG:_ALG;
|
|
__Alli:_Alliance;
|
|
__ARK:_ARK;
|
|
__ati:_Ati;
|
|
__chips:_chipstech;
|
|
__Cir54:_Cirrus54;
|
|
__Cir64:_Cirrus64;
|
|
__Cirrus:_Cirrus;
|
|
__Compaq:_Compaq;
|
|
__Everex:_Everex;
|
|
__Genoa:_Genoa;
|
|
__HMC:_HMC;
|
|
__MXIC:_MXIC;
|
|
__NCR:_NCR;
|
|
__Oak:_Oak;
|
|
__P2000:_P2000;
|
|
__WD:_paradise;
|
|
__Realtek:_Realtek;
|
|
__S3:_S3;
|
|
__SC:_Sierra;
|
|
__SiS:_SiS;
|
|
__Trid:_Trident;
|
|
__Tseng:_Tseng;
|
|
__UMC:_UMC;
|
|
__Video7:_Video7;
|
|
__Weitek:_weitek;
|
|
__Yamaha:_Yamaha;
|
|
__Matrox:_matrox;
|
|
end;
|
|
end;
|
|
if vids=vid1 then
|
|
begin
|
|
if force_chip<>__none then cv.chip:=force_chip;
|
|
addvideo;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
end.
|