Rev 54 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
54 | pj | 1 | /* |
2 | * attdacs.c: |
||
3 | * |
||
4 | * RAMDAC definition for industry-standard AT&T20C490/498 DACs and |
||
5 | * compatibles. |
||
6 | */ |
||
7 | |||
8 | #include <stdlib.h> |
||
9 | #include <stdio.h> |
||
10 | #include "libvga.h" |
||
11 | |||
12 | #include "timing.h" |
||
13 | #include "vgaregs.h" |
||
14 | #include "driver.h" /* for __svgalib_driver_report */ |
||
15 | #include "ramdac.h" |
||
16 | |||
17 | /* |
||
18 | * RAMDAC definition for industry-standard AT&T20C490 DAC with 8-bit pixel |
||
19 | * port, and compatibles. |
||
20 | * These RAMDACs can do 32K and 64K color mode (16bpp) with doubled VCLK |
||
21 | * and 16M (8-8-8) truecolor with tripled VCLK. |
||
22 | * 0xA0 is written to the Hidden DAC register for 32K, 0xC0 for 64K and |
||
23 | * 0xE0 for 16M. |
||
24 | */ |
||
25 | |||
26 | #ifdef INCLUDE_ATT20C490_DAC_TEST |
||
27 | static int att20c490_probe(void) |
||
28 | { |
||
29 | unsigned char oldcomm, notcomm, oldpel, v; |
||
30 | int flag = 0; |
||
31 | |||
32 | _ramdac_dactocomm(); |
||
33 | oldcomm = inb(PEL_MSK); |
||
34 | _ramdac_dactopel(); |
||
35 | oldpel = inb(PEL_MSK); |
||
36 | |||
37 | notcomm = ~oldcomm; |
||
38 | outb(PEL_MSK, notcomm); |
||
39 | _ramdac_dactocomm(); |
||
40 | v = inb(PEL_MSK); |
||
41 | if (v != notcomm) { |
||
42 | if ((_ramdac_setcomm(0xe0) & 0xe0) == 0xe0) { |
||
43 | if ((_ramdac_setcomm(0x60) & 0xe0) == 0) { |
||
44 | if ((_ramdac_setcomm(2) & 2) > 0) |
||
45 | flag = 1; /* 20c490 */ |
||
46 | else |
||
47 | flag = 1; /* 20c493 */ |
||
48 | } else { |
||
49 | _ramdac_setcomm(oldcomm); |
||
50 | if (inb(PEL_MSK) == notcomm) |
||
51 | if (_ramdac_setcomm(0xFF) == 0xFF) |
||
52 | flag = 1; /* 20c491/20c492 */ |
||
53 | } |
||
54 | } |
||
55 | } |
||
56 | _ramdac_dactocomm(); |
||
57 | outb(PEL_MSK, oldcomm); |
||
58 | _ramdac_dactopel(); |
||
59 | outb(PEL_MSK, oldpel); |
||
60 | return flag; |
||
61 | } |
||
62 | #else |
||
63 | #define att20c490_probe 0 |
||
64 | #endif |
||
65 | |||
66 | #ifdef INCLUDE_ATT20C490_DAC |
||
67 | static void att20c490_init(void) |
||
68 | { |
||
69 | if (__svgalib_driver_report) |
||
81 | giacomo | 70 | cprintf("svgalib: Using AT&T20C490-compatible truecolor DAC.\n"); |
54 | pj | 71 | #if 0 |
72 | dactocomm(); |
||
73 | inb(PEL_MSK); /* Skip command register. */ |
||
81 | giacomo | 74 | cprintf("svgalib: DAC Manufacturer ID = 0x%02X, ", inb(PEL_MSK)); |
75 | cprintf("Device ID = 0x%02X.\n", inb(PEL_MSK)); |
||
54 | pj | 76 | #endif |
77 | } |
||
78 | |||
79 | static int __svgalib_att20c490_map_clock(int bpp, int pixelclock) |
||
80 | { |
||
81 | if (bpp == 16) |
||
82 | return pixelclock * 2; |
||
83 | if (bpp == 24) |
||
84 | return pixelclock * 3; |
||
85 | return pixelclock; |
||
86 | } |
||
87 | |||
88 | static int __svgalib_att20c490_map_horizontal_crtc(int bpp, int pixelclock, int htiming) |
||
89 | { |
||
90 | if (bpp == 16) |
||
91 | return htiming * 2; |
||
92 | if (bpp == 24) |
||
93 | return htiming * 3; |
||
94 | return htiming; |
||
95 | } |
||
96 | |||
97 | |||
98 | static void att20c490_initializestate(unsigned char *regs, int bpp, int colormode, |
||
99 | int pixelclock) |
||
100 | { |
||
101 | regs[0] = 0; |
||
102 | if (colormode == RGB16_555) |
||
103 | regs[0] = 0xA0; |
||
104 | if (colormode == RGB16_565) |
||
105 | regs[0] = 0xC0; |
||
106 | if (colormode == RGB24_888_B) |
||
107 | regs[0] = 0xE0; |
||
108 | } |
||
109 | |||
110 | static void att20c490_qualify_cardspecs(CardSpecs * cardspecs, int dacspeed) |
||
111 | { |
||
112 | dacspeed = __svgalib_setDacSpeed(dacspeed, 80000); |
||
113 | cardspecs->maxPixelClock4bpp = dacspeed; |
||
114 | cardspecs->maxPixelClock8bpp = dacspeed; |
||
115 | cardspecs->maxPixelClock16bpp = dacspeed / 2; |
||
116 | cardspecs->maxPixelClock24bpp = dacspeed / 3; |
||
117 | cardspecs->maxPixelClock32bpp = 0; |
||
118 | cardspecs->mapClock = __svgalib_att20c490_map_clock; |
||
119 | cardspecs->mapHorizontalCrtc = __svgalib_att20c490_map_horizontal_crtc; |
||
120 | } |
||
121 | |||
122 | DacMethods __svgalib_ATT20C490_methods = |
||
123 | { |
||
124 | ATT20C490, |
||
125 | "AT&T-compatible truecolor DAC, 80 MHz rated", |
||
126 | 0, |
||
127 | att20c490_probe, |
||
128 | att20c490_init, |
||
129 | att20c490_qualify_cardspecs, |
||
130 | __svgalib_Sierra_32K_savestate, |
||
131 | __svgalib_Sierra_32K_restorestate, |
||
132 | att20c490_initializestate, |
||
133 | 1 /* State size. */ |
||
134 | }; |
||
135 | #endif |
||
136 | |||
137 | /* |
||
138 | * RAMDAC definition for industry-standard AT&T20C498 DAC with 16-bit |
||
139 | * pixel port, and compatibles. |
||
140 | * Differently rated versions exist, such as 80, 110, 135 and 170 MHz. |
||
141 | * This code assumes the DAC is actually connected with a 16-bit path. |
||
142 | * (an example of a 498-compatible DAC being used with a 8-bit path |
||
143 | * is the Hercules Stingray Pro/V with the IC Works ZoomDAC). |
||
144 | */ |
||
145 | |||
146 | #ifdef INCLUDE_ATT20C498_DAC_TEST |
||
147 | static int att20c498_probe(void) |
||
148 | { |
||
149 | return 0; |
||
150 | } |
||
151 | #else |
||
152 | #define att20c498_probe 0 |
||
153 | #endif |
||
154 | |||
155 | #ifdef INCLUDE_ATT20C498_DAC |
||
156 | static void att20c498_init(void) |
||
157 | { |
||
158 | if (__svgalib_driver_report) |
||
81 | giacomo | 159 | cprintf("svgalib: Using AT&T20C498-compatible DAC, 80 MHz rated.\n"); |
54 | pj | 160 | } |
161 | |||
162 | static int att20c498_map_clock(int bpp, int pixelclock) |
||
163 | { |
||
164 | if (bpp == 8 && pixelclock > 80000) |
||
165 | /* Use 16-bit path, clock doubling at RAMDAC. */ |
||
166 | return pixelclock / 2; |
||
167 | if (bpp == 16) |
||
168 | return pixelclock; |
||
169 | if (bpp == 32) |
||
170 | return pixelclock * 2; |
||
171 | return pixelclock; |
||
172 | } |
||
173 | |||
174 | static int att20c498_map_horizontal_crtc(int bpp, int pixelclock, int htiming) |
||
175 | { |
||
176 | /* Not sure. */ |
||
177 | if (bpp == 8 && pixelclock > 80000) |
||
178 | /* Use 16-bit path, clock doubling at RAMDAC. */ |
||
179 | return htiming / 2; |
||
180 | if (bpp == 32) |
||
181 | return htiming * 2; |
||
182 | return htiming; |
||
183 | } |
||
184 | |||
185 | static void att20c498_initializestate(unsigned char *regs, int bpp, int colormode, |
||
186 | int pixelclock) |
||
187 | { |
||
188 | regs[0] = 0; |
||
189 | if (colormode == CLUT8_8) |
||
190 | regs[0] = 0x02; |
||
191 | if (colormode == RGB16_555) |
||
192 | regs[0] = 0x10; |
||
193 | if (colormode == RGB16_565) |
||
194 | regs[0] = 0x30; |
||
195 | if (colormode == RGB32_888_B) |
||
196 | regs[0] = 0x50; |
||
197 | } |
||
198 | |||
199 | static void att20c498_qualify_cardspecs(CardSpecs * cardspecs, int dacspeed) |
||
200 | { |
||
201 | dacspeed = __svgalib_setDacSpeed(dacspeed, 110000); |
||
202 | cardspecs->maxPixelClock4bpp = 0; |
||
203 | cardspecs->maxPixelClock8bpp = dacspeed; |
||
204 | cardspecs->maxPixelClock16bpp = dacspeed; |
||
205 | cardspecs->maxPixelClock24bpp = 0; |
||
206 | cardspecs->maxPixelClock32bpp = dacspeed / 2; |
||
207 | cardspecs->mapClock = att20c498_map_clock; |
||
208 | cardspecs->mapHorizontalCrtc = att20c498_map_horizontal_crtc; |
||
209 | } |
||
210 | |||
211 | DacMethods __svgalib_ATT20C498_methods = |
||
212 | { |
||
213 | ATT20C498, |
||
214 | "AT&T20C498 DAC", |
||
215 | 0, |
||
216 | att20c498_probe, |
||
217 | att20c498_init, |
||
218 | att20c498_qualify_cardspecs, |
||
219 | __svgalib_Sierra_32K_savestate, |
||
220 | __svgalib_Sierra_32K_restorestate, |
||
221 | att20c498_initializestate, |
||
222 | 1 /* State size. */ |
||
223 | }; |
||
224 | #endif |