home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / VGADOC4B.ZIP / IDVGA.PAS < prev    next >
Pascal/Delphi Source File  |  1995-09-29  |  135KB  |  4,469 lines

  1. unit idvga;
  2. interface
  3. procedure DumpRegisters;
  4.  
  5. procedure AnalyseMode;
  6.  
  7. procedure CalcRegisters;
  8.  
  9. function dumpVGAregs:word;
  10.  
  11. procedure dumpVGAregfile;
  12.  
  13. procedure loadmodes;
  14.  
  15. function FormatRgs(var b:byte):word;   {Format registers for dump}
  16.  
  17.   {Weitek W5x86 Enable function
  18.    Sets the Extention & Bank enable flags in SEQ index $11}
  19. function WeitekEnable(flag:word):word;
  20.  
  21.   {Check for PCI devices}
  22. procedure findPCI;
  23.  
  24.  {Checks for a PCI card with ID=sign, returns index in PCIrec, 0 if not found
  25.   start is the PCI device to start at (0 first time, last ID next time)}
  26. function CheckPCI(start,vendor,device:word):integer;
  27.  
  28. procedure findvideo;
  29.  
  30. procedure testdac;
  31.  
  32. function dacis8bit:boolean;
  33.  
  34. function DACflags:word;
  35.  
  36. procedure wPCIbyte(index,val:word);
  37. procedure wPCIword(index,val:word);
  38. procedure wPCIlong(index:word;val:longint);
  39. function rPCIbyte(index:word):word;
  40. function rPCIword(index:word):word;
  41. function rPCIlong(index:word):longint;
  42.  
  43.  
  44.  
  45. const
  46.   PCIdevs:word=0;       {Number of PCI video devices}
  47. var
  48.   PCItype:word;
  49.   PCIrec:array[1..10] of record
  50.            PCIbase:word;
  51.            case integer of
  52.              0:(l:array[0..63] of longint);
  53.              1:(vendor,device,command,status:word;
  54.                 rev,prog:byte;class:word;
  55.                 cache,latency,header,bist:byte;
  56.                 base0,base1,base2,base3,base4,base5
  57.                      ,xx0,xx1,rom,xx2,xx3:longint;
  58.                 iline,ipin,mingnt,maxlat:byte);
  59.          end;
  60.  
  61.  
  62. {$i idvga2.pas}   {Holds all the Chipset, mode etc definitions.}
  63.  
  64.  
  65. function DACflags:word;
  66. var flag:word;
  67. begin
  68.   flag:=0;
  69.   case cv.dactype of
  70.   _dac0,_dac8,_dacCEG:;
  71.  
  72.   _dacInt:;
  73.   _dac15,_dac16,_dacADAC1,_dacSC486,_dacUMC188:
  74.        flag:=DFL_CmdReg;
  75.  
  76.   _dacALG1101:;
  77.   _dacALG1201,_dacALG1301:
  78.        flag:=DFL_CmdReg;
  79.  
  80.   _dacATI68860,_dacATI68880:
  81.        flag:=DFL_8bit;
  82.  
  83.   _dacATT490,_dacATT491:
  84.        flag:=DFL_CmdReg+DFL_8bit;
  85.   _dacATT492,_dacATT493:
  86.        flag:=DFL_CmdReg;
  87.   _dacATT498,_dacATT1498,_dacATT2498:
  88.        flag:=DFL_CmdReg+DFL_8bit;
  89.  
  90.   _dacBt477:
  91.        flag:=DFL_8bit;
  92.   _dacBt481,_dacBt482:
  93.        flag:=DFL_CmdReg+DFL_8bit+DFL_cursor;
  94.   _dacBt484,_dacBt485,_dacATT504,_dacATT505:
  95.        flag:=DFL_8bit+DFL_cursor;
  96.  
  97.   _dacCH8391,
  98.   _dacCH8398:
  99.        flag:=DFL_CmdReg+DFL_8bit+DFL_Clock;
  100.  
  101.   _dacCL5200:
  102.        flag:=DFL_CmdReg;
  103.  
  104.   _dacIBM514,_dacIBM524,_dacIBM525,_dacIBM528:
  105.        flag:=DFL_cursor+DFL_8bit+DFL_Clock;
  106.  
  107.   _dacICS5301:
  108.        flag:=DFL_CmdReg;
  109.  
  110.   _dacICW498,_dacICW516:
  111.        flag:=DFL_CmdReg+DFL_8bit;
  112.  
  113.   _dacMU1880,_dacMU4870:
  114.        flag:=DFL_CmdReg;
  115.   _dacMU4910:
  116.        flag:=DFL_CmdReg+DFL_8bit;
  117.   _dacMU9910:
  118.        flag:=DFL_CmdReg+DFL_8bit+DFL_Clock;
  119.  
  120.   _dacS3_716,_dacS3_708:
  121.        flag:=DFL_CmdReg+DFL_8bit+DFL_Clock;
  122.   _dacSC15021,_dacSC15025:
  123.        flag:=DFL_CmdReg+DFL_8bit;
  124.   _dacSTG1700,_dacSTG1702:
  125.        flag:=DFL_CmdReg+DFL_8bit;
  126.   _dacSTG1703:
  127.        flag:=DFL_CmdReg+DFL_8bit+DFL_Clock;
  128.   _dacTLC34075,_dacTLC34076:
  129.        flag:=DFL_8bit;    {8bit DACs from input pin}
  130.   _dacTR8001:
  131.        flag:=DFL_CmdReg+DFL_8bit;
  132.   _dacTVP3010,_dacTVP3020:
  133.        flag:=DFL_8bit+DFL_Cursor;
  134.   _dacTVP3025,_dacTVP3026:
  135.        flag:=DFL_8bit+DFL_Cursor+DFL_Clock;
  136.   end;
  137.   DACflags:=flag;
  138. end;
  139.  
  140. procedure loadmodes;              {Load extended modes for this chip}
  141. var
  142.   t:text;
  143.   s,pat:string;
  144.   md,x,xres,yres,err,mreq,byt:word;
  145.   vbe0:_vbe0;
  146.   vbe1:_vbe1;
  147.   xbe1:_xbe1;
  148.   xbe2:_xbe2;
  149.   ok:boolean;
  150.  
  151. function VESAmemmode(model,bits,redinf,grninf,bluinf,resinf:word):integer;
  152. const
  153.   mode6s=8;
  154.   mode:array[1..mode6s] of byte=(
  155.        _p15,_p16,_p24 ,_p24b,_p32 ,_p32b,_p32c,_p32d);
  156.   blui:array[1..mode6s] of word =(
  157.           5,   5,    8,$1008,    8,$1008, $808,$1808);
  158.   grni:array[1..mode6s] of word =(
  159.        $505,$506, $808, $808, $808, $808,$1008,$1008);
  160.   redi:array[1..mode6s] of word =(
  161.        $A05,$B05,$1008,    8,$1008,    8,$1808, $808);
  162.   resi:array[1..mode6s] of word =(
  163.        $F01,   0,    0,    0,$1808,$1808,    8,    8);
  164. var x:word;
  165. begin
  166.   VESAmemmode:=_text;  {catch weird modes}
  167.   if (bits=15) and (resinf=0) then resinf:=$F01;   {Bloody ATI Vesa driver @#$}
  168.   if (bits=15) and (bluinf=5) and (grninf=$405) then grninf:=$505;
  169.                                                    {@#$ Mach64 VESA driver}
  170.   case model of
  171.     0:VESAmemmode:=_text;
  172.     1:case bits of
  173.         1:VESAmemmode:=_cga1;
  174.         2:VESAmemmode:=_cga2;
  175.       end;
  176.     2:VESAmemmode:=_herc;
  177.     3:case bits of
  178.         2:VESAmemmode:=_pl2;
  179.         4:VESAmemmode:=_pl4;
  180.       end;
  181.     4:case bits of
  182.         4:VESAmemmode:=_pk4;
  183.         8:VESAmemmode:=_p8;
  184.        15:VESAmemmode:=_p15;
  185.        16:VESAmemmode:=_p16;
  186.        24:VESAmemmode:=_p24;
  187.       end;
  188.     5:; {YUV coding}
  189.     6:for x:=1 to mode6s do
  190.       if (redinf=redi[x]) and (grninf=grni[x]) and (bluinf=blui[x])
  191.         and (resinf=resi[x]) then VESAmemmode:=mode[x];
  192.     7:;
  193.   end;
  194. end;
  195.  
  196.  
  197. procedure addmode(md,xres,yres,bytes:word;memmode:integer);
  198. begin
  199.   inc(nomodes);
  200.   modetbl[nomodes].md     :=md;
  201.   modetbl[nomodes].xres   :=xres;
  202.   modetbl[nomodes].yres   :=yres;
  203.   modetbl[nomodes].bytes  :=bytes;
  204.   modetbl[nomodes].memmode:=memmode;
  205.   modetbl[nomodes].flags  :=MFL_enabled;
  206.   if memmode>=_PL4 then
  207.     modetbl[nomodes].flags:=modetbl[nomodes].flags OR MFL_graphics;
  208. end;
  209.  
  210. begin
  211.   nomodes:=0;
  212.  
  213.   if (cv.flags and FLG_StdVGA)>0 then
  214.   begin
  215.     move(stdmodetbl,modetbl,novgamodes*sizeof(modetype));
  216.     nomodes:=novgamodes;
  217.   end;
  218.  
  219.   case cv.chip of
  220.    __vesa:begin
  221.             vbe0.sign:=$41534556;    (* VESA *)
  222.             viop($4F00,0,0,0,@vbe0);
  223.  
  224.                {S3 VESA driver can return wrong segment if run with QEMM}
  225.             IF seg(vbe0.model^)=$E000 then
  226.               vbe0.model:=ptr($C000,ofs(vbe0.model^));
  227.             x:=1;
  228.             while vbe0.model^[x]<>$FFFF do
  229.             begin
  230.               vesamodeinfo(vbe0.model^[x],vbe1);
  231.               if (vbe1.attr and 1)<>0 then
  232.               begin
  233.                 memmode:=VESAmemmode(vbe1.model,vbe1.bits,vbe1.redinf
  234.                    ,vbe1.grninf,vbe1.bluinf,vbe1.resinf);
  235.                 addmode(vbe0.model^[x],vbe1.width,vbe1.height,vbe1.bytes,memmode);
  236.               end;
  237.               inc(x);
  238.             end;
  239.           end;
  240.     __xbe:begin
  241.             viop($4E01,0,0,cv.id,@xbe1);
  242.             x:=1;
  243.             while xbe1.modep^[x]<>$FFFF do
  244.             begin
  245.               viop($4E02,0,xbe1.modep^[x],cv.id,@xbe2);
  246.               if (rp.ax=$4E) and ((xbe2.attrib and 1)>0) then
  247.               begin
  248.                 memmode:=VESAmemmode(xbe2.model,xbe2.bits,xbe2.redinf
  249.                    ,xbe2.grninf,xbe2.bluinf,xbe2.resinf);
  250.                 if xbe2.bits=4 then memmode:=_pk4;
  251.                 addmode(xbe1.modep^[x],xbe2.pixels,xbe2.lins,xbe2.bytes,memmode);
  252.               end;
  253.               inc(x);
  254.             end;
  255.  
  256.           end;
  257.   else
  258.     for x:=1 to NBRMODES do
  259.       if MODELIST[x].chp=cv.chip then
  260.       begin
  261.         ok:=true;
  262.         md     :=MODELIST[x].md;
  263.         memmode:=MODELIST[x].mode;
  264.         xres   :=MODELIST[x].xres;
  265.         yres   :=MODELIST[x].yres;
  266.         planes:=1;
  267.         if memmode<_herc then bytes:=xres*2
  268.             else bytes:=(xres*usebits[memmode]) shr 3;
  269.         if memmode=_pl4 then
  270.         begin
  271.           bytes:=xres shr 3;
  272.           planes:=4;
  273.         end;
  274.  
  275.         case cv.dactype of
  276.           _dacCEG,
  277.             _dac8:if memmode>_p8 then ok:=false;
  278.            _dac15:if memmode>_p15 then ok:=false;
  279.            _dac16,_dacMU4870:
  280.                   if memmode>_p16 then ok:=false;
  281.       _dacALG1101:if (memmode=_p15) or (memmode>_p16) then ok:=false;
  282.         end;
  283.         case cv.chip of
  284.          __ALG:if (md=$48) and (cv.Version=ALG_2228) then bytes:=2048;
  285.          __ARK:if (memmode=_P24) and (cv.Version>=ARK_2000PV) then
  286.                begin
  287.                  memmode:=_P32;
  288.                  bytes:=xres*4;
  289.                end;
  290.          __ATI:begin
  291.                  if (md<$100) and (cv.Version<ATI_M64_GX) then
  292.                  begin
  293.                    rp.bx:=$5506;
  294.                    rp.bp:=$FFFF;
  295.                    rp.si:=0;
  296.                    vio($1200+md);
  297.                    if rp.bp=$FFFF then ok:=false;
  298.                  end;
  299.                        {The VGA chip can't handle the ATI dac yet}
  300.                  if (cv.dactype=_dacATI68860) and (memmode>_P8) then ok:=false;
  301.                end;
  302.       __Compaq:if (cv.Version<CPQ_QV) and (md>$2E) then ok:=false;
  303.        __Cir54:if (cv.Version<CL_GD5430) and ((memmode=_p32) or (xres>1280)) then ok:=false;
  304.  
  305.           __S3:if (cv.version<=S3_924) then
  306.                begin
  307.                  if ((md>$105) and (md<$200)) or (md=$212) or (md=$211) then ok:=false;
  308.                end
  309.                else begin
  310.                  if md>$210 then ok:=false;
  311.                  if (cv.version<S3_928) and (memmode=_p32) then memmode:=_p24;
  312.                  if (cv.version=S3_928) and (memmode=_PK4a) then ok:=false;
  313.                end;
  314.         __Trid:if cv.version=TR_IITAGX then
  315.                  if (md>=$60) then ok:=false;
  316.        __Tseng:case cv.version of
  317.                  ET_3000:if md=$2F then ok:=false;
  318.                  ET_4000:case cv.subvers of
  319.                            TS_SpeedStar:if (hi(md)=2) or (md=$53E) then ok:=false;
  320.                            TS_Genoa7900:if (hi(md)=1) or (hi(md)=2) then ok:=false;
  321.                          else
  322.                            if (md=$53E) or (hi(md)=1) then ok:=false;
  323.                          end;
  324.                else if (md=$53E) or (hi(md)=1) then ok:=false;
  325.                end;
  326.         end;
  327.         byt  :=MODELIST[x].size;
  328.         if (byt>0) then bytes:=byt;
  329.         mreq:=(longint(bytes*planes)*yres+1023) div 1024;
  330.         if ok and (cv.mm>=mreq) then
  331.           addmode(md,xres,yres,bytes,memmode);
  332.       end;
  333.     for x:=1 to noumodes do  {User overrides (.CFG)}
  334.       if usermodes[x].flags=cv.chip then
  335.         if usermodes[x].memmode=__None then
  336.         begin
  337.           for xres:=1 to nomodes do
  338.             if modetbl[xres].md=usermodes[x].md then
  339.               modetbl[xres].flags:=0;    {Disable}
  340.         end
  341.         else addmode(usermodes[x].md,usermodes[x].xres,usermodes[x].yres
  342.                     ,usermodes[x].bytes,usermodes[x].memmode);
  343.   end;
  344. end;
  345.  
  346.  
  347. procedure findPCI;
  348. const ROMs:array[0..3] of string[4]=(' 32K',' 64K','128K','256K');
  349. var
  350.   i,j:word;
  351.   PCIid:longint;
  352.   tmp:longint;
  353.  
  354. procedure wrPCI(txt:string;base:longint);
  355. begin
  356.   write('      '+txt+': '+hex8(base)+'  at ');
  357.   if (base and 1)>0 then write('I/O: '+hex4(base and $FF00)+'h')
  358.   else write('Mem: '+hex8(base and $FFFFFF00)+'h (',base shr 20,'M)');
  359.   if (base and 8)>0 then write(' Cachable');
  360.   writeln;
  361. end;
  362.  
  363. begin
  364.   PCItype:=0;
  365.   outp($CF8,0);
  366.   outp($CFA,0);
  367.   if (inp($CF8)=0) and (inp($CFA)=0) then PCItype:=2
  368.   else begin
  369.     tmp:=inplong($CF8);
  370.     for i:=1 to 10 do;  {delay}
  371.     outplong($CF8,$80000000);
  372.     for i:=1 to 10 do;
  373.     if inplong($CF8)=$80000000 then PCItype:=1;
  374.     for i:=1 to 10 do;
  375.     outplong($CF8,tmp);
  376.   end;
  377.   if PCItype>0 then
  378.   begin
  379.     clrscr;
  380.     Writeln('PCI bus type ',PCItype,' Devices:');
  381.     writeln(' Bus: Vendor: Device:');
  382.     case PCItype of
  383.       1:begin   {PCI type 1}
  384.           for i:=0 to 127{511} do
  385.           begin
  386.             outplong($CF8,$80000000+i*longint(2048));
  387.             tmp:=inplong($CFC);
  388.             if (word(tmp)<>$FFFF) and ((tmp shr 16)<>$FFFF) then
  389.             begin
  390.               inc(PCIdevs);
  391.               PCIrec[PCIdevs].PCIbase:=i;
  392.               PCIrec[PCIdevs].l[0]:=tmp;
  393.               for j:=1 to 63 do
  394.               begin
  395.                 outplong($CF8,$80000000+i*longint(2048)+j*4);
  396.                 PCIrec[PCIdevs].l[j]:=inplong($CFC);
  397.               end;
  398.               if PCIrec[PCIdevs].class<>$300 then dec(PCIdevs);
  399.             end;
  400.           end;
  401.         end;
  402.       2:begin   {PCI type 2}
  403.           outp($CF8,$80);
  404.           outp($CFA,0);   {Bus select?}
  405.           for i:=0 to 15 do
  406.           begin
  407.             tmp:=inplong($C000+i*256);
  408.             if (word(tmp)<>$FFFF) and ((tmp shr 16)<>$FFFF) then
  409.             begin
  410.               inc(PCIdevs);
  411.               PCIrec[PCIdevs].PCIbase:=i;
  412.               PCIrec[PCIdevs].l[0]:=tmp;
  413.               for j:=1 to 63 do PCIrec[PCIdevs].l[j]:=inplong($C000+i*256+j*4);
  414.               if PCIrec[PCIdevs].class<>$300 then dec(PCIdevs);
  415.             end;
  416.           end;
  417.           outp($CF8,0);
  418.         end;
  419.     end;
  420.     if PCIdevs>0 then
  421.     begin
  422.       settextmode;
  423.       for i:=1 to PCIdevs do
  424.       begin
  425.         writeln('  Vendor: '+hex4(PCIrec[i].vendor)+'  Device: '+hex4(PCIrec[i].device));
  426.         if PCIrec[i].base0<>0 then wrPCI('Base0',PCIrec[i].base0);
  427.         if PCIrec[i].base1<>0 then wrPCI('Base1',PCIrec[i].base1);
  428.         if PCIrec[i].base2<>0 then wrPCI('Base2',PCIrec[i].base2);
  429.         if PCIrec[i].base3<>0 then wrPCI('Base3',PCIrec[i].base3);
  430.         if PCIrec[i].base4<>0 then wrPCI('Base4',PCIrec[i].base4);
  431.         if PCIrec[i].base5<>0 then wrPCI('Base5',PCIrec[i].base5);
  432.         if PCIrec[i].rom<>0   then wrPCI('ROM  ',PCIrec[i].rom);
  433.  
  434.         writeln;
  435.       end;
  436.       if readkey='' then;
  437.     end;
  438.   end;
  439. end;
  440.  
  441.  
  442.  {Checks for a PCI card with ID=sign, returns index in PCIrec, 0 if not found
  443.   START is the }
  444. function CheckPCI(start,vendor,device:word):integer;
  445. var i:integer;
  446. begin
  447.   i:=start;
  448.   repeat inc(i);
  449.   until (i>PCIdevs) or ((PCIrec[i].vendor=vendor) and
  450.       ((PCIrec[i].device=device) or (device=$FFFF)));
  451.   if i<=PCidevs then CheckPCI:=i
  452.                 else CheckPCI:=0;  {Default: None found}
  453. end;
  454.  
  455. procedure wPCIbyte(index,val:word);
  456. begin
  457.   case PCItype of
  458.     1:begin
  459.         outplong($CF8,$80000000+PCIrec[cv.PCIid].PCIbase*longint(2048)+index);
  460.         outp($CFC,val);
  461.       end;
  462.     2:begin
  463.         outp($CF8,$80);
  464.         outp($CFA,0);   {Bus select?}
  465.         outp($C000+PCIrec[cv.PCIid].PCIbase*256+index,val);
  466.         outp($CF8,0);
  467.       end;
  468.   end;
  469. end;
  470.  
  471. procedure wPCIword(index,val:word);
  472. begin
  473.   case PCItype of
  474.     1:begin
  475.         outplong($CF8,$80000000+PCIrec[cv.PCIid].PCIbase*longint(2048)+index);
  476.         outpw($CFC,val);
  477.       end;
  478.     2:begin
  479.         outp($CF8,$80);
  480.         outp($CFA,0);   {Bus select?}
  481.         outpw($C000+PCIrec[cv.PCIid].PCIbase*256+index,val);
  482.         outp($CF8,0);
  483.       end;
  484.   end;
  485. end;
  486.  
  487. procedure wPCIlong(index:word;val:longint);
  488. begin
  489.   case PCItype of
  490.     1:begin
  491.         outplong($CF8,$80000000+PCIrec[cv.PCIid].PCIbase*longint(2048)+index);
  492.         outpl($CFC,val);
  493.       end;
  494.     2:begin
  495.         outp($CF8,$80);
  496.         outp($CFA,0);   {Bus select?}
  497.         outpl($C000+PCIrec[cv.PCIid].PCIbase*256+index,val);
  498.         outp($CF8,0);
  499.       end;
  500.   end;
  501. end;
  502.  
  503. function rPCIbyte(index:word):word;
  504. begin
  505.   case PCItype of
  506.     1:begin
  507.         outplong($CF8,$80000000+PCIrec[cv.PCIid].PCIbase*longint(2048)+index);
  508.         rPCIbyte:=inp($CFC);
  509.       end;
  510.     2:begin
  511.         outp($CF8,$80);
  512.         outp($CFA,0);   {Bus select?}
  513.         rPCIbyte:=inp($C000+PCIrec[cv.PCIid].PCIbase*256+index);
  514.         outp($CF8,0);
  515.       end;
  516.   end;
  517. end;
  518.  
  519. function rPCIword(index:word):word;
  520. begin
  521.   case PCItype of
  522.     1:begin
  523.         outplong($CF8,$80000000+PCIrec[cv.PCIid].PCIbase*longint(2048)+index);
  524.         rPCIword:=inpw($CFC);
  525.       end;
  526.     2:begin
  527.         outp($CF8,$80);
  528.         outp($CFA,0);   {Bus select?}
  529.         rPCIword:=inpw($C000+PCIrec[cv.PCIid].PCIbase*256+index);
  530.         outp($CF8,0);
  531.       end;
  532.   end;
  533. end;
  534.  
  535. function rPCIlong(index:word):longint;
  536. begin
  537.   case PCItype of
  538.     1:begin
  539.         outplong($CF8,$80000000+PCIrec[cv.PCIid].PCIbase*longint(2048)+index);
  540.         rPCIlong:=inpl($CFC);
  541.       end;
  542.     2:begin
  543.         outp($CF8,$80);
  544.         outp($CFA,0);   {Bus select?}
  545.         rPCIlong:=inpl($C000+PCIrec[cv.PCIid].PCIbase*256+index);
  546.         outp($CF8,0);
  547.       end;
  548.   end;
  549. end;
  550.  
  551.  
  552.  
  553.  
  554.     (* Analyse the current mode *)
  555.  
  556. var
  557.   oldreg:boolean;
  558.  
  559. function getbios(offs,lnn:word):string;
  560. var s:string;
  561. begin
  562.   s[0]:=chr(lnn);
  563.   move(mem[biosseg:offs],s[1],lnn);
  564.   getbios:=s;
  565. end;
  566.  
  567.  
  568. procedure checkmem(mx:word);
  569. var
  570.   fail:boolean;
  571.   ma:array[0..99] of byte;
  572.   x:word;
  573. begin
  574.   memmode:=_p8;
  575.  
  576.   fail:=true;
  577.   while (mx>1) and fail do
  578.   begin
  579.     setbank(mx-1);
  580.     move(mem[SegA000:0],ma,100);
  581.     for x:=0 to 99 do
  582.       mem[SegA000:x]:=ma[x] xor $aa;
  583.     setbank(mx-1);
  584.     fail:=false;
  585.     for x:=0 to 99 do
  586.       if mem[SegA000:x]<>ma[x] xor $aa then fail:=true;
  587.     move(ma,mem[SegA000:0],100);
  588.     if not fail then
  589.     begin
  590.       setbank((mx shr 1)-1);
  591.       for x:=0 to 99 do
  592.         mem[SegA000:x]:=ma[x] xor $55;
  593.       setbank(mx-1);
  594.       fail:=true;
  595.       for x:=0 to 99 do
  596.         if mem[SegA000:x]<>ma[x] xor $55 then fail:=false;
  597.       move(ma,mem[SegA000:0],100);
  598.     end;
  599.     mx:=mx shr 1;
  600.   end;
  601.   cv.mm:=mx*128;
  602. end;
  603.  
  604.  
  605. procedure DumpRegisters;
  606.  
  607. procedure dumprg(base,start,ende:word;var rg:regblk);
  608. var six,ix:word;
  609.   same:boolean;
  610. begin
  611.   rg.base:=base;
  612.   six:=inp(base);
  613.   outp(base,0);
  614.   ix:=inp(base) xor 255;
  615.   outp(base,255);
  616.   ix:=ix and inp(base);
  617.  
  618.   if ende=0 then
  619.     if ix>127 then ende:=255
  620.     else if ix>63 then ende:=127
  621.     else if ix>31 then ende:=63
  622.     else if ix>15 then ende:=31
  623.     else if ix>7 then ende:=15
  624.     else ende:=7;
  625.   for ix:=start to ende do
  626.     rg.x[ix]:=rdinx(base,ix);
  627.   rg.nbr:=ende;
  628.   outp(base,six);
  629.   same:=true;
  630.   while (rg.nbr>7) and same do    {Check for doubles}
  631.   begin
  632.     six:=succ(rg.nbr) div 2;
  633.     for ix:=0 to six-1 do
  634.       if rg.x[ix]<>rg.x[ix+six] then same:=false;
  635.     if same then rg.nbr:=rg.nbr div 2;
  636.   end;
  637.  
  638. end;
  639.  
  640. procedure DumpTridOldRegs;
  641. begin
  642.   wrinx(SEQ,$B,0);
  643.   rgs.tridold0d:=rdinx(SEQ,$D);
  644.   rgs.tridold0e:=rdinx(SEQ,$E);
  645.   if rdinx(SEQ,$B)=0 then;  {New mode}
  646.   oldreg:=true;
  647. end;
  648.  
  649. procedure DumpXGAregs;
  650. var x:word;
  651. begin
  652.   dumprg(cv.IOadr+10,0,0,rgs.xxregs);
  653.   for x:=0 to 15 do
  654.     rgs.xgaregs[x]:=inp(cv.IOadr+x);
  655. end;
  656.  
  657. var x,y,m:word;
  658.   VESAcheat:boolean;
  659. begin
  660.   if cv.chip=__VESA then
  661.   begin
  662.     cv.chip:=__Alli;
  663.     cv.ioadr:=$1ce;
  664.     cv.dactype:=_dacSTG1703;
  665.     VESAcheat:=true;
  666.   end
  667.   else VESAcheat:=false;
  668.   case cv.chip of  { Enable ext }
  669.      __S3:begin
  670.         wrinx(crtc,$38,$48);
  671.         wrinx(crtc,$39,$A5);
  672.             if (cv.version=S3_732) or (cv.Version=S3_764) then wrinx(SEQ,8,6);
  673.       end;
  674.    __Trid:begin
  675.             outpw(SEQ,$B);
  676.             if inp(SEQ+1)=0 then;
  677.             x:=rdinx(SEQ,$E) XOR 2;
  678.             outp(SEQ+1,x OR $80);   {Enable extended registers}
  679.           end;
  680.  __Compaq:wrinx(GRC,$F,5);
  681.  {__Video7:wrinx(SEQ,6,$EA); }
  682.   end;
  683.   fillchar(rgs,sizeof(rgs),0);
  684.   oldreg:=false;
  685.   vclk:=0;
  686.   for x:=$3C2 to $3DF do rgs.stdregs[x]:=inp(x);
  687.   rgs.stdregs[$3DA]:=inp(CRTC+6);
  688.   rgs.stdregs[$3C0]:=inp($3C0);
  689.   for x:=0 to 31 do rgs.attregs[x]:=rdinx($3C0,x);
  690.   x:=rdinx($3C0,$30);
  691.   rgs.mode:=curmode;
  692.   dumprg(CRTC,0,0,rgs.crtcregs);
  693.   dumprg(SEQ,0,0,rgs.seqregs);
  694.   dumprg(GRC,0,0,rgs.grcregs);
  695.   case cv.chip of
  696.    __Alli:begin
  697.             if mem[SegA000:$D8]=0 then;
  698.             outpw(SEQ,$1210);
  699.             setinx(SEQ,$1C,8);
  700.             modinx(SEQ,$1B,7,1);
  701.  
  702.             rgs.xxregs.nbr:=255;
  703.             rgs.xxregs.base:=1;
  704.             move(mem[SegA000:0],rgs.xxregs.x,256);
  705.             clrinx(SEQ,$1B,7);
  706.             clrinx(SEQ,$1C,8);
  707.           end;
  708.     __ati:begin
  709.             dumprg(cv.IOadr,$A0,$BF,rgs.xxregs);
  710.             rgs.xxregs.x[0]:=inp($6AEC);
  711.             rgs.xxregs.x[1]:=inp($6AED);
  712.             rgs.xxregs.x[2]:=inp($6AEE);
  713.             rgs.xxregs.x[3]:=inp($6AEF);
  714.             rgs.xxregs.x[4]:=inp($72EC);
  715.             rgs.xxregs.x[5]:=inp($72ED);
  716.             rgs.xxregs.x[6]:=inp($72EE);
  717.             rgs.xxregs.x[7]:=inp($72EF);
  718.             rgs.xxregs.x[8]:=inp($62EC);
  719.             rgs.xxregs.x[9]:=inp($62ED);
  720.             rgs.xxregs.x[10]:=inp($62EE);
  721.             rgs.xxregs.x[11]:=inp($62EF);
  722.             rgs.xxregs.x[12]:=inp($1EEC);
  723.             rgs.xxregs.x[13]:=inp($1EED);
  724.             rgs.xxregs.x[14]:=inp($1EEE);
  725.             rgs.xxregs.x[15]:=inp($1EEF);
  726.           end;
  727.   __chips:dumprg(cv.IOadr,0,0,rgs.xxregs);
  728.    __VESA,
  729.  __compaq:begin
  730.         for x:=1 to 15 do
  731.           for m:=0 to 15 do
  732.         rgs.xxregs.x[(x-1)*16+m]:=inp(x*$1000+$3C0+m);
  733.         rgs.xxregs.base:=$3C;
  734.         rgs.xxregs.nbr:=240;
  735.       end;
  736.      __WD:if cv.Version=WD_90c24 then
  737.             begin
  738.               wrinx(SEQ,$35,$50);  {Unlock clock regs}
  739.               rgs.seqregs.x[$31]:=rdinx(SEQ,$31);
  740.               wrinx(crtc,$34,$A6);
  741.               wrinx(crtc,$35,$30);
  742.               for x:=$31 to $3F do
  743.                 rgs.crtcregs.x[x]:=rdinx(crtc,x);
  744.               wrinx(crtc,$34,0);
  745.               wrinx(crtc,$35,0);
  746.             end;
  747.    __Mach64:begin
  748.               move(mem[cv.Xseg:0],rgs.xxregs.x,256);
  749.               rgs.xxregs.x[$D4]:=inp($6AEC);
  750.               rgs.xxregs.x[$D5]:=inp($6AED);
  751.               rgs.xxregs.x[$D6]:=inp($6AEE);
  752.               rgs.xxregs.x[$D7]:=inp($6AEF);
  753.               rgs.xxregs.base:=$2EC;
  754.               rgs.xxregs.nbr:=256;
  755.             end;
  756.    __Mach32:begin
  757.             rgs.xxregs.base:=$2E8;
  758.             rgs.xxregs.nbr:=128;
  759.             for x:=0 to 63 do    {Mach8 & 32}
  760.             begin
  761.               m:=inpw($2E8+(x shl 10));
  762.               rgs.xxregs.x[x*2]:=lo(m);
  763.               rgs.xxregs.x[x*2+1]:=hi(m);
  764.             end;
  765.             if cv.Version>=ATI_GUP_3 then  {Mach32}
  766.             begin
  767.               for x:=0 to 63 do
  768.               begin
  769.                 m:=inpw($2EE+(x shl 10));
  770.                 rgs.xxregs.x[x*2+128]:=lo(m);
  771.                 rgs.xxregs.x[x*2+129]:=hi(m);
  772.               end;
  773.               rgs.xxregs.nbr:=256;
  774.             end;
  775.           end;
  776.   __Tseng:if cv.version>=ET_4W32 then dumprg($217A,0,0,rgs.xxregs);
  777.     __hmc:dumprg(SEQ,$0,$FF,rgs.xxregs);
  778.     __Matrox,
  779.     __oak:dumprg($3DE,0,0,rgs.xxregs);
  780.    __trid:DumpTridOldRegs;
  781.  (*   __agx:if (inp(cv.IOadr) and 4)=0 then DumpTridOldRegs
  782.       else DumpXGAregs;  *)
  783.     __AGX,__xbe,__xga:
  784.           DumpXGAregs;
  785.   else rgs.xxregs.base:=0;
  786.   end;
  787.  
  788.   for x:=0 to 15 do
  789.     rgs.dacregs[x]:=rdDACreg(x);
  790.   if (DACflags and DFL_CmdReg)>0 then
  791.   begin
  792.     dac2comm;
  793.     rgs.dacregs[16]:=inp($3C6);
  794.     dac2pel;
  795.   end;
  796.   rgs.dacinxd.nbr :=0;
  797.   rgs.dacinxd.base:=0;
  798.   case cv.dactype of
  799. _dacCL5200:begin
  800.              outp($3C6,0);
  801.              dac2comm;
  802.              rgs.dacregs[6]:=inp($3C6);
  803.              dac2pel;
  804.              outp($3C6,rgs.dacregs[2]);
  805.            end;
  806. _dacMU1880:begin
  807.              dac2comm;
  808.              dac2comm;
  809.              x:=8;
  810.              while (x>0) and (inp($3C6)<>$8E) do dec(x);
  811.              rgs.dacinxd.x[6]:=inp($3C6);
  812.              rgs.dacinxd.x[6]:=inp($3C6);
  813.              dac2pel;
  814.  
  815.            end;
  816.  _dacSC15021,_dacSc15025:
  817.            begin    {Sierra SC15025 24bit DAC}
  818.              y:=inp(SetDACpage(dacHIcmd));
  819.              outp(SetDACpage(dacHIcmd),y or 16);
  820.              dumprg($3C7,0,31,rgs.dacinxd);
  821.              outp(SetDACpage(dacHIcmd),y);
  822.            end;
  823.  _dacSTG1700,_dacSTG1702,_dacSTG1703:
  824.            begin
  825.              rgs.dacinxd.base:=$3C6;
  826.              rgs.dacinxd.nbr:=7;
  827.              y:=inp(SetDACpage(dacHIcmd));
  828.              outp(SetDACpage(dacHIcmd),y or 16);
  829.              dac2comm;
  830.              m:=inp($3C6);
  831.              outp($3C6,0);
  832.              outp($3C6,0);
  833.              for x:=0 to 7 do
  834.                rgs.dacinxd.x[x]:=inp($3C6);
  835.              if cv.dactype=_dacSTG1703 then
  836.              begin
  837.                for x:=8 to $5F do
  838.                  rgs.dacinxd.x[x]:=inp($3C6);
  839.                rgs.dacinxd.nbr:=$5F;
  840.              end;
  841.              wrDACreg(dacHIcmd,y);
  842.            end;
  843.  _dacBt481,_dacBt482:
  844.            begin
  845.              if cv.chip=__AGX then outp(cv.IOadr,1);
  846.            (*  outp(SetDACpage(dacBT1cmdA),1);
  847.              for x:=0 to 15 do {This screws up the DAC, so we drop it for now}
  848.              begin
  849.                outp($3C8,x);
  850.                rgs.dacinxd.x[x]:=inp($3C6);
  851.              end;
  852.              rgs.dacinxd.base:=$3C6;
  853.              rgs.dacinxd.nbr:=15;
  854.              outp(SetDACpage(dacBT1cmdA),rgs.dacregs[dacBT1cmdA]); *)
  855.              if cv.chip=__AGX then outp(cv.IOadr,4);
  856.            end;
  857.  _dacBt484,_dacBt485,_dacATT504,_dacATT505:
  858.            begin    {BrookTree Bt484/5 or ATT20c504/5 DAC}
  859.              outp(SetDACpage(dacBTcmd0),rgs.dacregs[dacBTcmd0] or $80);
  860.              outp(SetDACpage(0),0);
  861.              rgs.dacregs[dacBTstat]:=inp(SetDACpage(dacBTstat));
  862.              outp(SetDACpage(0),1);
  863.              rgs.dacregs[16]:=inp(SetDACpage(dacBTstat));
  864.              outp(SetDACpage(dacBTcmd0),rgs.dacregs[dacBTcmd0]);
  865.            end;
  866. _dacCH8391,
  867. _dacCH8398:begin
  868.              outp(SetDACpage(7),0);
  869.              for x:=1 to 4 do y:=inp(SetDACpage(4));
  870.              rgs.dacregs[16]:=inp(SetDACpage(4));
  871.              outp(SetDACpage(7),0);
  872.              for x:=0 to 47 do rgs.dacinxd.x[x]:=inp(SetDACpage(5));
  873.              rgs.dacinxd.base:=$3C8;
  874.              rgs.dacinxd.nbr :=47;
  875.            end;
  876.  _dacS3_708,_dacS3_716:
  877.            begin  {S3 SDAC and GenDAC}
  878.              outp(SetDACpage(7),0);
  879.              for x:=0 to 31 do  {There are 16 16bit registers}
  880.              begin
  881.                {outp(SetDACpage(7),x);}
  882.                rgs.dacinxd.x[x]:=inp(SetDACpage(5));
  883.              end;
  884.              rgs.dacinxd.base:=$3C6;
  885.              rgs.dacinxd.nbr:=31;
  886.            end;
  887.  _dacTVP3010,_dacTVP3020,_dacTVP3025:
  888.            begin    {TI TVP 302x DAC}
  889.              y:=rdDACreg(dacTVPindex);
  890.              for y:=0 to $3F do
  891.              begin
  892.                wrDACreg(dacTVPindex,y);
  893.                rgs.dacinxd.x[y]:=rdDACreg(dacTVPdata);
  894.              end;
  895.  
  896.              wrDACreg(dacTVPindex,$2C);
  897.              wrDACreg(dacTVPdata,0);  {PLL 1st byte}
  898.              wrDACreg(dacTVPindex,$2D);
  899.              rgs.dacinxd.x[$40]:=rdDACreg(dacTVPdata);
  900.              wrDACreg(dacTVP6index,$2E);
  901.              rgs.dacinxd.x[$43]:=rdDACreg(dacTVPdata);
  902.              wrDACreg(dacTVPindex,$2F);
  903.              rgs.dacinxd.x[$46]:=rdDACreg(dacTVPdata);
  904.              wrDACreg(dacTVPindex,$2C);
  905.              wrDACreg(dacTVPdata,1);  {PLL 2nd byte}
  906.              wrDACreg(dacTVPindex,$2D);
  907.              rgs.dacinxd.x[$41]:=rdDACreg(dacTVPdata);
  908.              wrDACreg(dacTVPindex,$2E);
  909.              rgs.dacinxd.x[$44]:=rdDACreg(dacTVPdata);
  910.              wrDACreg(dacTVPindex,$2F);
  911.              rgs.dacinxd.x[$47]:=rdDACreg(dacTVPdata);
  912.              wrDACreg(dacTVPindex,$2C);
  913.              wrDACreg(dacTVPdata,2);  {PLL 3rd byte}
  914.              wrDACreg(dacTVPindex,$2D);
  915.              rgs.dacinxd.x[$42]:=rdDACreg(dacTVPdata);
  916.              wrDACreg(dacTVPindex,$2E);
  917.              rgs.dacinxd.x[$45]:=rdDACreg(dacTVPdata);
  918.              wrDACreg(dacTVPindex,$2F);
  919.              rgs.dacinxd.x[$48]:=rdDACreg(dacTVPdata);
  920.              rgs.dacinxd.nbr:=$48;
  921.              rgs.dacinxd.base:=$3C6;
  922.              wrDACreg(dacTVP6index,y);
  923.            end;
  924.  _dacTVP3026:
  925.            begin    {TI TVP 3026 DAC}
  926.              y:=rdDACreg(dacTVP6index);
  927.              for y:=0 to $3F do
  928.              begin
  929.                wrDACreg(dacTVP6index,y);
  930.                rgs.dacinxd.x[y]:=rdDACreg(dacTVP6data);
  931.              end;
  932.  
  933.              wrDACreg(dacTVP6index,$2C);
  934.              wrDACreg(dacTVP6data,0);  {PLL 1st byte}
  935.              wrDACreg(dacTVP6index,$2D);
  936.              rgs.dacinxd.x[$40]:=rdDACreg(dacTVP6data);
  937.              wrDACreg(dacTVP6index,$2E);
  938.              rgs.dacinxd.x[$43]:=rdDACreg(dacTVP6data);
  939.              wrDACreg(dacTVP6index,$2F);
  940.              rgs.dacinxd.x[$46]:=rdDACreg(dacTVP6data);
  941.              wrDACreg(dacTVP6index,$2C);
  942.              wrDACreg(dacTVP6data,1);  {PLL 2nd byte}
  943.              wrDACreg(dacTVP6index,$2D);
  944.              rgs.dacinxd.x[$41]:=rdDACreg(dacTVP6data);
  945.              wrDACreg(dacTVP6index,$2E);
  946.              rgs.dacinxd.x[$44]:=rdDACreg(dacTVP6data);
  947.              wrDACreg(dacTVP6index,$2F);
  948.              rgs.dacinxd.x[$47]:=rdDACreg(dacTVP6data);
  949.              wrDACreg(dacTVP6index,$2C);
  950.              wrDACreg(dacTVP6data,2);  {PLL 3rd byte}
  951.              wrDACreg(dacTVP6index,$2D);
  952.              rgs.dacinxd.x[$42]:=rdDACreg(dacTVP6data);
  953.              wrDACreg(dacTVP6index,$2E);
  954.              rgs.dacinxd.x[$45]:=rdDACreg(dacTVP6data);
  955.              wrDACreg(dacTVP6index,$2F);
  956.              rgs.dacinxd.x[$48]:=rdDACreg(dacTVP6data);
  957.              rgs.dacinxd.nbr:=$48;
  958.              rgs.dacinxd.base:=$3C6;
  959.              wrDACreg(dacTVP6index,y);
  960.            end;
  961. _dacMU9910:begin
  962.              rgs.dacinxd.base:=$83C9;
  963.              rgs.dacinxd.nbr:=$1F;
  964.              outp(SetDACpage(7),0);
  965.              for y:=0 to $1F do
  966.                rgs.dacinxd.x[y]:=inp(SetDACpage(5));
  967.            end;
  968. _dacIBM514,_dacIBM524,_dacIBM525,_dacIBM528:
  969.            begin
  970.              rgs.dacinxd.base:=$3C6;
  971.              rgs.dacinxd.nbr:=255;
  972.  
  973.            (*  wrDACreg(dacIBMind1,0);
  974.              for x:=0 to 255 do
  975.              begin
  976.                wrDACreg(dacIBMind0,x);
  977.                rgs.dacinxd.x[x]:=rdDACreg(dacIBMdata);
  978.              end;
  979.              wrDACreg(dacIBMind0,rgs.dacregs[dacIBMind0]); *)
  980.            end;
  981.   end;
  982.   clearDACpage;
  983.   case cv.chip of  { Disable ext }
  984.      __S3:begin
  985.             if (cv.version=S3_732) or (cv.Version=S3_764) then
  986.               wrinx(SEQ,8,rgs.seqregs.x[8]);
  987.         wrinx(crtc,$38,0);
  988.         wrinx(crtc,$39,$5A);
  989.       end;
  990.    __Trid:if cv.version>=TR_GUI9440 then
  991.           begin
  992.             setinx(SEQ,$C,$60);
  993.             rgs.dacregs[ 8]:=inp($43C8);
  994.             rgs.dacregs[ 9]:=inp($43C9);
  995.             rgs.dacregs[10]:=inp($43C6);
  996.             rgs.dacregs[11]:=inp($43C7);
  997.             wrinx(SEQ,$C,rgs.seqregs.x[$C]);
  998.           end;
  999.   end;
  1000.   if VESAcheat then cv.chip:=__VESA;
  1001. end;
  1002.  
  1003. procedure CalcRegisters;
  1004. {const
  1005.   wd24clk:array[0..15] of real=(29.979,77.408,0,80.092,25.175,28.322
  1006.           ,65,36,39.822,50.114,42.060,44.297,31.5,35.501,75.166,50.114); }
  1007. var x,m,wid,wordadr,pixwid,clksel,vclkdiv:word;
  1008.     force256,graph,isilace:boolean;
  1009.     hfreqfact:word;
  1010.  
  1011.   VESAcheat,
  1012.   SerialDAC:boolean;     {If set the DAC takes one byte at a time}
  1013. begin
  1014.   if cv.chip=__VESA then
  1015.   begin
  1016.     cv.chip:=__Alli;
  1017.     VESAcheat:=true;
  1018.   end
  1019.   else VESAcheat:=false;
  1020.   SerialDAC:=true;
  1021.   m:=rgs.grcregs.x[6];
  1022.   case (m shr 2) and 3 of
  1023.   0,1:calcvseg:=SegA000;
  1024.     2:calcvseg:=SegB000;
  1025.     3:calcvseg:=SegB800;
  1026.   end;
  1027.   clksel:=(rgs.stdregs[$3CC] shr 2) and 3;
  1028.   vclkdiv:=12;     {Base 12.}
  1029.   begin
  1030.     ilace:=false;
  1031.     isilace:=false;  {Interlaced, but do not double lines!!}
  1032.     extpixfact:=1;
  1033.     extlinfact:=1;
  1034.  
  1035.     hfreqfact:=1;
  1036.     calclines:=rgs.crtcregs.x[$12]+1;
  1037.     pixwid:=8;
  1038.     calcpixels:=rgs.crtcregs.x[1]+1;
  1039.     force256:=false;
  1040.     calchtot:=rgs.crtcregs.x[0]+5;
  1041.     calcvtot:=rgs.crtcregs.x[6]+2;
  1042.  
  1043.     calchblks:=rgs.crtcregs.x[2];
  1044.     calchrtrs:=rgs.crtcregs.x[4];
  1045.     calchblke:=rgs.crtcregs.x[3] and 31;
  1046.     calchrtre:=rgs.crtcregs.x[5] and 31;
  1047.     hrtrmask:=$1F;   {Retrace and blanking masks (valid bits)}
  1048.     hblkmask:=$3F;
  1049.     calcvblks:=rgs.crtcregs.x[$15];
  1050.     calcvrtrs:=rgs.crtcregs.x[$10];
  1051.     calcvblke:=rgs.crtcregs.x[$16] and 127;
  1052.     calcvrtre:=rgs.crtcregs.x[$11] and 15;
  1053.     vblkmask:=$7F;
  1054.     vrtrmask:=$F;
  1055.  
  1056.     if (rgs.crtcregs.x[7] and   1)>0 then inc(calcvtot, 256);
  1057.     if (rgs.crtcregs.x[7] and   2)>0 then inc(calclines,256);
  1058.     if (rgs.crtcregs.x[7] and   4)>0 then inc(calcvrtrs,256);
  1059.     if (rgs.crtcregs.x[7] and   8)>0 then inc(calcvblks,256);
  1060.     if (rgs.crtcregs.x[7] and $20)>0 then inc(calcvtot, 512);
  1061.     if (rgs.crtcregs.x[7] and $40)>0 then inc(calclines,512);
  1062.     if (rgs.crtcregs.x[7] and $80)>0 then inc(calcvrtrs,512);
  1063.     if (rgs.crtcregs.x[5] and $80)>0 then inc(calchblke, 32);
  1064.     if (rgs.crtcregs.x[9] and $20)>0 then inc(calcvblks,512);
  1065.  
  1066.     if (rgs.seqregs.x[1] and 8)>0 then vclkdiv:=vclkdiv*2;
  1067.  
  1068.     graph:=(rgs.attregs[$10] and 1)>0;
  1069.     if graph then
  1070.     begin
  1071.       extlinfact:=(rgs.crtcregs.x[9] and $1F)+1;
  1072.       if (rgs.crtcregs.x[9] and $80)>0 then extlinfact:=extlinfact*2;
  1073.     end
  1074.     else begin
  1075.       if {((rgs.attregs[$10] and 4)>0) or} ((rgs.seqregs.x[1] and 1)=0) then charwid:=9 else charwid:=8;
  1076.       charhigh:=(rgs.crtcregs.x[9] and $1f)+1;
  1077.     end;
  1078.  
  1079.     wid:=rgs.crtcregs.x[$13];
  1080.     wordadr:=2;
  1081.     if (rgs.crtcregs.x[$14] and 64)<>0 then wordadr:=8
  1082.     else if (rgs.crtcregs.x[$17] and 64)=0 then wordadr:=4;
  1083.     case cv.chip of
  1084.       __Acer:wid:=wid+(rgs.crtcregs.x[$81] and 3) shl 8;
  1085.        __AGX:begin
  1086.            calcpixels:=rgs.xxregs.x[$13]*256+rgs.xxregs.x[$12]+1;
  1087.            calchtot:=rgs.xxregs.x[$11]*256+rgs.xxregs.x[$10]+1;
  1088.            pixwid:=8;
  1089.            calclines :=rgs.xxregs.x[$23]*256+rgs.xxregs.x[$22]+1;
  1090.            calcvtot:=rgs.xxregs.x[$21]*256+rgs.xxregs.x[$20]+1;
  1091.            wid :=rgs.xxregs.x[$44]*256+rgs.xxregs.x[$43];
  1092.            wordadr:=8;
  1093.                vclkdiv:=12;  {Nominal}
  1094.                if (rgs.xxregs.x[$50] and 8)>0 then ilace:=true;
  1095.          end;
  1096.      __ahead:begin
  1097.            if (rgs.grcregs.x[$1c] and 12)=12 then ilace:=true;
  1098.            if (rgs.seqregs.x[4] and 8)<>0 then wordadr:=16;
  1099.          end;
  1100.        __ALG:begin
  1101.            if (rgs.grcregs.x[$C] and $10)>0 then wordadr:=wordadr shl 1
  1102.                else if (rgs.crtcregs.x[$14] and 64)>0 then  {Packed mode}
  1103.                begin
  1104.                  pixwid:=4;
  1105.                  vclkdiv:=vclkdiv*2;
  1106.                end;
  1107.            if (rgs.crtcregs.x[$19] and 1)>0 then
  1108.            begin
  1109.          ilace:=true;
  1110.          wordadr:=wordadr shr 1;
  1111.            end;
  1112.                if (cv.version>ALG_2101) and ((rgs.crtcregs.x[$19] and $80)>0) then
  1113.                begin
  1114.                  if (rdinx(crtc,$2A) and 1)>0 then inc(calchtot,256);
  1115.                  if (rdinx(crtc,$28) and $80)>0 then inc(wid,256);
  1116.                end;
  1117.          end;
  1118.       __Alli:begin
  1119.                if (rgs.grcregs.x[5] and $40)>0 then
  1120.                begin
  1121.                  force256:=true;
  1122.                  wordadr:=8;
  1123.                end;
  1124.                inc(wid,(rgs.crtcregs.x[$1C] shr 4)*256);
  1125.                if (rgs.crtcregs.x[$1A] and 1)>0 then inc(calcvtot,1024);
  1126.                if (rgs.crtcregs.x[$1A] and 2)>0 then inc(calclines,1024);
  1127.                if (rgs.crtcregs.x[$1A] and 4)>0 then inc(calcvrtrs,1024);
  1128.                if (rgs.crtcregs.x[$1A] and 8)>0 then inc(calcvblks,1024);
  1129.                if (rgs.crtcregs.x[$1B] and 1)>0 then inc(calchtot,256);
  1130.                if (rgs.crtcregs.x[$1B] and 4)>0 then inc(calchblks,256);
  1131.                if (rgs.crtcregs.x[$1B] and 8)>0 then inc(calchrtrs,256);
  1132.              end;
  1133.        __ARK:begin
  1134.                if (rgs.crtcregs.x[$44] and 4)>0 then ilace:=true;
  1135.                if (rgs.crtcregs.x[$41] and 128)>0 then inc(calchtot,256);
  1136.                if (rgs.crtcregs.x[$41] and  64)>0 then inc(calcpixels,256);
  1137.                if (rgs.crtcregs.x[$41] and  32)>0 then inc(calchblks,256);
  1138.                if (rgs.crtcregs.x[$41] and  16)>0 then inc(calchrtrs,256);
  1139.                if (rgs.crtcregs.x[$41] and   8)>0 then inc(wid,256);
  1140.                if (rgs.crtcregs.x[$40] and 128)>0 then inc(calcvtot,1024);
  1141.                if (rgs.crtcregs.x[$40] and  64)>0 then inc(calclines,1024);
  1142.                if (rgs.crtcregs.x[$40] and  32)>0 then inc(calcvblks,1024);
  1143.                if (rgs.crtcregs.x[$40] and  16)>0 then inc(calcvrtrs,1024);
  1144.              end;
  1145.        __ati:begin
  1146.                if cv.Version=ATI_18800 then
  1147.                begin
  1148.                  if (rgs.xxregs.x[$B2] and 1)<>0 then ilace:=true;
  1149.                end
  1150.              else if (rgs.xxregs.x[$BE] and 2)<>0 then ilace:=true;
  1151.            if (rgs.xxregs.x[$B0] and $20)>0 then
  1152.            begin
  1153.          force256:=true;
  1154.          if cv.Version=ATI_18800 then wordadr:=8
  1155.                                          else wordadr:=16;
  1156.            end;
  1157.                if ((rgs.xxregs.x[$B3] and $40)>0) and (cv.Version>ATI_18800) then
  1158.                begin
  1159.                  pixwid:=pixwid*2;
  1160.                  wordadr:=wordadr*2;
  1161.                end;
  1162.                if ((rgs.xxregs.x[$B6] and $10)>0) and ((cv.version<ATI_GUP_3)
  1163.                    or (cv.Version>=ATI_M64_GX)) then
  1164.                begin
  1165.                  force256:=false;
  1166.                end;
  1167.                if ((rgs.xxregs.x[$B1] and $40)>0) then
  1168.                begin
  1169.                  calclines:=calclines div 2;
  1170.                  calcvtot:=calcvtot div 2;
  1171.                end;
  1172.                if ((rgs.seqregs.x[4] and 8)>0) and not force256 then
  1173.                   pixwid:=pixwid*2;   {Mode 65h (PK4) fix}
  1174.  
  1175.  
  1176.                if (cv.Version=ATI_28800_6) and ((rgs.xxregs.x[$AD] and 8)>0) then
  1177.                begin
  1178.                  if (rgs.xxregs.x[$AD] and 1)>0 then inc(calchtot,256);
  1179.                  if (rgs.xxregs.x[$AD] and 2)>0 then inc(calchblks,256);
  1180.                  if (rgs.xxregs.x[$AD] and 4)>0 then inc(calchrtrs,256);
  1181.                end;
  1182.          end;
  1183.      __chips:begin
  1184.            if (rgs.xxregs.x[$D] and 1)<>0 then inc(wid,256);
  1185.                if (rgs.xxregs.x[$17] and 1)>0 then inc(calchtot,256);
  1186.                if (rgs.xxregs.x[$D] and 4)>0 then inc(wid,256);
  1187.            if (rgs.xxregs.x[$B] and 4)>0 then
  1188.            begin
  1189.                  force256:=true;
  1190.          wordadr:=8;
  1191.              if cv.version<CT_65520 then
  1192.                  begin
  1193.                    pixwid:=4;
  1194.                    vclkdiv:=vclkdiv*2;
  1195.                  end;
  1196.            end;
  1197.                if (rgs.xxregs.x[$28] and $20)>0 then ilace:=true;
  1198.          end;
  1199.      __cir54:begin
  1200.            if (rgs.seqregs.x[4] and 8)>0 then wordadr:=8;
  1201.            if (rgs.crtcregs.x[$1B] and 16)>0 then inc(wid,256);
  1202.            if (rgs.crtcregs.x[$1A] and 1)>0 then ilace:=true;
  1203.                if (rgs.crtcregs.x[$1B] and $80)>0 then
  1204.                begin
  1205.                  inc(calchblke,(rgs.crtcregs.x[$1A] and $30) shl 2);
  1206.                  hblkmask:=$FF;
  1207.                  calcvblke:=rgs.crtcregs.x[$16]+((rgs.crtcregs.x[$1A] and $C0) shl 2);
  1208.                  vblkmask:=$3FF;
  1209.                end;
  1210.          end;
  1211.      __cir64:begin
  1212.            if (rgs.seqregs.x[4] and 8)<>0 then wordadr:=8;
  1213.            if (rgs.grcregs.x[$82] and 7)=2 then pixwid:=4;
  1214.            if (rgs.grcregs.x[$79] and  1)>0 then inc(calchtot,1024);
  1215.            if (rgs.grcregs.x[$79] and  2)>0 then inc(calclines,1024);
  1216.            if (rgs.grcregs.x[$79] and 16)>0 then inc(calchrtrs,1024);
  1217.                inc(calchblks,(rgs.grcregs.x[$79] and $C) shl 7);
  1218.          end;
  1219.     __compaq:begin
  1220.            if (rgs.grcregs.x[$F] and $F0)=0 then wordadr:=8;
  1221.                inc(wid,(rgs.grcregs.x[$42] and 3)*256);
  1222.            if (rgs.crtcregs.x[$14] and 64)>0 then pixwid:=4;
  1223.                if (rgs.grcregs.x[$51] and $40)>0 then inc(calcvtot,1024);
  1224.                if (rgs.grcregs.x[$51] and $80)>0 then inc(calcvrtrs,1024);
  1225.               { if (rgs.grcregs.x[$51] and $20)>0 then inc(calchrtre,32);
  1226.                hrtrmask:=$3F; }
  1227.                if cv.version>CPQ_QV then
  1228.                begin
  1229.                  SerialDAC:=false;   {Dirty Hack!!}
  1230.                  if memmode>=_PK4 then pixwid:=pixwid shr 2;
  1231.                end;
  1232.          end;
  1233.      __genoa:begin
  1234.                if (rgs.crtcregs.x[$2F] and 1)<>0 then ilace:=true;
  1235.                if (rgs.crtcregs.x[$2F] and 2)<>0 then wordadr:=16;
  1236.                if (rgs.seqregs.x[4] and 8)>0 then pixwid:=4;
  1237.              end;
  1238.        __hmc:begin
  1239.                IF (rgs.xxregs.x[$E7] and 1)>0 then ilace:=true;
  1240.                if (rgs.xxregs.x[$E7] and 2)>0 then force256:=true;
  1241.               { if (rgs.xxregs.x[$E7] and 64)>0 then inc(clksel,4);
  1242.                vclk:=HMCclk[clksel]; }
  1243.              end;
  1244.     __Mach32:begin
  1245.                calcpixels:=rgs.xxregs.x[$D8]+1;   {B2EE}
  1246.                calchtot  :=rgs.xxregs.x[$D9]+1;   {B2EF}
  1247.                calcvtot  :=(rgs.xxregs.x[$E0]+rgs.xxregs.x[$E1]*256)+1; {C2EE}
  1248.                calclines :=(rgs.xxregs.x[$E2]+rgs.xxregs.x[$E3]*256)+1; {C6EE}
  1249.                calchrtrs :=rgs.xxregs.x[$DA];   {B6EE}
  1250.                calchrtre :=calchrtrs+(rgs.xxregs.x[$DC] and $1F);   {BAEE}
  1251.                calcvrtrs :=(rgs.xxregs.x[$E4]+rgs.xxregs.x[$E5]*256)+1; {CAEE}
  1252.                calcvrtre :=calcvrtrs+(rgs.xxregs.x[$E8] and $1F);   {D2EE}
  1253.                pixwid:=8;
  1254.                case rgs.xxregs.x[$C6] and $30 of   {8EEE}
  1255.                    0:calcmmode:=_pk4;
  1256.                  $10:calcmmode:=_p8;
  1257.                  $20:case rgs.xxregs.x[$C6] and $C0 of
  1258.                         0:calcmmode:=_p15;
  1259.                       $40:calcmmode:=_p16;
  1260.                      end;
  1261.                  $30:case rgs.xxregs.x[$C7] and 6 of
  1262.                        0:calcmmode:=_p24;
  1263.                        2:calcmmode:=_p32c;
  1264.                        4:calcmmode:=_p24b;
  1265.                        6:calcmmode:=_p32b;
  1266.                      end;
  1267.                end;
  1268.                {There is no way to determine the bytes/scanline (Write only)}
  1269.              end;
  1270.     __Mach64:begin
  1271.                calchtot  :=(rgs.xxregs.x[$0]+rgs.xxregs.x[$1]*256)+1;
  1272.                calcpixels:=(rgs.xxregs.x[$2]+rgs.xxregs.x[$3]*256)+1;
  1273.                calcvtot  :=(rgs.xxregs.x[$8]+rgs.xxregs.x[$9]*256)+1;
  1274.                calclines :=(rgs.xxregs.x[$A]+rgs.xxregs.x[$B]*256)+1;
  1275.                wid       :=(rgs.xxregs.x[$16]+rgs.xxregs.x[$17]*256) shr 6;
  1276.                calchrtrs :=rgs.xxregs.x[$4];
  1277.                calchrtre :=calchrtrs+(rgs.xxregs.x[$6] and $1F);
  1278.                calcvrtrs :=(rgs.xxregs.x[$C]+rgs.xxregs.x[$D]*256)+1;
  1279.                calcvrtre :=calcvrtrs+(rgs.xxregs.x[$E] and $1F);
  1280.                pixwid:=8;
  1281.                calcmmode:=_P8;
  1282.                if (rgs.xxregs.x[$1C] and 2)>0 then ilace:=true;
  1283.                case rgs.xxregs.x[$1D] and 7 of
  1284.                  1:calcmmode:=_PK4;
  1285.                  2:calcmmode:=_P8;
  1286.                  3:calcmmode:=_P15;
  1287.                  4:calcmmode:=_P16;
  1288.                  5:calcmmode:=_P24;
  1289.                  6:calcmmode:=_P32;
  1290.                end;
  1291.                wordadr:=usebits[calcmmode];
  1292.                SerialDAC:=false;
  1293.              end;
  1294.     __Matrox:begin
  1295.                if (rgs.xxregs.x[$D] and $40)>0 then
  1296.                begin
  1297.                  ilace:=true;
  1298.                  if (rgs.xxregs.x[1] and 8)=0 then   {not Ext 256c}
  1299.                    wordadr:=wordadr shr 1;
  1300.                end;
  1301.                if (rgs.xxregs.x[1] and 8)>0 then   {Ext 256c}
  1302.                  wordadr:=wordadr shl 2;
  1303.  
  1304.              end;
  1305.       __mxic:if (rgs.seqregs.x[$F0] and 3)=3 then ilace:=true;
  1306.        __NCR:begin
  1307.            if (rgs.seqregs.x[$20] and 2)<>0 then
  1308.            begin
  1309.          force256:=true;
  1310.          wordadr:=8;
  1311.            end;
  1312.            if (rgs.seqregs.x[$1F] and $10)<>0 then
  1313.          case rgs.seqregs.x[$1F] and 15 of
  1314.            0:pixwid:=4;
  1315.           11:pixwid:=16;
  1316.          else pixwid:=(rgs.seqregs.x[$1F] and 15)+6;
  1317.          end;
  1318.            if (rgs.crtcregs.x[$30] and $10)<>0 then
  1319.            begin
  1320.          ilace:=true;
  1321.          extlinfact:=1;
  1322.            end;
  1323.                if (rgs.crtcregs.x[$30] and  1)>0 then inc(calchtot,256);
  1324.            if (rgs.crtcregs.x[$30] and  2)>0 then inc(calcpixels,256);
  1325.                if (rgs.crtcregs.x[$30] and  4)>0 then inc(calchblks,256);
  1326.                if (rgs.crtcregs.x[$30] and  8)>0 then inc(calchrtrs,256);
  1327.            if (rgs.crtcregs.x[$31] and 16)>0 then inc(wid,256);
  1328.                if cv.version>=NCR_77c22Ep then
  1329.                begin
  1330.                  if (rgs.crtcregs.x[$32] and 1)>0 then inc(calchtot,512);
  1331.                  if (rgs.crtcregs.x[$32] and 2)>0 then inc(calcpixels,512);
  1332.                  if (rgs.crtcregs.x[$32] and 4)>0 then inc(calchblks,512);
  1333.                  if (rgs.crtcregs.x[$32] and 8)>0 then inc(calchrtrs,512);
  1334.                  if (rgs.crtcregs.x[$33] and 1)>0 then inc(calcvtot,1024);
  1335.                  if (rgs.crtcregs.x[$33] and 2)>0 then inc(calclines,1024);
  1336.                  if (rgs.crtcregs.x[$33] and 4)>0 then inc(calcvblks,1024);
  1337.                  if (rgs.crtcregs.x[$33] and 8)>0 then inc(calcvrtrs,1024);
  1338.                  if (rgs.crtcregs.x[$30] and 32)>0 then
  1339.                  begin
  1340.                    inc(calchblke,(rgs.crtcregs.x[$32] and $30) shl 2);
  1341.                    hblkmask:=$FF;
  1342.                    inc(calchrtre,(rgs.crtcregs.x[$32] and $C0) shr 1);
  1343.                    hrtrmask:=$7F;
  1344.                    calcvblke:=rgs.crtcregs.x[$16]+((rgs.crtcregs.x[$33] and $60) shl 3);
  1345.                    vblkmask:=$3FF;
  1346.                    inc(calchrtre,(rgs.crtcregs.x[$33] and $80) shr 3);
  1347.                    vrtrmask:=$1F;
  1348.                  end;
  1349.                end;
  1350.          end;
  1351.        __oak:if cv.version<>OAK_037 then
  1352.              begin
  1353.            if (rgs.xxregs.x[$14] and 128)<>0 then ilace:=true;
  1354.                if (rgs.xxregs.x[$14] and 1)>0 then inc(calcvtot,1024);
  1355.                if (rgs.xxregs.x[$14] and 2)>0 then inc(calclines,1024);
  1356.                if (rgs.xxregs.x[$14] and 4)>0 then inc(calcvrtrs,1024);
  1357.                if cv.Version<=OAK_083 then
  1358.                begin
  1359.                  if (rgs.seqregs.x[4] and 8)<>0 then wordadr:=16;
  1360.                       {Cheat for 256 color mode}
  1361.                end
  1362.                else begin
  1363.                  if (rgs.seqregs.x[4] and 8)<>0 then
  1364.                    if (rgs.xxregs.x[$21] and 4)>0 then wordadr:=16
  1365.                                                   else pixwid:=4;
  1366.                end;
  1367.          end;
  1368.      __p2000:begin
  1369.            if (rgs.grcregs.x[$13] and $40)<>0 then
  1370.            begin
  1371.          wordadr:=wordadr shr 1;
  1372.          ilace:=true;
  1373.            end;
  1374.            if (rgs.grcregs.x[$21] and $20)<>0 then inc(wid,256);
  1375.          end;
  1376.         __WD:begin
  1377.            if (cv.version>=WD_90c00) then
  1378.                  if (rgs.crtcregs.x[$2D] and $20)>0 then ilace:=true;
  1379.            if (cv.version>=WD_90c30) then
  1380.                begin
  1381.                  if (rgs.crtcregs.x[$3D] and 1)>0 then inc(calcvtot,1024);
  1382.                  if (rgs.crtcregs.x[$3D] and 2)>0 then inc(calclines,1024);
  1383.                  if (rgs.crtcregs.x[$3D] and 4)>0 then inc(calcvrtrs,1024);
  1384.                  if (rgs.crtcregs.x[$3D] and 8)>0 then inc(calcvblks,1024);
  1385.                end;
  1386.            if (rgs.seqregs.x[4] and 8)>0 then wordadr:=8;
  1387.                       {Cheat for 256 color mode}
  1388.          {  if (rgs.grcregs.x[$C] and 2)>0 then inc(clksel,4);
  1389.            vclk:=WDclk[clksel];  }
  1390.            if (cv.version>=WD_90c33) and ((rgs.crtcregs.x[$3E] and $20)>0) then inc(calchtot,256);
  1391.          end;
  1392.    __realtek:begin
  1393.            if (rgs.seqregs.x[4] and 8)<>0 then
  1394.                begin
  1395.                  pixwid:=4;
  1396.                  hfreqfact:=2;
  1397.                end;
  1398.            if (rgs.grcregs.x[$C] and $10)<>0 then
  1399.            begin
  1400.          pixwid:=pixwid*2;
  1401.          wid:=wid*2;
  1402.            end;
  1403.            if (rgs.crtcregs.x[$19] and 1)<>0 then
  1404.            begin
  1405.          ilace:=true;
  1406.          wid:=wid div 2;
  1407.            end;
  1408.          end;
  1409.     __s3:begin
  1410.            if (rgs.crtcregs.x[$42] and $20)<>0 then ilace:=true;
  1411.            if (rgs.crtcregs.x[$43] and 4)<>0   then inc(wid,256);
  1412.            if (rgs.crtcregs.x[$43] and $80)<>0 then pixwid:=pixwid*2;
  1413.            if (rgs.seqregs.x[4] and 8)<>0 then wordadr:=8 else wordadr:=2;
  1414.            if (rgs.attregs[$10] and 1)=0 then wid:=wid*2;
  1415.                if (rgs.crtcregs.x[$3A] and $10)>0 then force256:=true;
  1416.                if (cv.Version>S3_924) then
  1417.                begin
  1418.                  if (rgs.crtcregs.x[$5D] and  1)>0 then inc(calchtot,256);
  1419.                  if (rgs.crtcregs.x[$5D] and  2)>0 then inc(calcpixels,256);
  1420.                  if (rgs.crtcregs.x[$5D] and  4)>0 then inc(calchblks,256);
  1421.                  if (rgs.crtcregs.x[$5D] and 16)>0 then inc(calchrtrs,256);
  1422.                  if (rgs.crtcregs.x[$5E] and  1)>0 then inc(calcvtot,1024);
  1423.                  if (rgs.crtcregs.x[$5E] and  2)>0 then inc(calclines,1024);
  1424.                  if (rgs.crtcregs.x[$5E] and  4)>0 then inc(calcvblks,1024);
  1425.                  if (rgs.crtcregs.x[$5E] and 16)>0 then inc(calcvrtrs,1024);
  1426.                  if (rgs.crtcregs.x[$51] and $30)>0 then
  1427.                    wid:=(wid and $FF)+(rgs.crtcregs.x[$51] and $30) shl 4;
  1428.                end;
  1429.          end;
  1430.         __SC:wid:=wid+(rgs.crtcregs.x[$1E] and $30) shl 4;
  1431.        __SiS:begin
  1432.                wid:=wid+(rgs.seqregs.x[$A] and $F0) shl 4;
  1433.                if (rgs.seqregs.x[6] and $20)>0 then
  1434.                begin
  1435.                  ilace:=true;
  1436.                  wid:=wid shr 1;
  1437.                end;
  1438.              end;
  1439.       __trid:begin
  1440.                if memmode>=_P8 then wordadr:=8;   {Req'd for 9440 800x600 16bit}
  1441.            if (rgs.tridold0d and 16)<>0 then wordadr:=wordadr*2
  1442.            else if cv.version<TR_GUI9440 then
  1443.                begin
  1444.                  if (rgs.seqregs.x[4] and 8)>0 then pixwid:=pixwid div 2;
  1445.                  if memmode>=_p8 then vclkdiv:=vclkdiv*2;
  1446.                end;
  1447.            if (rgs.crtcregs.x[$1e] and 4)<>0 then
  1448.                  if cv.version=TR_IITAGX then isilace:=true
  1449.                  else begin
  1450.                    ilace:=true;
  1451.                    if cv.version<TR_GUI9440 then wordadr:=wordadr div 2;
  1452.                  end;
  1453.                if (cv.mm=512) and (memmode>=_p8) and
  1454.                  (cv.version<TR_IITAGX) then hfreqfact:=2;
  1455.                if (rgs.grcregs.x[$F] and 8)>0 then pixwid:=pixwid*2;
  1456.                if (rgs.crtcregs.x[$29] and $10)>0 then inc(wid,256);
  1457.          end;
  1458.      __Tseng:if cv.version=ET_3000 then
  1459.              begin
  1460.            if (rgs.crtcregs.x[$25] and $80)>0 then ilace:=true;
  1461.                if (rgs.crtcregs.x[$25] and 1)>0 then inc(calcvblks,1024);
  1462.                if (rgs.crtcregs.x[$25] and 2)>0 then inc(calcvtot,1024);
  1463.                if (rgs.crtcregs.x[$25] and 4)>0 then inc(calclines,1024);
  1464.                if (rgs.crtcregs.x[$25] and 8)>0 then inc(calcvrtrs,1024);
  1465.            if (rgs.grcregs.x[5] and $40)>0 then wordadr:=16;
  1466.            if (rgs.seqregs.x[7] and $40)>0 then
  1467.            begin
  1468.          pixwid:=pixwid*2;
  1469.          wordadr:=wordadr*2;
  1470.            end;
  1471.          end
  1472.              else begin
  1473.                if (rgs.crtcregs.x[$3F] and $80)>0 then inc(wid,256);
  1474.                if (rgs.crtcregs.x[$3F] and  1)>0 then inc(calchtot,256);
  1475.                if (rgs.crtcregs.x[$3F] and  4)>0 then inc(calchblks,256);
  1476.                if (rgs.crtcregs.x[$3F] and 16)>0 then inc(calchrtrs,256);
  1477.                if (rgs.crtcregs.x[$35] and 1)>0 then inc(calcvblks,1024);
  1478.                if (rgs.crtcregs.x[$35] and 2)>0 then inc(calcvtot,1024);
  1479.                if (rgs.crtcregs.x[$35] and 4)>0 then inc(calclines,1024);
  1480.                if (rgs.crtcregs.x[$35] and 8)>0 then inc(calcvrtrs,1024);
  1481.                if (rgs.crtcregs.x[$35] and $80)>0 then isilace:=true;
  1482.                if (rgs.attregs[$10] and $40)>0 then pixwid:=4;
  1483.            {    if ((rgs.attregs[$16] and $20)>0) and (cv.version>=ET_4W32P) then pixwid:=pixwid*2; }
  1484.              end;
  1485.        __UMC:begin
  1486.            if (rgs.crtcregs.x[$33] and $10)>0 then wordadr:=16
  1487.                else if ((rgs.attregs[$10] and 64)>0) then
  1488.                begin
  1489.                  pixwid:=4;
  1490.                  hfreqfact:=2;
  1491.                end;
  1492.            if (rgs.crtcregs.x[$2F] and 1)>0 then
  1493.            begin
  1494.          ilace:=true;
  1495.          wordadr:=wordadr div 2;
  1496.                  dec(calclines);
  1497.            end;
  1498.          end;
  1499.     __video7:begin
  1500.            if (rgs.seqregs.x[$E0] and 1)<>0 then ilace:=true;
  1501.                if (rgs.attregs[$10] and $40)>0 then
  1502.                begin
  1503.                  pixwid:=4;
  1504.                  wordadr:=8;
  1505.                  hfreqfact:=2;
  1506.                end;
  1507.                if (rgs.seqregs.x[$C8] and $10)>0 then
  1508.                begin
  1509.                  force256:=true;
  1510.                  wordadr:=8;
  1511.                end;
  1512.          end;
  1513.     __Weitek:begin
  1514.                if (rgs.grcregs.x[$C] and 4)>0 then
  1515.                begin
  1516.                  wordadr:=8;
  1517.                  force256:=true;
  1518.                end;
  1519.              end;
  1520.  __xbe,__xga:begin
  1521.            calchtot  :=rgs.xxregs.x[$11]*256+rgs.xxregs.x[$10]+1;
  1522.            calcpixels:=rgs.xxregs.x[$13]*256+rgs.xxregs.x[$12]+1;
  1523.            calchblks :=rgs.xxregs.x[$15]*256+rgs.xxregs.x[$14]+1;
  1524.            calchblke :=rgs.xxregs.x[$17]*256+rgs.xxregs.x[$16]+1;
  1525.            calchrtrs :=rgs.xxregs.x[$19]*256+rgs.xxregs.x[$18]+1;
  1526.            calchrtre :=rgs.xxregs.x[$1B]*256+rgs.xxregs.x[$1A]+1;
  1527.            pixwid:=8;
  1528.            calclines :=rgs.xxregs.x[$23]*256+rgs.xxregs.x[$22]+1;
  1529.            calcvtot  :=rgs.xxregs.x[$21]*256+rgs.xxregs.x[$20]+1;
  1530.            calcvblks :=rgs.xxregs.x[$25]*256+rgs.xxregs.x[$24]+1;
  1531.            calcvblke :=rgs.xxregs.x[$27]*256+rgs.xxregs.x[$26]+1;
  1532.            calcvrtrs :=rgs.xxregs.x[$29]*256+rgs.xxregs.x[$28]+1;
  1533.            calcvrtre :=rgs.xxregs.x[$2B]*256+rgs.xxregs.x[$2A]+1;  {Hm!!}
  1534.            wid :=rgs.xxregs.x[$44]*256+rgs.xxregs.x[$43];
  1535.            wordadr:=8;
  1536.                case rgs.xxregs.x[$51] and 7 of
  1537.                  2:calcmmode:=_pk4;
  1538.                  3:calcmmode:=_p8;
  1539.                  4:calcmmode:=_p16;  {or _p15}
  1540.                  5:calcmmode:=_p24;
  1541.                end;
  1542.                if (rgs.xxregs.x[$50] and 8)>0 then isilace:=true;
  1543.          end;
  1544.     end;
  1545.  
  1546.     if (cv.flags and FLG_StdVGA)>0 then
  1547.     begin
  1548.       calchblke:=(calchblks and (not hblkmask))+calchblke;
  1549.       if calchblke<=calchblks then inc(calchblke,hblkmask+1);
  1550.       if calchblke>calchtot then calchblke:=calchtot+(hblkmask and calchblke);
  1551.       calchrtre:=(calchrtrs and (not hrtrmask))+calchrtre;
  1552.       if calchrtre<=calchrtrs then inc(calchrtre,hrtrmask+1);
  1553.       if calchrtre>calchtot then calchrtre:=calchtot+(hrtrmask and calchrtre);
  1554.       calcvblke:=(calcvblks and (not vblkmask))+calcvblke;
  1555.       if calcvblke<=calcvblks then inc(calcvblke,vblkmask+1);
  1556.       calcvrtre:=(calcvrtrs and (not vrtrmask))+calcvrtre;
  1557.       if calcvrtre<=calcvrtrs then inc(calcvrtre,vrtrmask+1);
  1558.  
  1559.       if (rgs.crtcregs.x[$17] and 4)>0 then
  1560.       begin
  1561.         calclines:=calclines*2;
  1562.         calcvtot:=calcvtot*2;
  1563.       end;
  1564.       if ilace then calclines:=calclines*2;
  1565.       if isilace then ilace:=true;
  1566.       if (rgs.attregs[$10] and 1)=0 then  {Text}
  1567.       begin
  1568.         calclines:=calclines div ((rgs.crtcregs.x[9] and $1F)+1);
  1569.         if (rgs.attregs[$10] and 2)=0 then calcmmode:=_TEXT
  1570.                       else calcmmode:=_TXT4;
  1571.         pixwid:=charwid;
  1572.       end
  1573.       else begin
  1574.         if ((rgs.crtcregs.x[$17] and 1)=0)
  1575.           and ((rgs.attregs[$10] and 64)=0) then {CGA}
  1576.         begin
  1577.       if (rgs.crtcregs.x[$17] and $40)>0 then calcmmode:=_cga1
  1578.                          else calcmmode:=_cga2;
  1579.       extlinfact:=extlinfact shr 1;
  1580.         end
  1581.         else if ((rgs.attregs[$10] and 64)=0) and ((rgs.grcregs.x[5] and 64)=0)
  1582.           and not force256 then  {16 color}
  1583.         begin
  1584.       if ((rgs.attregs[$10] and 2)>0) then calcmmode:=_pl1
  1585.       else if (rgs.attregs[$12]=5) then
  1586.       begin
  1587.         calcmmode:=_pl2;
  1588.         pixwid:=pixwid*2;
  1589.       end
  1590.       else if (rgs.seqregs.x[4] and 8)>0 then calcmmode:=_pk4
  1591.                          else calcmmode:=_pl4;
  1592.         end
  1593.         else calcmmode:=_p8;
  1594.       end;
  1595.     end;
  1596.  
  1597.  
  1598.     if (calcmmode>=_PK4) and (cv.dactype>_dac8) then
  1599.     begin
  1600.       x:=rgs.dacregs[6]{getdaccomm};
  1601.  
  1602.       case cv.dactype of
  1603.    _dac15:if x>127 then calcmmode:=_p15;
  1604.    _dac16:case (x and $c0) of
  1605.            $80:calcmmode:=_p15;
  1606.            $c0:calcmmode:=_p16;
  1607.           end;
  1608.  _dacALG1101:
  1609.           if (cv.chip=__ALG) and ((rgs.crtcregs.x[$19] and 16)>0) then
  1610.             calcmmode:=_p16;     {Only used on ALG chips ??}
  1611.  _dacMU1880:
  1612.           begin
  1613.             outp($3C8,0);
  1614.             for m:=1 to 4 do x:=inp($3C6);
  1615.               while x<>$8e do x:=inp($3C6);
  1616.               x:=inp($3C6);
  1617.               rgs.stdregs[$3c1]:=x;
  1618.               case x of
  1619.                 $A6:calcmmode:=_p16;
  1620.                 $A0:calcmmode:=_p15;
  1621.                 $9E:calcmmode:=_p24b;
  1622.               end;
  1623.           end;
  1624.  _dacICS5301,_dacMU4910,_dacMU9910,_dacATT490,_dacATT491,_dacATT492,
  1625.  _dacATT493,_dacCH8391:
  1626.           case (x and $E0) of
  1627.          $80,$A0:calcmmode:=_p15;
  1628.              $C0:calcmmode:=_p16;
  1629.              $E0:calcmmode:=_p24;
  1630.           end;
  1631.  _dacATT498,_dacATT1498,_dacATT2498:
  1632.           case x shr 4 of
  1633.             1:begin
  1634.                 calcmmode:=_p15;
  1635.                 pixwid:=pixwid*2;
  1636.                 vclkdiv:=vclkdiv div 2;
  1637.               end;
  1638.             2:begin
  1639.                 pixwid:=pixwid*2;
  1640.                 vclkdiv:=vclkdiv div 2;
  1641.               end;
  1642.             3:begin
  1643.                 calcmmode:=_p16;
  1644.                 pixwid:=pixwid*2;
  1645.                 vclkdiv:=vclkdiv div 2;
  1646.               end;
  1647.             5:begin
  1648.                 calcmmode:=_p32;
  1649.                 pixwid:=pixwid*2;
  1650.                 vclkdiv:=vclkdiv div 2;
  1651.               end;
  1652.             6:calcmmode:=_p16;
  1653.            10:calcmmode:=_p15;
  1654.           end;
  1655.  _dacALG1201,_dacALG1301:
  1656.           case (x and $E0) of
  1657.             $A0:calcmmode:=_p15;
  1658.             $C0:calcmmode:=_p16;
  1659.             $E0:calcmmode:=_p24;
  1660.           end;
  1661.  _dacADAC1:
  1662.           case (x and $C7) of
  1663.             $C1:calcmmode:=_p16;
  1664.             $C5:calcmmode:=_p24;
  1665.             $80:calcmmode:=_p15;
  1666.           end;
  1667.  _dacSC15021,_dacSC15025:
  1668.           begin
  1669.             case (x and $E1) of
  1670.               $41:calcmmode:=_p32b;
  1671.               $40:calcmmode:=_p32;
  1672.               $61:calcmmode:=_p24b;
  1673.               $60:calcmmode:=_p24;
  1674.   $80,$81,$A0,$A1:calcmmode:=_p15;
  1675.           $C0,$E0:calcmmode:=_p16;
  1676.             end;
  1677.             if rgs.dacinxd.x[$10]>0 then
  1678.             begin
  1679.               pixwid:=pixwid*2;
  1680.               vclkdiv:=vclkdiv div 2;
  1681.             end;
  1682.           end;
  1683. _dacTR8001:case x and $E0 of
  1684.              $A0:calcmmode:=_p15;
  1685.              $E0:calcmmode:=_p16;
  1686.              $C0:calcmmode:=_p24;
  1687.            end;
  1688. _dacUMC188:case (x and $D0) of
  1689.              $80:calcmmode:=_p15;
  1690.              $C0:calcmmode:=_p16;
  1691.  $10,$50,$90,$D0:calcmmode:=_p24;
  1692.            end;
  1693.   _dacSTG1700,_dacSTG1702,_dacSTG1703:
  1694.            if (x and 8)>0 then
  1695.              case rgs.dacinxd.x[3] of
  1696.                1:begin
  1697.                    calcmmode:=_P15;
  1698.                    pixwid:=pixwid*2;
  1699.                  end;
  1700.                2:begin
  1701.                    calcmmode:=_p15;
  1702.                    pixwid:=pixwid*2;
  1703.                    vclkdiv:=vclkdiv div 2;
  1704.                  end;
  1705.                3:begin
  1706.                    calcmmode:=_p16;
  1707.                    pixwid:=pixwid*2;
  1708.                    vclkdiv:=vclkdiv div 2;
  1709.                  end;
  1710.                4:begin
  1711.                    calcmmode:=_P32;
  1712.                    pixwid:=pixwid*2;
  1713.                    vclkdiv:=vclkdiv div 2;
  1714.                  end;
  1715.                5:begin  {P8 - two pixels/clock}
  1716.                    calcmmode:=_P8;
  1717.                    vclkdiv:=vclkdiv div 2;
  1718.                  end;
  1719.                6:begin
  1720.                    calcmmode:=_P16;
  1721.                    pixwid:=pixwid*2;
  1722.                  end;
  1723.                9:begin
  1724.                    calcmmode:=_p24;
  1725.                    pixwid:=pixwid*2;
  1726.                    vclkdiv:=vclkdiv div 2;
  1727.                  end;
  1728.              end
  1729.              else
  1730.                case x and $E0 of
  1731.                  $A0:calcmmode:=_p15;
  1732.                  $C0:calcmmode:=_p16;
  1733.                  $E0:calcmmode:=_p24;
  1734.                end;
  1735. _dacCH8398:case rgs.dacregs[dacHIcmd] shr 4 of
  1736.              6:calcmmode:=_p16;
  1737.              3:begin
  1738.                  calcmmode:=_p16;
  1739.                  pixwid:=pixwid*2;
  1740.                  vclkdiv:=vclkdiv div 2;
  1741.                end;
  1742.              7:calcmmode:=_p24;  {24bpp = 2pixels/3VCLKs}
  1743.             $B:begin  {24bpp = 2pixels/3VCLKs}
  1744.                  calcmmode:=_p24;
  1745.                  pixwid:=pixwid*2;
  1746.                  vclkdiv:=vclkdiv div 2;
  1747.                end;
  1748.             $C:calcmmode:=_p15;
  1749.              1:begin  {15bit 1VCLK/pixel}
  1750.                  calcmmode:=_p15;
  1751.                  pixwid:=pixwid*2;
  1752.                  vclkdiv:=vclkdiv div 2;
  1753.                end;
  1754.            end;
  1755.  _dacS3_708,_dacS3_716:
  1756.            case rgs.dacregs[dacHIcmd] and $F0 of
  1757.                (*  $10:begin  {2 8bpp pixels/VCLK}
  1758.                        vclkdiv:=vclkdiv div 2;
  1759.                      end; *)
  1760.              $20:calcmmode:=_p15;
  1761.              $30:begin
  1762.                    calcmmode:=_p15;
  1763.                    vclkdiv:=vclkdiv div 2;
  1764.                  end;
  1765.              $50:begin
  1766.                    calcmmode:=_p16;
  1767.                    vclkdiv:=vclkdiv div 2;
  1768.                  end;
  1769.              $60:calcmmode:=_p16;
  1770.              $70:begin  {32bpp = 2 VCLKs}
  1771.                    calcmmode:=_p32;
  1772.                    vclkdiv:=vclkdiv div 2;
  1773.                  end;
  1774.              $E0:calcmmode:=_p24;
  1775.            end;
  1776.  _dacBt481,_dacBt482:
  1777.            case rgs.dacregs[6] and $F0 of
  1778.              $A0:calcmmode:=_P15;
  1779.              $E0:calcmmode:=_P16;
  1780.              $F0:calcmmode:=_P24;
  1781.            end;
  1782.  _dacBt484,_dacBt485,_dacATT504,_dacATT505:
  1783.            if (rgs.dacregs[9] and $20)>0 then
  1784.            begin
  1785.              case rgs.dacregs[8] and $78 of
  1786.                $10:calcmmode:=_p32;
  1787.                $30:calcmmode:=_p15;
  1788.                $38:calcmmode:=_p16;
  1789.                $60:calcmmode:=_pk4;
  1790.              end;
  1791.              pixwid:=pixwid*4;
  1792.              if (cv.dactype=_dacBt485) or (cv.dactype=_dacATT505) then
  1793.                if (rgs.dacregs[16] and 8)>0 then vclkdiv:=vclkdiv div 2; {clk*2}
  1794.            end;
  1795.  _dacTVP3010,_dacTVP3020,_dacTVP3025,_dacTVP3026:
  1796.            begin
  1797.              case rgs.dacinxd.x[$18] and $CF of
  1798.                $C:calcmmode:=_P15;
  1799.                $D:calcmmode:=_P16;
  1800.              6,$E:calcmmode:=_P32;
  1801.              end;
  1802.              if (rgs.dacinxd.x[$1A] and $10)>0 then
  1803.              begin
  1804.                vclkdiv:=vclkdiv div 2;
  1805.                pixwid:=pixwid*2;
  1806.              end;
  1807.              SerialDAC:=false;
  1808.            end;
  1809.  _dacTLC34075:
  1810.            begin    {TLC34075}
  1811.              if (rgs.dacregs[9]=1) then {On the ATI Mach32 the VCLK is
  1812.                                          looped back to CLK1, really should
  1813.                                          test explicitly for such loops }
  1814.                case (rgs.dacregs[10] shr 3) and 7 of
  1815.                  1:vclkdiv:=vclkdiv*2;
  1816.                  2:vclkdiv:=vclkdiv*4;
  1817.                  3:vclkdiv:=vclkdiv*8;
  1818.                  4:vclkdiv:=vclkdiv*16;
  1819.                  5:vclkdiv:=vclkdiv*32;
  1820.                end;
  1821.              SerialDAC:=false;
  1822.            end;
  1823.    _dacInt:case cv.chip of
  1824.              __chips:case rdinx(cv.IOadr,6) and $C of
  1825.                        0:if (cv.Version=CT_64300) and
  1826.                            ((rgs.xxregs.x[$28] and $10)=0) then calcmmode:=_pk4;
  1827.                        4:calcmmode:=_p15;
  1828.                        8:calcmmode:=_p24;
  1829.                       $C:calcmmode:=_p16;
  1830.                      end;
  1831.              __cir54:begin
  1832.                        case x and $CF of
  1833.                      $80,$C0:calcmmode:=_p15;
  1834.                          $C1:calcmmode:=_p16;
  1835.                          $C5:if (cv.Version>=CL_GD5430) and
  1836.                                ((rgs.seqregs.x[7] and 8)>0) then calcmmode:=_p32
  1837.                              else calcmmode:=_p24;
  1838.                          $C8:;  {8bit Grey scale}
  1839.                          $C9:;  {3-3-2 RGB}
  1840.                        end;
  1841.                        SerialDAC:=false;
  1842.                      end;
  1843.                 __WD:case rdinx(SEQ,$26) and $C of
  1844.                        4:calcmmode:=_P16;
  1845.                      {  8:calcmmode:=_p16b;  }
  1846.                       $C:calcmmode:=_P15;
  1847.                      end;
  1848.                 __S3:case rgs.crtcregs.x[$67] shr 4 of
  1849.                       { 1:vclkdiv:=vclkdiv div 2;  {2px/VCLK}
  1850.                        3:begin
  1851.                            calcmmode:=_P15;
  1852.                            vclkdiv:=vclkdiv div 2;  {1px/VCLK}
  1853.                          end;
  1854.                        5:begin
  1855.                            calcmmode:=_P16;
  1856.                            vclkdiv:=vclkdiv div 2;  {1px/VCLK}
  1857.                          end;
  1858.                        7:begin
  1859.                            calcmmode:=_P32;
  1860.                            vclkdiv:=vclkdiv div 2;  {1px/2VCLK}
  1861.                          end;
  1862.                       13:begin
  1863.                            calcmmode:=_P32;    {1px/VCLK}
  1864.                            SerialDAC:=false;
  1865.                          end;
  1866.                      end;
  1867.                __SiS:begin
  1868.                        case rgs.seqregs.x[6] and $1C of
  1869.                           4:calcmmode:=_P15;
  1870.                           8:calcmmode:=_P16;
  1871.                          16:calcmmode:=_P24;
  1872.                        end;
  1873.                        SerialDAC:=false;
  1874.                      end;
  1875.               __Trid:if cv.version<TR_GUI9440 then
  1876.                        case rgs.dacregs[6] shr 5 of
  1877.                          5:calcmmode:=_p15;
  1878.                          7:calcmmode:=_p16;
  1879.                          6:calcmmode:=_p24;
  1880.                        end
  1881.                      else begin
  1882.                        case rgs.dacregs[6] shr 4 of
  1883.                          1:calcmmode:=_p15;
  1884.                          3:calcmmode:=_p16;
  1885.                         13:begin
  1886.                              calcmmode:=_p24;
  1887.                              SerialDAC:=false;
  1888.                              vclkdiv:=vclkdiv*3;
  1889.                            end;
  1890.                        end;
  1891.                      end;
  1892.            end;
  1893.       end;
  1894.       if SerialDAC then
  1895.     case calcmmode of               {Adjust for HiColor}
  1896.       _p15,_p16:begin
  1897.                   pixwid:=pixwid div 2;
  1898.                   vclkdiv:=vclkdiv*2;
  1899.                 end;
  1900.      _P24,_P24b:begin
  1901.                   calcpixels:=calcpixels div 3;
  1902.                   calchtot:=calchtot div 3;
  1903.                   calchblks:=calchblks div 3;
  1904.                   calchblke:=calchblke div 3;
  1905.                   calchrtrs:=calchrtrs div 3;
  1906.                   calchrtre:=calchrtre div 3;
  1907.                   vclkdiv:=vclkdiv*3;
  1908.                 end;
  1909.            _p32:begin
  1910.                   pixwid:=pixwid div 4;
  1911.                   vclkdiv:=vclkdiv*4;
  1912.                 end;
  1913.     end;
  1914.     end;
  1915.   end;
  1916.   if calcmmode>=_herc then calcpixels:=calcpixels*pixwid;
  1917.   calcbytes:=wid*wordadr;
  1918.  
  1919.   vclk:=GetClockFreq;
  1920.  
  1921.  
  1922.   calchtot :=calchtot*pixwid;
  1923.   calchblks:=calchblks*pixwid;
  1924.   calchblke:=calchblke*pixwid;
  1925.   calchrtrs:=calchrtrs*pixwid;
  1926.   calchrtre:=calchrtre*pixwid;
  1927.   vclk:=(vclk*12) div vclkdiv;
  1928.   if vclk>0 then
  1929.   begin
  1930.     hclk:=(vclk*1000) div (calchtot*hfreqfact);
  1931.     fclk:=(hclk*1000) div calcvtot;
  1932.   end;
  1933.   if extlinfact>0 then calclines:=calclines div extlinfact;
  1934.   BWlow :=hclk;
  1935.   case memmode of
  1936.  _PL4,_PK4,_PK4a:BWlow:=BWlow div 2;
  1937.        _P15,_P16:BWlow:=BWlow*2;
  1938.       _P24,_P24b:BWlow:=BWlow*3;
  1939.      _P32.._P32d:BWlow:=BWlow*4;
  1940.   end;
  1941.  
  1942.   BWhigh:=(BWlow*calchtot) div 1000;
  1943.   BWlow :=(BWlow*calcpixels) div 1000;
  1944.  
  1945.   if memmode<=_TXT4 then
  1946.   begin
  1947.     BWlow :=BWlow*3;
  1948.     BWhigh:=(BWhigh*3) div 8;
  1949.   end;
  1950.  
  1951.   if VESAcheat then cv.chip:=__VESA;
  1952.   rgs.bytes :=calcbytes;
  1953.   rgs.pixels:=calcpixels;
  1954.   rgs.lins  :=calclines;
  1955.   rgs.mmode :=calcmmode;
  1956.   rgs.chip  :=cv.chip;
  1957. end;
  1958.  
  1959.  
  1960. procedure AnalyseMode;
  1961. begin
  1962.   DumpRegisters;
  1963.   CalcRegisters;
  1964. end;
  1965.  
  1966. procedure wrregs(var rg:regblk);
  1967. var x:word;
  1968. begin
  1969.   write(hex4(rg.base)+':');
  1970.   for x:=0 to rg.nbr do
  1971.   begin
  1972.     if (x mod 25=0) and (x>0) then
  1973.       write('('+hex2(x)+'):');
  1974.  
  1975.     write(' '+hex2(rg.x[x]));
  1976.   end;
  1977.   writeln;
  1978. end;
  1979.  
  1980. function dumpVGAregs:word;
  1981. var x,y:word;
  1982. begin
  1983.   settextmode;  {Set 43/50 line text mode}
  1984.   writeln('Mode: '+hex2(rgs.mode)+'h Pixels: '+istr(rgs.pixels)+' lines: '+istr(rgs.lins)
  1985.        +' bytes: '+istr(rgs.bytes)+' colors: '+istr(modecols[rgs.mmode]));
  1986.   writeln;
  1987.   if oldreg then writeln('SEQ (OLD): 0Dh: ',hex2(rgs.tridold0d)
  1988.                   ,' 0Eh: ',hex2(rgs.tridold0e));
  1989.  
  1990.   for x:=$3C0 to $3CF do write(' '+hex2(rgs.stdregs[x]));
  1991.   writeln;
  1992.   for x:=$3D0 to $3DF do write(' '+hex2(rgs.stdregs[x]));
  1993.   writeln;
  1994.   write('03C0:');
  1995.   for x:=0 to 31 do
  1996.   begin
  1997.     if x=25 then write('(19):');
  1998.     write(' '+hex2(rgs.attregs[x]));
  1999.   end;
  2000.   writeln;
  2001.   wrregs(rgs.seqregs);
  2002.   wrregs(rgs.grcregs);
  2003.   wrregs(rgs.crtcregs);
  2004.   if rgs.xxregs.base<>0 then
  2005.   begin
  2006.     if (rgs.xxregs.base and $ff8f)=$210A then
  2007.     begin
  2008.       write(hex4(rgs.xxregs.base and $fff0)+':');
  2009.       for x:=0 to 15 do write(' '+hex2(rgs.xgaregs[x]));
  2010.       writeln;
  2011.     end;
  2012.     wrregs(rgs.xxregs);
  2013.   end;
  2014.   writeln;
  2015.   write('DAC: ');
  2016.   for x:=0 to 16 do
  2017.     write(' '+hex2(rgs.dacregs[x]));
  2018.   writeln;
  2019.   if rgs.dacinxd.base<>0 then wrregs(rgs.dacinxd);
  2020.   dumpVGAregs:=getkey;
  2021. end;
  2022.  
  2023. function FormatRgs(var b:byte):word;   {Format registers for dump}
  2024. type
  2025.   barr=array[1..2000] of byte;
  2026. var
  2027.   blk:^barr;
  2028.   bts,x:word;
  2029.  
  2030. procedure appb(b:byte);
  2031. begin
  2032.   inc(bts);
  2033.   blk^[bts]:=b;
  2034. end;
  2035.  
  2036. procedure appw(w:word);
  2037. begin
  2038.   appb(lo(w));
  2039.   appb(hi(w));
  2040. end;
  2041.  
  2042. procedure apprgs(var r:regblk);
  2043. var x:word;
  2044. begin
  2045.   appw(1);
  2046.   appw(r.base);
  2047.   appb(0);
  2048.   appb(r.nbr);
  2049.   for x:=0 to r.nbr do appb(r.x[x]);
  2050. end;
  2051.  
  2052. begin
  2053.   blk:=@b;
  2054.   bts:=0;
  2055.   appw(1);
  2056.   appw($3C0);
  2057.   appb(0);
  2058.   appb(31);
  2059.   for x:=0 to 31 do appb(rgs.attregs[x]);
  2060.   apprgs(rgs.seqregs);
  2061.   apprgs(rgs.grcregs);
  2062.   apprgs(rgs.crtcregs);
  2063.   if rgs.xxregs.base<>0 then apprgs(rgs.xxregs);
  2064.   if oldreg then
  2065.   begin
  2066.     appw($FF);
  2067.     appw(0);
  2068.     appb(rgs.tridold0d);
  2069.     appw($FF);
  2070.     appw(1);
  2071.     appb(rgs.tridold0e);
  2072.   end;
  2073.   for x:=0 to 16 do {DAC registers 0-10h}
  2074.   begin
  2075.     appw($FF);
  2076.     appw($F000+x);
  2077.     appb(rgs.dacregs[x]);
  2078.   end;
  2079.   if rgs.dacinxd.nbr>0 then apprgs(rgs.dacinxd);
  2080.   if (rgs.xxregs.base and $FF8F)=$210A then
  2081.   begin
  2082.     appw(16);
  2083.     appw(rgs.xxregs.base-$A);
  2084.     for x:=0 to 15 do appb(rgs.xgaregs[x]);
  2085.   end;
  2086.   appw($3C2);
  2087.   appb(rgs.stdregs[$3C2]);
  2088.   appw(4);
  2089.   appw($3CA);
  2090.   for x:=$3CA to $3CD do appb(rgs.stdregs[x]);
  2091.   appw(8);
  2092.   appw(crtc+4);
  2093.   for x:=$3D8 to $3DF do appb(rgs.stdregs[x]);
  2094.   appw(0);
  2095.   FormatRgs:=bts;
  2096. end;
  2097.  
  2098.  
  2099. procedure dumpVGAregfile;
  2100. var
  2101.   f:file of regtype;
  2102. begin
  2103.   assign(f,'register.vga');
  2104.   {$i-}
  2105.   reset(f);
  2106.   {$i+}
  2107.   if ioresult=0 then seek(f,filesize(f)) else rewrite(f);
  2108.   write(f,rgs);
  2109.   close(f);
  2110. end;
  2111.  
  2112.  
  2113.  
  2114.  
  2115.  
  2116. function tstrg(pt,msk:word):boolean;       {Returns true if the bits in MSK
  2117.                                             of register PT are read/writable}
  2118. var old,nw1,nw2:word;
  2119. begin
  2120.   old:=inp(pt);
  2121.   outp(pt,old and not msk);
  2122.   nw1:=inp(pt) and msk;
  2123.   outp(pt,old or msk);
  2124.   nw2:=inp(pt) and msk;
  2125.   outp(pt,old);
  2126.   tstrg:=(nw1=0) and (nw2=msk);
  2127. end;
  2128.  
  2129. function testinx2(pt,rg,msk:word):boolean;   {Returns true if the bits in MSK
  2130.                                               of register PT index RG are
  2131.                                               read/writable}
  2132. var old,nw1,nw2:word;
  2133. begin
  2134.   old:=rdinx(pt,rg);
  2135.   wrinx(pt,rg,old and not msk);
  2136.   nw1:=rdinx(pt,rg) and msk;
  2137.   wrinx(pt,rg,old or msk);
  2138.   nw2:=rdinx(pt,rg) and msk;
  2139.   wrinx(pt,rg,old);
  2140.   testinx2:=(nw1=0) and (nw2=msk);
  2141. end;
  2142.  
  2143. function testinx(pt,rg:word):boolean;     {Returns true if all bits of
  2144.                                            register PT index RG are
  2145.                                            read/writable.}
  2146. var old,nw1,nw2:word;
  2147. begin
  2148.   testinx:=testinx2(pt,rg,$ff);
  2149. end;
  2150.  
  2151. procedure UNK(vers,code:word);
  2152. begin
  2153.   cv.version:=vers;
  2154.   cv.subvers:=code;
  2155. end;
  2156.  
  2157. procedure SetVersion(vers:word;nam:string);
  2158. begin
  2159.   cv.Version:=vers;
  2160.   cv.name:=nam;
  2161. end;
  2162.  
  2163.  
  2164. procedure SetDAC(typ:word;Name:string);
  2165. begin
  2166.   cv.dactype:=typ;
  2167.   cv.dacname:=name;
  2168. end;
  2169.  
  2170.  
  2171. procedure addvideo;
  2172. var nam,s:string;
  2173.     x,nr,err:word;
  2174.     ok:boolean;
  2175. begin
  2176.   nam:='';
  2177.   if force_version<>0 then cv.version:=force_version;
  2178.   if cv.version<>0 then
  2179.   begin
  2180.     for x:=1 to NBRCHIPS do
  2181.     begin
  2182.       if cv.version=CHIPSLIST[x].nbr then
  2183.       begin
  2184.         nam:=CHIPSLIST[x].nam;
  2185.         if nam[length(nam)]='(' then nam:=nam+hex4(cv.subvers)+')';
  2186.       end;
  2187.     end;
  2188.   end;
  2189.   if cv.Version=ET_4000 then
  2190.     case cv.Subvers of
  2191.       TS_SpeedStar:nam:=nam+' (SpeedStar)';
  2192.       TS_Genoa7900:nam:=nam+' (Genoa7900)';
  2193.     end;
  2194.   cv.flags:=cv.flags or FLG_ExtDAC;    {Allow Ext DAC addressing}
  2195.   if (cv.flags and FLG_StdVGA)>0 then ok:=setmode($12,false);  {Set std mode}
  2196.   if cv.dactype=_dac0 then testdac;
  2197.   if (cv.chip=__ALG) and (cv.dactype=_dac8) then SetDAC(_dacALG1101,'ALG1101');
  2198.  
  2199.   if (DACflags and DFL_CmdReg)>0 then   {Must have CMD register}
  2200.   begin
  2201.     x:=inp(SetDACpage(dacHIcmd));      {test if RS2/3 works}
  2202.     clearDACpage;
  2203.     if x<>getdaccomm then cv.flags:=cv.flags and (not FLG_ExtDAC);
  2204.   end;
  2205.  
  2206.   if cv.dactype=_dacInt then cv.dacname:='Internal';
  2207.   if force_mm<>0 then cv.mm:=force_mm;
  2208.   fillchar(cv.clks,sizeof(cv.clks),0);
  2209.   if (cv.chip<>__vesa) and clocktest then findclocks;
  2210.   inc(vids);
  2211.   vid[vids]:=cv;
  2212.   vid[vids].name :=nam+' '+cv.name;
  2213.   vid[vids].sname:=chipnam[cv.chip];
  2214.   SetTextMode;    {Reset any special bits}
  2215. end;
  2216.  
  2217.  
  2218.  
  2219.  
  2220.  
  2221.    (*  Tests for various adapters  *)
  2222.  
  2223.  
  2224. procedure _Acer;
  2225. var old:word;
  2226. begin
  2227.   old:=rdinx(GRC,$FF);
  2228.   clrinx(GRC,$FF,7);
  2229.   if not testinx2(GRC,$10,$9F) then
  2230.   begin
  2231.     clrinx(GRC,$FF,7);
  2232.     if testinx2(GRC,$10,$9F) then
  2233.     begin
  2234.       cv.chip:=__Acer;
  2235.       case rdinx(GRC,$E) and $C of
  2236.         0:cv.mm:=256;
  2237.         1:cv.mm:=512;
  2238.         2:cv.mm:=1024;
  2239.         3:cv.mm:=2048;
  2240.       end;
  2241.       addvideo;
  2242.     end;
  2243.   end;
  2244.   wrinx(GRC,$FF,old);
  2245. end;
  2246.  
  2247. procedure _ahead;
  2248. var old:word;
  2249. begin
  2250.   old:=rdinx(GRC,$F);
  2251.   wrinx(GRC,$F,0);
  2252.   if not testinx2(GRC,$C,$FB) then
  2253.   begin
  2254.     wrinx(GRC,$F,$20);
  2255.     if testinx2(GRC,$C,$FB) then
  2256.     begin
  2257.       cv.chip:=__ahead;
  2258.       case rdinx(GRC,$F) and 15 of
  2259.     0:cv.Version:=AH_A;
  2260.     1:begin
  2261.         cv.Version:=AH_B;
  2262.         cv.features:=ft_rwbank;
  2263.             cv.clktype:=clk_ext4;
  2264.       end;
  2265.       end;
  2266.       case rdinx(GRC,$1F) and 3 of
  2267.     0:cv.mm:=256;
  2268.     1:cv.mm:=512;
  2269.     2:;
  2270.     3:cv.mm:=1024;
  2271.       end;
  2272.       addvideo;
  2273.     end;
  2274.   end;
  2275.   wrinx(GRC,$F,old);
  2276. end;
  2277.  
  2278. procedure _ALG;
  2279. var old:integer;
  2280. begin
  2281.   old:=rdinx(crtc,$1A);
  2282.   clrinx(crtc,$1A,$10);
  2283.   if not testinx2(crtc,$19,$CF) then
  2284.   begin
  2285.     setinx(crtc,$1A,$10);
  2286.     if testinx2(crtc,$19,$CF) and testinx2(crtc,$1A,$3F) then
  2287.     begin
  2288.       cv.chip:=__ALG;
  2289.       cv.subvers:=rdinx(crtc,$1A);
  2290.       case cv.subvers shr 6 of
  2291.         3:begin
  2292.             cv.Version:=ALG_2101;
  2293.             {SetDAC(_dacalg,'ALG1101');}
  2294.            end;
  2295.         2:if (rdinx(crtc,$1B) and 4)>0 then cv.Version:=ALG_2228
  2296.                                        else cv.Version:=ALG_2301;
  2297.            {The 2228/2301/230x should probably be ID'd from the PCI ID ?}
  2298.         1:cv.version:=ALG_2201;
  2299.       else cv.Version:=ALG_Unknown;
  2300.       end;
  2301.       cv.clktype:=clk_ext4;
  2302.       cv.features:=ft_rwbank+ft_blit+ft_cursor+ft_line;
  2303.       if cv.version>ALG_2101 then cv.features:=ft_rwbank;  {CBL don't work yet!}
  2304.       case rdinx(crtc,$1E) and 3 of
  2305.     0:cv.mm:=256;
  2306.     1:cv.mm:=512;
  2307.     2:cv.mm:=1024;
  2308.     3:cv.mm:=2048;
  2309.       end;
  2310.       addvideo;
  2311.     end;
  2312.   end;
  2313.   wrinx(crtc,$1A,old);
  2314. end;
  2315.  
  2316. procedure _Alliance;
  2317. begin
  2318.   if (rdinx(SEQ,$11)=$41) and (rdinx(SEQ,$12)=$53) then
  2319.   begin
  2320.     cv.chip:=__Alli;
  2321.     cv.version:=ALi_3210;
  2322.  
  2323.     if mem[SegA000:$D8]=0 then;
  2324.     outpw(SEQ,$1210);
  2325.     setinx(SEQ,$1C,8);
  2326.     modinx(SEQ,$1B,7,1);
  2327.     cv.mm:=mem[SegA000:$F0]*64;   {Video Memory}
  2328.     clrinx(SEQ,$1B,7);
  2329.     clrinx(SEQ,$1C,8);
  2330.     addvideo;
  2331.   end;
  2332. end;
  2333.  
  2334. procedure _ARK;
  2335. var old:word;
  2336. begin
  2337.   old:=rdinx(SEQ,$1D);
  2338.   wrinx(SEQ,$1D,0);    {Lock the ext registers}
  2339.   if not (testinx(SEQ,$11) and testinx(SEQ,$12)) then
  2340.   begin
  2341.     wrinx(SEQ,$1D,old);
  2342.     if testinx(SEQ,$11) and testinx(SEQ,$12) then
  2343.     begin
  2344.       cv.chip:=__ARK;
  2345.       cv.SubVers:=rdinx(crtc,$50);
  2346.       case cv.SubVers and $F8 of
  2347.         $88:cv.Version:=ARK_1000VL;
  2348.         $90:cv.Version:=ARK_1000PV;
  2349.         $98:cv.Version:=ARK_2000PV;
  2350.       else cv.version:=ARK_Unknown;
  2351.       end;
  2352.       cv.clktype:=clk_ext4;
  2353.       cv.features:=ft_rwbank+ft_cursor;
  2354.       if cv.Version=ARK_2000PV then
  2355.         case rdinx(SEQ,$10) shr 6 of
  2356.           0:cv.mm:=1024;
  2357.           1:cv.mm:=2048;
  2358.           2:cv.mm:=4096;
  2359.           3:cv.mm:=8192;
  2360.         end
  2361.       else
  2362.         if (rdinx(SEQ,$10) and $40)>0 then cv.mm:=2048
  2363.                                       else cv.mm:=1024;
  2364.       addvideo;
  2365.     end;
  2366.   end;
  2367.   wrinx(SEQ,$1D,old);
  2368. end;
  2369.  
  2370.  
  2371. procedure _ati;
  2372. var w,mall,mvga:word;
  2373.   l:longint;
  2374. begin
  2375.   if getbios($31,9)='761295520' then
  2376.   begin
  2377.     case memw[biosseg:$40] of
  2378.      $3133:begin
  2379.          cv.IOadr:={memw[biosseg:$10]}$1CE;
  2380.          w:=rdinx(cv.IOadr,$BB);
  2381.          case w and 15 of
  2382.            0:_crt:='EGA';
  2383.            1:_crt:='Analog Monochrome';
  2384.            2:_crt:='Monochrome';
  2385.            3:_crt:='Analog Color';
  2386.            4:_crt:='CGA';
  2387.            6:_crt:='';
  2388.            7:_crt:='IBM 8514/A';
  2389.          else _crt:='Multisync';
  2390.          end;
  2391.          cv.chip:=__ati;
  2392.          cv.SubVers:=mem[biosseg:$43];
  2393.          case cv.SubVers of
  2394.           $31:cv.Version:=ATI_18800;
  2395.           $32:cv.Version:=ATI_18800_1;
  2396.           $33:cv.Version:=ATI_28800_2;
  2397.           $34:cv.Version:=ATI_28800_4;
  2398.           $35,$36:if (rdinx(cv.IOadr,$AA) and 15)=6 then
  2399.                        cv.Version:=ATI_28800_6
  2400.                   else cv.Version:=ATI_28800_5;
  2401.               $20:begin
  2402.             cv.SubVers:=inpw($6EEC);
  2403.                     case cv.Subvers of
  2404.                       $57:cv.Version:=ATI_M64_CX;
  2405.                       $D7:cv.Version:=ATI_M64_GX;
  2406.                     else  cv.Version:=ATI_M64_Unk;
  2407.                     end;
  2408.                     cv.Xseg:=$BFC0;  {Memory mapped regs at BFC00h}
  2409.                     if (inpw($72EC) and $E00)=$A00 then
  2410.                       SetDAC(_dacATI68860,'ATI 68860');  {Hack!}
  2411.                   end;
  2412.          $61..$63:begin  {Mach32}
  2413.             cv.SubVers:=inpw($FAEE);
  2414.             case cv.SubVers and $3FF of
  2415.              $2F7:cv.Version:=ATI_GUP_6;
  2416.              $177:cv.Version:=ATI_GUP_LX;
  2417.              $017:cv.Version:=ATI_GUP_AX;
  2418.             0:cv.Version:=ATI_GUP_3;
  2419.                     else  cv.Version:=ATI_M32_Unk;
  2420.             end;
  2421.           end;
  2422.          else cv.Version:=ATI_Unknown;
  2423.          end;
  2424.              if cv.Version=ATI_18800 then cv.clktype:=clk_ext3
  2425.                                      else cv.clktype:=clk_ext4;
  2426.          if cv.Version>=ATI_18800_1 then cv.features:=ft_rwbank;
  2427.          case cv.Version of
  2428.        ATI_18800,ATI_18800_1:
  2429.                if (rdinx(cv.IOadr,$BB) and $20)<>0 then cv.mm:=512;
  2430.        ATI_28800_2:if (rdinx(cv.IOadr,$B0) and $10)<>0 then cv.mm:=512;
  2431.        ATI_28800_4,ATI_28800_5,ATI_28800_6:
  2432.                case rdinx(cv.IOadr,$B0) and $18 of
  2433.                0:cv.mm:=256;
  2434.              $10:cv.mm:=512;
  2435.                8,$18:cv.mm:=1024;
  2436.                end;
  2437.        ATI_GUP_3..ATI_GUP_LX:
  2438.                        begin
  2439.                  case inp($36EE) and $C of
  2440.                0:mall:=512;
  2441.                4:mall:=1024;
  2442.                8:mall:=2048;
  2443.               12:mall:=4096;
  2444.                  end;
  2445.                          mvga:=mall;
  2446.                          if (inp($42EE) and $10)>0 then   {Split VGA/Mach mem}
  2447.                          begin
  2448.                            mvga:=(inp($42EE) and $F)*256;
  2449.                            if mvga>mall then mvga:=mall;
  2450.                          end;
  2451.                          cv.mm:=mvga;
  2452.                        end;
  2453.             ATI_M64_GX:begin
  2454.                          l:=inpl($52EC);
  2455.                          case l and 7 of
  2456.                            0:mall:=512;
  2457.                            1:mall:=1024;
  2458.                            2:mall:=2048;
  2459.                            3:mall:=4096;
  2460.                            4:mall:=6144;
  2461.                            5:mall:=8192;
  2462.                          end;
  2463.                          mvga:=mall;
  2464.                          if (l and $40000)>0 then
  2465.                          begin
  2466.                            case (l shr 16) and 3 of
  2467.                              0:mvga:=0;
  2468.                              1:mvga:=256;
  2469.                              2:mvga:=512;
  2470.                              3:mvga:=1024;
  2471.                            end;
  2472.                            if mvga>mall then mvga:=mall;
  2473.                          end;
  2474.                          cv.mm:=mvga;
  2475.                          if cv.mm>1024 then cv.mm:=1024;
  2476.                        end;
  2477.          end;
  2478.        end;
  2479.      $3233:begin
  2480.          cv.Version:=ATI_EGA;
  2481.          video:='EGA';
  2482.          cv.chip:=__ega;
  2483.        end;
  2484.     end;
  2485.     addvideo;
  2486.     if cv.version>=ATI_GUP_3 then  {Now add the VGA part}
  2487.     begin
  2488.       if cv.Version>=ATI_M64_GX then cv.chip:=__Mach64
  2489.                                 else cv.chip:=__Mach32;
  2490.       cv.flags:=cv.flags and (not FLG_StdVGA);
  2491.       cv.mm:=mall;
  2492.       if mvga<mall then cv.mm:=mall-mvga;
  2493.       cv.features:=cv.features or ft_cursor or ft_line or ft_blit;
  2494.                     if (inpw($72EC) and $E00)=$A00 then
  2495.                       SetDAC(_dacATI68860,'ATI 68860');  {Hack!}
  2496.       addvideo;
  2497.     end;
  2498.   end;
  2499. end;
  2500.  
  2501. procedure _chipstech;
  2502. var prt,old,x:word;
  2503. begin
  2504.   vio($5F00);
  2505.   if rp.al=$5F then
  2506.   begin
  2507.     cv.subvers:=rp.bl;
  2508.     case cv.SubVers shr 4 of
  2509.       0:cv.Version:=CT_451;
  2510.       1:cv.Version:=CT_452;
  2511.       2:cv.Version:=CT_455;
  2512.       3:cv.Version:=CT_453;
  2513.       4:cv.Version:=CT_450;
  2514.       5:cv.Version:=CT_456;
  2515.       6:cv.Version:=CT_457;
  2516.       7:cv.Version:=CT_65520;
  2517.       8:cv.Version:=CT_65530;
  2518.       9:cv.Version:=CT_65510;
  2519.      10:cv.Version:=CT_64200;
  2520.      11:if cv.subvers>=$B8 then cv.Version:=CT_64310
  2521.                            else cv.Version:=CT_64300;
  2522.      12:cv.Version:=CT_65535;
  2523.      13:if cv.subvers>=$D8 then cv.Version:=CT_65545
  2524.                            else cv.Version:=CT_65540;
  2525.     else cv.Version:=CT_Unknown;
  2526.     end;
  2527.     cv.clktype:=clk_ext3;
  2528.     if cv.version<CT_450 then
  2529.     begin
  2530.       prt:=$46E8;     {Should be $94 for MCA systems}
  2531.       outp(prt,$1E);    {Setup mode}
  2532.  
  2533.       x:=inp($103);
  2534.       outp($103,x or $80);  {Enable extensions}
  2535.       outp(prt,$E);
  2536.       if (x and $40)=0 then cv.IOadr:=$3D6 else cv.IOadr:=$3B6;
  2537.     end
  2538.     else begin
  2539.       cv.IOadr:=$3D6;
  2540.       if cv.version=CT_64300 then
  2541.       begin
  2542.         cv.clktype:=clk_internal;
  2543.         setDAC(_dacInt,'CT 24bit DAC');
  2544.       end
  2545.       else setDAC(_dacInt,'CT 15/16bit DAC');
  2546.     end;
  2547.     cv.SubVers:=rdinx(cv.IOadr,0);
  2548.     cv.chip:=__chips;
  2549.     if cv.version=CT_452 then cv.features:=ft_cursor;
  2550.     case rdinx(cv.IOadr,4) and 3 of
  2551.        1:cv.mm:=512;
  2552.      2,3:begin
  2553.            cv.mm:=1024;
  2554.            if (cv.Version>=CT_64300) and ((rdinx(cv.IOadr,$F) and 3)=3) then
  2555.              cv.mm:=2048
  2556.          end;
  2557.     end;
  2558.     addvideo;
  2559.   end;
  2560. end;
  2561.  
  2562. procedure _cirrus;
  2563. var old,old6:word;
  2564. begin
  2565.   old6:=rdinx(SEQ,6);
  2566.   old:=rdinx(crtc,$C);
  2567.   outp(crtc+1,0);
  2568.   cv.SubVers:=rdinx(crtc,$1F);
  2569.   wrinx(SEQ,6,lo(cv.Subvers shr 4) or lo(cv.Subvers shl 4));
  2570.                          {The SubVers value is rotated by 4}
  2571.   if inp(SEQ+1)=0 then
  2572.   begin
  2573.     outp($3c5,cv.SubVers);
  2574.     if inp($3c5)=1 then
  2575.     begin
  2576.       case cv.SubVers of
  2577.     $EC:cv.Version:=CL_GD5x0;
  2578.     $CA:cv.Version:=CL_GD6x0;
  2579.     $EA:cv.Version:=CL_V7_OEM;
  2580.       else cv.Version:=CL_old_unk;
  2581.       end;
  2582.       cv.chip:=__cirrus;
  2583.       cv.features:=ft_cursor;
  2584.       addvideo;
  2585.     end;
  2586.   end;
  2587.   wrinx(crtc,$C,old);
  2588.   wrinx(SEQ,6,old6);
  2589. end;
  2590.  
  2591.  
  2592. procedure _cirrus54;
  2593. var x,old:word;
  2594. begin
  2595.   old:=rdinx(SEQ,6);
  2596.   wrinx(SEQ,6,0);
  2597.   if (rdinx(SEQ,6)=$F) then
  2598.   begin
  2599.     wrinx(SEQ,6,$12);
  2600.     if (rdinx(SEQ,6)=$12) and testinx2(SEQ,$1E,$3F) {and testinx2(crtc,$1B,$ff)} then
  2601.     begin
  2602.       case rdinx(SEQ,$A) and $18 of      {Alternate method:}
  2603.     0:cv.mm:=256;                    { case rdinx(SEQ,$F) and $18}
  2604.     8:cv.mm:=512;                    {   $10: cv.mm:=1024; }
  2605.        16:cv.mm:=1024;                   {   $18: cv.mm:=2048;  May not work}
  2606.        24:cv.mm:=2048;                   { else cv.mm:=512}
  2607.       end;
  2608.       cv.SubVers:=rdinx(crtc,$27);
  2609.       if testinx(GRC,9) then
  2610.       begin
  2611.         cv.features:=ft_cursor;
  2612.     case cv.SubVers of
  2613.             $18:cv.Version:=CL_AVGA2;
  2614.             $88:cv.Version:=CL_GD5402;
  2615.             $89:cv.Version:=CL_GD5402r1;
  2616.             $8A:cv.Version:=CL_GD5420;
  2617.             $8B:cv.Version:=CL_GD5420r1;
  2618.        $8C..$8F:cv.Version:=CL_GD5422;
  2619.        $90..$93:cv.Version:=CL_GD5426;
  2620.        $94..$97:cv.Version:=CL_GD5424;
  2621.        $98..$9B:cv.Version:=CL_GD5428;
  2622.        $9C..$9F:cv.Version:=CL_GD5429;   {Might not get here ??}
  2623.        $A0..$A3:cv.Version:=CL_GD5430;
  2624.   {     $A4..$A7:cv.Version:=CL_GD543x;  Probably does not exist}
  2625.        $A8..$AB:cv.version:=CL_GD5434;
  2626.        $2C..$2F:cv.version:=CL_GD7542;   {Nordic}
  2627.        $30..$33:cv.version:=CL_GD7543;   {Viking}
  2628.        $34..$37:cv.version:=CL_GD7541;   {Nordic Lite}
  2629.     else cv.Version:=CL_Unk54;
  2630.     end;
  2631.     SetDAC(_dacInt,'Cirrus Internal');
  2632.         if cv.Version>=CL_GD5426 then
  2633.           cv.features:=ft_cursor+ft_blit;
  2634.         if cv.Version>=CL_GD7541 then
  2635.           case rdinx(SEQ,$A) and 15 of
  2636.             0:cv.mm:=256;
  2637.             1:cv.mm:=512;
  2638.             2:cv.mm:=1024;
  2639.             3:cv.mm:=2048;
  2640.             4:cv.mm:=4096;
  2641.           end;
  2642.         if cv.Version>=CL_GD5430 then
  2643.           case rdinx(SEQ,$15) and 15 of    {Alternate method:}
  2644.             0:cv.mm:=256;              { case rdinx(SEQ,$F) and $18}
  2645.             1:cv.mm:=512;              {   $10: cv.mm:=1024; }
  2646.             2:cv.mm:=1024;             {   $18: cv.mm:=2048; }
  2647.             3:cv.mm:=2048;             { else cv.mm:=512;    }
  2648.             4:cv.mm:=4096;             { end;                }
  2649.           end;                         { if (rdinx(SEQ,$F) and $80)>0 then }
  2650.       end                                                { cv.mm:=cv.mm*2; }
  2651.       else if testinx(SEQ,$19) then
  2652.       begin
  2653.     case cv.SubVers shr 6 of
  2654.       0:cv.Version:=CL_GD6205;
  2655.       1:cv.Version:=CL_GD6235;
  2656.       2:cv.Version:=CL_GD6215;
  2657.       3:cv.Version:=CL_GD6225;
  2658.     end;
  2659.         cv.mm:=512;
  2660.         cv.features:=0;
  2661.       end
  2662.       else begin
  2663.     cv.Version:=CL_AVGA2;
  2664.         cv.features:=ft_cursor;
  2665.     case rdinx(SEQ,$A) and 3 of
  2666.       0:cv.mm:=256;
  2667.       1:cv.mm:=512;
  2668.       2:cv.mm:=1024;
  2669.     end;
  2670.       end;
  2671.       cv.chip:=__cir54;
  2672.       cv.clktype:=clk_internal;
  2673.       addvideo;
  2674.     end;
  2675.   end
  2676.   else wrinx(SEQ,6,old);
  2677. end;
  2678.  
  2679. procedure _cirrus64;
  2680. var x,old:word;
  2681. begin
  2682.   old:=rdinx(GRC,$A);
  2683.   wrinx(GRC,$A,$CE);  {Lock}
  2684.   if (rdinx(GRC,$A)=0) then
  2685.   begin
  2686.     wrinx(GRC,$A,$EC);  {unlock}
  2687.     if (rdinx(GRC,$A)=1) then
  2688.     begin
  2689.       cv.SubVers:=rdinx(GRC,$AA);
  2690.       case cv.SubVers shr 4 of
  2691.     4:cv.Version:=CL_GD6440;
  2692.     5:cv.Version:=CL_GD6412;
  2693.     6:cv.Version:=CL_GD5410;
  2694.     7:if testinx2(GRC,$87,$90) then cv.Version:=CL_GD6420B
  2695.                                    else cv.Version:=CL_GD6420A;
  2696.     8:cv.Version:=CL_GD6410;
  2697.       else cv.Version:=CL_Unk64;
  2698.       end;
  2699.       case rdinx(GRC,$BB) shr 6 of
  2700.     0:cv.mm:=256;
  2701.     1:cv.mm:=512;
  2702.     2:cv.mm:=768;
  2703.     3:cv.mm:=1024;
  2704.       end;
  2705.       cv.chip:=__cir64;
  2706.       cv.clktype:=clk_internal;
  2707.       addvideo;
  2708.     end;
  2709.   end;
  2710.   wrinx(GRC,$A,old);
  2711. end;
  2712.  
  2713.  
  2714. procedure _compaq;
  2715. var old,x:word;
  2716. begin
  2717.   old:=rdinx(GRC,$F);
  2718.   wrinx(GRC,$F,0);
  2719.   if not testinx(GRC,$45) then
  2720.   begin
  2721.     wrinx(GRC,$F,5);
  2722.     if testinx(GRC,$45) then
  2723.     begin
  2724.       cv.chip:=__compaq;
  2725.       cv.features:=ft_blit;
  2726.       cv.SubVers:=rdinx(GRC,$C) shr 3;
  2727.       case cv.SubVers of
  2728.     3:cv.Version:=CPQ_IVGS;
  2729.     5:cv.Version:=CPQ_AVGA;
  2730.     6:cv.Version:=CPQ_QV1024;
  2731.        $E:if (rdinx(GRC,$56) and 4)<>0 then cv.Version:=CPQ_QV1280
  2732.                                        else cv.Version:=CPQ_QV1024;
  2733.       $10:cv.Version:=CPQ_AVPort;  {What is this ?}
  2734.       else cv.Version:=CPQ_Unknown;
  2735.       end;
  2736.       if (rdinx(GRC,$C) and $B8)=$30 then  {QVision}
  2737.       begin
  2738.     cv.features:=cv.features + ft_cursor;
  2739.     wrinx(GRC,$F,5);
  2740.     case rdinx(GRC,$54) of
  2741.       0:cv.mm:=1024;  {old QV1024 fix}
  2742.       2:cv.mm:=512;
  2743.       4:cv.mm:=1024;
  2744.       8:cv.mm:=2048;
  2745.     end;
  2746.         cv.clktype:=clk_ext4;
  2747.       end
  2748.       else begin
  2749.     rp.bx:=0;
  2750.     rp.cx:=0;
  2751.     vio($BF03);
  2752.     if (rp.ch and 64)=0 then cv.mm:=512;
  2753.         cv.clktype:=clk_ext3;
  2754.       end;
  2755.       addvideo;
  2756.     end
  2757.   end;
  2758.   wrinx(GRC,$F,old);
  2759. end;
  2760.  
  2761. procedure _everex;
  2762. var x:word;
  2763. begin
  2764.   rp.bx:=0;
  2765.   vio($7000);
  2766.   if rp.al=$70 then
  2767.   begin
  2768.     x:=rp.dx shr 4;
  2769.     if  (x<>$678) and (x<>$236)
  2770.     and (x<>$620) and (x<>$673) then     {Some Everex boards use Trident chips.}
  2771.     begin
  2772.       case rp.ch shr 6 of
  2773.     0:cv.mm:=256;
  2774.     1:cv.mm:=512;
  2775.     2:cv.mm:=1024;
  2776.     3:cv.mm:=2048;
  2777.       end;
  2778.       cv.name:='Everex Ev'+hx[x shr 8]+hx[(x shr 4) and 15]+hx[x and 15];
  2779.       cv.chip:=__everex;
  2780.       addvideo;
  2781.     end;
  2782.   end;
  2783. end;
  2784.  
  2785. procedure _genoa;
  2786. var ad:word;
  2787. begin
  2788.   ad:=memw[biosseg:$37];
  2789.   if (memw[biosseg:ad+2]=$6699) and (mem[biosseg:ad]=$77) then
  2790.   begin
  2791.     case mem[biosseg:ad+1] of
  2792.       0:cv.Version:=GE_6200;
  2793.     $11:begin
  2794.       cv.Version:=GE_6400;
  2795.       cv.mm:=512;
  2796.     end;
  2797.     $22:cv.Version:=GE_6100;
  2798.     $33:cv.Version:=GE_5100;  {Do we need to detect the Tseng versions ??}
  2799.     $55:begin
  2800.       cv.Version:=GE_5300;
  2801.       cv.mm:=512;
  2802.     end;
  2803.     end;
  2804.     cv.clktype:=clk_ext3;
  2805.     if mem[biosseg:ad+1]<$33 then cv.chip:=__genoa {else cv.chip:=__ET3000};
  2806.     addvideo;
  2807.   end
  2808. end;
  2809.  
  2810. procedure _hmc;
  2811. begin
  2812. (*  if testinx(SEQ,$E7) and testinx(SEQ,$EE) then *)
  2813.  
  2814.   if testinx2(SEQ,$E7,$7F) and testinx2(SEQ,$EE,$F1) then
  2815.   begin
  2816.     if (rdinx(SEQ,$E7) and $10)>0 then cv.mm:=512;
  2817.     cv.chip:=__HMC;
  2818.     cv.clktype:=clk_ext4;
  2819.     if testinx(SEQ,$E7) and testinx(SEQ,$EE) then cv.Version:=HMC_304
  2820.                                              else cv.Version:=HMC_314;
  2821.     addvideo;
  2822.   end;
  2823. end;
  2824.  
  2825. procedure _Imagine;
  2826. var inx:integer;
  2827. begin
  2828.   inx:=CheckPCI(0,$105D,$2309);
  2829.   if inx>0 then
  2830.   begin
  2831.     cv.IOadr:=PCIrec[inx].base5 and $FFFE;
  2832.     case inp(cv.IOadr+$18) and $C0 of
  2833.         0:cv.mm:=4096;
  2834.       $40:cv.mm:=8192;
  2835.       $80:cv.mm:=16384;
  2836.       $C0:cv.mm:=32768;
  2837.     end;
  2838.     cv.version:=IMG_128;
  2839.     cv.chip:=__IMAG;
  2840.     cv.name:='';
  2841.     addvideo;
  2842.   end;
  2843. end;
  2844.  
  2845.  
  2846. procedure _matrox;
  2847. const
  2848.   segm:array[1..7] of word=($AC00,$C800,$CC00,$D000,$D400,$D800,$DC00);
  2849.  
  2850.   procedure addMGA(sgm:word);
  2851.   var l:longint;
  2852.   begin
  2853.     cv.mm:=2048;       {Still have to figure out memory, 2048 for now}
  2854.     cv.Xseg:=sgm;
  2855.     cv.chip:=__MGA;
  2856.     cv.subvers:=memw[sgm:$1E48];
  2857.     case cv.subvers of
  2858.       $1700:cv.version:=MGA_Titan;
  2859.       $1702:cv.version:=MGA_Helena;
  2860.     else cv.Version:=MGA_Unknown;
  2861.     end;
  2862.     cv.flags:=cv.flags and (not FLG_StdVGA);
  2863.     addvideo;
  2864.   end;
  2865.  
  2866. var i,j,inx:word;
  2867. begin    {First check for the Matrox VGA}
  2868.   if testinx(crtc,$E1) and testinx($3DE,0) then
  2869.   begin
  2870.     cv.chip:=__Matrox;
  2871.     cv.version:=MGA_VGA;   {Hm}
  2872.     cv.mm:=1024;
  2873.     addvideo;
  2874.   end;
  2875.  
  2876.   cv.dactype:=_dac0;   {Force DAC test}
  2877.   j:=0;
  2878.   for i:=1 to 7 do  {Check for MGA-II (Ultima)}
  2879.     if memw[segm[i]:$1E4A]=$A268 then
  2880.       addMGA(segm[i]);
  2881.   if getbios($78,3)='_VB' then
  2882.     addMGA($AC00);
  2883.  
  2884.   inx:=0;
  2885.   repeat
  2886.     inx:=CheckPCI(inx,$102B,$FFFF);  {Look for any Matrox}
  2887.     if (inx>0) and ((PCIrec[inx].device=$518) or (PCIrec[inx].device=$D10)) then
  2888.     begin
  2889.       cv.PCIid:=inx;
  2890.       wPCIlong($10,$AC000);  {MAP Matrox regs at AC000h}
  2891.       addMGA($AC00);
  2892.       wPCIlong($10,PCIrec[inx].l[4]);  {remap}
  2893.     end;
  2894.   until inx=0;
  2895. end;
  2896.  
  2897. procedure _MediaVis;   {MediaVision}
  2898. const
  2899.   IObase:array[0..4] of word=($538,$E88,$F48,$60C,$148);
  2900. var
  2901.   i,j,w:integer;
  2902. begin
  2903.   j:=0;i:=0;
  2904.   while (i<5) do
  2905.     if inp(IObase[i])=$38 then i:=i+100  {found one, now stop}
  2906.                           else inc(i);
  2907.  (*  - While this will detect an uninitialised PG1024, it will also falsely
  2908.        claim that about every second VGA card is a PG!!
  2909.   if i<100 then
  2910.   begin
  2911.     i:=0;
  2912.     while (i<5) do
  2913.       if (inp(IObase[i])=$FF) and (inp(IObase[i]+1)=$FF) then
  2914.          i:=i+100  {found one, now stop}
  2915.       else inc(i);
  2916.   end; *)
  2917.   if i>=100 then  {Found a PG1024}
  2918.   begin
  2919.     cv.IOadr  :=IObase[i-100];
  2920.     cv.chip   :=__MV;
  2921.     cv.mm     :=2304; {2.25Mb = 9*256K}
  2922.     cv.version:=MV_PG1024;
  2923.     addvideo;
  2924.   end
  2925.  
  2926. (* The 1280 detection does not work yet!
  2927.   else begin {Now try for a 1280}
  2928.  
  2929.     if (inp($539) and $CF)=$0A then outp($539,0);
  2930.     if (inp($E89) and $CF)=$4A then outp($E89,0);
  2931.     if (inp($F49) and $CF)=$8A then outp($F49,0);
  2932.     if (inp($60D) and $CF)=$CA then outp($60D,0);
  2933.     for i:=0 to 3 do
  2934.     begin
  2935.       w:=IObase[i]+1;
  2936.       if inp(w)=$FF then
  2937.       begin
  2938.         outp(w,$8A);
  2939.         for j:=1 to 100 do;
  2940.         if inp(w)=$FF then
  2941.         begin
  2942.           for j:=1 to 100 do;
  2943.           outp(w,$54);
  2944.           for j:=1 to 100 do;
  2945.           if inp(w)=$FF then
  2946.           begin
  2947.             outp(w,1);
  2948.             if inp(w)=$0A then;
  2949.  
  2950.             i:=999;   {Stop the loop}
  2951.           end;
  2952.         end;
  2953.         outp(w,$FF);
  2954.       end;
  2955.     end;
  2956.   end; *)
  2957. end;
  2958.  
  2959. procedure _mxic;
  2960. var old:integer;
  2961. begin
  2962.   old:=rdinx(SEQ,$A7);
  2963.   wrinx(SEQ,$A7,0);       {disable extensions}
  2964.   if not testinx(SEQ,$C5) then
  2965.   begin
  2966.     wrinx(SEQ,$A7,$87);   {enable extensions}
  2967.     if testinx(SEQ,$C5) then
  2968.     begin
  2969.       cv.chip:=__mxic;
  2970.       cv.clktype:=clk_ext3;
  2971.       if (rdinx(SEQ,$26) and 1)=0 then cv.Version:=MX_86010
  2972.       else cv.Version:=MX_86000;   {Does this work, else test 85h bit 1 ??}
  2973.       case (rdinx(SEQ,$C2)  shr 2) and 3 of
  2974.     0:cv.mm:=256;
  2975.     1:cv.mm:=512;
  2976.     2:cv.mm:=1024;
  2977.       end;
  2978.       addvideo;
  2979.     end;
  2980.   end;
  2981.   wrinx(SEQ,$A7,old);
  2982. end;
  2983.  
  2984. procedure _ncr;
  2985. var x:word;
  2986. begin
  2987.   if testinx2(SEQ,5,5) then
  2988.   begin
  2989.     wrinx(SEQ,5,0);        {Disable extended registers}
  2990.     if not testinx(SEQ,$10) then
  2991.     begin
  2992.       wrinx(SEQ,5,1);        {Enable extended registers}
  2993.       if testinx(SEQ,$10) then
  2994.       begin
  2995.     cv.chip:=__ncr;
  2996.         cv.clktype:=clk_ext3;
  2997.     cv.SubVers:=rdinx(SEQ,8);
  2998.     case cv.SubVers shr 4 of
  2999.       0:cv.Version:=NCR_77C22;
  3000.       1:cv.Version:=NCR_77C21;
  3001.       2:if (cv.SubVers and 15)<8 then cv.Version:=NCR_77C22E
  3002.                                      else cv.Version:=NCR_77C22Ep;
  3003.           3:cv.Version:=NCR_77c32BLT;
  3004.     else cv.Version:=NCR_Unknown;
  3005.     end;
  3006.     cv.features:=ft_rwbank+ft_cursor;
  3007.         if cv.Version>=NCR_77c32BLT then cv.features:=cv.features+ft_blit;
  3008.     cv.name:=cv.name+' Rev. '+istr(rdinx(SEQ,8) and 15);
  3009.         memmode:=_P8;
  3010.     if setmode($13,false) then;
  3011.     checkmem(64);
  3012.     addvideo;
  3013.       end;
  3014.     end;
  3015.   end;
  3016. end;
  3017.  
  3018. procedure _oak;
  3019. var old:word;
  3020.  
  3021. begin
  3022.   if testinx($3DE,9) or testinx2($3DE,$D,$38) then
  3023.   begin
  3024.     cv.chip:=__oak;
  3025.     cv.features:=ft_rwbank;
  3026.     if testinx2($3DE,$23,$1F) then
  3027.     begin
  3028.       case rdinx($3DE,2) and 6 of
  3029.     0:cv.mm:=256;
  3030.     2:cv.mm:=512;
  3031.     4:cv.mm:=1024;
  3032.     6:cv.mm:=2048;
  3033.       end;
  3034.       if (rdinx($3DE,0) and 2)=0 then cv.Version:=OAK_087
  3035.                  else cv.version:=OAK_083;
  3036.       {SetDAC(_dac16,'OAK OTI-066HC');  {Cheat}
  3037.       cv.clktype:=clk_ext4;
  3038.     end
  3039.     else begin
  3040.       cv.clktype:=clk_ext3;
  3041.       cv.SubVers:=inp($3DE) shr 5;
  3042.       case cv.SubVers of
  3043.     0:cv.Version:=OAK_037;
  3044.     2:cv.Version:=OAK_067;
  3045.     5:cv.Version:=OAK_077;
  3046.     7:cv.Version:=OAK_057;
  3047.       else cv.Version:=OAK_Unknown;
  3048.       end;
  3049.  
  3050.       case rdinx($3DE,$D) shr 6 of
  3051.     2:cv.mm:=512;
  3052.       1,3:cv.mm:=1024;    {1 might not give 1M??}
  3053.       end;
  3054.     end;
  3055.     addvideo;
  3056.   end;
  3057. end;
  3058.  
  3059. procedure _p2000;
  3060. begin
  3061.   if testinx2(GRC,$3D,$3F) and tstrg($3D6,$1F) and tstrg($3D7,$1F) then
  3062.   begin
  3063.     cv.Version:=PR_2000;
  3064.     cv.chip:=__p2000;
  3065.     cv.features:=ft_rwbank+ft_blit;
  3066.     memmode:=_P8;
  3067.     if setmode($13,false) then;
  3068.     checkmem(32);
  3069.     cv.clktype:=clk_ext4;
  3070.     addvideo;
  3071.   end;
  3072. end;
  3073.  
  3074. procedure _paradise;
  3075. var old,old2:word;
  3076. begin
  3077.   old:=rdinx(GRC,$F);
  3078.   setinx(GRC,$F,$17);   {Lock registers}
  3079.  
  3080.   if not testinx2(GRC,9,$7F) then
  3081.   begin
  3082.     wrinx(GRC,$F,5);      {Unlock them again}
  3083.     if testinx2(GRC,9,$7F) then
  3084.     begin
  3085.       cv.clktype:=clk_ext3;
  3086.       old2:=rdinx(crtc,$29);
  3087.       modinx(crtc,$29,$8F,$85);   {Unlock WD90Cxx registers}
  3088.       if not testinx(crtc,$2B) then cv.Version:=WD_PVGA1A
  3089.       else begin
  3090.     wrinx(SEQ,6,$48);   {Enable C1x extensions}
  3091.     if not testinx2(SEQ,7,$F0) then cv.Version:=WD_90C00
  3092.     else if not testinx(SEQ,$10) then
  3093.     begin
  3094.           if testinx2(crtc,$31,$68) then cv.Version:=WD_90c22
  3095.           else if testinx2(crtc,$31,$90) then cv.Version:=WD_90c20A
  3096.           else cv.Version:=WD_90C20;
  3097.       wrinx(crtc,$34,$A6);
  3098.       if (rdinx(crtc,$32) and $20)<>0 then wrinx(crtc,$34,0);
  3099.     end
  3100.     else begin
  3101.           cv.clktype:=clk_ext4;
  3102.       cv.features:=ft_rwbank;
  3103.       if testinx2(SEQ,$14,$F) then
  3104.       begin
  3105.             wrinx(crtc,$34,0);   {Disable c2x registers}
  3106.             wrinx(crtc,$35,0);   {Disable c2x registers}
  3107.         cv.SubVers:=(rdinx(crtc,$36) shl 8)+rdinx(crtc,$37);
  3108.         case cv.SubVers of
  3109.           $3234:begin
  3110.                       cv.Version:=WD_90c24;
  3111.                       cv.features:=cv.features+ft_cursor+ft_blit;
  3112.                       cv.clktype:=clk_internal;
  3113.                       SetDAC(_dacInt,'WD 16bit');
  3114.                     end;
  3115.           $3236:cv.Version:=WD_90C26;
  3116.           $3330:cv.Version:=WD_90c30;
  3117.           $3331:begin
  3118.                       cv.Version:=WD_90C31;
  3119.                       cv.features:=cv.features+ft_cursor+ft_blit;
  3120.                     end;
  3121.           $3333:begin
  3122.                       cv.Version:=WD_90C33;
  3123.                       cv.features:=cv.features+ft_cursor+ft_blit+ft_line;
  3124.                     end;
  3125.         end;
  3126.       end
  3127.       else if not testinx2(SEQ,$10,4) then cv.Version:=WD_90C10
  3128.                       else cv.Version:=WD_90C11;
  3129.     end;
  3130.       end;
  3131.       wrinx(GRC,$F,5);      {Unlock them again}
  3132.       case rdinx(GRC,$B) shr 6 of
  3133.         2:cv.mm:=512;
  3134.         3:cv.mm:=1024;
  3135.       end;
  3136.       if (cv.Version>=WD_90c33) and ((rdinx(crtc,$3E) and $80)>0) then cv.mm:=2048;
  3137.       wrinx(crtc,$29,old2);
  3138.       cv.chip:=__WD;
  3139.       addvideo;
  3140.     end;
  3141.   end;
  3142.   wrinx(GRC,$F,old);
  3143. end;
  3144.  
  3145. procedure _realtek;
  3146. begin
  3147.   if testinx2(crtc,$1F,$3F) and tstrg($3D6,$F) and tstrg($3D7,$F) then
  3148.   begin
  3149.     cv.chip:=__realtek;
  3150.     cv.clktype:=clk_ext3;
  3151.     cv.SubVers:=rdinx(crtc,$1A) shr 6;
  3152.     case cv.SubVers of
  3153.       0:cv.Version:=RT_3103;
  3154.       1:cv.Version:=RT_3105;
  3155.       2:cv.Version:=RT_3106;
  3156.     else cv.Version:=RT_unknown;
  3157.     end;
  3158.     case rdinx(crtc,$1E) and 15 of
  3159.       0:cv.mm:=256;
  3160.       1:cv.mm:=512;
  3161.       2:if cv.SubVers=0 then cv.mm:=768  else cv.mm:=1024;
  3162.       3:if cv.SubVers=0 then cv.mm:=1024 else cv.mm:=2048;
  3163.     end;
  3164.     cv.features:=ft_rwbank;
  3165.     addvideo;
  3166.   end;
  3167. end;
  3168.  
  3169. procedure _s3;
  3170. begin
  3171.   wrinx(crtc,$38,0);
  3172.   if not testinx2(crtc,$35,$F) then
  3173.   begin
  3174.     wrinx(crtc,$38,$48);
  3175.     if testinx2(crtc,$35,$F) then
  3176.     begin
  3177.       cv.features:=ft_blit+ft_line+ft_cursor;
  3178.       cv.SubVers:=rdinx(crtc,$30);
  3179.       cv.clktype:=clk_ext4;
  3180.       case cv.SubVers of
  3181.     $81:cv.Version:=S3_911;
  3182.     $82:cv.Version:=S3_924;    {Also known as 911A}
  3183.     $90:cv.Version:=S3_928;
  3184.     $91:cv.Version:=S3_928C;
  3185.     $94:cv.Version:=S3_928D;
  3186.         $95:cv.Version:=S3_928E;
  3187.     $A0:if (rdinx(crtc,$36) and 2)>0 then cv.Version:=S3_801AB
  3188.                          else cv.Version:=S3_805AB;
  3189.    $A2..$A4:if (rdinx(crtc,$36) and 2)>0 then cv.Version:=S3_801C
  3190.                                          else cv.Version:=S3_805C;
  3191.     $A5,$A7:if (rdinx(crtc,$36) and 2)>0 then cv.Version:=S3_801D
  3192.                          else cv.Version:=S3_805D;
  3193.         $A6:if (rdinx(crtc,$36) and 2)>0 then cv.Version:=S3_801P
  3194.                      else cv.Version:=S3_805P;
  3195.         $A8:if (rdinx(crtc,$36) and 2)>0 then cv.Version:=S3_801I
  3196.                      else cv.Version:=S3_805I;
  3197.     $B0:cv.Version:=S3_928PCI;
  3198.     $C0:cv.Version:=S3_864;
  3199.     $C1:cv.Version:=S3_864P;
  3200.     $D0:cv.Version:=S3_964;
  3201.     $E0,$E1:case rdinx(crtc,$2E) of   {Not sure of this yet}
  3202.               $10:cv.Version:=S3_732;
  3203.               $11:cv.Version:=S3_764;
  3204.               $80:cv.Version:=S3_866;
  3205.               $90:cv.Version:=S3_868;
  3206.           $B0,$F0:cv.Version:=S3_968;
  3207.             end;
  3208.       else cv.Version:=S3_Unknown;
  3209.       end;
  3210.       if (cv.Version=S3_732) or  (cv.Version=S3_764) then
  3211.       begin
  3212.         cv.clktype:=clk_internal;
  3213.         SetDAC(_dacInt,'S3 Trio');
  3214.       end;
  3215.       cv.mm:=512;
  3216.       if (rdinx(crtc,$36) and $20)=0 then
  3217.         if (cv.subvers<$90) then cv.mm:=1024   {911 and 924}
  3218.         else case rdinx(crtc,$36) shr 6 of
  3219.                0:cv.mm:=4096;
  3220.                1:cv.mm:=3072;
  3221.                2:cv.mm:=2048;
  3222.                3:cv.mm:=1024;
  3223.              end;
  3224.       cv.chip:=__S3;
  3225.       addvideo;
  3226.     end;
  3227.   end;
  3228. end;
  3229.  
  3230. procedure _Sierra;
  3231. var old,i:word;
  3232. begin
  3233.   old:=rdinx(SEQ,$11);
  3234.   setinx(SEQ,$11,$20);
  3235.   if not testinx(SEQ,$15) then
  3236.   begin
  3237.     i:=rdinx(SEQ,$11);
  3238.     outp(SEQ+1,i);
  3239.     outp(SEQ+1,i);
  3240.     outp(SEQ+1,i and $DF);
  3241.     if testinx(SEQ,$15) then
  3242.     begin
  3243.       setinx(SEQ,$11,$20);
  3244.       cv.chip:=__Acer;
  3245.       case rdinx(SEQ,7) shr 5 of
  3246.         4:cv.version:=SC_15064;
  3247.       else cv.version:=SC_Unknown;
  3248.       end;
  3249.       if setmode($13,false) then;
  3250.       checkmem(64);
  3251.       addvideo;
  3252.     end;
  3253.   end;
  3254.   wrinx(SEQ,$11,old);
  3255. end;
  3256.  
  3257. procedure _SiS;
  3258. var old:word;
  3259. begin
  3260.   old:=rdinx(SEQ,5);
  3261.   wrinx(SEQ,5,0);
  3262.   if rdinx(SEQ,5)=$21 then
  3263.   begin
  3264.     wrinx(SEQ,5,$86);
  3265.     if rdinx(SEQ,5)=$A1 then
  3266.     begin
  3267.       cv.chip:=__SiS;
  3268.       cv.Version:=SIS_201;
  3269.       case rdinx(SEQ,$F) and 3 of
  3270.         0:cv.mm:=1024;
  3271.         1:cv.mm:=2048;
  3272.         2:cv.mm:=4096;
  3273.       end;
  3274.       cv.dactype:=_dacInt;
  3275.       cv.clktype:=clk_ext4;
  3276.       cv.features:=ft_cursor+ft_rwbank;
  3277.       addvideo;
  3278.     end;
  3279.   end;
  3280.   wrinx(SEQ,5,old);
  3281. end;
  3282.  
  3283. procedure _trident;
  3284. var old,val,Xseg,x:word;
  3285.   Phadr:longint;
  3286. begin
  3287.   wrinx(SEQ,$B,0);           {Force old mode}
  3288.   cv.SubVers:=inp(SEQ+1);    { ---  new mode}
  3289.   old:=rdinx(SEQ,$E);
  3290.   outp(SEQ+1,old xor $55);
  3291.   val:=inp(SEQ+1);
  3292.   outp(SEQ+1,old);
  3293.   if ((val xor old) and 15)=7 then  {Check for inverting bit 1}
  3294.   begin
  3295.     outp($3c5,old xor 2);   (* Trident should restore bit 1 reversed *)
  3296.     case cv.SubVers of
  3297.         1:cv.Version:=TR_8800BR;   {This'll never happen - no new mode}
  3298.         2:cv.Version:=TR_8800CS;
  3299.         3:cv.Version:=TR_8900B;
  3300.     4,$13:cv.Version:=TR_8900C;
  3301.       $23:cv.Version:=TR_9000;
  3302.       $33:if (rdinx(crtc,$28) and $80)>0 then cv.Version:=TR_8900CL
  3303.                 {Does this work?}        else cv.Version:=TR_9000C;
  3304.       $43:cv.Version:=TR_9000i;
  3305.       $53:cv.Version:=TR_9200CXr;
  3306.       $63:cv.Version:=TR_LCD9100B;
  3307.       $73:cv.Version:=TR_GUI9420;   {Haven't seen this yet ?}
  3308.       $83:cv.Version:=TR_LX8200;
  3309.       $93:cv.Version:=TR_9400CXi;
  3310.       $A3:cv.Version:=TR_LCD9320;
  3311.       $C3:cv.Version:=TR_GUI9420;
  3312.       $D3:cv.Version:=TR_GUI9660;
  3313.       $E3:cv.Version:=TR_GUI9440;
  3314.       $F3:cv.Version:=TR_GUI9430;  {not quite sure}
  3315.           {The $63, $73, $83, $A3 entries are still in doubt}
  3316.     else cv.Version:=TR_Unknown;
  3317.     end;
  3318.     case cv.version of
  3319.       TR_8800BR,
  3320.       TR_8800CS,
  3321.        TR_8900B:cv.clktype:=clk_ext3;
  3322.       TR_9200CXr,TR_9400CXi,TR_GUI9420,TR_GUI9430
  3323.                :begin
  3324.                   cv.clktype:=clk_ext4;
  3325.                   cv.dactype:=_dacInt;
  3326.                 end;
  3327.      TR_GUI9440:begin
  3328.                   cv.clktype:=clk_internal;
  3329.                   cv.dactype:=_dacInt;
  3330.                 end;
  3331.     else cv.clktype:=clk_ext4;
  3332.     end;
  3333.     if (cv.version>=TR_9000C) then cv.features:=cv.features+ft_rwbank;
  3334.     if (cv.version>=TR_GUI9440) then cv.features:=cv.features+ft_cursor;
  3335.     if cv.version=TR_9000i then setDAC(_dac16,'Trident 9000i');
  3336.     cv.chip:=__trid;
  3337.     if (pos('Zymos Poach 51',getbios(0,255))>0) or
  3338.        (pos('Zymos Poach 51',getbios(230,255))>0) then
  3339.     begin
  3340.       cv.name:=cv.name+' (Zymos Poach)';
  3341.       cv.chip:=__poach;
  3342.     end;
  3343.     case rdinx(crtc,$1F) and 3 of
  3344.       0:cv.mm:=256;
  3345.       1:cv.mm:=512;
  3346.       2:cv.mm:=768;
  3347.       3:if (cv.Version>=TR_8900CL) and ((rdinx(crtc,$1F) and 4)>0) then
  3348.              cv.mm:=2048
  3349.         else cv.mm:=1024;
  3350.     end;
  3351.     if (cv.SubVers=2) and (tstrg($2168,$F)) then
  3352.     begin
  3353.       cv.clktype:=clk_ext2;
  3354.       cv.Version:=TR_IITAGX;
  3355.       cv.mm:=512;   {Might be able to address 1Mb, but scroll etc only works}
  3356.       addvideo;     {in the first 512K anyhow !}
  3357.  
  3358.       cv.IOadr:=$2160;
  3359.       cv.chip:=__AGX;
  3360.       old:=inp(cv.IOadr);
  3361.       modreg(cv.IOadr,7,4); {Enable XGA mode}
  3362.       if testinx2(cv.IOadr+10,$7F,$30) then cv.version:=IIT_AGX1x
  3363.       else if testinx2(cv.IOadr+10,$71,$F) then cv.version:=IIT_AGX16
  3364.       else if (rdinx(cv.IOadr+10,$6C) and 1)>0 then cv.version:=IIT_AGX15
  3365.                                                else cv.Version:=IIT_AGX14;
  3366.       if (rdinx(cv.IOadr+10,$6D) and 1)>0 then cv.Xseg:=$B1F0 else cv.Xseg:=$D1F0;
  3367.       outp(cv.IOadr,old);
  3368.       if cv.Version>=IIT_AGX14 then cv.clktype:=clk_ext5
  3369.                                else cv.clktype:=clk_ext4;
  3370.       memmode:=_p8;
  3371.       if setmode($65,false) then;
  3372.       checkmem(32);
  3373.       cv.features:=ft_blit+ft_line+ft_cursor;
  3374.       Phadr:=$FF800000;
  3375.       cv.flags:=cv.flags and (not FLG_StdVGA);
  3376.     end;
  3377.     addvideo;
  3378.   end
  3379.   else begin  {Trident 8800BR tests}
  3380.     if (cv.subvers=1) and testinx2(SEQ,$E,6) then
  3381.     begin
  3382.       cv.Version:=TR_8800BR;
  3383.       cv.chip:=__trid;
  3384.       if (rdinx(crtc,$1F) and 2)>0 then cv.mm:=512;
  3385.       addvideo;
  3386.     end;
  3387.   end;
  3388. end;
  3389.  
  3390. procedure _tseng;
  3391. var x,vs:word;
  3392.   s:string;
  3393. begin
  3394.   outp($3BF,3);
  3395.   outp(crtc+4,$A0);    {Enable Tseng 4000 extensions}
  3396.   if tstrg($3CD,$3F) then
  3397.   begin
  3398.     cv.chip:=__Tseng;
  3399.     cv.features:=ft_rwbank;
  3400.     cv.clktype:=clk_ext5;
  3401.     if testinx2(crtc,$33,$F) then
  3402.     begin
  3403.       if tstrg($3CB,$33) then
  3404.       begin
  3405.         cv.features:=cv.features+ft_cursor+ft_blit;
  3406.     cv.SubVers:=rdinx($217A,$EC);
  3407.     case cv.SubVers shr 4 of
  3408.       0:cv.Version:=ET_4W32;
  3409.           1:cv.Version:=ET_4W32i_a;
  3410.           2:cv.Version:=ET_4W32p_a;
  3411.           3:cv.Version:=ET_4W32i_b;
  3412.           5:cv.Version:=ET_4W32p_b;
  3413.           6:cv.Version:=ET_4W32p_d;
  3414.           7:cv.Version:=ET_4W32p_c;
  3415.          11:cv.Version:=ET_4W32i_c;
  3416.     else Unk(ET_4Unk,cv.SubVers);
  3417.     end;
  3418.     case rdinx(crtc,$37) and $9 of
  3419.            0:cv.mm:=2048;
  3420.        1:cv.mm:=4096;
  3421.      {  9:mm:=256;}
  3422.        8:cv.mm:=512;
  3423.        9:cv.mm:=1024;
  3424.     end;
  3425.         if cv.version>=ET_4W32p_a then cv.features:=cv.features or ft_line;
  3426.         if (cv.Version<>ET_4W32) and ((rdinx(crtc,$32) and $80)>0) then
  3427.           cv.mm:=cv.mm*2;
  3428.       end
  3429.       else begin
  3430.     cv.Version:=ET_4000;
  3431.     case rdinx(crtc,$37) and $B of
  3432.      3,9:cv.mm:=256;
  3433.       10:cv.mm:=512;
  3434.       11:cv.mm:=1024;
  3435.     end;
  3436.         cv.subvers:=0;
  3437.         for x:=0 to 10 do
  3438.         begin
  3439.           s:=getbios(x*230,255);
  3440.           if pos('Genoa Systems',s)>0 then cv.subvers:=TS_Genoa7900
  3441.           else if pos('SpeedSTAR',s)>0 then cv.subvers:=TS_SpeedStar;
  3442.         end;
  3443.       end;
  3444.     end
  3445.     else begin
  3446.       cv.Version:=ET_3000;
  3447.       if setmode($13,false) then;
  3448.       x:=inp(CRTC+6);
  3449.       x:=rdinx($3C0,$36);
  3450.       outp($3C0,x or $10);
  3451.       case (rdinx(GRC,6) shr 2) and 3 of
  3452.        0,1:vs:=SegA000;
  3453.      2:vs:=SegB000;
  3454.      3:vs:=SegB800;
  3455.       end;
  3456.  
  3457.       meml[vs:1]:=$12345678;
  3458.       if memw[vs:2]=$3456 then cv.mm:=512;
  3459.  
  3460.       wrinx($3C0,$36,x);     {reset value and reenable DAC}
  3461.     end;
  3462.     addvideo;
  3463.   end;
  3464. end;
  3465.  
  3466. procedure _UMC;
  3467. var old:integer;
  3468. begin
  3469.   old:=inp($3BF);
  3470.   outp($3BF,3);
  3471.   if not testinx(SEQ,6) then
  3472.   begin
  3473.     outp($3BF,$AC);
  3474.     if testinx(SEQ,6) then
  3475.     begin
  3476.       cv.chip:=__UMC;
  3477.       cv.clktype:=clk_ext3;
  3478.       case rdinx(SEQ,7) shr 6 of
  3479.     1:cv.mm:=512;
  3480.       2,3:cv.mm:=1024;
  3481.       end;
  3482.       if testinx2(crtc,$35,$F) then
  3483.       begin
  3484.         cv.version:=UMC_418;
  3485.         if ((rdinx(GRC,$B) and $7F)=$2A) then cv.mm:=1024;
  3486.       end
  3487.       else cv.version:=UMC_408;
  3488.       cv.features:=ft_rwbank;
  3489.       addvideo;
  3490.     end;
  3491.   end;
  3492.   outp($3BF,old);
  3493. end;
  3494.  
  3495.  
  3496. procedure _video7;
  3497. var ram:string[10];
  3498.   old:integer;
  3499. begin
  3500.   vio($6f00);
  3501.   if rp.bx=$5637 then
  3502.   begin
  3503.     vio($6f07);
  3504.     if rp.ah<128 then ram:='VRAM' else ram:='FASTWRITE';
  3505.  
  3506.  (* old:=rdinx(crtc,$C);
  3507.   wrinx(crtc,$C,old);
  3508.   wrinx($3C4,6,$EA);    {Enable Extensions}
  3509.   if rdinx(crtc,$1F)=(old XOR $EA) then
  3510.   begin
  3511.     wrinx(crtc,$C,old XOR $FF);
  3512.     if rdinx(crtc,$1F)=(old XOR $15) then
  3513.     begin
  3514.       cv.SubVers:=(rdinx($3C4,$8F) shl 8)+rdinx($3C4,$8E);
  3515.  
  3516.   wrinx(crtc,$C,old); *)
  3517.  
  3518.     wrinx(SEQ,6,$EA);  {Enable extensions}
  3519.     cv.Subvers:=(rdinx(SEQ,$8F) shl 8)+rdinx(SEQ,$8E);
  3520.     case cv.Subvers of
  3521.   $8000..$FFFF:cv.Version:=V7_VEGA;
  3522.   $7000..$70FF:cv.Version:=V7_208_13;    {Fastwrite}
  3523.   $7140..$714F:cv.Version:=V7_208A;      {1024i}
  3524.      $7151:cv.Version:=V7_208B;      {VRAm II b}
  3525.      $7152:cv.Version:=V7_208CD;     {VRAm II c}
  3526.      $7760:cv.Version:=V7_216BC;
  3527.      $7763:cv.Version:=V7_216D;
  3528.      $7764:cv.Version:=V7_216E;
  3529.      $7765:cv.Version:=V7_216F;
  3530.     else cv.Version:=V7_Unknown;
  3531.     end;
  3532.     case rp.ah and 127 of
  3533.       2:cv.mm:=512;
  3534.       4:cv.mm:=1024;
  3535.     end;
  3536.     cv.chip:=__video7;
  3537.     cv.features:=ft_cursor;
  3538.     if cv.Version>=V7_208A then
  3539.     begin
  3540.     {  cv.Features:=cv.features+ft_rwbank; {Don't work }
  3541.       cv.clktype:=clk_ext4;
  3542.     end;
  3543.     addvideo;
  3544.   end;
  3545. end;
  3546.  
  3547.  
  3548.   {Sets the Extention & Bank enable flags in SEQ index $11}
  3549. function WeitekEnable(flag:word):word;
  3550. var x,y:word;
  3551. begin
  3552.   disable;
  3553.   x:=rdinx(SEQ,$11);
  3554.   for y:=1 to 10 do; {delay}
  3555.   outp(SEQ+1,x);
  3556.   for y:=1 to 10 do;
  3557.   outp(SEQ+1,x);
  3558.   for y:=1 to 10 do;
  3559.   WeitekEnable:=x;
  3560.   x:=inp(SEQ+1);
  3561.   for y:=1 to 10 do;
  3562.   outp(SEQ+1,(x and $9F) or flag);
  3563.   WeitekEnable:=x;
  3564.   enable;
  3565. end;
  3566.  
  3567.  
  3568. procedure _Weitek;
  3569. var old,x,y,z:word;
  3570.   rr:array[0..$1FF] of byte;
  3571. begin
  3572.   old:=WeitekEnable($60);   {Disable}
  3573.   if not testinx(SEQ,$12) then
  3574.   begin
  3575.     x:=WeitekEnable(0);     {Enable}
  3576.     if testinx(SEQ,$12) and tstrg($3CD,$FF) then
  3577.     begin
  3578.       cv.chip:=__Weitek;
  3579.       cv.features:=ft_rwbank;
  3580.       cv.SubVers:=rdinx(SEQ,7);
  3581.       cv.clktype:=clk_ext3;
  3582.       case cv.subvers shr 5 of
  3583.         1:begin
  3584.             cv.Version:=WT_5186;  {Should check for version and memory}
  3585.           (*  if (rdinx(SEQ,$12) and $80)>0 then
  3586.                cv.mm:=512;   {Untested} *)
  3587.           end;
  3588.         2:begin
  3589.             outp($9100,0);
  3590.             z:=inp($9104);
  3591.             outp($9100,1);
  3592.             z:=(inp($9104) shl 8)+z;
  3593.             if (z=$100E) then
  3594.             begin
  3595.               cv.Version:=WT_P9100;
  3596.               cv.mm:=1024;   {Hm}
  3597.             end
  3598.             else begin
  3599.               cv.Version:=WT_5286;
  3600.               case rdinx(SEQ,$12) shr 6 of
  3601.                 0:cv.mm:=256;
  3602.                 1:cv.mm:=512;
  3603.                 2:cv.mm:=1024;
  3604.               end;
  3605.             end;
  3606.           end;
  3607.       else cv.Version:=WT_Unk;
  3608.       end;
  3609.       addvideo;
  3610.       x:=WeitekEnable($60);  {dis. VGA}
  3611.       z:=rdinx(SEQ,$12);
  3612.       clrinx(SEQ,$12,$80);
  3613.       setinx(SEQ,$12,$10);
  3614.       outp($3CD,$10);
  3615.  
  3616.       move(mem[SegA000:0],rr,$200);
  3617.       wrinx(SEQ,$12,z);
  3618.     end;
  3619.   end;
  3620.   wrinx(SEQ,$11,old);
  3621. end;
  3622.  
  3623. procedure _XGA;
  3624. var p:pointer;
  3625.  posbase,cardid,xga_base,x,cx:word;
  3626.  temp0,temp1,temp2,temp3:byte;
  3627. begin
  3628.   getintvec($15,p);
  3629.   if (seg(p^)<>0) then
  3630.   begin
  3631.     rp.ax:=$C400;
  3632.     rp.dx:=$ffff;
  3633.     intr($15,rp);
  3634.     if not odd(rp.flags) and (rp.dx<>$ffff) then
  3635.     begin
  3636.       posbase:=rp.dx;
  3637.       for cx:=0 to 9 do
  3638.       begin
  3639.     disable;   (* CLI -  Disable interrupts *)
  3640.     if cx=0 then outp($94,$DF)
  3641.     else begin
  3642.       rp.ax:=$C401;
  3643.       rp.bx:=cx;
  3644.       intr($15,rp);
  3645.     end;
  3646.     cardid:=inpw(posbase);
  3647.     temp0:=inp(posbase+2);
  3648.     temp1:=inp(posbase+3);
  3649.     temp2:=inp(posbase+4);
  3650.     temp3:=inp(posbase+5);
  3651.     if cx=0 then outp($94,$FF)
  3652.     else begin
  3653.       rp.ax:=$C402;
  3654.       rp.bx:=cx;
  3655.       intr($15,rp);
  3656.     end;
  3657.     enable;   (* STI -  Enable interrupts *)
  3658.     if (cardid>=$8FD8) and (cardid<=$8FDB) then
  3659.     begin
  3660.       cv.IOadr:=$2100+(temp0 and $E)*8;
  3661.       x:=rdinx(cv.IOadr+10,$52) and 15;
  3662.       if (x<>0) and (x<>15) then
  3663.       begin
  3664.         cv.chip:=__XGA;
  3665.         outp(cv.IOadr+4,0);
  3666.       {  outp(cv.IOadr,4);
  3667.         checkmem(16); }
  3668.             cv.mm:=1024;
  3669.         case cardid of
  3670.          $8FDA:cv.Version:=XGA_NI;
  3671.          $8FDB:cv.Version:=XGA_org;
  3672.         end;
  3673.  
  3674.         cv.Xseg:=(temp0 shr 4)*$2000+$C1C0+(temp0 and $E)*4;
  3675.         cv.Phadr:=((temp2 and $FE)*word(8)+(temp0 and $E))*longint($200000);
  3676.         addvideo;
  3677.       end;
  3678.     end;
  3679.       end;
  3680.     end;
  3681.   end;
  3682. end;
  3683.  
  3684. procedure _yamaha;
  3685. begin
  3686.   if testinx2(crtc,$7C,$7C) then
  3687.   begin
  3688.     cv.Version:=YA_6388;
  3689.     addvideo;
  3690.   end;
  3691. end;
  3692.  
  3693. procedure _xbe;
  3694. var
  3695.   x:word;
  3696.   xbe0:_xbe0;
  3697.   xbe1:_xbe1;
  3698.  
  3699. begin
  3700.   viop($4E00,0,0,0,@xbe0);
  3701.   if (rp.ax=$4E) and (xbe0.sign=$41534556) then
  3702.   begin
  3703.     for x:=0 to xbe0.xgas-1 do
  3704.     begin
  3705.       viop($4E01,0,0,x,@xbe1);
  3706.       if (rp.ax=$4E) then
  3707.       begin
  3708.     cv.chip:=__xbe;
  3709.         cv.features:=ft_blit+ft_line;
  3710.     cv.mm:=xbe1.memory*longint(64);
  3711.     cv.id:=x;
  3712.     cv.IOadr :=xbe1.iobase;
  3713.     cv.Xseg  :=xbe1.memreg shr 16;
  3714.     cv.Phadr :=xbe1.vidadr;
  3715.     cv.name  :=gtstr(xbe1.oemadr^);
  3716.     UNK(VS_XBE,xbe0.vers);
  3717.     addvideo;
  3718.       end;
  3719.     end;
  3720.   end;
  3721. end;
  3722.  
  3723. procedure _vesa;
  3724. var
  3725.   vesarec:_vbe0;
  3726.   x:word;
  3727. begin
  3728.   viop($4f00,0,0,0,@vesarec);
  3729.   if (rp.ax=$4f) and (vesarec.sign=$41534556) then
  3730.   begin
  3731.     cv.chip:=__vesa;
  3732.     cv.mm:=vesarec.mem*longint(64);
  3733.     cv.name:=gtstr(vesarec.oemadr^);
  3734.     UNK(VS_VBE,vesarec.vers);
  3735.     cv.dactype:=_dac8;    {Dummy, to keep Cirrus 542x out of trouble}
  3736.     addvideo;
  3737.   end;
  3738. end;
  3739.  
  3740.  
  3741. type
  3742.   pel=record
  3743.     index,red,green,blue:byte;
  3744.       end;
  3745.  
  3746. procedure readpelreg(index:word;var p:pel);
  3747. begin
  3748.   p.index:=index;
  3749.   disable;
  3750.   outp($3C7,index);
  3751.   p.red  :=inp($3C9);
  3752.   p.blue :=inp($3C9);
  3753.   p.green:=inp($3C9);
  3754.   enable;
  3755. end;
  3756.  
  3757. procedure writepelreg(var p:pel);
  3758. begin
  3759.   disable;
  3760.   outp($3C8,p.index);
  3761.   outp($3C9,p.red);
  3762.   outp($3C9,p.blue);
  3763.   outp($3C9,p.green);
  3764.   enable;
  3765. end;
  3766.  
  3767. function setcomm(cmd:word):word;
  3768. begin
  3769.   dac2comm;
  3770.   outp($3c6,cmd);
  3771.   dac2comm;
  3772.   setcomm:=inp($3c6);
  3773. end;
  3774.  
  3775. function dacis8bit:boolean;
  3776. var
  3777.   pel2,x,y,z,v:word;
  3778.   pel1:pel;
  3779. begin
  3780.   pel2:=inp($3C8);
  3781.   readpelreg(255,pel1);
  3782.   v:=pel1.red;
  3783.   pel1.red:=255;
  3784.   writepelreg(pel1);
  3785.   readpelreg(255,pel1);
  3786.   x:=pel1.red;
  3787.   pel1.red:=v;
  3788.   writepelreg(pel1);
  3789.   outp($3C8,pel2);
  3790.   dacis8bit:=(x=255);
  3791. end;
  3792.  
  3793. procedure testdac;      {Test for type of DAC}
  3794. var
  3795.   x,y,z,v,oldcomm,oldpel,notcomm:word;
  3796.   dac8,dac8now:boolean;
  3797.   data:array[9..12] of byte;
  3798.  
  3799. procedure waitforretrace;
  3800. begin
  3801.   repeat until (inp(CRTC+6) and 8)=0;
  3802.   repeat until (inp(CRTC+6) and 8)>0;    {Wait until we're in retrace}
  3803. end;
  3804.  
  3805. procedure SetDACCmd(cmd:integer);
  3806. begin
  3807.   dac2comm;
  3808.   outp($3C6,cmd);
  3809.   dac2pel;
  3810. end;
  3811.  
  3812.  
  3813. function testdacbit(bit:word):boolean;
  3814. var v:word;
  3815. begin
  3816.   dac2pel;
  3817.   outp($3C6,oldpel and (bit xor $FF));
  3818.   dac2comm;
  3819.   disable;
  3820.   outp($3C6,oldcomm or bit);
  3821.   dac2comm;
  3822.   v:=inp($3C6);
  3823.   outp($3C6,v and (bit xor $FF));
  3824.   enable;
  3825.   testdacbit:=(v and bit)<>0;
  3826. end;
  3827.  
  3828. function rdSCdac(Inx:word):word;
  3829. begin
  3830.   dac2comm;
  3831.   outp($3C6,inp($3C6) or $10);
  3832.   rdSCdac:=rdinx($3C7,inx);
  3833.   dac2comm;
  3834.   outp($3C6,inp($3C6) and $EF);
  3835.   dac2pel;
  3836. end;
  3837.  
  3838. procedure wrBTinx(inx,val:word);
  3839. var x:word;
  3840. begin
  3841.   dac2comm;
  3842.   x:=daccomm;
  3843.   outp($3C6,1);
  3844.  { dac2pel;}
  3845.   outp($3C8,Inx);
  3846.   outp($3C6,val);
  3847.   dac2comm;
  3848.   outp($3C6,x and $FE);
  3849.   dac2pel;
  3850. end;
  3851.  
  3852. function rdBTinx(Inx:word):word;
  3853. var x:word;
  3854. begin
  3855.   dac2comm;
  3856.   x:=daccomm;
  3857.   outp($3C6,1);
  3858.  { dac2pel;}
  3859.   outp($3C8,Inx);
  3860.   rdBTinx:=inp($3C6);
  3861.   dac2comm;
  3862.   outp($3C6,x and $FE);
  3863.   dac2pel;
  3864. end;
  3865.  
  3866.  
  3867. var zz:integer;
  3868.   t:text;
  3869. begin
  3870.   setDAC(_dac8,'Normal');
  3871.   dac2comm;
  3872.   oldcomm:=inp($3c6);
  3873.   dac2pel;
  3874.   oldpel:=inp($3c6);
  3875.  
  3876.   if cv.dactype=_dac8 then
  3877.   begin
  3878.     dac2comm;
  3879.     outp($3C6,0);
  3880.     dac8:=dacis8bit;
  3881.     dac2pel;
  3882.  
  3883.     notcomm:=oldcomm xor 255;
  3884.     outp($3C6,notcomm);
  3885.     dac2comm;
  3886.     v:=inp($3C6);
  3887.     if v<>notcomm then    {We have a "Hidden Command" register}
  3888.     begin
  3889.       dac2pel;
  3890.       dac2comm;
  3891.       x:=inp($3C6);
  3892.       x:=inp($3C6);
  3893.       y:=inp($3C6);
  3894.       z:=inp($3C6);
  3895.       dac2pel;
  3896.       if (x=$84) and (y=$98) then
  3897.       begin
  3898.         if z=$4F then setDAC(_dacICW516,'IC Works W30c516')
  3899.         else if setcomm($A)=0 then setDAC(_dacATT2498,'ATT 22c498')
  3900.                               else setDAC(_dacATT1498,'ATT 21c498');
  3901.       end
  3902.       else begin
  3903.         setDACcmd($10);
  3904.         if rdinx($3C7,9)=$53 then
  3905.         begin
  3906.           x:=rdinx($3C7,10);
  3907.           x:=x*256+rdinx($3C7,11);
  3908.           case x of     {Looks like the 15021 & 25 are the only values}
  3909.             15021:setDAC(_dacSC15021,'SC15021');
  3910.             15025:setDAC(_dacSC15025,'SC15025');
  3911.           else setDAC(_dacSC15021,'Unknown SC 15xxx');
  3912.           end;
  3913.         end;
  3914.         setDACcmd(oldcomm);
  3915.       end;
  3916.       if cv.dactype=_dac8 then
  3917.       begin
  3918.         setDACcmd($10);
  3919.         dac2comm;
  3920.         x:=inp($3C6);
  3921.         outp($3C6,0);
  3922.         outp($3C6,0);
  3923.         if inp($3C6)=$44 then
  3924.           case inp($3C6) of
  3925.             0:setDAC(_dacSTG1700,'STG1700');
  3926.             2:setDAC(_dacSTG1702,'STG1702');
  3927.             3:begin
  3928.                 setDAC(_dacSTG1703,'STG1703');
  3929.                 cv.clktype:=clk_STG;
  3930.               end;
  3931.           else setDAC(_dacSTG1700,'Unknown STG');
  3932.           end;
  3933.         setDACcmd(oldcomm);
  3934.       end;
  3935.       if cv.dactype=_dac8 then
  3936.       begin
  3937.         dac2pel;
  3938.         x:=inp($3C6);
  3939.         x:=inp($3C6);
  3940.         x:=inp($3C6);
  3941.         x:=inp($3C6);
  3942.         if (x and $F0)=$70 then
  3943.         begin
  3944.           setDAC(_dacS3_716,'S3 86c716 (SDAC)');
  3945.           cv.clktype:=clk_sdac;
  3946.         end;
  3947.         dac2pel;
  3948.       end;
  3949.       if cv.dactype=_dac8 then
  3950.       begin
  3951.         dac2comm;
  3952.         if daccomm=$31 then setDAC(_dacALG1301,'ALG1301');
  3953.         dac2pel;
  3954.       end;
  3955.       if cv.dactype=_dac8 then
  3956.         if (setcomm($E0) and $E0)<>$E0 then
  3957.         begin
  3958.           dac2pel;
  3959.           x:=inp($3C6);
  3960.           repeat
  3961.         y:=x;         {wait for the same value twice}
  3962.         x:=inp($3C6);
  3963.           until (x=y);
  3964.           z:=x;
  3965.           dac2comm;
  3966.           if daccomm<>$8E then
  3967.           begin                 {If command register=$8e, we've got an SS24}
  3968.         y:=8;
  3969.         repeat
  3970.           x:=inp($3C6);
  3971.           dec(y);
  3972.         until (x=$8E) or (y=0);
  3973.           end
  3974.           else x:=daccomm;
  3975.           if x=$8e then setDAC(_dacMU1880,'SS24')
  3976.                else setDAC(_dacSC486,'Sierra SC11486');
  3977.           dac2pel;
  3978.         end
  3979.         else begin
  3980.           if (setcomm($60) and $E0)=0 then
  3981.           begin
  3982.             if (setcomm(2) and 2)>0 then setDAC(_dacATT490,'ATT 20c490')
  3983.                                     else setDAC(_dacATT493,'ATT 20c493');
  3984.           end
  3985.           else begin  {Bit 5-7 fully r/w}
  3986.             dac2pel;
  3987.             outp($3C6,notcomm);     {PEL register}
  3988.         x:=setcomm(oldcomm);
  3989.         if inp($3C6)=notcomm then     {Falls back to PEL register}
  3990.         begin                         {after 1st read}
  3991.               x:=setcomm($FC);
  3992.               if x<>$FC then
  3993.                 case x of
  3994.                   $E2:setDAC(_dacALG1201,'ALG1201');
  3995.                   $E0:setDAC(_dacICS5301,'ICS 5301');
  3996.                   $F4:setDAC(_dacS3_708,'S3/ICS 86c708 GenDAC');
  3997.                 else
  3998.                   if testdacbit($F0) then setDAC(_dacUMC188,'UMC UM70c188')
  3999.                                      else setDAC(_dacADAC1,'Acumos ADAC1');
  4000.                 end
  4001.           else begin  {All 8 bits fully r/w}
  4002.             dac8now:=dacis8bit;
  4003.             dac2comm;
  4004.             outp($3C6,(oldcomm or 2) and $FE);
  4005.             dac8now:=dacis8bit;
  4006.             if dac8now then
  4007.                 begin
  4008.               if dacis8bit then
  4009.                   begin
  4010.                     x:=setcomm(oldcomm or $10);
  4011.                     dac2comm;
  4012.                     x:=inp($3C6);
  4013.                     outp($3C6,1);
  4014.                     x:=x;  {delay}
  4015.                     outp($3C6,0);
  4016.                     if inp($3C6)=0 then setDAC(_dacATT491,'ATT 20c491')
  4017.                   end
  4018.                 end
  4019.                  { else setDAC(_dacCL24,'Cirrus 24bit DAC')}
  4020.             else
  4021.                   if trigdac=$B3 then
  4022.                   begin
  4023.                     setDAC(_dacCH8391,'CHRONTEL CH8391');
  4024.                     cv.clktype:=clk_CHRON;
  4025.                   end
  4026.                   else setDAC(_dacATT492,'ATT 20c492');
  4027.           end;
  4028.         end
  4029.         else begin
  4030.           {if trigdac=notcomm then setDAC(_dacCL24,'Cirrus 24bit DAC')
  4031.           else} begin
  4032.             dac2pel;
  4033.             outp($3C6,$FF);
  4034.             case trigdac of
  4035.                   $44:begin
  4036.                         setDAC(_dacMU9910,'MUSIC MU9C9910');
  4037.                         cv.clktype:=CLK_MUSIC;
  4038.                       end;
  4039.               $82:setDAC(_dacMU4910,'MUSIC MU9C4910');
  4040.               $8E:setDAC(_dacMU1880,'MUSIC MU9C1880 (SS2410)');
  4041.             else begin
  4042.                   if setcomm(1)=$AA then setDAC(_dacALG1201,'ALG1201')
  4043.                   else begin
  4044.                          dac2comm;
  4045.                          if daccomm=$C0 then
  4046.                          begin
  4047.                            setDAC(_dacCH8398,'CH8398');
  4048.                            cv.clktype:=clk_CHRON;
  4049.                          end
  4050.                          else
  4051.                            if testdacbit($10) then
  4052.                            begin
  4053.                              outp($3C8,2);
  4054.                              SetDACcmd(oldcomm or 2);
  4055.                              dac8now:=dacis8bit;
  4056.                              SetDACcmd(oldcomm and $FD);
  4057.                              if dac8now then    {The Bt481 ends here too}
  4058.                              begin
  4059.                                outp($3C8,0);
  4060.                                SetDACcmd(oldcomm or 2);
  4061.                                dac8now:=dacis8bit;
  4062.                                SetDACcmd(oldcomm and $FD);
  4063.                                if dac8now then setDAC(_dacTR8001,'Trident TKD8001')
  4064.                                           else setDAC(_dacBt481,'Bt481');
  4065.                              end
  4066.                              else setDAC(_dac16,'OAK 66HC');
  4067.                            end
  4068.                            else begin
  4069.                              dac2pel;
  4070.                              outp($3C6,$FF);
  4071.                              dac2comm;
  4072.                              outp($3C6,0);
  4073.                              dac2pel;
  4074.                              dac2comm;
  4075.                              outp($3C6,$7F);
  4076.                              dac2comm;
  4077.                              x:=inp($3C6);
  4078.                              dac2comm;
  4079.                              dac2comm;
  4080.                              outp($3C6,$FF);
  4081.                              dac2comm;
  4082.                              v:=inp($3C6);
  4083.                              dac2comm;
  4084.                              outp($3C6,oldcomm);
  4085.                              dac2pel;
  4086.                              if (x=$60) and (v=$E0) then setDAC(_dac16,'UMC 70c178')
  4087.                              else if (x=$7F) and (v=$FE) then setDAC(_dac16,'Sierra SC11487')
  4088.                                                     else setDAC(_dac15,'Sierra Sc11483');
  4089.                            end;
  4090.                        end;
  4091.             end;
  4092.           end;
  4093.         end;
  4094.           end;
  4095.         end;
  4096.  
  4097.       end;
  4098.  
  4099.       dac2comm;
  4100.       outp($3c6,oldcomm);
  4101.     end;
  4102.     dac2pel;
  4103.     outp($3c6,oldpel);
  4104.  
  4105.   end;
  4106.  
  4107.   if (cv.dactype=_dac8) then
  4108.   begin
  4109.     oldpel :=rdDACreg(dacSTDpelMask) xor $FF;
  4110.     oldcomm:=rdDACreg(dacSTDpelMask+4);
  4111.     x      :=rdDACreg(dacSTDpelMask+8);
  4112.     wrDACreg(dacSTDpelMask,oldpel);
  4113.     y :=rdDACreg(dacSTDpelMask+4);
  4114.     z :=rdDACreg(dacSTDpelMask+8);
  4115.     zz:=rdDACreg(dacSTDpelMask);
  4116.     if (zz=oldpel) and (y<>oldpel) or (z<>oldpel) then
  4117.     begin   { Either RS2 or RS3 finds a register <> $3C6,
  4118.               We have an advanced DAC and access to it! }
  4119.       wrDACreg(dacSTDpelMask,0);
  4120.       wrDACreg(dacTLCtest,3);
  4121.       case rdDACreg(dacTLCtest) of
  4122.         $75:setDAC(_dacTLC34075,'TLC34075');
  4123.         $76:setDAC(_dacTLC34076,'TLC34076');
  4124.       else
  4125.         if cv.chip=__S3 then
  4126.         begin
  4127.           outpw(crtc,$A539);
  4128.           y:=rdinx(crtc,$5C);   {Force TI mode}
  4129.           clrinx(crtc,$5C,$20);
  4130.           wrDACreg(dacTVPindex,6);
  4131.           z:=rdDACreg(dacTVPdata);
  4132.           wrDACreg(dacTVPdata,z and $7F);
  4133.         end;
  4134.         x:=rdDACreg(dacTVPindex);
  4135.         wrDACreg(dacTVPindex,$3F);
  4136.         y:=rdDACreg(dacTVPdata);
  4137.         wrDACreg(dacTVPdata,y xor $FF);
  4138.         z:=rdDACreg(dacTVPdata);
  4139.         if z<>y then  {Must be read-only for TVP}
  4140.           wrDACreg(dacTVPdata,y)
  4141.         else
  4142.           case y of
  4143.             $10:setDAC(_dacTVP3010,'TVP 3010');
  4144.             $20:setDAC(_dacTVP3020,'TVP 3020');
  4145.             $25:begin
  4146.                   setDAC(_dacTVP3025,'TVP 3025');
  4147.                   cv.clktype:=clk_TVP302x;
  4148.                 end;
  4149.           end;
  4150.         wrDACreg(dacTVPindex,x);
  4151.         if cv.dactype=_dac8 then
  4152.         begin
  4153.           x:=rdDACreg(dacTVP6index);
  4154.           wrDACreg(dacTVP6index,$3F);
  4155.           y:=rdDACreg(dacTVP6data);
  4156.           wrDACreg(dacTVP6data,y xor $FF);
  4157.           z:=rdDACreg(dacTVP6data);
  4158.           if z<>y then  {Must be read-only for TVP}
  4159.             wrDACreg(dacTVP6data,y)
  4160.           else
  4161.             case y of
  4162.               $26:begin
  4163.                     setDAC(_dacTVP3026,'TVP 3026');
  4164.                     cv.clktype:=clk_TVP302x;
  4165.                   end;
  4166.             end;
  4167.           wrDACreg(dacTVP6index,x);
  4168.         end;
  4169.         if cv.chip=__S3 then
  4170.         begin
  4171.           wrDACreg(dacTVPindex,6);
  4172.           wrDACreg(dacTVPdata,z);
  4173.           outpw(crtc,$A539);
  4174.           wrinx(crtc,$5C,y);
  4175.         end;
  4176.         if (cv.dactype=_dac8) then
  4177.         begin
  4178.           x:=rdDACreg(dacHIcmd);
  4179.           wrDACreg(dacHIcmd,x and $FE);
  4180.           y:=rdDACreg(dacSTDpelMask);
  4181.           wrDACreg(dacHIcmd,x or 1);   {Switch to Bt481 Indexed}
  4182.           wrDACreg(dacSTDwrInx,dacBTIipixm);
  4183.           wrDACreg(dacSTDpelMask,y xor $55);
  4184.           z:=rdDACreg(dacSTDpelMask);
  4185.           wrDACreg(dacSTDwrInx,dacBTIcurX);
  4186.           wrDACreg(dacSTDpelMask,y xor $AA);
  4187.           v:=rdDACreg(dacSTDpelMask);
  4188.           wrDACreg(dacSTDwrInx,dacBTIipixm);
  4189.           zz:=rdDACreg(dacSTDpelMask);
  4190.           wrDACreg(dacHIcmd,x and $FE); {Back to std regs}
  4191.           if (y=rdDACreg(dacSTDpelMask)) and (z=(y xor $55)) then
  4192.           begin
  4193.             if v=(y xor $AA) then setDAC(_dacBt481,'Bt482')
  4194.                              else setDAC(_dacBt482,'Bt481');
  4195.           end
  4196.           else begin
  4197.             x:=rdDACreg(dacIBMind0);
  4198.             wrDACreg(dacIBMind1,0);
  4199.             wrDACreg(dacIBMind0,dacIBMiRev);
  4200.             y:=rdDACreg(dacIBMdata);
  4201.             wrDACreg(dacIBMind0,dacIBMiId);
  4202.             y:=y+256*rdDACreg(dacIBMdata);
  4203.             if (y>$FF) and (y<$2FF) then  {Range ??}
  4204.             begin
  4205.               wrDACreg(dacIBMind0,dacIBMiRev);
  4206.               wrDACreg(dacIBMdata,y xor $FF);
  4207.               wrDACreg(dacIBMind0,dacIBMiId);
  4208.               wrDACreg(dacIBMdata,hi(y) xor $FF);
  4209.               wrDACreg(dacIBMind0,dacIBMiRev);
  4210.               z:=rdDACreg(dacIBMdata);
  4211.               wrDACreg(dacIBMind0,dacIBMiId);
  4212.               z:=z+256*rdDACreg(dacIBMdata);
  4213.               if (y=z) then
  4214.               begin
  4215.                 case y of
  4216.                   $2F0:SetDAC(_dacIBM524,'IBM RGB524');
  4217.                 else SetDAC(_dacIBM524,'Unknown IBM RGB');
  4218.                 end;
  4219.                 cv.clktype:=clk_IBM52x;
  4220.               end
  4221.               else begin
  4222.                 wrDACreg(dacIBMind0,dacIBMiRev);
  4223.                 wrDACreg(dacIBMdata,y);
  4224.                 wrDACreg(dacIBMind0,dacIBMiId);
  4225.                 wrDACreg(dacIBMdata,hi(y));
  4226.               end;
  4227.             end
  4228.           end;
  4229.         end;
  4230.       end;
  4231.  
  4232.       if cv.dactype=_dac8 then
  4233.       begin
  4234.         wrDACreg(dacSTDwrInx,0);  {Force the Bt485 status register}
  4235.         wrDACreg(dacBTcmd0,rdDACreg(dacBTcmd0) and $7F);
  4236.         x:=rdDACreg(dacBTstat);
  4237.         case x and $F0 of
  4238.           $40:setDAC(_dacATT504,'AT&T20c504');
  4239.           $D0:setDAC(_dacATT505,'AT&T20c505');
  4240.      $80..$B0:begin
  4241.                 y:=rdDACreg(dacBTcmd0);
  4242.                 wrDACreg(dacBTcmd0,y or $80);  {Enable STat/Cmd3}
  4243.                 wrDACreg(dacSTDwrInx,1);  {Force the cmd3 reg}
  4244.                 z:=rdDACreg(dacBTstat);
  4245.                 if z=x then
  4246.                 begin
  4247.                   wrDACreg(dacBTstat,x xor $55);
  4248.                   wrDACreg(dacSTDwrInx,0);  {Force the stat reg}
  4249.                   v:=rdDACreg(dacBTstat);
  4250.                   wrDACreg(dacSTDwrInx,1);  {Force the stat reg}
  4251.                   wrDACreg(dacBTstat,z);
  4252.                   if v=x then z:=x+1;  {Ie. Bt485}
  4253.                 end;
  4254.                 wrDACreg(dacBTcmd0,y);
  4255.                 if x=z then setDAC(_dacBT484,'Bt484')
  4256.                        else setDAC(_dacBT485,'Bt485');
  4257.               end;
  4258.         else
  4259.           x:=rdDACreg(0);
  4260.           y:=rdDACreg(4);
  4261.           wrDACreg(0,x XOR $FF);
  4262.           if rdDACreg(4)<>y then setDAC(_dacBT477,'Bt477');
  4263.                             {else setDAC(_dacIBM525,'IBM RGB525')}
  4264.  
  4265.         end;
  4266.       end;
  4267.     end;
  4268.     wrDACreg(dacSTDpelMask,oldpel);
  4269.   end;
  4270.   clearDACpage;
  4271.  
  4272.  
  4273.  
  4274.   if cv.dactype=_dac8 then
  4275.   begin
  4276.     WaitforRetrace;
  4277.     outp($3C8,222);
  4278.     outp($3C9,$43);
  4279.     outp($3C9,$45);
  4280.     outp($3C9,$47);    {Write 'CEGEDSUN' + mode to DAC index 222}
  4281.     outp($3C8,222);
  4282.     outp($3C9,$45);
  4283.     outp($3C9,$44);
  4284.     outp($3C9,$53);
  4285.     outp($3C8,222);
  4286.     outp($3C9,$55);
  4287.     outp($3C9,$4E);
  4288.     outp($3C9,13);     {Should be in CEG mode now}
  4289.     outp($3C6,255);
  4290.     x:=(inp($3c6) shr 4) and 7;
  4291.     if x<7 then
  4292.     begin
  4293.       setDAC(_dacCEG,'Edsun CEG rev. '+chr(x+48));
  4294.       WaitforRetrace;
  4295.       outp($3C8,223);
  4296.       outp($3C9,0);    {Back in normal dac mode}
  4297.     end;
  4298.   end;
  4299. end;
  4300.  
  4301.  
  4302. procedure findbios;     {Finds the most likely BIOS segment}
  4303. var
  4304.   score:array[0..7] of byte;
  4305.   x,y:word;
  4306. begin
  4307.   biosseg:=$c000;
  4308.   for x:=0 to 6 do score[x]:=1;
  4309.   for x:=0 to 7 do
  4310.   begin
  4311.     rp.bh:=x;
  4312.     vio($1130);
  4313.     if (rp.es>=$c000) and ((rp.es and $7ff)=0) then
  4314.       inc(score[(rp.es-$c000) shr 11]);
  4315.   end;
  4316.  
  4317.   for x:=0 to 6 do
  4318.   begin
  4319.     y:=$c000+(x shl 11);
  4320.     if (memw[y:0]<>$aa55) or (mem[y:2]<48) then
  4321.       score[x]:=0;                       {fail if no rom}
  4322.   end;
  4323.   for x:=6 downto 0 do
  4324.     if score[x]>0 then
  4325.       biosseg:=$c000+(x shl 11);
  4326. end;
  4327.  
  4328. type
  4329.   fnctyp=procedure;
  4330.  
  4331. const
  4332.   chps=30;
  4333.   chptype:array[1..chps] of byte=(__chips,__WD,__Video7
  4334.             ,__Everex,__Trid,__ati,__Ahead,__NCR,__S3,__ALG,__ARK
  4335.             ,__Cir54,__Cir64,__MXIC,__UMC,__Genoa,__Weitek,__SIS
  4336.             ,__Tseng,__Realtek,__P2000,__Acer,__SC,__Alli
  4337.             ,__Yamaha ,__Matrox,__Oak,__Cirrus,__Compaq,__HMC);
  4338.  
  4339. (* Known test ordering requirements:
  4340.  
  4341.   UMC before Genoa, otherwise the UMC will be ID'd as Genoa 6400
  4342.   C&T before HMC, as HMC test disturbs C&T
  4343.   MXIC before Tseng, as Tseng test disturbs MXIC
  4344.   SiS before Tseng, as the SiS will be ID'd as a Tseng
  4345. *)
  4346.  
  4347.  
  4348. procedure findvideo;
  4349. var  old,chp,vid1:word;
  4350.  
  4351. begin
  4352.   vids:=0;
  4353.   cv.dactype:=_dac0;
  4354.   cv.features:=0;
  4355.   cv.flags:=0;
  4356.   if odd(inp($3CC)) then CRTC:=$3D4 else CRTC:=$3B4;
  4357.   if dotest[__VESA] then _vesa;
  4358.   if dotest[__XBE] then _xbe;
  4359.   if dotest[__XGA] then _XGA;
  4360.   _Imagine;
  4361.  
  4362.   _crt:='';
  4363.   cv.chip:=__none;
  4364.   secondary:='';
  4365.   cv.name:='';
  4366.   video:='none';
  4367.   rp.bx:=$1010;
  4368.   vio($1200);
  4369.   if rp.bh<=1 then
  4370.   begin
  4371.     video:='EGA';
  4372.     cv.chip:=__ega;
  4373.  
  4374.     cv.mm:=rp.bl;
  4375.     vio($1a00);
  4376.     if rp.al=$1a then
  4377.     begin
  4378.       if (rp.bl<4) and (rp.bh>3) then
  4379.       begin
  4380.     old:=rp.bl;
  4381.     rp.bl:=rp.bh;
  4382.     rp.bh:=old;
  4383.       end;
  4384.       video:='MCGA';
  4385.       case rp.bl of
  4386.     2,4,6,10:_crt:='TTL Color';
  4387.     1,5,7,11:_crt:='Monochrome';
  4388.         8,12:_crt:='Analog Color';
  4389.       end;
  4390.       case rp.bh of
  4391.     1:secondary:='Monochrome';
  4392.     2:secondary:='CGA';
  4393.       end;
  4394.       findbios;
  4395.       if (getbios($31,9)='') and (getbios($40,2)='22') then
  4396.       begin
  4397.     video:='EGA';       {@#%@  lying ATI EGA Wonder !}
  4398.     cv.name:='ATI EGA Wonder';
  4399.     addvideo;
  4400.       end else
  4401.       if (rp.bl<10) or (rp.bl>12) then
  4402.       begin
  4403.         _MediaVis;
  4404.     chp:=0;vid1:=vids;
  4405.     while (vids=vid1) and (chp<chps) do
  4406.     begin
  4407.       inc(chp);
  4408.  
  4409.       video:='VGA';
  4410.       cv.chip:=__vga;
  4411.       cv.mm:=256;
  4412.       cv.features:=0;
  4413.       cv.dactype:=_dac0;
  4414.       cv.version:=0;
  4415.       cv.subvers:=0;
  4416.           cv.clktype:=clk_ext2;
  4417.           cv.flags:=FLG_StdVGA;
  4418.       if debug then
  4419.       begin
  4420.         writeln('Testing: '+header[chptype[chp]]);
  4421.         if readkey='' then;
  4422.       end;
  4423.       if dotest[chptype[chp]] then
  4424.             case chptype[chp] of
  4425.                 __Acer:_Acer;
  4426.                __Ahead:_Ahead;
  4427.                  __ALG:_ALG;
  4428.                 __Alli:_Alliance;
  4429.                  __ARK:_ARK;
  4430.                  __ati:_Ati;
  4431.                __chips:_chipstech;
  4432.                __Cir54:_Cirrus54;
  4433.                __Cir64:_Cirrus64;
  4434.               __Cirrus:_Cirrus;
  4435.               __Compaq:_Compaq;
  4436.               __Everex:_Everex;
  4437.                __Genoa:_Genoa;
  4438.                  __HMC:_HMC;
  4439.                 __MXIC:_MXIC;
  4440.                  __NCR:_NCR;
  4441.                  __Oak:_Oak;
  4442.                __P2000:_P2000;
  4443.                   __WD:_paradise;
  4444.              __Realtek:_Realtek;
  4445.                   __S3:_S3;
  4446.                   __SC:_Sierra;
  4447.                  __SiS:_SiS;
  4448.                 __Trid:_Trident;
  4449.                __Tseng:_Tseng;
  4450.                  __UMC:_UMC;
  4451.               __Video7:_Video7;
  4452.               __Weitek:_weitek;
  4453.               __Yamaha:_Yamaha;
  4454.               __Matrox:_matrox;
  4455.             end;
  4456.     end;
  4457.     if vids=vid1 then
  4458.         begin
  4459.           if force_chip<>__none then cv.chip:=force_chip;
  4460.           addvideo;
  4461.         end;
  4462.       end;
  4463.     end;
  4464.   end;
  4465. end;
  4466.  
  4467. begin
  4468. end.
  4469.