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