RAMDACs AcuMos: ADAC1 15/16/24 bit. Analog Devices: ADV471 6bit DAC 15 overlay registers ADV475 6bit DAC 15 overlay registers ADV476 6bit DAC ADV477 8bit DAC 15 overlay registers ADV478 6/8bit DAC 15 overlay registers ATI: ATI68830 15/16/24bit Up to 80 MHz ! ATI68860 15/16/24bit ??? ATI68875 15/16/24bit Up to 135 MHz ! Used in ATI Graphics Ultra + and Pro. Same as TI34075 ?? AT&T: ATT20c490 15/16/24 bit. 6/8 bit DAC. ATT20c491 15/16/24 bit. 6/8 bit DAC w/gamma correction ATT20c492 15/16/18 bit 6bit DACs. w/gamma correction ATT20c493 15/16/18 bit 6bit DACs ATT20c497 24bit ? Avance Logic: ALG1101 16-bit. Appears to be different from the other HiColor DACs. Avasem: AV3676 6bit DAC Brooktree: Bt476 6bit DAC. Bt478 6/8bit DAC. Bt481 Bt482 Bt484 15/16/24bit 6/8bit DAC. Has hardware cursor. Bt485 15/16/24bit 6/8bit DAC. Has hardware cursor. Cirrus Logic CL-GD5200 15/16/24 bit Same as Acumos ADAC1 Diamond: SS2410 15/24 bit. Inmos: IMSG171 IMSG176 6bit DAC IMSG178 MUSIC: MU9C1710 8 bit ?? MU9C4870 15/16 bit Similar to Sierra "Mark 3". MU9C4910 15/16/24bit OAK: OTI66 6bit DAC OTI66HC 15/16bit Similar to Sierra "Mark 3" Samsung: KDA476 6bit DAC Sierra "Mark1": Only works if the VGA controller can send a byte on both the rising AND falling edge of the dot clock. SC11481 15-bit. 6-bit DAC. Overlay. SC11486 15-bit. 6-bit DAC. SC11488 15 bit. 6/8 bit DAC. Overlay. Sierra "Mark2": SC11482 15-bit. 6-bit DAC. Overlay. SC11483 15-bit. 6-bit DAC. SC11484 15-bit. 6/8 bit DAC. Overlay. Sierra "Mark3": SC11485 15/16 bit. 6-bit DAC. Overlay. SC11487 15/16 bit. 6-bit DAC. SC11489 15/16 bit. 6/8 bit DAC. Overlay. SC15025 15/16/24 bit. SC15026 15/16/24 bit. UMC: UM70c178 15/16 bit Similar to Sierra "Mark 3" 15-bit modes have 5 bits of each basic color: bit 0- 4 blue. 5- 9 green. 10-14 red. The pixel is stored in two bytes in Intel style (little endian). 16-bit modes have 5 bits of red and blue, and 6 bits of green: bits 0- 4 blue. 5-10 green. 11-15 red. The pixel is stored in two bytes in Intel style (little endian). 24-bit modes have 8 bits of each basic color: bits 0- 7 blue. 8-15 green 16=23 red. The pixel is stored in three bytes in Intel style (little endian). The DACs are addressed on port 3C6h-3C9h. Advanced DACs have 1 or 2 extra address lines (RS2 and RS3). These may be controlled from high address bits (A10-A15) or from registers. In the following +A is used if RS2 is set, +B is used if RS3 is set and +C if both RS2 and RS3 are set. HiColor DACs: (Sierra SC1148x, MUSIC MU9C4870, OAK OTI66HC, UMC UM70C178) 3C6h+A (R/W): Command Register bit 5 (not SC11481/6/8) If set two pixel clocks are used to latch the two bytes needed for each pixel. Low byte is latched first. If clear the low byte is latched on the rising edge of the pixel clock and the high byte is latched on the falling edge. Only some VGA chips (ET4000 and C&T655x0) can handle this. 6 (SC11485/7/9, OTI66HC, UM70C178) Set in 16bit (64k) modes (Only valid if bit 7 set). On the SC11482/3/4 this bit is read/writable, but has no function. On the SC11481/6/8 this bit does not exist. 7 Set in HiColor (32k/64k) modes, clear in palette modes. Note: This register can also be accessed at 3C6h by reading 3C6h four times, then all accesses to 3C6h will go the this register until one of the registers 3C7h, 3C8h or 3C9h is accessed. 3C7h+A (R/W): Overlay RAM Read Address (SC11481/2/4/5/8/9 only) bit 0-3 Read index for the Overlay registers. 3C8h+A (R/W): Overlay RAM Write Address (SC11481/2/4/5/8/9 only) bit 0-3 Write index for the Overlay registers. 3C9h+A (R/W): Overlay RAM (SC11481/2/4/5/8/9 only) bit 0-5 Data port for the overlay registers. Works like the PEL data register (3C9h) except that the overlay registers are accessed and the Overlay Address registers are used for indexes. Note: on the SC11484/8/9 the Color Look-up Table and the overlay registers are 24bits wide (rather than 18bits) if the 8/6 pin is high. Sierra SC15025/6 Truecolor DACs: 3C6h+A (R/W): Command Register bit 5-7 Mode: 0: Normal, 3: 24bit, 4,5: 15bit, 6,7: 16bit 4 If set 3C7h is the index port and 3C8h the data port for an extra register set: index 8h: DAC width. 00h: 6bit, 01h: 8bit 9h: 53h Ah: 00h ?? Bh: DAC Speed. ACh: 135MHz, B1h: 80NHz Ch-Fh: FFh ?? 10h: 00h ?? Note: This register can also be accessed at 3C6h by reading 3C6h four times, then all accesses to 3C6h will go the this register until one of the registers 3C7h, 3C8h or 3C9h is accessed. AT&T 20c49x Truecolor DACs: 3C6h+A (R/W): Command Register bit 1 (not 492,493) In mode 0 this bit when set selects 8bit DACs, when clear 6bit DACs. 5-7 Mode: 0: Palette, 5: 15bit (32k), 6: 16bit (64k), 7: 24bit (16m) Note: This register can also be accessed at 3C6h by reading 3C6h four times, then all accesses to 3C6h will go the this register until one of the registers 3C7h, 3C8h or 3C9h is accessed. BrookTree Bt484, Bt485 Truecolor DACs: 3C6h+A (R/W): Command Reg 0 bit 1 Set if DAC and palette registers are 8bit DACs, clear if 6bit. 7 If clear the Status register is present at 3C&h+A, if set 3C8h determines which register is present at 3C6h+A: 00h Status Register 01h Command Register 3 3C6h+B is the Command Register 3, if clear the Status Register 3C7h+A (R/W): Cursor Read Address bit 0-7 The PEL data register (0..255) to be read from 3C9h. Note: After reading the 3 bytes at 3C9h this register will increment, pointing to the next data register. 3C8h+A (R/W): Cursor Write Address bit 0-7 The PEL data register (0..255) to be written to 3C9h. Note: After writing the 3 bytes at 3C9h this register will increment, pointing to the next data register. 3C9h+A (R/W): Cursor Data bit 0-5 Color value Note: Each read or write of this register will cycle through first the registers for Red, Blue and Green, then increment the appropriate address register. Note: the registers 3C7h-3C9h (+A) works like the normal 3C7h-3C9h registers, except that a separate set of palette registers (16 overlay registers ?) are being accessed. Index 00h Overscan color 01h Cursor Background 02h Cursor Foreground 3C6h+B (R/W): Status Reg Note: The two registers at 3C6h+B are selected by bit 7 of 3C6h+A. 3C6h+B (R/W): Command Reg 3 Bit 0-1 Bits 8-9 of the Palette Write Address (3C8h) 2 Set if using 64x64 cursor, clear if 32x32 cursor. 3 Enable Clock Doubler if set ? Note: The two registers at 3C6h+B are selected by bit 7 of 3C6h+A. 3C7h+B (R/W): Cursor Ram Data bit 0-7 Data port for the Hardware Cursor Map. There are 2 128byte (32x32bit) maps. The map at offset 0 is the cursor image and the one at 80h is the cursor shape. To update the cursor map, write the start address to 3C8h and start writing to this register. The index will increment for each byte. 3C8h+B (R/W): Command Reg 1 bit 0-7 Mode: 10h: 24bit, 30h: 15bit, 38h: 16bit, 40h: 8bit palette, 60h: 4bit palette 3C9h+B (R/W): Command Reg 2 bit 0-1 Cursor mode. 2 for Windows, 3 for X11, 0 for off ?? 3 Set in interlaced modes ? 2-7 Always 8 ?? 3C6h+C W(R/W): Hardware Cursor X-position bit 0-1 The X-position of the rightmost pixel of the hardware cursor 3C8h+C W(R/W): Hardware Cursor Y-position bit 0-11 The Y-position of the lower scanline of the hardware cursor Forcing HiColor DACs into command mode: procedure dactocomm; {switches DAC to command register} var x:word; begin x:=inp($3C8); {clear old state} x:=inp($3C6); x:=inp($3C6); x:=inp($3C6); {Read $3C6 4 times.} x:=inp($3C6); end; Now reads and writes to $3C6 will access the command register. Any access to $3C7-$3C9 will switch back to the PEL mask register. Forcing HiColor DACs into normal mode: procedure dactopel; {switches DAC back to normal mode} var x:word; begin x:=inp($3C8); end; function testdac:string; var x,y,z,v,oldcommreg,oldpelreg:word; type pel=record index,red,green,blue:byte; end; procedure readpelreg(index:word;var p:pel); begin p.index:=index; disable; outp($3C7,index); p.red :=inp($3C9); p.blue :=inp($3C9); p.green:=inp($3C9); enable; end; procedure writepelreg(var p:pel); begin disable; outp($3C8,p.index); outp($3C9,p.red); outp($3C9,p.blue); outp($3C9,p.green); enable; end; function setcomm(cmd:word):word; begin dac2comm; outp($3c6,cmd); dac2comm; setcomm:=inp($3c6); end; procedure waitforretrace; begin repeat until (inp(CRTC+6) and 8)=0; repeat until (inp(CRTC+6) and 8)>0; {Wait until we're in retrace} end; function dacis8bit:boolean; var pel2,x,v:word; pel1:pel; begin pel2:=inp($3C8); readpelreg(255,pel1); v:=pel1.red; pel1.red:=255; writepelreg(pel1); readpelreg(255,pel1); x:=pel1.red; pel1.red:=v; writepelreg(pel1); outp($3C8,pel2); dacis8bit:=(x=255); end; function testdacbit(bit:word):boolean; begin dac2pel; outp($3C6,oldpel and (bit xor $FF)); dac2comm; disable; outp($3C6,oldcomm or bit); v:=inp($3C6); outp($3C6,v and (bit xor $FF)); enable; testdacbit:=(v and bit)<>0; end; begin setDAC(_dac8,'Normal'); dac2comm; oldcomm:=inp($3C6); dactopel; oldpel:=inp($3c6); dac2comm; outp($3c6,0); dac8:=dacis8bit; dac2pel; notcomm:=oldcomm xor 255; outp($3c6,notcomm); dac2comm; v:=inp($3c6); if v<>notcomm then if (setcomm($E0) and $e0)<>$e0 then begin {Bits 5-7 of command register NOT writable.} dac2pel; x:=inp($3C6); repeat y:=x; {wait for the same value twice} x:=inp($3C6); until (x=y); z:=x; dac2comm; if daccomm<>$8E then begin {If command register=$8e, we've got an SS24} y:=8; repeat x:=inp($3C6); dec(y); until (x=$8E) or (y=0); end else x:=daccomm; if x=$8e then setDAC(_dacss24,'SS24') else setDAC(_dac15,'Sierra SC11486'); dac2pel; end else begin if (setcomm($60) and $E0)=0 then begin if (setcomm(2) and 2)>0 then setDAC(_dacatt,'ATT 20c490') else setDAC(_dacatt,'ATT 20c490'); end else begin x:=setcomm(oldcomm); if inp($3c6)=notcomm then begin if setcomm($FF)<>$ff then setDAC(_dacadac1,'Acumos ADAC1') else begin dac8now:=dacis8bit; dac2comm; outp($3C6,(oldcomm or 2) and $FE); dac8now:=dacis8bit; if dac8now then if dacis8bit then setDAC(_dacatt,'ATT 20c491') else setDAC(_dacCL24,'Cirrus 24bit DAC') else setDAC(_dacatt,'ATT 20c492'); end; end else begin if trigdac=notcomm then setDAC(_dacCL24,'Cirrus 24bit DAC') else begin dac2pel; outp($3c6,$FF); case trigdac of $44:setDAC(_dacmus,'MUSIC ??'); $82:setDAC(_dacmus,'MUSIC MU9C4910'); $8e:setDAC(_dacss24,'Diamond SS2410'); else if testdacbit($10) then setDAC(_dacsc24,'Sierra 16m') else if testdacbit(4) then setDAC(_dacUnk9,'Unknown DAC #9') else setDAC(_dac16,'Sierra 32k/64k'); end; end; end; end; end; dac2comm; outp($3c6,oldcomm); end; dac2pel; outp($3c6,oldpel); if (dactype=_dac8) and (DAC_RS2<>0) and (DAC_RS3<>0) then begin oldpel :=inp($3C6); oldcomm:=inp($3C6+DAC_RS2); outp($3C6+DAC_RS2,oldpel xor $FF); if (inp($3C6)=oldpel) and (inp($3C6+DAC_RS2)=(oldpel xor $FF)) then SetDAC(_dacBt484,'Brooktree Bt484'); outp($3C6+DAC_RS2,oldcomm); outp($3C6,oldpel); end; if dactype=_dac8 then begin WaitforRetrace; outp($3C8,222); outp($3C9,$43); outp($3C9,$45); outp($3C9,$47); {Write 'CEGEDSUN' + mode to DAC index 222} outp($3C8,222); outp($3C9,$45); outp($3C9,$44); outp($3C9,$53); outp($3C8,222); outp($3C9,$55); outp($3C9,$4E); outp($3C9,13); {Should be in CEG mode now} outp($3C6,255); x:=(inp($3c6) shr 4) and 7; if x<7 then begin setDAC(_dacCEG,'Edsun CEG rev. '+chr(x+48)); WaitforRetrace; outp($3C8,223); outp($3C9,0); {Back in normal dac mode} end; end; end; This ID's all known DAC types, except: - Sierra "mark2" and "Mark3" are all ID'd as Mark 3. - Avance Logic ALG1101 DAC can not be ID'd. - TI 34075, ATI 68830, 68860 and 68875 can not be ID'd - The Edsun CEG test has not been verified.