]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/fb/tga.c
Use __FBSDID().
[FreeBSD/FreeBSD.git] / sys / dev / fb / tga.c
1 /*-
2  * Copyright (c) 2000, 2001 Andrew Miklic, Andrew Gallatin, Peter Jeremy,
3  * and Thomas V. Crimi
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 /*
31  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
32  * All rights reserved.
33  *
34  * Author: Chris G. Demetriou
35  * 
36  * Permission to use, copy, modify and distribute this software and
37  * its documentation is hereby granted, provided that both the copyright
38  * notice and this permission notice appear in all copies of the
39  * software, derivative works or modified versions, and any portions
40  * thereof, and that both notices appear in supporting documentation.
41  * 
42  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 
43  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 
44  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
45  * 
46  * Carnegie Mellon requests users of this software to return to
47  *
48  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
49  *  School of Computer Science
50  *  Carnegie Mellon University
51  *  Pittsburgh PA 15213-3890
52  *
53  * any improvements or extensions that they make and grant Carnegie the
54  * rights to redistribute these changes.
55  */
56
57 #include <sys/cdefs.h>
58 __FBSDID("$FreeBSD$");
59
60 #include <machine/stdarg.h>
61
62 #include <sys/param.h>
63 #include <sys/systm.h>
64 #include <sys/kernel.h>
65 #include <sys/conf.h>
66 #include <sys/proc.h>
67 #include <sys/fcntl.h>
68 #include <sys/malloc.h>
69 #include <sys/fbio.h>
70 #include <sys/consio.h>
71
72 #include <isa/isareg.h>
73 #include <dev/fb/vgareg.h>
74
75 #include <vm/vm.h>
76 #include <vm/vm_param.h>
77 #include <vm/pmap.h>
78
79 #include <machine/md_var.h>
80 #include <machine/pc/bios.h>
81 #include <machine/clock.h>
82 #include <machine/bus_memio.h>
83 #include <machine/bus.h>
84 #include <machine/pc/vesa.h>
85 #include <machine/resource.h>
86 #include <machine/rpb.h>
87
88 #include <sys/bus.h>
89 #include <sys/rman.h>
90
91 #include <dev/pci/pcireg.h>
92 #include <dev/pci/pcivar.h>
93
94 #include <dev/fb/fbreg.h>
95 #include <dev/syscons/syscons.h>
96 #include <dev/fb/gfb.h>
97 #include <dev/gfb/gfb_pci.h>
98 #include <dev/fb/tga.h>
99 #include <dev/tga/tga_pci.h>
100
101 #include "opt_fb.h"
102
103 /* TGA-specific FB video driver function declarations */
104 static int tga_error(void);
105 static vi_init_t tga_init;
106 static void tga2_init(struct gfb_softc *, int);
107
108 /* TGA-specific functionality. */
109 static gfb_builtin_save_palette_t tga_builtin_save_palette;
110 static gfb_builtin_load_palette_t tga_builtin_load_palette;
111 #ifdef TGA2
112 static gfb_builtin_save_palette_t tga2_builtin_save_palette;
113 static gfb_builtin_load_palette_t tga2_builtin_load_palette;
114 static gfb_builtin_save_cursor_palette_t tga2_builtin_save_cursor_palette;
115 static gfb_builtin_load_cursor_palette_t tga2_builtin_load_cursor_palette;
116 #endif 
117 static gfb_builtin_read_hw_cursor_t tga_builtin_read_hw_cursor;
118 static gfb_builtin_set_hw_cursor_t tga_builtin_set_hw_cursor;
119 static gfb_builtin_set_hw_cursor_shape_t tga_builtin_set_hw_cursor_shape;
120 static void bt463_load_palette_intr(struct gfb_softc *);
121 static void bt463_load_cursor_palette_intr(struct gfb_softc *);
122 static int tga_schedule_intr(struct gfb_softc *, void (*)(struct gfb_softc *));
123
124 /* RAMDAC interface functions */
125 static gfb_ramdac_wr_t tga_bt485_wr;
126 static gfb_ramdac_rd_t tga_bt485_rd;
127 static gfb_ramdac_wr_t tga_bt463_wr;
128 static gfb_ramdac_rd_t tga_bt463_rd;
129 static gfb_ramdac_wr_t tga2_ibm561_wr;
130 static gfb_ramdac_rd_t tga2_ibm561_rd;
131 static void tga2_ics9110_wr(struct gfb_softc *, int);
132
133 /* RAMDAC-specific functions */
134 static gfb_ramdac_init_t bt463_init;
135 static void bt463_update_window_type(struct gfb_softc *);
136 #if 0
137 static gfb_ramdac_save_palette_t bt463_save_palette;
138 static gfb_ramdac_load_palette_t bt463_load_palette;
139 #endif 
140 static gfb_ramdac_save_cursor_palette_t bt463_save_cursor_palette;
141 static gfb_ramdac_load_cursor_palette_t bt463_load_cursor_palette;
142 static gfb_ramdac_init_t bt485_init;
143 static gfb_ramdac_save_palette_t bt485_save_palette;
144 static gfb_ramdac_load_palette_t bt485_load_palette;
145 static gfb_ramdac_save_cursor_palette_t bt485_save_cursor_palette;
146 static gfb_ramdac_load_cursor_palette_t bt485_load_cursor_palette;
147 static gfb_ramdac_read_hw_cursor_t bt485_read_hw_cursor;
148 static gfb_ramdac_set_hw_cursor_t bt485_set_hw_cursor;
149 static gfb_ramdac_set_hw_cursor_shape_t bt485_set_hw_cursor_shape;
150 static gfb_ramdac_init_t ibm561_init;
151 static gfb_ramdac_save_palette_t ibm561_save_palette;
152 static gfb_ramdac_load_palette_t ibm561_load_palette;
153 static gfb_ramdac_save_cursor_palette_t ibm561_save_cursor_palette;
154 static gfb_ramdac_load_cursor_palette_t ibm561_load_cursor_palette;
155
156 /* Video Driver-generic functions */
157 static vi_query_mode_t tga_query_mode;
158 static vi_set_mode_t tga_set_mode;
159 static vi_blank_display_t tga_blank_display;
160 #if 0
161 static vi_ioctl_t tga_ioctl;
162 #endif
163 static vi_set_border_t tga_set_border;
164 static vi_set_win_org_t tga_set_win_org;
165 static vi_fill_rect_t tga_fill_rect;
166 static vi_bitblt_t tga_bitblt;
167 static vi_clear_t tga_clear;
168 static vi_putc_t tga_putc;
169 static vi_puts_t tga_puts;
170 static vi_putm_t tga_putm;
171
172 static video_switch_t tgavidsw = {
173         gfb_probe,
174         tga_init,
175         gfb_get_info,
176         tga_query_mode,
177         tga_set_mode,
178         gfb_save_font,
179         gfb_load_font,
180         gfb_show_font,
181         gfb_save_palette,
182         gfb_load_palette,
183         tga_set_border,
184         gfb_save_state,
185         gfb_load_state,
186         tga_set_win_org,
187         gfb_read_hw_cursor,
188         gfb_set_hw_cursor,
189         gfb_set_hw_cursor_shape,
190         tga_blank_display,
191         gfb_mmap,
192         gfb_ioctl,
193         tga_clear,
194         tga_fill_rect,
195         tga_bitblt,
196         tga_error,
197         tga_error,
198         gfb_diag,
199         gfb_save_cursor_palette,
200         gfb_load_cursor_palette,
201         gfb_copy,
202         gfb_putp,
203         tga_putc,
204         tga_puts,
205         tga_putm,
206 };
207
208 VIDEO_DRIVER(tga, tgavidsw, NULL);
209
210 extern sc_rndr_sw_t txtrndrsw;
211 RENDERER(tga, 0, txtrndrsw, gfb_set);
212
213 #ifdef SC_PIXEL_MODE
214 extern sc_rndr_sw_t gfbrndrsw;
215 RENDERER(tga, PIXEL_MODE, gfbrndrsw, gfb_set);
216 #endif /* SC_PIXEL_MODE */
217
218 #ifndef SC_NO_MODE_CHANGE
219 extern sc_rndr_sw_t grrndrsw;
220 RENDERER(tga, GRAPHICS_MODE, grrndrsw, gfb_set);
221 #endif /* SC_NO_MODE_CHANGE */
222
223 RENDERER_MODULE(tga, gfb_set);
224
225 #define MHz     * 1000000
226 #define KHz     * 1000
227
228 extern struct gfb_softc *gfb_device_softcs[2][MAX_NUM_GFB_CARDS];
229
230 /*
231    The following 3 variables exist only because we need statically
232    allocated structures very early in boot to support tga_configure()...
233 */
234 extern struct gfb_softc console;
235 extern video_adapter_t console_adp;
236 extern struct gfb_conf console_gfbc;
237 extern u_char console_palette_red[256];
238 extern u_char console_palette_green[256];
239 extern u_char console_palette_blue[256];
240 extern u_char console_cursor_palette_red[3];
241 extern u_char console_cursor_palette_green[3];
242 extern u_char console_cursor_palette_blue[3];
243
244 static struct monitor decmonitors[] = {
245         /* 0x0: 1280 x 1024 @ 72Hz */
246         { 1280, 32,     160,    232,
247           1024, 3,      3,      33,
248           130808 KHz },
249
250         /* 0x1: 1280 x 1024 @ 66Hz */
251         { 1280, 32,     160,    232,
252           1024, 3,      3,      33,
253           119840 KHz },
254
255         /* 0x2: 1280 x 1024 @ 60Hz */
256         { 1280, 44,     184,    200,
257           1024, 3,      3,      26,
258           108180 KHz },
259
260         /* 0x3: 1152 x  900 @ 72Hz */
261         { 1152, 64,     112,    176,
262           900,  6,      10,     44,
263           103994 KHz },
264
265         /* 0x4: 1600 x 1200 @ 65Hz */
266         { 1600, 32,     192,    336,
267           1200, 1,      3,      46,
268           175 MHz },
269
270         /* 0x5: 1024 x  768 @ 70Hz */
271         { 1024, 24,     136,    144,
272           768,  3,      6,      29,
273           75 MHz },
274
275         /* 0x6: 1024 x  768 @ 72Hz */
276         { 1024, 16,     128,    128,
277           768,  1,      6,      22,
278           74 MHz },
279
280         /* 0x7: 1024 x  864 @ 60Hz */
281         { 1024, 12,     128,    116,
282           864,  0,      3,      34,
283           69 MHz },
284
285         /* 0x8: 1024 x  768 @ 60Hz */
286         { 1024, 56,     64,     200,
287           768,  7,      9,      26,
288           65 MHz },
289
290         /* 0x9:  800 x  600 @ 72Hz */
291         { 800,  56,     120,    64,
292           600,  37,     6,      23,
293           50 MHz },
294
295         /* 0xa:  800 x  600 @ 60Hz */
296         { 800,  40,     128,    88,
297           600,  1,      4,      23,
298           40 MHz },
299
300         /* 0xb:  640 x  480 @ 72Hz */
301         { 640,  24,     40,     128,
302           480,  9,      3,      28,
303           31500 KHz },
304
305         /* 0xc:  640 x  480 @ 60Hz */
306         { 640,  16,     96,     48,
307           480,  10,     2,      33,
308           25175 KHz },
309
310         /* 0xd: 1280 x 1024 @ 75Hz */
311         { 1280, 16,     144,    248,
312           1024, 1,      3,      38,
313           135 MHz  },
314
315         /* 0xe: 1280 x 1024 @ 60Hz */
316         { 1280, 19,     163,    234,
317           1024, 6,      7,      44,
318           110 MHz },
319
320         /* 0xf: 1600 x 1200 @ 75Hz */
321         /* XXX -- this one's weird.  rcd */
322         { 1600, 32,     192,    336,
323           1200, 1,      3,      46,
324           202500 KHz }
325 };
326
327 #undef MHz
328 #undef KHz
329
330 #undef KB
331 #define KB      * 1024
332 #undef MB
333 #define MB      * 1024 * 1024
334
335 /*
336  * These are the 16 default VGA colors--these are replicated 16 times as the
337  * initial (default) color-map.  The text rendering functions use entries
338  * 0..15 for normal foreground/background colors.  The entries 128..255 are
339  * used for blinking entries--when "on," they contain the foreground color
340  * entries; when "off," they contain the background color entries...
341  */
342 static const struct cmap {
343         u_char red;
344         u_char green;
345         u_char blue;
346 } default_cmap[16] = {
347         {0x00, 0x00, 0x00},     /* Black */
348         {0x00, 0x00, 0xff},     /* Blue */
349         {0x00, 0xff, 0x00},     /* Green */
350         {0x00, 0xc0, 0xc0},     /* Cyan */
351         {0xff, 0x00, 0x00},     /* Red */
352         {0xc0, 0x00, 0xc0},     /* Magenta */
353         {0xc0, 0xc0, 0x00},     /* Brown */
354         {0xc0, 0xc0, 0xc0},     /* Light Grey */
355         {0x80, 0x80, 0x80},     /* Dark Grey */
356         {0x80, 0x80, 0xff},     /* Light Blue */
357         {0x80, 0xff, 0x80},     /* Light Green */
358         {0x80, 0xff, 0xff},     /* Light Cyan */
359         {0xff, 0x80, 0x80},     /* Light Red */
360         {0xff, 0x80, 0xff},     /* Light Magenta */
361         {0xff, 0xff, 0x80},     /* Yellow */
362         {0xff, 0xff, 0xff}      /* White */
363 };
364
365 extern struct gfb_font bold8x16;
366
367 /*****************************************************************************
368  *
369  * FB-generic functions
370  *
371  ****************************************************************************/
372
373 static int
374 tga_init(int unit, video_adapter_t *adp, int flags)
375 {
376         struct gfb_softc *sc;
377         struct gfb_conf *gfbc;
378         unsigned int monitor;
379         int card_type;
380         int gder;
381         int deep;
382         int addrmask;
383         int cs;
384         int error;
385         gfb_reg_t ccbr;
386
387         /* Assume the best... */
388         error = 0;
389
390         sc = gfb_device_softcs[adp->va_model][unit];
391         gfbc = sc->gfbc;
392
393         /* Initialize palette counts... */
394         gfbc->palette.count = 256;
395         gfbc->cursor_palette.count = 3;
396
397         /* Initialize the adapter... */
398         gder = BASIC_READ_TGA_REGISTER(adp, TGA_REG_GDER);
399         addrmask = (gder & GDER_ADDR_MASK) >> GDER_ADDR_SHIFT;
400         deep = (gder & GDER_DEEP) != 0;
401         cs = (gder & GDER_CS) == 0;
402         card_type = TGA_TYPE_UNKNOWN;
403         adp->va_little_bitian = 1;
404         adp->va_little_endian = 0;
405         adp->va_initial_mode = 0;
406         adp->va_initial_bios_mode = 0;
407         adp->va_mode = 0;
408         adp->va_info.vi_mem_model = V_INFO_MM_TEXT;
409         adp->va_info.vi_mode = M_VGA_M80x30;
410         adp->va_info.vi_flags = V_INFO_COLOR;
411         adp->va_buffer = adp->va_mem_base;
412         adp->va_buffer_size = 4 MB * (1 + addrmask);
413         adp->va_registers = adp->va_buffer + TGA_REG_SPACE_OFFSET;
414         adp->va_registers_size = 2 KB;
415         adp->va_window = adp->va_buffer + (adp->va_buffer_size / 2);
416         adp->va_info.vi_window = vtophys(adp->va_window);
417         adp->va_window_size = (deep ? 4 MB : 2 MB);
418         adp->va_info.vi_window_size = adp->va_window_size;
419         adp->va_window_gran = adp->va_window_size;
420         adp->va_info.vi_window_gran = adp->va_window_gran;
421         adp->va_info.vi_buffer = vtophys(adp->va_buffer);
422         adp->va_info.vi_buffer_size = adp->va_buffer_size;
423         adp->va_disp_start.x = 0;
424         adp->va_disp_start.y = 0;
425         adp->va_info.vi_depth = (deep ? 32 : 8);
426         adp->va_info.vi_planes = adp->va_info.vi_depth / 8;
427         adp->va_info.vi_width = (READ_GFB_REGISTER(adp, TGA_REG_VHCR) &
428                                    VHCR_ACTIVE_MASK);
429         adp->va_info.vi_width |= (READ_GFB_REGISTER(adp, TGA_REG_VHCR) &
430                                    0x30000000) >> 19;
431         switch(adp->va_info.vi_width) {
432         case 0:
433                 adp->va_info.vi_width = 8192;
434                 break;
435         case 1:
436                 adp->va_info.vi_width = 8196;
437                 break;
438         default:
439                 adp->va_info.vi_width *= 4;
440                 break;
441         }
442         adp->va_info.vi_height = (READ_GFB_REGISTER(adp, TGA_REG_VVCR) &
443                                    VVCR_ACTIVE_MASK);
444         adp->va_line_width = adp->va_info.vi_width * adp->va_info.vi_depth / 8;
445         if(READ_GFB_REGISTER(adp, TGA_REG_VHCR) & VHCR_ODD)
446                 adp->va_info.vi_width -= 4;
447
448         /*
449            Set the video base address and the cursor base address to
450            something known such that the video base address is at
451            least 1 KB past the cursor base address (the cursor is 1 KB
452            in size, so leave room for it)...we pick 4 KB  and 0 KB,
453            respectively, since they begin at the top of the framebuffer
454            for minimal fragmentation of the address space, and this will
455            always leave enough room for the cursor for all implementations...
456         */
457
458         /* Set the video base address... */     
459         tga_set_win_org(sc->adp, 4 KB);
460
461         /* Set the cursor base address... */    
462         ccbr = READ_GFB_REGISTER(sc->adp, TGA_REG_CCBR);
463         ccbr = (ccbr & 0xfffffc0f) | (0 << 4);
464         WRITE_GFB_REGISTER(sc->adp, TGA_REG_CCBR, ccbr);
465
466         /* Type the card... */
467         if(adp->va_type == KD_TGA) {
468                 if(!deep) {
469
470                         /* 8bpp frame buffer */
471                         gfbc->ramdac_name = "BT485";
472                         gfbc->ramdac_init = bt485_init;
473                         gfbc->ramdac_rd = tga_bt485_rd;
474                         gfbc->ramdac_wr = tga_bt485_wr;
475                         gfbc->ramdac_save_palette = bt485_save_palette;
476                         gfbc->ramdac_load_palette = bt485_load_palette;
477                         gfbc->ramdac_save_cursor_palette =
478                             bt485_save_cursor_palette;
479                         gfbc->ramdac_load_cursor_palette =
480                             bt485_load_cursor_palette;
481                         gfbc->ramdac_read_hw_cursor = bt485_read_hw_cursor;
482                         gfbc->ramdac_set_hw_cursor = bt485_set_hw_cursor;
483                         gfbc->ramdac_set_hw_cursor_shape =
484                             bt485_set_hw_cursor_shape;
485
486                         if(addrmask == GDER_ADDR_4MB) {
487
488                                 /* 4MB core map; T8-01 or T8-02 */
489                                 if(!cs) {
490                                         card_type = TGA_TYPE_T8_01;
491                                         gfbc->name = "T8-01";
492                                 } else {
493                                         card_type = TGA_TYPE_T8_02;
494                                         gfbc->name = "T8-02";
495                                 }
496                         } else if(addrmask == GDER_ADDR_8MB) {
497
498                                 /* 8MB core map; T8-22 */
499                                 if(cs) {/* sanity */
500                                         card_type = TGA_TYPE_T8_22;
501                                         gfbc->name = "T8-22";
502                                 }
503                         } else if(addrmask == GDER_ADDR_16MB) {
504
505                                 /* 16MB core map; T8-44 */
506                                 if(cs) {/* sanity */
507                                         card_type = TGA_TYPE_T8_44;
508                                         gfbc->name = "T8-44";
509                                 }
510                         } else if(addrmask == GDER_ADDR_32MB) {
511
512                                 /* 32MB core map; ??? */
513                                 card_type = TGA_TYPE_UNKNOWN;
514                         }
515                 } else {
516
517                         /* 32bpp frame buffer */
518                         gfbc->ramdac_name = "BT463";
519                         gfbc->ramdac_init = bt463_init;
520                         gfbc->ramdac_rd = tga_bt463_rd;
521                         gfbc->ramdac_wr = tga_bt463_wr;
522                         gfbc->builtin_save_palette = tga_builtin_save_palette;
523                         gfbc->builtin_load_palette = tga_builtin_load_palette;
524                         gfbc->ramdac_save_cursor_palette =
525                             bt463_save_cursor_palette;
526                         gfbc->ramdac_load_cursor_palette =
527                             bt463_load_cursor_palette;
528                         gfbc->builtin_read_hw_cursor =
529                             tga_builtin_read_hw_cursor;
530                         gfbc->builtin_set_hw_cursor = tga_builtin_set_hw_cursor;
531                         gfbc->builtin_set_hw_cursor_shape =
532                             tga_builtin_set_hw_cursor_shape;
533
534                         /* 32bpp frame buffer */
535                         if(addrmask == GDER_ADDR_4MB) {
536
537                                 /* 4MB core map; ??? */
538                                 card_type = TGA_TYPE_UNKNOWN;
539                         } else if(addrmask == GDER_ADDR_8MB) {
540
541                                 /* 8MB core map; ??? */
542                                 card_type = TGA_TYPE_UNKNOWN;
543                         } else if(addrmask == GDER_ADDR_16MB) {
544
545                                 /* 16MB core map; T32-04 or T32-08 */
546                                 if(!cs) {
547                                         card_type = TGA_TYPE_T32_04;
548                                         gfbc->name = "T32-04";
549                                 } else {
550                                         card_type = TGA_TYPE_T32_08;
551                                         gfbc->name = "T32-08";
552                                 }
553                         } else if(addrmask == GDER_ADDR_32MB) {
554
555                                 /* 32MB core map; T32-88 */
556                                 if(cs) {/* sanity */
557                                         card_type = TGA_TYPE_T32_88;
558                                         gfbc->name = "T32-88";
559                                 }
560                         }
561                 }
562         }
563         else if(adp->va_type == KD_TGA2) {
564                 gfbc->ramdac_name = "IBM561";
565                 gfbc->ramdac_init = ibm561_init;
566                 gfbc->ramdac_rd = tga2_ibm561_rd;
567                 gfbc->ramdac_wr = tga2_ibm561_wr;
568                 gfbc->ramdac_save_palette = ibm561_save_palette;
569                 gfbc->ramdac_load_palette = ibm561_load_palette;
570                 gfbc->ramdac_save_cursor_palette = ibm561_save_cursor_palette;
571                 gfbc->ramdac_load_cursor_palette = ibm561_load_cursor_palette;
572                 gfbc->builtin_read_hw_cursor = tga_builtin_read_hw_cursor;
573                 gfbc->builtin_set_hw_cursor = tga_builtin_set_hw_cursor;
574                 gfbc->builtin_set_hw_cursor_shape =
575                     tga_builtin_set_hw_cursor_shape;
576
577                 /* 4MB core map */
578                 if(addrmask == GDER_ADDR_4MB)
579                         card_type = TGA_TYPE_UNKNOWN;
580
581                 /* 8MB core map */
582                 else if(addrmask == GDER_ADDR_8MB) {
583                         card_type = TGA2_TYPE_3D30;
584                         gfbc->name = "3D30";
585                 }
586
587                 /* 16MB core map */
588                 else if(addrmask == GDER_ADDR_16MB) {
589                         card_type = TGA2_TYPE_4D20;
590                         gfbc->name = "4D20";
591                 }
592                 else if(addrmask == GDER_ADDR_32MB)
593                         card_type = TGA_TYPE_UNKNOWN;
594         }
595
596         /*
597           For now, just return for TGA2 cards (i.e.,
598           allow syscons to treat this device as a normal
599           VGA device, and don't do anything TGA2-specific,
600           e.g., only use the TGA2 card in VGA mode for now
601           as opposed to 2DA mode...
602         */
603         if(adp->va_type == KD_TGA2)
604                 return(error);
605
606         /* If we couldn't identify the card, err-out... */
607         if(card_type == TGA_TYPE_UNKNOWN) {
608                 printf("tga%d: Unknown TGA type\n", unit);
609                 error = ENODEV;
610                 goto done;
611         } 
612
613         /* Clear and disable interrupts... */
614         WRITE_GFB_REGISTER(adp, TGA_REG_SISR, 0x00000001);
615
616         /* Perform TGA2-specific initialization, if necessary... */
617         if(adp->va_type == KD_TGA2) {
618                 monitor = (~READ_GFB_REGISTER(adp, TGA_REG_GREV) >> 16 ) & 0x0f;
619                 tga2_init(sc, monitor);
620         }
621 done:
622         return(error);
623 }
624
625 static void
626 tga2_init(sc, monitor)
627         struct gfb_softc *sc;
628         int monitor;
629 {
630         return;
631         tga2_ics9110_wr(sc, decmonitors[monitor].dotclock);
632         WRITE_GFB_REGISTER(sc->adp, TGA_REG_VHCR,
633             ((decmonitors[monitor].hbp / 4) << VHCR_BPORCH_SHIFT) |
634             ((decmonitors[monitor].hsync / 4) << VHCR_HSYNC_SHIFT) |
635             (((decmonitors[monitor].hfp) / 4) << VHCR_FPORCH_SHIFT) |
636             ((decmonitors[monitor].cols) / 4));
637         WRITE_GFB_REGISTER(sc->adp, TGA_REG_VVCR,
638             (decmonitors[monitor].vbp << VVCR_BPORCH_SHIFT) |
639             (decmonitors[monitor].vsync << VVCR_VSYNC_SHIFT) |
640             (decmonitors[monitor].vfp << VVCR_FPORCH_SHIFT) |
641             (decmonitors[monitor].rows));
642         WRITE_GFB_REGISTER(sc->adp, TGA_REG_VVBR, 1);
643         GFB_REGISTER_READWRITE_BARRIER(sc, TGA_REG_VHCR, 3);
644         WRITE_GFB_REGISTER(sc->adp, TGA_REG_VVVR,
645             READ_GFB_REGISTER(sc->adp, TGA_REG_VVVR) | 1);
646         GFB_REGISTER_READWRITE_BARRIER(sc, TGA_REG_VVVR, 1);
647         WRITE_GFB_REGISTER(sc->adp, TGA_REG_GPMR, 0xffffffff);
648         GFB_REGISTER_READWRITE_BARRIER(sc, TGA_REG_GPMR, 1);
649 }
650
651 static int
652 tga_query_mode(video_adapter_t *adp, video_info_t *info)
653 {
654         int error;
655
656         /* Assume the best... */
657         error = 0;
658
659         /* Verify that this mode is supported on this adapter... */
660         if(adp->va_type == KD_TGA2) {
661                 if((info->vi_mode != TGA2_2DA_MODE) &&
662                     (info->vi_mode != TGA2_VGA_MODE))
663                         error = ENODEV;
664         }
665         else {
666                 if(info->vi_mode != 0)
667                         error = ENODEV;
668         }
669         return(error);
670 }
671
672 static int
673 tga_set_mode(video_adapter_t *adp, int mode)
674 {
675         int error;
676         gfb_reg_t gder;
677         gfb_reg_t vgae_mask;
678
679         /* Assume the best... */
680         error = 0;
681         
682         gder = READ_GFB_REGISTER(adp, TGA_REG_GDER);
683
684         /*
685            Determine the adapter type first
686            so we know which modes are valid for it...
687         */
688         switch(adp->va_type) {
689         case KD_TGA2:
690
691                 /*
692                    Verify that this mode is supported
693                    on this adapter...
694                 */
695                 switch(mode) {
696                 case TGA2_2DA_MODE:
697                         vgae_mask = ~0x00400000;
698                         WRITE_GFB_REGISTER(adp, TGA_REG_GDER,
699                             gder & vgae_mask);
700                         adp->va_mode = mode;
701                         break;
702                 case TGA2_VGA_MODE:
703                         vgae_mask = 0x00400000;
704                         WRITE_GFB_REGISTER(adp, TGA_REG_GDER,
705                             gder | vgae_mask);
706                         adp->va_mode = mode;
707                         break;
708                 default:
709                         error = ENODEV;
710                 }
711                 break;
712         case KD_TGA:
713
714                 /*
715                    Verify that this mode is supported
716                    on this adapter...
717                 */
718                 switch(mode) {
719                 case 0:
720                         break;
721                 default:
722                         error = ENXIO;
723                 }
724                 break;
725         default:
726                 error = ENODEV;
727         }
728         return(error);
729 }
730
731 static int
732 tga_blank_display(video_adapter_t *adp, int mode)
733 {
734         gfb_reg_t blanked;
735         int error;
736
737         /* Assume the best... */
738         error = 0;
739
740         blanked = READ_GFB_REGISTER(adp, TGA_REG_VVVR) &
741             (VVR_BLANK | VVR_VIDEOVALID | VVR_CURSOR);
742
743         /* If we're not already blanked, then blank...*/
744         switch(mode) {
745         case V_DISPLAY_BLANK:
746                 if(blanked != (VVR_VIDEOVALID | VVR_BLANK)) {
747                         blanked = VVR_VIDEOVALID | VVR_BLANK;
748                         WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, blanked);
749                 }
750                 break;
751         case V_DISPLAY_STAND_BY:
752                 if(blanked != VVR_BLANK) {
753                         blanked = VVR_BLANK;
754                         WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, blanked);
755                 }
756                 break;
757         case V_DISPLAY_ON:
758                 if(blanked != (VVR_VIDEOVALID | VVR_CURSOR)) {
759                         blanked = VVR_VIDEOVALID | VVR_CURSOR;
760                         WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, blanked);
761                 }
762                 break;
763         default:
764                 break;
765         }
766         return(0);
767 }
768
769 #if 0
770
771 static int
772 tga_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
773 {
774         struct gfb_softc *sc;
775         int error;
776
777         error = 0;
778         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
779         switch (cmd) {
780         case FBIOPUTCMAP:
781 #if 0
782                 tga_schedule_intr(sc, bt463_load_palette_intr);
783                 break;
784 #endif
785         case FBIO_GETWINORG:
786         case FBIO_SETWINORG:
787         case FBIO_SETDISPSTART:
788         case FBIO_SETLINEWIDTH:
789         case FBIO_GETPALETTE:
790         case FBIOGTYPE:
791         case FBIOGETCMAP:
792         default:
793                 error = fb_commonioctl(adp, cmd, arg); 
794         }
795         return(error);
796 }
797
798 #endif /* 0 */
799
800 static int
801 tga_set_border(video_adapter_t *adp, int color) {
802         return(ENODEV);
803 }
804
805 static int
806 tga_set_win_org(video_adapter_t *adp, off_t offset) {
807         gfb_reg_t vvbr;
808         u_int16_t window_orig;
809         int gder;
810         int deep;
811         int cs;
812
813         /* Get the adapter's parameters... */
814         gder = BASIC_READ_TGA_REGISTER(adp, TGA_REG_GDER);
815         deep = (gder & 0x1) != 0;
816         cs = (gder & 0x200) == 0;
817
818         /*
819            Set the window (framebuffer) origin according to the video
820            base address...
821         */
822         window_orig = offset / ((1 + cs) * (1 + deep) * (1 + deep) * 2 KB);
823         adp->va_window_orig = window_orig * ((1 + cs) * (1 + deep) *
824             (1 + deep) * 2 KB);
825
826         /* Set the video base address... */
827         vvbr = READ_GFB_REGISTER(adp, TGA_REG_VVBR);
828         vvbr = (vvbr & 0xfffffe00) | window_orig;
829         WRITE_GFB_REGISTER(adp, TGA_REG_VVBR, vvbr);
830         return(0);
831 }
832
833 static int
834 tga_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) {
835         int off;
836         gfb_reg_t gpxr;
837         gfb_reg_t gmor;
838         gfb_reg_t gbcr0;
839         gfb_reg_t gbcr1;
840         gfb_reg_t color;
841
842         /* Save the pixel mode... */
843         gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
844
845         /* Save the pixel mask... */
846         gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
847
848         /* Save the block-color... */
849         gbcr0 = READ_GFB_REGISTER(adp, TGA_REG_GBCR0);
850         gbcr1 = READ_GFB_REGISTER(adp, TGA_REG_GBCR1);
851
852         /* Set the pixel mode (block-fill)... */
853         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
854                            (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_BLK_FILL);
855
856         /* Set the pixel mask (enable writes to all pixels)... */
857         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, 0xffffffff);
858
859         color = ((val & 0xff00) << 24) || ((val & 0xff00) << 16) ||
860             ((val & 0xff00) << 8) || ((val & 0xff00) << 0);
861
862         /* Set the color for the block-fill... */
863         WRITE_GFB_REGISTER(adp, TGA_REG_GBCR0, color);
864         WRITE_GFB_REGISTER(adp, TGA_REG_GBCR1, color);
865
866         /*
867            Just traverse the buffer, one 2K-pixel span at a time, setting
868            each pixel to the bolck-color...
869         */
870         for(off = (x * y); off < ((x + cx) * (y + cy)); off += (2 KB))
871                 WRITE_GFB_BUFFER(adp, off >> 2L, 0x000007ff);
872
873         /* Restore the pixel mode... */
874         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
875
876         /* Restore the pixel mask... */
877         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
878
879         /* Restore the block-color... */
880         WRITE_GFB_REGISTER(adp, TGA_REG_GBCR0, gbcr0);
881         WRITE_GFB_REGISTER(adp, TGA_REG_GBCR1, gbcr1);
882
883         return(0);
884 }
885
886 static int
887 tga_bitblt(video_adapter_t *adp, ...) {
888         va_list args;
889         int i, count;
890         gfb_reg_t gmor;
891         gfb_reg_t gopr;
892         vm_offset_t src, dst;
893
894         va_start(args, adp);
895
896         /* Save the pixel mode... */
897         gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
898
899         /* Save the raster op... */
900         gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
901
902         /* Set the pixel mode (copy)... */
903         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
904             (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_COPY);
905
906         /* Set the raster op (src)... */
907         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x3);
908
909         src = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
910             0x0000000000fffff8;
911         dst = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
912             0x0000000000fffff8;
913         count = va_arg(args, int);
914         for(i = 0; i < count; i+= 64, src += 64, dst += 64) {
915                 WRITE_GFB_REGISTER(adp, TGA_REG_GCSR, src);
916                 WRITE_GFB_REGISTER(adp, TGA_REG_GCDR, dst);
917         }
918
919         /* Restore the raster op... */
920         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
921
922         /* Restore the pixel mode... */
923         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
924
925         va_end(args);
926         return(0);
927 }
928
929 static int
930 #if 0
931 tga_clear(video_adapter_t *adp, int n)
932 #else
933 tga_clear(video_adapter_t *adp)
934 #endif
935 {
936         int off;
937         gfb_reg_t gpxr;
938         gfb_reg_t gmor;
939         gfb_reg_t gopr;
940
941 #if 0
942         if(n == 0) return(0);
943 #endif
944
945         /* Save the pixel mode... */
946         gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
947
948         /* Save the pixel mask... */
949         gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
950
951         /* Save the raster op... */
952         gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
953
954         /* Set the pixel mode (opaque-fill)... */
955         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
956                            (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_OPQ_FILL);
957
958         /* Set the pixel mask (enable writes to all pixels)... */
959         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, 0xffffffff);
960
961         /* Set the raster op (clear)... */
962         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x00);
963
964         /*
965            Just traverse the buffer, one 2K-pixel span at a time, clearing
966            each pixel...
967         */
968 #if 0
969         for(off = 0; off < (n * adp->va_line_width); off += (2 KB))
970 #endif
971         for(off = 0; off < adp->va_window_size; off += (2 KB))
972                 WRITE_GFB_BUFFER(adp, off >> 2L, 0x000007ff);
973
974         /* Restore the pixel mask... */
975         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
976
977         /* Restore the raster op... */
978         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
979
980         /* Restore the pixel mode... */
981         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
982
983         return(0);
984 }
985
986 int
987 tga_putc(video_adapter_t *adp, vm_offset_t off, u_int8_t c, u_int8_t a)
988 {
989         int i;
990         gfb_reg_t gpxr;
991         gfb_reg_t gmor;
992         gfb_reg_t gopr;
993         gfb_reg_t gbgr;
994         gfb_reg_t gfgr;
995         gfb_reg_t mask;
996         int row, col;
997         u_int8_t *pixel;
998         vm_offset_t poff;
999         struct gfb_softc *sc;
1000         int pixel_size;
1001
1002         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1003         pixel_size = adp->va_info.vi_depth / 8;
1004
1005         /* Save the pixel mode... */
1006         gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
1007
1008         /* Save the pixel mask... */
1009         gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
1010
1011         /* Save the raster op... */
1012         gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
1013
1014         /* Save the background color... */
1015         gbgr = READ_GFB_REGISTER(adp, TGA_REG_GBGR);
1016
1017         /* Save the foreground color... */
1018         gfgr = READ_GFB_REGISTER(adp, TGA_REG_GFGR);
1019
1020         /* Set the pixel mode (opaque-stipple)... */
1021         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
1022             (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_OPQ_STPL);
1023
1024         /* Set the pixel mask (enable writes to the first cwidth pixels)... */
1025         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P,
1026             (1 << adp->va_info.vi_cwidth) - 1);
1027
1028         /* Set the raster op (src)... */
1029         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x3);
1030
1031         /* Set the foreground color mask from the attribute byte... */
1032         mask = (a & 0x80) ? a : (a & 0x0f);
1033
1034         /* Propagate the 8-bit mask across the full 32 bits... */
1035         mask |= (mask << 24) | (mask << 16) | (mask << 8);
1036
1037         /* Set the foreground color... */
1038         WRITE_GFB_REGISTER(adp, TGA_REG_GFGR, mask);
1039
1040         /* Set the background color mask from the attribute byte... */
1041         mask = (a >> 4) & 0x07;
1042
1043         /* Propagate the 8-bit mask across the full 32 bits... */
1044         mask |= (mask << 24) | (mask << 16) | (mask << 8);
1045
1046         /* Set the background color... */
1047         WRITE_GFB_REGISTER(adp, TGA_REG_GBGR, mask);
1048
1049         /* Get the start of the array of pixels rows for this character... */
1050         pixel = sc->gfbc->font + (c * adp->va_info.vi_cheight);
1051
1052         /* Calculate the new cursor position... */
1053         row = off / adp->va_info.vi_width;
1054         col = off % adp->va_info.vi_width;
1055
1056         /* Iterate over all the pixel rows for this character... */
1057         for(i = 0; i < adp->va_info.vi_cheight; i++) {
1058
1059                 /* Get the address of the character's pixel-row... */
1060                 poff = ((col * adp->va_info.vi_cwidth * pixel_size) +
1061                     (((row * adp->va_info.vi_cheight) + i) *
1062                     adp->va_line_width)) / sizeof(gfb_reg_t);
1063
1064                 /* Now display the current pixel row... */
1065                 WRITE_GFB_BUFFER(adp, poff, pixel[i]);
1066         }
1067
1068         /* Restore the foreground color... */
1069         WRITE_GFB_REGISTER(adp, TGA_REG_GFGR, gfgr);
1070
1071         /* Restore the background color... */
1072         WRITE_GFB_REGISTER(adp, TGA_REG_GBGR, gbgr);
1073
1074         /* Restore the pixel mode... */
1075         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
1076
1077         /* Restore the pixel mask... */
1078         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
1079
1080         /* Restore the raster op... */
1081         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
1082
1083         return(0);
1084 }
1085
1086 int
1087 tga_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
1088 {
1089         int i, j, k;
1090         gfb_reg_t gpxr;
1091         gfb_reg_t gmor;
1092         gfb_reg_t gopr;
1093         gfb_reg_t row, col;
1094         u_int8_t *pixel;
1095         u_int8_t c;
1096         u_int8_t a;
1097         gfb_reg_t p;
1098         vm_offset_t poff;
1099         struct gfb_softc *sc;
1100         int pixel_size;
1101
1102         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1103         pixel_size = adp->va_info.vi_depth / 8;
1104
1105         /* If the string in empty, just return now... */
1106         if(len == 0) return(0);
1107
1108         for(i = 0; i < len; i++)
1109                 tga_putc(adp, off + i, s[i] & 0x00ff, (s[i] & 0xff00) >> 8);
1110         return(0);
1111
1112         /* Save the pixel mode... */
1113         gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
1114
1115         /* Save the pixel mask... */
1116         gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
1117
1118         /* Save the raster op... */
1119         gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
1120
1121         /* Set the pixel mode (simple)... */
1122         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, (gmor & 0xffffffc0) | 0x00);
1123
1124         /* Set the pixel mask (enable writes to all 32 pixels)... */
1125         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, (gpxr & 0xfffffff0) | 0xf);
1126
1127         /* Set the raster op (src)... */
1128         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x03);
1129
1130         /*
1131            First, do as many characters-rows at a time as possible (as exist)...
1132         */
1133         for(i = 0; (len - i) > adp->va_info.vi_width;
1134             i += adp->va_info.vi_width) {
1135
1136                 /*
1137                    Iterate over all the pixels for each character in the
1138                    character-row, doing a scan-line at-a-time, rather than
1139                    a character at-a-time (like tga_putc())...
1140                 */
1141                 for(j = 0; j < adp->va_info.vi_cheight; j++) {
1142                         p = 0;
1143                         for(k = 0; k < adp->va_info.vi_width; k++) {
1144
1145                                 /*
1146                                    Get this character...
1147                                 */
1148                                 c = s[i + k] & 0x00ff;
1149
1150                                 /*
1151                                    Get the attribute for this character...
1152                                 */
1153                                 a = (s[i + k] & 0xff00) >> 8;
1154
1155                                 /*
1156                                    Get the start of the array of pixels rows for
1157                                    this character...
1158                                 */
1159                                 pixel = sc->gfbc->font +
1160                                         (c * adp->va_info.vi_cheight);
1161
1162                                 /* Shift the other pre-existing pixel rows... */
1163                                 p <<= 8;
1164
1165                                 /*
1166                                    Get the first pixel row for
1167                                    this character...
1168                                 */
1169                                 p |= pixel[j];
1170
1171                                 if (((k + 1) % sizeof(gfb_reg_t)) == 0) {
1172
1173                                         /*
1174                                            Calculate the new cursor
1175                                            position...
1176                                         */
1177                                         row = (off + i + (k -
1178                                             (sizeof(gfb_reg_t) - 1))) /
1179                                             adp->va_info.vi_width;
1180                                         col = (off + i + (k -
1181                                             (sizeof(gfb_reg_t) - 1))) %
1182                                             adp->va_info.vi_width;
1183
1184                                         /*
1185                                            Get the address of the current
1186                                            character's pixel-row...
1187                                         */
1188                                         poff = ((col * adp->va_info.vi_cwidth * 
1189                                             pixel_size) + (((row *
1190                                             adp->va_info.vi_cheight) + j) *
1191                                             adp->va_line_width)) /
1192                                             sizeof(gfb_reg_t);
1193
1194                                         /*
1195                                            Now display the current
1196                                            pixel row...
1197                                         */
1198                                         (*vidsw[adp->va_index]->putp)(adp, poff,
1199                                             p, a, sizeof(gfb_reg_t),
1200                                             adp->va_info.vi_depth, 1, 0);
1201
1202                                         /* Reset (clear) p... */
1203                                         p = 0;
1204                                 }
1205                         }
1206                 }
1207         }
1208
1209         /*
1210            Next, do as many character-sets at a time as possible (as exist)...
1211         */
1212         for(; (len - i) > sizeof(gfb_reg_t); i += sizeof(gfb_reg_t)) {
1213
1214                 /*
1215                    Iterate over all the pixels for each character in the
1216                    character-row, doing a scan-line at-a-time, rather than
1217                    a character at-a-time (like tga_putc())...
1218                 */
1219                 for(j = 0; j < adp->va_info.vi_cheight; j++) {
1220                         p = 0;
1221                         for(k = 0; k < sizeof(gfb_reg_t); k++) {
1222
1223                                 /*
1224                                    Get this character...
1225                                 */
1226                                 c = s[i + k] & 0x00ff;
1227
1228                                 /*
1229                                    Get the attribute for this character...
1230                                 */
1231                                 a = (s[i + k] & 0xff00) >> 8;
1232
1233                                 /*
1234                                    Get the start of the array of pixels rows for
1235                                    this character...
1236                                 */
1237                                 pixel = sc->gfbc->font +
1238                                     (c * adp->va_info.vi_cheight);
1239
1240                                 /* Shift the other pre-existing pixel rows... */
1241                                 p <<= 8;
1242
1243                                 /*
1244                                    Get the first pixel row for
1245                                    this character...
1246                                 */
1247                                 p |= pixel[j];
1248
1249                                 if (((k + 1) % sizeof(gfb_reg_t)) == 0) {
1250
1251                                         /*
1252                                            Calculate the new cursor
1253                                            position...
1254                                         */
1255                                         row = (off + i) / adp->va_info.vi_width;
1256                                         col = (off + i) % adp->va_info.vi_width;
1257
1258                                         /*
1259                                            Get the address of the current
1260                                            character's pixel-row...
1261                                         */
1262                                         poff = ((col * adp->va_info.vi_cwidth * 
1263                                             pixel_size) + (((row *
1264                                             adp->va_info.vi_cheight) + j) *
1265                                             adp->va_line_width)) /
1266                                             sizeof(gfb_reg_t);
1267
1268                                         /*
1269                                            Now display the current
1270                                            pixel row...
1271                                         */
1272                                         (*vidsw[adp->va_index]->putp)(adp, poff,
1273                                             p, a, sizeof(gfb_reg_t),
1274                                             adp->va_info.vi_depth, 1, 0);
1275
1276                                         /* Reset (clear) p... */
1277                                         p = 0;
1278                                 }
1279                         }
1280                 }
1281         }
1282
1283         /* Restore the pixel mode... */
1284         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
1285
1286         /* Restore the pixel mask... */
1287         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
1288
1289         /* Restore the raster op... */
1290         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
1291
1292         /* Finally, do the remaining characters a character at-a-time... */
1293         for(; i < len; i++) {
1294                 /*
1295                    Get this character...
1296                 */
1297                 c = s[i] & 0x00ff;
1298
1299                 /*
1300                    Get the attribute for this character...
1301                 */
1302                 a = (s[i] & 0xff00) >> 8;
1303
1304                 /*
1305                    Display this character...
1306                 */
1307                 tga_putc(adp, off + i, c, a);
1308         }
1309         return(0);
1310 }
1311
1312 int
1313 tga_putm(video_adapter_t *adp, int x, int y, u_int8_t *pixel_image,
1314             gfb_reg_t pixel_mask, int size)
1315 {
1316         gfb_reg_t gpxr;
1317         gfb_reg_t gmor;
1318         gfb_reg_t gopr;
1319         int i, pixel_size;
1320         vm_offset_t poff;
1321
1322         pixel_size = adp->va_info.vi_depth / 8;
1323
1324         /* Save the pixel mode... */
1325         gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
1326
1327         /* Save the pixel mask... */
1328         gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
1329
1330         /* Save the raster op... */
1331         gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
1332
1333         /* Set the pixel mode (simple)... */
1334         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
1335             (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_SIMPLE);
1336
1337         /* Set the pixel mask (enable writes to the first 8 pixels)... */
1338         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, (gpxr & 0xfffffff0) | 0xf);
1339
1340         /* Set the raster op (src)... */
1341         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x3);
1342
1343         /* Iterate over all the pixel rows for the mouse pointer... */
1344         for(i = 0; i < size; i++) {
1345
1346                 /* Get the address of the mouse pointer's pixel-row... */
1347                 poff = ((x * pixel_size) + ((y + i) * adp->va_line_width)) /
1348                     sizeof(gfb_reg_t);
1349
1350                 /* Now display the current pixel-row... */
1351                 (*vidsw[adp->va_index]->putp)(adp, poff, pixel_image[i],
1352                     pixel_mask, sizeof(u_int8_t), adp->va_info.vi_depth, 1, 0);
1353         }
1354
1355         /* Restore the pixel mode... */
1356         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
1357
1358         /* Restore the pixel mask... */
1359         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
1360
1361         /* Restore the raster op... */
1362         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
1363
1364         return(0);
1365 }
1366
1367 static int
1368 tga_error(void)
1369 {
1370         return(0);
1371 }
1372
1373 /*****************************************************************************
1374  *
1375  * TGA-specific functions
1376  *
1377  ****************************************************************************/
1378
1379 static int
1380 tga_builtin_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
1381 {
1382         int i;
1383         int error;
1384         struct gfb_softc *sc;
1385
1386         error = 0;
1387         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1388
1389         /*
1390          * We store 8 bit values in the palette buffer, while the standard
1391          * VGA has 6 bit DAC .
1392          */
1393         outb(PALRADR, 0x00);
1394         for(i = 0; i < palette->count; ++i) {
1395                 palette->red[i] = inb(PALDATA) << 2;
1396                 palette->green[i] = inb(PALDATA) << 2;
1397                 palette->blue[i] = inb(PALDATA) << 2;
1398         }
1399         return(error);
1400 }
1401
1402 static int
1403 tga_builtin_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
1404 {
1405         int i;
1406         int error;
1407         struct gfb_softc *sc;
1408
1409         error = 0;
1410         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1411
1412         /*
1413          * We store 8 bit values in the palette buffer, while the standard
1414          * VGA has 6 bit DAC .
1415         */
1416         outb(PIXMASK, 0xff);
1417         outb(PALWADR, 0x00);
1418         for(i = 0; i < palette->count; ++i) {
1419                 outb(PALDATA, palette->red[i] >> 2);
1420                 outb(PALDATA, palette->green[i] >> 2);
1421                 outb(PALDATA, palette->blue[i] >> 2);
1422         }
1423         return(error);
1424 }
1425
1426 #ifdef TGA2
1427 static int
1428 tga2_builtin_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
1429 {
1430         int i;
1431         int error;
1432         struct gfb_softc *sc;
1433
1434         error = 0;
1435         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1436
1437         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1438             BT463_IREG_CPALETTE_RAM & 0xff);
1439         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1440             (BT463_IREG_CPALETTE_RAM >> 8) & 0xff);
1441
1442         /* spit out the colormap data */
1443         for(i = 0; i < palette->count; i++) {
1444                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA,
1445                     palette->red[i]);
1446                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, 
1447                     palette->green[i]);
1448                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, 
1449                     palette->blue[i]);
1450         }
1451         return(error);
1452 }
1453
1454 static int
1455 tga2_builtin_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
1456 {
1457         int i;
1458         int error;
1459         struct gfb_softc *sc;
1460
1461         error = 0;
1462         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1463
1464         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1465             BT463_IREG_CPALETTE_RAM & 0xff);
1466         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1467             (BT463_IREG_CPALETTE_RAM >> 8) & 0xff);
1468
1469         /* spit out the colormap data */
1470         for(i = 0; i < palette->count; i++) {
1471                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA,
1472                     palette->red[i]);
1473                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, 
1474                     palette->green[i]);
1475                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, 
1476                     palette->blue[i]);
1477         }
1478         return(error);
1479 }
1480
1481 static int
1482 tga2_builtin_save_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
1483 {
1484         int i;
1485         int error;
1486         struct gfb_softc *sc;
1487
1488         error = 0;
1489         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1490
1491         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1492             BT463_IREG_CURSOR_COLOR_0 & 0xff);
1493         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1494             (BT463_IREG_CURSOR_COLOR_0 >> 8) & 0xff);
1495
1496         /* spit out the cursor data */
1497         for(i = 0; i < palette->count; i++) {
1498                 BTWNREG(sc, palette->red[i]);
1499                 BTWNREG(sc, palette->green[i]);
1500                 BTWNREG(sc, palette->blue[i]);
1501         }
1502         return(error);
1503 }
1504
1505 static int
1506 tga2_builtin_load_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
1507 {
1508         int i;
1509         int error;
1510         struct gfb_softc *sc;
1511
1512         error = 0;
1513         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1514
1515         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1516             BT463_IREG_CURSOR_COLOR_0 & 0xff);
1517         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1518             (BT463_IREG_CURSOR_COLOR_0 >> 8) & 0xff);
1519
1520         /* spit out the cursor data */
1521         for(i = 0; i < palette->count; i++) {
1522                 BTWNREG(sc, palette->red[i]);
1523                 BTWNREG(sc, palette->green[i]);
1524                 BTWNREG(sc, palette->blue[i]);
1525         }
1526         return(error);
1527 }
1528
1529 #endif /* TGA2 */
1530
1531 static int
1532 tga_builtin_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
1533 {
1534         gfb_reg_t cxyr;
1535         int error;
1536
1537         /* Assume the best... */
1538         error = 0;
1539
1540         cxyr = READ_GFB_REGISTER(adp, TGA_REG_CXYR) | 0x00ffffff;
1541         *col = (cxyr & 0x00000fff) / adp->va_info.vi_cwidth;
1542         *row = ((cxyr & 0x00fff000) >> 12) / adp->va_info.vi_cheight;
1543         return(error);
1544 }
1545
1546 static int
1547 tga_builtin_set_hw_cursor(video_adapter_t *adp, int col, int row)
1548 {
1549         int error;
1550         gfb_reg_t cxyr;
1551         gfb_reg_t vvvr;
1552
1553         /* Assume the best... */
1554         error = 0;
1555
1556         vvvr = READ_GFB_REGISTER(adp, TGA_REG_VVVR);
1557
1558         /*
1559            Make sure the parameters are in range for the screen
1560            size...
1561         */
1562         if((row > adp->va_info.vi_height) ||
1563             (col > adp->va_info.vi_width))
1564                 error = EINVAL;
1565         else if(((row * adp->va_info.vi_cheight) > 0x0fff) ||
1566             ((col * adp->va_info.vi_cwidth) > 0x0fff))
1567                 error = EINVAL;
1568         /*
1569            If either of the parameters is less than 0,
1570            then hide the cursor...
1571         */
1572         else if((row < 0) || (col < 0)) {
1573                 if((vvvr & 0x00000004) != 0) {
1574                         vvvr &= 0xfffffffb;
1575                         WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, vvvr);
1576                 }
1577         }
1578                 
1579         /* Otherwise, just move the cursor as requested... */
1580         else {
1581                 cxyr = READ_GFB_REGISTER(adp, TGA_REG_CXYR) & 0xff000000;
1582                 cxyr |= ((row * adp->va_info.vi_cheight) << 12);
1583                 cxyr |= (col * adp->va_info.vi_cwidth);
1584                 WRITE_GFB_REGISTER(adp, TGA_REG_CXYR, cxyr);
1585                 if((vvvr & 0x00000004) == 0) {
1586                         vvvr |= 0x00000004;
1587                 WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, vvvr);
1588                 }
1589         }
1590         return(error);
1591 }
1592
1593 static int
1594 tga_builtin_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
1595             int cellsize, int blink)
1596 {
1597         int i, j;
1598         vm_offset_t cba;
1599         gfb_reg_t window_orig;
1600         gfb_reg_t ccbr;
1601         gfb_reg_t vvvr;
1602         int error;
1603
1604         /* Assume the best... */
1605         error = 0;
1606
1607         vvvr = READ_GFB_REGISTER(adp, TGA_REG_VVVR);
1608
1609         /*
1610            Make sure the parameters are in range for the cursor
1611            (it's a 64x64 cursor)...
1612         */
1613         if(height > 64)
1614                 error = EINVAL;
1615
1616         /* If height is less than or equal to 0, then hide the cursor... */
1617         else if(height <= 0) {
1618                 if((vvvr & 0x00000004) != 0) {
1619                         vvvr &= 0xfffffffb;
1620                         WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, vvvr);
1621                 }
1622         }
1623
1624         /* Otherwise, just resize the cursor as requested... */
1625         else {
1626                 ccbr = READ_GFB_REGISTER(adp, TGA_REG_CCBR);
1627                 ccbr &= 0xffff03ff;
1628                 ccbr |= ((height - 1) << 10);
1629                 WRITE_GFB_REGISTER(adp, TGA_REG_CCBR, ccbr);
1630                 if((vvvr & 0x00000004) == 0) {
1631                         vvvr |= 0x00000004;
1632                         WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, vvvr);
1633                 }
1634
1635                 /* Save the window origin... */
1636                 window_orig = adp->va_window_orig;
1637
1638                 /*
1639                    Fill in the cursor image (64 rows of 64 pixels per cursor
1640                    row at 2 bits-per-pixel, so 64 rows of 16 bytes each)--we
1641                    set va_window_orig to the cursor base address temporarily
1642                    so that we can write to the cursor image...
1643                 */
1644                 cba = (READ_GFB_REGISTER(adp, TGA_REG_CCBR) & 0xfffffc0f) >> 4;
1645                 adp->va_window_orig = cba;
1646                 for(i = 0; i < (64 - height); i++) {
1647                         WRITE_GFB_BUFFER(adp, cba++, 0x00000000);
1648                         WRITE_GFB_BUFFER(adp, cba++, 0x00000000);
1649                 }
1650                 for(; i < 64; i++) {
1651                         for(j = 0; j < (((64 - cellsize) / 8) /
1652                             sizeof(gfb_reg_t)); j++)
1653                                 WRITE_GFB_BUFFER(adp, cba++, 0x00000000);
1654                         for(; j < ((64 / 8) / sizeof(gfb_reg_t)); j++)
1655                                 WRITE_GFB_BUFFER(adp, cba++, 0xffffffff);
1656                 }
1657
1658                 /* Restore the window origin... */
1659                 adp->va_window_orig = window_orig;
1660
1661         }
1662         return(error);
1663 }
1664
1665 static void
1666 bt463_load_palette_intr(struct gfb_softc *sc)
1667 {
1668         sc->gfbc->ramdac_save_palette(sc->adp, &sc->gfbc->palette);
1669 }
1670
1671 static void
1672 bt463_load_cursor_palette_intr(struct gfb_softc *sc)
1673 {
1674         sc->gfbc->ramdac_load_cursor_palette(sc->adp, &sc->gfbc->cursor_palette);
1675 }
1676
1677 static int
1678 tga_schedule_intr(struct gfb_softc *sc, void (*f)(struct gfb_softc *))
1679 {
1680         /* Busy-wait for the previous interrupt to complete... */
1681         while((READ_GFB_REGISTER(sc->adp, TGA_REG_SISR) & 0x00000001) != 0);
1682
1683         /* Arrange for f to be called at the next end-of-frame interrupt... */
1684         sc->gfbc->ramdac_intr = f;
1685
1686         /* Enable the interrupt... */
1687         WRITE_GFB_REGISTER(sc->adp, TGA_REG_SISR, 0x00010000);
1688         return(0);
1689 }
1690
1691 static u_int8_t
1692 tga_bt485_rd(struct gfb_softc *sc, u_int btreg)
1693 {
1694         gfb_reg_t rdval;
1695
1696         if(btreg > BT485_REG_MAX)
1697                 panic("tga_ramdac_rd: reg %d out of range\n", btreg);
1698         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPSR, (btreg << 1) | 0x1);
1699         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPSR, 1);
1700         rdval = READ_GFB_REGISTER(sc->adp, TGA_REG_EPDR);
1701         return((rdval >> 16) & 0xff);
1702 }
1703
1704 static void
1705 tga_bt485_wr(struct gfb_softc *sc, u_int btreg, u_int8_t val)
1706 {
1707         if(btreg > BT485_REG_MAX)
1708                 panic("tga_ramdac_wr: reg %d out of range\n", btreg);
1709         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPDR,
1710             (btreg << 9) | (0 << 8 ) | val);
1711         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPDR, 1);
1712 }
1713
1714 static u_int8_t
1715 tga2_ibm561_rd(struct gfb_softc *sc, u_int btreg)
1716 {
1717         bus_space_handle_t ramdac;
1718         u_int8_t retval;
1719
1720         if(btreg > BT485_REG_MAX)
1721                 panic("tga_ramdac_rd: reg %d out of range\n", btreg);
1722         ramdac = sc->bhandle + TGA2_MEM_RAMDAC + (0xe << 12) + (btreg << 8);
1723         retval = bus_space_read_4(sc->btag, ramdac, 0) & 0xff;
1724         bus_space_barrier(sc->btag, ramdac, 0, 4, BUS_SPACE_BARRIER_READ);
1725         return(retval);
1726 }
1727
1728 static void
1729 tga2_ibm561_wr(struct gfb_softc *sc, u_int btreg, u_int8_t val)
1730 {
1731         bus_space_handle_t ramdac;
1732
1733         if(btreg > BT485_REG_MAX)
1734                 panic("tga_ramdac_wr: reg %d out of range\n", btreg);
1735         ramdac = sc->bhandle + TGA2_MEM_RAMDAC + (0xe << 12) + (btreg << 8);
1736         bus_space_write_4(sc->btag, ramdac, 0, val & 0xff);
1737         bus_space_barrier(sc->btag, ramdac, 0, 4, BUS_SPACE_BARRIER_WRITE);
1738 }
1739
1740 static u_int8_t
1741 tga_bt463_rd(struct gfb_softc *sc, u_int btreg)
1742 {
1743         gfb_reg_t rdval;
1744
1745         /* 
1746          * Strobe CE# (high->low->high) since status and data are latched on 
1747          * the falling and rising edges (repsectively) of this active-low
1748          * signal.
1749          */
1750         
1751         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPSR, 1);
1752         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPSR, (btreg << 2) | 2 | 1);
1753         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPSR, 1);
1754         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPSR, (btreg << 2) | 2 | 0);
1755         GFB_REGISTER_READ_BARRIER(sc, TGA_REG_EPSR, 1);
1756         rdval = READ_GFB_REGISTER(sc->adp, TGA_REG_EPDR);
1757         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPSR, 1);
1758         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPSR, (btreg << 2) | 2 | 1);
1759         return((rdval >> 16) & 0xff);
1760 }
1761
1762 static void
1763 tga_bt463_wr(struct gfb_softc *sc, u_int btreg, u_int8_t val)
1764 {
1765         /* 
1766          * In spite of the 21030 documentation, to set the MPU bus bits for
1767          * a write, you set them in the upper bits of EPDR, not EPSR.
1768          */
1769         
1770         /* 
1771          * Strobe CE# (high->low->high) since status and data are latched on
1772          * the falling and rising edges of this active-low signal.
1773          */
1774
1775         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPDR, 1);
1776         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPDR, (btreg << 10) | 0x100 | val);
1777         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPDR, 1);
1778         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPDR, (btreg << 10) | 0x000 | val);
1779         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPDR, 1);
1780         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPDR, (btreg << 10) | 0x100 | val);
1781 }
1782
1783 static void
1784 tga2_ics9110_wr(struct gfb_softc *sc, int dotclock)
1785 {
1786         bus_space_handle_t clock;
1787         gfb_reg_t valU;
1788         int N, M, R, V, X;
1789         int i;
1790
1791         switch(dotclock) {
1792         case 130808000:
1793                 N = 0x40; M = 0x7; V = 0x0; X = 0x1; R = 0x1; break;
1794         case 119840000:
1795                 N = 0x2d; M = 0x2b; V = 0x1; X = 0x1; R = 0x1; break;
1796         case 108180000:
1797                 N = 0x11; M = 0x9; V = 0x1; X = 0x1; R = 0x2; break;
1798         case 103994000:
1799                 N = 0x6d; M = 0xf; V = 0x0; X = 0x1; R = 0x1; break;
1800         case 175000000:
1801                 N = 0x5F; M = 0x3E; V = 0x1; X = 0x1; R = 0x1; break;
1802         case  75000000:
1803                 N = 0x6e; M = 0x15; V = 0x0; X = 0x1; R = 0x1; break;
1804         case  74000000:
1805                 N = 0x2a; M = 0x41; V = 0x1; X = 0x1; R = 0x1; break;
1806         case  69000000:
1807                 N = 0x35; M = 0xb; V = 0x0; X = 0x1; R = 0x1; break;
1808         case  65000000:
1809                 N = 0x6d; M = 0x0c; V = 0x0; X = 0x1; R = 0x2; break;
1810         case  50000000:
1811                 N = 0x37; M = 0x3f; V = 0x1; X = 0x1; R = 0x2; break;
1812         case  40000000:
1813                 N = 0x5f; M = 0x11; V = 0x0; X = 0x1; R = 0x2; break;
1814         case  31500000:
1815                 N = 0x16; M = 0x05; V = 0x0; X = 0x1; R = 0x2; break;
1816         case  25175000:
1817                 N = 0x66; M = 0x1d; V = 0x0; X = 0x1; R = 0x2; break;
1818         case 135000000:
1819                 N = 0x42; M = 0x07; V = 0x0; X = 0x1; R = 0x1; break;
1820         case 110000000:
1821                 N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
1822         case 202500000:
1823                 N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
1824         default:
1825                 panic("unrecognized clock rate %d\n", dotclock);
1826         }
1827
1828         /* XXX -- hard coded, bad */
1829         valU  = N | ( M << 7 ) | (V << 14);
1830         valU |= (X << 15) | (R << 17);
1831         valU |= 0x17 << 19;
1832         clock = sc->bhandle + TGA2_MEM_EXTDEV + TGA2_MEM_CLOCK + (0xe << 12);
1833         for(i = 24; i > 0; i--) {
1834                 gfb_reg_t       writeval;
1835                 
1836                 writeval = valU & 0x1;
1837                 if (i == 1)  
1838                         writeval |= 0x2; 
1839                 valU >>= 1;
1840                 bus_space_write_4(sc->btag, clock, 0, writeval);
1841                 bus_space_barrier(sc->btag, clock, 0, 4,
1842                     BUS_SPACE_BARRIER_WRITE);
1843         }       
1844         clock = sc->bhandle + TGA2_MEM_EXTDEV + TGA2_MEM_CLOCK + (0xe << 12) +
1845             (0x1 << 11) + (0x1 << 11);
1846         bus_space_write_4(sc->btag, clock, 0, 0x0);
1847         bus_space_barrier(sc->btag, clock, 0, 0, BUS_SPACE_BARRIER_WRITE);
1848 }
1849
1850 /*****************************************************************************
1851  *
1852  * BrookTree RAMDAC-specific functions
1853  *
1854  ****************************************************************************/
1855
1856 static void
1857 bt463_init(struct gfb_softc *sc)
1858 {
1859         int i;
1860
1861         return;
1862
1863         /*
1864          * Init the BT463 for normal operation.
1865          */
1866
1867         /*
1868          * Setup:
1869          * reg 0: 4:1 multiplexing, 25/75 blink.
1870          * reg 1: Overlay mapping: mapped to common palette, 
1871          *        14 window type entries, 24-plane configuration mode,
1872          *        4 overlay planes, underlays disabled, no cursor. 
1873          * reg 2: sync-on-green enabled, pedestal enabled.
1874          */
1875
1876         BTWREG(sc, BT463_IREG_COMMAND_0, 0x40);
1877         BTWREG(sc, BT463_IREG_COMMAND_1, 0x48);
1878         BTWREG(sc, BT463_IREG_COMMAND_2, 0xC0);
1879
1880         /*
1881          * Initialize the read mask.
1882          */
1883         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1884             BT463_IREG_READ_MASK_P0_P7 & 0xff);
1885         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1886             (BT463_IREG_READ_MASK_P0_P7 >> 8) & 0xff);
1887         for(i = 0; i < 4; i++)
1888                 BTWNREG(sc, 0xff);
1889
1890         /*
1891          * Initialize the blink mask.
1892          */
1893         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1894             BT463_IREG_READ_MASK_P0_P7 & 0xff);
1895         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1896             (BT463_IREG_READ_MASK_P0_P7 >> 8) & 0xff);
1897         for(i = 0; i < 4; i++)
1898                 BTWNREG(sc, 0);
1899
1900         /*
1901          * Clear test register
1902          */
1903         BTWREG(sc, BT463_IREG_TEST, 0);
1904
1905         /*
1906          * Initalize the RAMDAC info struct to hold all of our
1907          * data, and fill it in.
1908          */
1909
1910         /* Initialize the window type table:
1911          *
1912          * Entry 0: 24-plane truecolor, overlays enabled, bypassed.
1913          *
1914          *  Lookup table bypass:      yes (    1 << 23 & 0x800000)  800000
1915          *  Colormap address:       0x000 (0x000 << 17 & 0x7e0000)       0 
1916          *  Overlay mask:             0xf (  0xf << 13 & 0x01e000)   1e000
1917          *  Overlay location:    P<27:24> (    0 << 12 & 0x001000)       0
1918          *  Display mode:       Truecolor (    0 <<  9 & 0x000e00)     000
1919          *  Number of planes:           8 (    8 <<  5 & 0x0001e0)     100
1920          *  Plane shift:                0 (    0 <<  0 & 0x00001f)       0
1921          *                                                        --------
1922          *                                                        0x81e100
1923          */       
1924 #if 0
1925         data->window_type[0] = 0x81e100;
1926 #endif
1927
1928         /* Entry 1: 8-plane pseudocolor in the bottom 8 bits, 
1929          *          overlays enabled, colormap starting at 0. 
1930          *
1931          *  Lookup table bypass:       no (    0 << 23 & 0x800000)       0
1932          *  Colormap address:       0x000 (0x000 << 17 & 0x7e0000)       0 
1933          *  Overlay mask:             0xf (  0xf << 13 & 0x01e000) 0x1e000
1934          *  Overlay location:    P<27:24> (    0 << 12 & 0x001000)       0
1935          *  Display mode:     Pseudocolor (    1 <<  9 & 0x000e00)   0x200
1936          *  Number of planes:           8 (    8 <<  5 & 0x0001e0)   0x100
1937          *  Plane shift:               16 ( 0x10 <<  0 & 0x00001f)      10
1938          *                                                        --------
1939          *                                                        0x01e310
1940          */       
1941 #if 0
1942         data->window_type[1] = 0x01e310;
1943 #endif
1944         /* The colormap interface to the world only supports one colormap, 
1945          * so having an entry for the 'alternate' colormap in the bt463 
1946          * probably isn't useful.
1947          */
1948
1949         /* Fill the remaining table entries with clones of entry 0 until we 
1950          * figure out a better use for them.
1951          */
1952 #if 0
1953         for(i = 2; i < BT463_NWTYPE_ENTRIES; i++) {
1954                 data->window_type[i] = 0x81e100;
1955         }
1956 #endif
1957
1958         tga_schedule_intr(sc, bt463_update_window_type);
1959         tga_schedule_intr(sc, bt463_load_cursor_palette_intr);
1960         tga_schedule_intr(sc, bt463_load_palette_intr);
1961 }
1962
1963 static void
1964 bt463_update_window_type(struct gfb_softc *sc)
1965 {
1966         int i;
1967
1968         /* The Bt463 won't accept window type data except during a blanking
1969          * interval, so we do this early in the interrupt.
1970          * Blanking the screen might also be a good idea, but it can cause 
1971          * unpleasant flashing and is hard to do from this side of the
1972          * ramdac interface.
1973          */
1974         /* spit out the window type data */
1975         for(i = 0; i < BT463_NWTYPE_ENTRIES; i++) {
1976 #if 0
1977                 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1978                     (BT463_IREG_WINDOW_TYPE_TABLE + i) & 0xff);
1979                 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1980                     ((BT463_IREG_WINDOW_TYPE_TABLE + i) >> 8) & 0xff);
1981                 BTWNREG(sc, (data->window_type[i]) & 0xff);
1982                 BTWNREG(sc, (data->window_type[i] >> 8) & 0xff);
1983                 BTWNREG(sc, (data->window_type[i] >> 16) & 0xff);
1984 #endif
1985         }
1986 }
1987
1988 #if 0
1989 static int
1990 bt463_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
1991 {
1992         struct gfb_softc *sc;
1993         int error, i;
1994
1995         error = 0;
1996         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1997
1998         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1999             BT463_IREG_CPALETTE_RAM & 0xff);
2000         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
2001             (BT463_IREG_CPALETTE_RAM >> 8) & 0xff);
2002
2003         /* get the colormap data */
2004         for(i = 0; i < palette->count; i++) {
2005                 palette->red[i] = sc->gfbc->ramdac_rd(sc, BT463_REG_CMAP_DATA);
2006                 palette->green[i] = sc->gfbc->ramdac_rd(sc,
2007                     BT463_REG_CMAP_DATA);
2008                 palette->blue[i] = sc->gfbc->ramdac_rd(sc, BT463_REG_CMAP_DATA);
2009         }
2010         return(error);
2011 }
2012
2013 static int
2014 bt463_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
2015 {
2016         struct gfb_softc *sc;
2017         int error, i;
2018
2019         error = 0;
2020         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2021
2022         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
2023             BT463_IREG_CPALETTE_RAM & 0xff);
2024         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
2025             (BT463_IREG_CPALETTE_RAM >> 8) & 0xff);
2026
2027         /* spit out the colormap data */
2028         for(i = 0; i < palette->count; i++) {
2029                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, palette->red[i]);
2030                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, palette->green[i]);
2031                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, palette->blue[i]);
2032         }
2033         return(error);
2034 }
2035
2036 #endif /* 0 */
2037
2038 static int
2039 bt463_save_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2040 {
2041         struct gfb_softc *sc;
2042         int error, i;
2043
2044         error = 0;
2045         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2046
2047         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
2048             BT463_IREG_CURSOR_COLOR_0 & 0xff);
2049         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
2050             (BT463_IREG_CURSOR_COLOR_0 >> 8) & 0xff);
2051
2052         /* spit out the cursor data */
2053         for(i = 0; i < palette->count; i++) {
2054                 palette->red[i] = BTRNREG(sc);
2055                 palette->green[i] = BTRNREG(sc);
2056                 palette->blue[i] = BTRNREG(sc);
2057         }
2058         return(error);
2059 }
2060
2061 static int
2062 bt463_load_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2063 {
2064         struct gfb_softc *sc;
2065         int error, i;
2066
2067         error = 0;
2068         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2069
2070         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
2071             BT463_IREG_CURSOR_COLOR_0 & 0xff);
2072         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
2073             (BT463_IREG_CURSOR_COLOR_0 >> 8) & 0xff);
2074
2075         /* spit out the cursor data */
2076         for(i = 0; i < palette->count; i++) {
2077                 BTWNREG(sc, palette->red[i]);
2078                 BTWNREG(sc, palette->green[i]);
2079                 BTWNREG(sc, palette->blue[i]);
2080         }
2081         return(error);
2082 }
2083
2084 static void
2085 bt485_init(struct gfb_softc *sc)
2086 {
2087         int i, j, num_cmap_entries;
2088         u_int8_t regval;
2089
2090         regval = sc->gfbc->ramdac_rd(sc, BT485_REG_COMMAND_0);
2091
2092         /*
2093          * Set the RAMDAC to 8 bit resolution, rather than 6 bit
2094          * resolution.
2095          */
2096         regval |= 0x02;
2097
2098         /*
2099          * Set the RAMDAC to sync-on-green.
2100          */
2101         regval |= 0x08;
2102         sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_0, regval);
2103
2104 #if 0
2105         /* Set the RAMDAC to 8BPP (no interesting options). */
2106         sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_1, 0x40);
2107
2108         /* Disable the cursor (for now) */
2109         regval = sc->gfbc->ramdac_rd(sc, BT485_REG_COMMAND_2);
2110         regval &= ~0x03;
2111         regval |= 0x24;
2112         sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_2, regval);
2113
2114         /* Use a 64x64x2 cursor */
2115         sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, BT485_IREG_COMMAND_3);
2116         regval = sc->gfbc->ramdac_rd(sc, BT485_REG_EXTENDED);
2117         regval |= 0x04;
2118         regval |= 0x08;
2119         sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, BT485_IREG_COMMAND_3);
2120         sc->gfbc->ramdac_wr(sc, BT485_REG_EXTENDED, regval);
2121
2122         /* Set the Pixel Mask to something useful */
2123         sc->gfbc->ramdac_wr(sc, BT485_REG_PIXMASK, 0xff);
2124 #endif
2125
2126         /* Generate the cursor color map (Light-Grey)... */
2127         for(i = 0; i < sc->gfbc->cursor_palette.count; i++) {
2128                 sc->gfbc->cursor_palette.red[i] = default_cmap[7].red;
2129                 sc->gfbc->cursor_palette.green[i] = default_cmap[7].green;
2130                 sc->gfbc->cursor_palette.blue[i] = default_cmap[7].blue;
2131         }
2132
2133 #if 0
2134         /* Enable cursor... */
2135         regval = sc->gfbc->ramdac_rd(sc, BT485_REG_COMMAND_2);
2136         if(!(regval & 0x01)) {
2137                 regval |= 0x01;
2138                 sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_2, regval);
2139         }
2140         else if(regval & 0x03) {
2141                 regval &= ~0x03;
2142                 sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_2, regval);
2143         }
2144 #endif
2145
2146         /* Generate the screen color map... */
2147         num_cmap_entries = sizeof(default_cmap) / sizeof(struct cmap);
2148         for(i = 0; i < sc->gfbc->palette.count / num_cmap_entries; i++)
2149                 for(j = 0; j < num_cmap_entries; j++) {
2150                         sc->gfbc->palette.red[(num_cmap_entries * i) + j] =
2151                             default_cmap[j].red;
2152                         sc->gfbc->palette.green[(num_cmap_entries * i) + j] =
2153                             default_cmap[j].green;
2154                         sc->gfbc->palette.blue[(num_cmap_entries * i) + j] =
2155                             default_cmap[j].blue;
2156                 }
2157 }
2158
2159 static int
2160 bt485_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
2161 {
2162         struct gfb_softc *sc;
2163         int error, i;
2164
2165         error = 0;
2166         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2167
2168         /* addr[9:0] assumed to be 0 */
2169         /* set addr[7:0] to 0 */
2170         sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, 0x00);
2171
2172         /* spit out the color data */
2173         for(i = 0; i < palette->count; i++) {
2174                 palette->red[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_PALETTE);
2175                 palette->green[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_PALETTE);
2176                 palette->blue[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_PALETTE);
2177         }
2178         return(error);
2179 }
2180
2181 static int
2182 bt485_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
2183 {
2184         struct gfb_softc *sc;
2185         int error, i;
2186
2187         error = 0;
2188         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2189
2190         /* addr[9:0] assumed to be 0 */
2191         /* set addr[7:0] to 0 */
2192         sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, 0x00);
2193
2194         /* spit out the color data */
2195         for(i = 0; i < palette->count; i++) {
2196                 sc->gfbc->ramdac_wr(sc, BT485_REG_PALETTE, palette->red[i]);
2197                 sc->gfbc->ramdac_wr(sc, BT485_REG_PALETTE, palette->green[i]);
2198                 sc->gfbc->ramdac_wr(sc, BT485_REG_PALETTE, palette->blue[i]);
2199         }
2200         return(error);
2201 }
2202
2203 static int
2204 bt485_save_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2205 {
2206         struct gfb_softc *sc;
2207         int error, i;
2208
2209         error = 0;
2210         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2211
2212         /* addr[9:0] assumed to be 0 */
2213         /* set addr[7:0] to 1 */
2214         sc->gfbc->ramdac_wr(sc, BT485_REG_COC_WRADDR, 0x01);
2215
2216         /* spit out the cursor color data */
2217         for(i = 0; i < palette->count; i++) {
2218                 palette->red[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_COCDATA);
2219                 palette->green[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_COCDATA);
2220                 palette->blue[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_COCDATA);
2221         }
2222         return(error);
2223 }
2224
2225 static int
2226 bt485_load_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2227 {
2228         struct gfb_softc *sc;
2229         int error, i;
2230
2231         error = 0;
2232         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2233
2234         /* addr[9:0] assumed to be 0 */
2235         /* set addr[7:0] to 1 */
2236         sc->gfbc->ramdac_wr(sc, BT485_REG_COC_WRADDR, 0x01);
2237
2238         /* spit out the cursor color data */
2239         for(i = 0; i < palette->count; i++) {
2240                 sc->gfbc->ramdac_wr(sc, BT485_REG_COCDATA, palette->red[i]);
2241                 sc->gfbc->ramdac_wr(sc, BT485_REG_COCDATA, palette->green[i]);
2242                 sc->gfbc->ramdac_wr(sc, BT485_REG_COCDATA, palette->blue[i]);
2243         }
2244         return(error);
2245 }
2246
2247 static int
2248 bt485_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
2249 {
2250         struct gfb_softc *sc;
2251         int error, s;
2252
2253         error = 0;
2254         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2255         s = spltty();
2256         *col = (sc->gfbc->ramdac_rd(sc, BT485_REG_CURSOR_X_HIGH) & 0x0f) << 8;
2257         *col |= sc->gfbc->ramdac_rd(sc, BT485_REG_CURSOR_X_LOW) & 0xff;
2258         *col /= adp->va_info.vi_cwidth;
2259         *col -= 8;
2260         *row = (sc->gfbc->ramdac_rd(sc, BT485_REG_CURSOR_Y_HIGH) & 0x0f) << 8;
2261         *row |= sc->gfbc->ramdac_rd(sc, BT485_REG_CURSOR_Y_LOW) & 0xff;
2262         *row /= adp->va_info.vi_cheight;
2263         *row -= 4;
2264         splx(s);
2265         return(error);
2266 }
2267
2268 static int
2269 bt485_set_hw_cursor(video_adapter_t *adp, int col, int row)
2270 {
2271         struct gfb_softc *sc;
2272         int error, s;
2273
2274         error = 0;
2275
2276         /* Make sure the parameters are in range for the screen
2277            size... */
2278         if((row > adp->va_info.vi_height) || (col > adp->va_info.vi_width))
2279                 error = EINVAL;
2280         else if(((row * adp->va_info.vi_cheight) > 0x0fff) ||
2281             ((col * adp->va_info.vi_cwidth) > 0x0fff))
2282                 error = EINVAL;
2283         else if((row < 0) || (col < 0)) {
2284                 /* If either of the parameters is less than 0, then hide the
2285                    cursor... */
2286                 col = -8;
2287                 row = -4;
2288         } else {
2289                 /* Otherwise, just move the cursor as requested... */
2290                 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2291                 s = spltty();
2292                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_X_LOW,
2293                     ((col + 8) * adp->va_info.vi_cwidth) & 0xff);
2294                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_X_HIGH,
2295                     (((col + 8) * adp->va_info.vi_cwidth) >> 8) & 0x0f);
2296                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_Y_LOW,
2297                     ((row + 4) * adp->va_info.vi_cheight) & 0xff);
2298                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_Y_HIGH,
2299                     (((row + 4) * adp->va_info.vi_cheight) >> 8) & 0x0f);
2300                 splx(s);
2301         }
2302         return(error);
2303 }
2304
2305 static int
2306 bt485_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
2307     int cellsize, int blink)
2308 {
2309         struct gfb_softc *sc;
2310         int error, cell_count, count, i, j;
2311         u_int8_t regval;
2312
2313         error = 0;
2314         cellsize /= 2;
2315         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2316
2317         /*
2318            Make sure the parameters are in range for the cursor
2319            (it's a 64x64 cursor)...
2320         */
2321         if(height > 64)
2322                 error = EINVAL;
2323         else if(height <= 0) {
2324                 /* If height is less than or equal to 0, then hide the
2325                    cursor... */
2326         } else {
2327                 /* Otherwise, just resize the cursor as requested... */
2328
2329                 /* 64 pixels per cursor-row, 2 bits-per-pixel, so counts in
2330                    bytes... */
2331                 cell_count = cellsize / 8;
2332                 count = 64 / 8;
2333         
2334                  /* 
2335                   * Write the cursor image data:
2336                   *     set addr[9:8] to 0,
2337                   *     set addr[7:0] to 0,
2338                   *     spit it all out.
2339                   */
2340                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2341                     BT485_IREG_COMMAND_3);
2342                 regval = sc->gfbc->ramdac_rd(sc, BT485_REG_EXTENDED);
2343                 regval &= ~0x03;
2344                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2345                     BT485_IREG_COMMAND_3);
2346                 sc->gfbc->ramdac_wr(sc, BT485_REG_EXTENDED, regval);
2347                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, 0);
2348
2349                 /* Fill-in the desired pixels in the specified pixel-rows... */
2350                 for(i = 0; i < height; i++) {
2351                         for(j = 0; j < cell_count; j++)
2352                                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2353                                     0xff);
2354                         for(j = 0; j < count - cell_count; j++)
2355                                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2356                                     0x00);
2357                 }
2358
2359                 /* Clear the remaining pixel rows... */
2360                 for(; i < 64; i++)
2361                         for(j = 0; j < count; j++)
2362                                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2363                                     0x00);
2364
2365                 /*
2366                  * Write the cursor mask data:
2367                  *      set addr[9:8] to 2,
2368                  *      set addr[7:0] to 0,
2369                  *      spit it all out.
2370                  */
2371                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2372                     BT485_IREG_COMMAND_3);
2373                 regval = sc->gfbc->ramdac_rd(sc, BT485_REG_EXTENDED);
2374                 regval &= ~0x03; regval |= 0x02;
2375                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2376                     BT485_IREG_COMMAND_3);
2377                 sc->gfbc->ramdac_wr(sc, BT485_REG_EXTENDED, regval);
2378                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, 0);
2379
2380                 /* Fill-in the desired pixels in the specified pixel-rows... */
2381                 for(i = 0; i < height; i++) {
2382                         for(j = 0; j < cell_count; j++)
2383                                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2384                                     0xff);
2385                         for(j = 0; j < count - cell_count; j++)
2386                                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2387                                     0x00);
2388                 }
2389
2390                 /* Clear the remaining pixel rows... */
2391                 for(; i < 64; i++)
2392                         for(j = 0; j < count; j++)
2393                                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2394                                     0x00);
2395
2396                 /* set addr[9:0] back to 0 */
2397                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2398                     BT485_IREG_COMMAND_3);
2399                 regval = sc->gfbc->ramdac_rd(sc, BT485_REG_EXTENDED);
2400                 regval &= ~0x03;
2401                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2402                     BT485_IREG_COMMAND_3);
2403                 sc->gfbc->ramdac_wr(sc, BT485_REG_EXTENDED, regval);
2404         }
2405         return(error);
2406 }
2407
2408 static void
2409 ibm561_init(struct gfb_softc *sc)
2410 {
2411 }
2412
2413 static int
2414 ibm561_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
2415 {
2416         int error;
2417
2418         error = 0;
2419         return(error);
2420 }
2421
2422 static int
2423 ibm561_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
2424 {
2425         int error;
2426
2427         error = 0;
2428         return(error);
2429 }
2430
2431 static int
2432 ibm561_save_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2433 {
2434         int error;
2435
2436         error = 0;
2437         return(error);
2438 }
2439
2440 static int
2441 ibm561_load_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2442 {
2443         int error;
2444
2445         error = 0;
2446         return(error);
2447 }
2448
2449 #undef MB
2450 #undef KB