vidc20config.c revision 1.5 1 /* $NetBSD: vidc20config.c,v 1.5 2001/12/15 22:21:46 bjh21 Exp $ */
2
3 /*
4 * Copyright (c) 2001 Reinoud Zandijk
5 * Copyright (c) 1996 Mark Brinicombe
6 * Copyright (c) 1996 Robert Black
7 * Copyright (c) 1994-1995 Melvyn Tang-Richardson
8 * Copyright (c) 1994-1995 RiscBSD kernel team
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the RiscBSD kernel team
22 * 4. The name of the company nor the name of the author may be used to
23 * endorse or promote products derived from this software without specific
24 * prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE RISCBSD TEAM ``AS IS'' AND ANY EXPRESS
27 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36 * THE POSSIBILITY OF SUCH DAMAGE.
37 *
38 * NetBSD kernel project
39 *
40 * vidcvideo.c
41 *
42 * This file is the lower basis of the wscons driver for VIDC based ARM machines.
43 * It features the initialisation and all VIDC writing and keeps in internal state
44 * copy.
45 * Its currenly set up as a library file and not as a device; it could be named
46 * vidcvideo0 eventually.
47 */
48
49 #include <sys/cdefs.h>
50 #include <sys/types.h>
51 #include <sys/param.h>
52 #include <arm/iomd/vidc.h>
53 #include <arm/arm32/katelib.h>
54 #include <machine/bootconfig.h>
55 #include <machine/intr.h>
56
57 #include <sys/systm.h>
58 #include <sys/device.h>
59 #include <uvm/uvm_extern.h>
60
61 #include <arm/iomd/iomdreg.h>
62 #include <arm/iomd/iomdvar.h>
63 #include <arm/iomd/vidc20config.h>
64
65 /*
66 * A structure containing ALL the information required to restore
67 * the VIDC20 to any given state. ALL vidc transactions should
68 * go through these procedures, which record the vidc's state.
69 * it may be an idea to set the permissions of the vidc base address
70 * so we get a fault, so the fault routine can record the state but
71 * I guess that's not really necessary for the time being, since we
72 * can make the kernel more secure later on. Also, it is possible
73 * to write a routine to allow 'reading' of the vidc registers.
74 */
75
76 static struct vidc_state vidc_lookup = {
77 { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
78 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
79 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
80 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
81 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
82 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
83 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
84 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0
85 },
86
87 VIDC_PALREG,
88 VIDC_BCOL,
89 VIDC_CP1 ,
90 VIDC_CP2,
91 VIDC_CP3,
92 VIDC_HCR,
93 VIDC_HSWR,
94 VIDC_HBSR,
95 VIDC_HDSR,
96 VIDC_HDER,
97 VIDC_HBER,
98 VIDC_HCSR,
99 VIDC_HIR,
100 VIDC_VCR,
101 VIDC_VSWR,
102 VIDC_VBSR,
103 VIDC_VDSR,
104 VIDC_VDER,
105 VIDC_VBER,
106 VIDC_VCSR,
107 VIDC_VCER,
108 VIDC_EREG,
109 VIDC_FSYNREG,
110 VIDC_CONREG,
111 VIDC_DCTL
112 };
113
114 struct vidc_state vidc_current[1];
115
116
117 /*
118 * XXX global display variables XXX ... should be a structure
119 */
120 static int cold_init = 0; /* flags initialisation */
121 extern videomemory_t videomemory;
122
123 static struct vidc_mode vidc_initialmode;
124 static struct vidc_mode *vidc_currentmode;
125
126 unsigned int dispstart;
127 unsigned int dispsize;
128 unsigned int dispbase;
129 unsigned int dispend;
130 unsigned int ptov;
131 unsigned int vmem_base;
132 unsigned int phys_base;
133 unsigned int transfersize;
134
135
136 /* cursor stuff */
137 char *cursor_normal;
138 char *cursor_transparent;
139 int p_cursor_normal;
140 int p_cursor_transparent;
141 int cursor_width;
142 int cursor_height;
143
144
145 /*
146 * VIDC mode definitions
147 * generated from RISC OS mode definition file by an `awk' script
148 */
149 extern struct vidc_mode vidcmodes[];
150
151
152 /*
153 * configuration printing
154 *
155 */
156
157 void
158 vidcvideo_printdetails(void)
159 {
160 printf(": refclk=%dMHz %dKB %s ", (vidc_fref / 1000000),
161 videomemory.vidm_size / 1024,
162 (videomemory.vidm_type == VIDEOMEM_TYPE_VRAM) ? "VRAM" : "DRAM");
163 }
164
165 /*
166 * Common functions to directly access VIDC registers
167 */
168 int
169 vidcvideo_write(reg, value)
170 u_int reg;
171 int value;
172 {
173 int counter;
174
175 int *current;
176 int *tab;
177
178 tab = (int *)&vidc_lookup;
179 current = (int *)vidc_current;
180
181
182 /*
183 * OK, the VIDC_PALETTE register is handled differently
184 * to the others on the VIDC, so take that into account here
185 */
186 if (reg==VIDC_PALREG) {
187 vidc_current->palreg = 0;
188 WriteWord(vidc_base, reg | value);
189 return 0;
190 }
191
192 if (reg==VIDC_PALETTE) {
193 WriteWord(vidc_base, reg | value);
194 vidc_current->palette[vidc_current->palreg] = value;
195 vidc_current->palreg++;
196 vidc_current->palreg = vidc_current->palreg & 0xff;
197 return 0;
198 }
199
200 /*
201 * Undefine SAFER if you wish to speed things up (a little)
202 * although this means the function will assume things abou
203 * the structure of vidc_state. i.e. the first 256 words are
204 * the palette array
205 */
206
207 #define SAFER
208
209 #ifdef SAFER
210 #define INITVALUE 0
211 #else
212 #define INITVALUE 256
213 #endif
214
215 for ( counter=INITVALUE; counter<= sizeof(struct vidc_state); counter++ ) {
216 if ( reg==tab[counter] ) {
217 WriteWord ( vidc_base, reg | value );
218 current[counter] = value;
219 return 0;
220 }
221 }
222 return -1;
223 }
224
225
226 void
227 vidcvideo_setpalette(vidc)
228 struct vidc_state *vidc;
229 {
230 int counter = 0;
231
232 vidcvideo_write(VIDC_PALREG, 0x00000000);
233 for (counter = 0; counter < 255; counter++)
234 vidcvideo_write(VIDC_PALETTE, vidc->palette[counter]);
235 }
236
237
238 void
239 vidcvideo_setstate(vidc)
240 struct vidc_state *vidc;
241 {
242 vidcvideo_write ( VIDC_PALREG, vidc->palreg );
243 vidcvideo_write ( VIDC_BCOL, vidc->bcol );
244 vidcvideo_write ( VIDC_CP1, vidc->cp1 );
245 vidcvideo_write ( VIDC_CP2, vidc->cp2 );
246 vidcvideo_write ( VIDC_CP3, vidc->cp3 );
247 vidcvideo_write ( VIDC_HCR, vidc->hcr );
248 vidcvideo_write ( VIDC_HSWR, vidc->hswr );
249 vidcvideo_write ( VIDC_HBSR, vidc->hbsr );
250 vidcvideo_write ( VIDC_HDSR, vidc->hdsr );
251 vidcvideo_write ( VIDC_HDER, vidc->hder );
252 vidcvideo_write ( VIDC_HBER, vidc->hber );
253 vidcvideo_write ( VIDC_HCSR, vidc->hcsr );
254 vidcvideo_write ( VIDC_HIR, vidc->hir );
255 vidcvideo_write ( VIDC_VCR, vidc->vcr );
256 vidcvideo_write ( VIDC_VSWR, vidc->vswr );
257 vidcvideo_write ( VIDC_VBSR, vidc->vbsr );
258 vidcvideo_write ( VIDC_VDSR, vidc->vdsr );
259 vidcvideo_write ( VIDC_VDER, vidc->vder );
260 vidcvideo_write ( VIDC_VBER, vidc->vber );
261 vidcvideo_write ( VIDC_VCSR, vidc->vcsr );
262 vidcvideo_write ( VIDC_VCER, vidc->vcer );
263 /*
264 * Right, dunno what to set these to yet, but let's keep RiscOS's
265 * ones for now, until the time is right to finish this code
266 */
267
268 /* vidcvideo_write ( VIDC_EREG, vidc->ereg ); */
269 /* vidcvideo_write ( VIDC_FSYNREG, vidc->fsynreg ); */
270 /* vidcvideo_write ( VIDC_CONREG, vidc->conreg ); */
271 /* vidcvideo_write ( VIDC_DCTL, vidc->dctl ); */
272
273 }
274
275
276 void
277 vidcvideo_getstate(vidc)
278 struct vidc_state *vidc;
279 {
280 *vidc = *vidc_current;
281 }
282
283
284 void
285 vidcvideo_getmode(mode)
286 struct vidc_mode *mode;
287 {
288 *mode = *vidc_currentmode;
289 }
290
291
292 void
293 vidcvideo_stdpalette()
294 {
295 WriteWord(vidc_base, VIDC_PALREG | 0x00000000);
296 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL( 0, 0, 0));
297 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 0, 0));
298 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL( 0, 255, 0));
299 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 255, 0));
300 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL( 0, 0, 255));
301 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 0, 255));
302 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL( 0, 255, 255));
303 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 255, 255));
304 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(128, 128, 128));
305 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 128, 128));
306 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(128, 255, 128));
307 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 255, 128));
308 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(128, 128, 255));
309 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 128, 255));
310 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(128, 255, 255));
311 WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 255, 255));
312 }
313
314
315 /* small inline mod function ... why here? */
316 static __inline int
317 mod(int n)
318 {
319 if (n < 0)
320 return(-n);
321 else
322 return(n);
323 }
324
325
326 static int
327 vidcvideo_coldinit(void)
328 {
329 int found;
330 int loop;
331
332 /* Blank out the cursor */
333
334 vidcvideo_write(VIDC_CP1, 0x0);
335 vidcvideo_write(VIDC_CP2, 0x0);
336 vidcvideo_write(VIDC_CP3, 0x0);
337
338 /* Try to determine the current mode */
339 vidc_initialmode.hder = bootconfig.width+1;
340 vidc_initialmode.vder = bootconfig.height+1;
341 vidc_initialmode.log2_bpp = bootconfig.log2_bpp;
342
343 dispbase = vmem_base = dispstart = videomemory.vidm_vbase;
344 phys_base = videomemory.vidm_pbase;
345
346 /* Nut - should be using videomemory.vidm_size - mark */
347 if (videomemory.vidm_type == VIDEOMEM_TYPE_DRAM) {
348 dispsize = videomemory.vidm_size;
349 transfersize = 16;
350 } else {
351 dispsize = bootconfig.vram[0].pages * NBPG;
352 transfersize = dispsize >> 10;
353 };
354
355 ptov = dispbase - phys_base;
356
357 dispend = dispstart+dispsize;
358
359 /* try to find the current mode from the bootloader in my table */
360 vidc_currentmode = &vidcmodes[0];
361 loop = 0;
362 found = 0;
363 while (vidcmodes[loop].pixel_rate != 0) {
364 if (vidcmodes[loop].hder == (bootconfig.width + 1)
365 && vidcmodes[loop].vder == (bootconfig.height + 1)
366 && vidcmodes[loop].frame_rate == bootconfig.framerate) {
367 vidc_currentmode = &vidcmodes[loop];
368 found = 1;
369 }
370 ++loop;
371 }
372
373 /* if not found choose first mode but dont be picky on the framerate */
374 if (!found) {
375 vidc_currentmode = &vidcmodes[0];
376 loop = 0;
377 found = 0;
378
379 while (vidcmodes[loop].pixel_rate != 0) {
380 if (vidcmodes[loop].hder == (bootconfig.width + 1)
381 && vidcmodes[loop].vder == (bootconfig.height + 1)) {
382 vidc_currentmode = &vidcmodes[loop];
383 found = 1;
384 }
385 ++loop;
386 }
387 }
388
389 vidc_currentmode->log2_bpp = bootconfig.log2_bpp;
390
391 dispstart = dispbase;
392 dispend = dispstart+dispsize;
393
394 IOMD_WRITE_WORD(IOMD_VIDINIT, dispstart-ptov);
395 IOMD_WRITE_WORD(IOMD_VIDSTART, dispstart-ptov);
396 IOMD_WRITE_WORD(IOMD_VIDEND, (dispend-transfersize)-ptov);
397 return 0;
398 }
399
400
401 /* simple function to abstract vidc variables ; returns virt start address of screen */
402 /* XXX asumption that video memory is mapped in twice */
403 void *vidcvideo_hwscroll(int bytes) {
404 dispstart += bytes;
405 if (dispstart >= dispbase + dispsize) dispstart -= dispsize;
406 if (dispstart < dispbase) dispstart += dispsize;
407 dispend = dispstart+dispsize;
408
409 /* return the start of the bit map of the screen (left top) */
410 return (void *) dispstart;
411 }
412
413
414 /* reset the HW scroll to be at the start for the benefit of f.e. X */
415 void *vidcvideo_hwscroll_reset(void) {
416 void *cookie = (void *) dispstart;
417
418 dispstart = dispbase;
419 dispend = dispstart + dispsize;
420 return cookie;
421 }
422
423
424 /* put HW scroll back to where it was */
425 void *vidcvideo_hwscroll_back(void *cookie) {
426 dispstart = (int) cookie;
427 dispend = dispstart + dispsize;
428 return cookie;
429 }
430
431
432 /* this function is to be called at vsync */
433 void vidcvideo_progr_scroll(void) {
434 IOMD_WRITE_WORD(IOMD_VIDINIT, dispstart-ptov);
435 IOMD_WRITE_WORD(IOMD_VIDSTART, dispstart-ptov);
436 IOMD_WRITE_WORD(IOMD_VIDEND, (dispend-transfersize)-ptov);
437 }
438
439
440 /*
441 * Select a new mode by reprogramming the VIDC chip
442 * XXX this part is known not to work for 32bpp
443 */
444
445 struct vidc_mode newmode;
446
447 static const int bpp_mask_table[] = {
448 0, /* 1bpp */
449 1, /* 2bpp */
450 2, /* 4bpp */
451 3, /* 8bpp */
452 4, /* 16bpp */
453 6 /* 32bpp */
454 };
455
456
457 void
458 vidcvideo_setmode(struct vidc_mode *mode)
459 {
460 register int acc;
461 int bpp_mask;
462 int ereg;
463 int best_r, best_v;
464 int least_error;
465 int r, v, f;
466
467 /*
468 * Find out what bit mask we need to or with the vidc20 control register
469 * in order to generate the desired number of bits per pixel.
470 * log_bpp is log base 2 of the number of bits per pixel.
471 */
472
473 bpp_mask = bpp_mask_table[mode->log2_bpp];
474
475 newmode = *mode;
476 vidc_currentmode = &newmode;
477
478 least_error = INT_MAX;
479 best_r = 0; best_v = 0;
480
481 for (v = 63; v > 0; v--) {
482 for (r = 63; r > 0; r--) {
483 f = ((v * vidc_fref) /1000) / r;
484 if (least_error >=
485 abs(f - vidc_currentmode->pixel_rate)) {
486 least_error =
487 abs(f - vidc_currentmode->pixel_rate);
488 best_r = r;
489 best_v = v;
490 }
491 }
492 }
493
494 if (best_r > 63) best_r=63;
495 if (best_v > 63) best_v=63;
496 if (best_r < 1) best_r= 1;
497 if (best_v < 1) best_v= 1;
498
499 vidcvideo_write(VIDC_FSYNREG, (best_v-1)<<8 | (best_r-1)<<0);
500
501 acc=0;
502 acc+=vidc_currentmode->hswr; vidcvideo_write(VIDC_HSWR, (acc - 8 ) & (~1));
503 acc+=vidc_currentmode->hbsr; vidcvideo_write(VIDC_HBSR, (acc - 12) & (~1));
504 acc+=vidc_currentmode->hdsr; vidcvideo_write(VIDC_HDSR, (acc - 18) & (~1));
505 acc+=vidc_currentmode->hder; vidcvideo_write(VIDC_HDER, (acc - 18) & (~1));
506 acc+=vidc_currentmode->hber; vidcvideo_write(VIDC_HBER, (acc - 12) & (~1));
507 acc+=vidc_currentmode->hcr; vidcvideo_write(VIDC_HCR, (acc - 8 ) & (~3));
508
509 acc=0;
510 acc+=vidc_currentmode->vswr; vidcvideo_write(VIDC_VSWR, (acc - 1));
511 acc+=vidc_currentmode->vbsr; vidcvideo_write(VIDC_VBSR, (acc - 1));
512 acc+=vidc_currentmode->vdsr; vidcvideo_write(VIDC_VDSR, (acc - 1));
513 acc+=vidc_currentmode->vder; vidcvideo_write(VIDC_VDER, (acc - 1));
514 acc+=vidc_currentmode->vber; vidcvideo_write(VIDC_VBER, (acc - 1));
515 acc+=vidc_currentmode->vcr; vidcvideo_write(VIDC_VCR, (acc - 1));
516
517 IOMD_WRITE_WORD(IOMD_FSIZE, vidc_currentmode->vcr
518 + vidc_currentmode->vswr
519 + vidc_currentmode->vber
520 + vidc_currentmode->vbsr - 1);
521
522 if (dispsize <= 1024*1024)
523 vidcvideo_write(VIDC_DCTL, vidc_currentmode->hder>>2 | 1<<16 | 1<<12);
524 else
525 vidcvideo_write(VIDC_DCTL, vidc_currentmode->hder>>2 | 3<<16 | 1<<12);
526
527 ereg = 1<<12;
528 if (vidc_currentmode->sync_pol & 0x01)
529 ereg |= 1<<16;
530 if (vidc_currentmode->sync_pol & 0x02)
531 ereg |= 1<<18;
532 vidcvideo_write(VIDC_EREG, ereg);
533 if (dispsize > 1024*1024) {
534 if (vidc_currentmode->hder >= 800)
535 vidcvideo_write(VIDC_CONREG, 7<<8 | bpp_mask<<5);
536 else
537 vidcvideo_write(VIDC_CONREG, 6<<8 | bpp_mask<<5);
538 } else {
539 vidcvideo_write(VIDC_CONREG, 7<<8 | bpp_mask<<5);
540 }
541 }
542
543
544 /* not used for now */
545 void
546 vidcvideo_set_display_base(base)
547 u_int base;
548 {
549 dispstart = dispstart-dispbase + base;
550 dispbase = vmem_base = base;
551 dispend = base + dispsize;
552 ptov = dispbase - phys_base;
553 }
554
555
556 /*
557 * Main initialisation routine for now
558 */
559
560 static int cursor_init = 0;
561
562 int
563 vidcvideo_init(void)
564 {
565 vidcvideo_coldinit();
566 if (cold_init && (cursor_init == 0))
567 /* vidcvideo_flash_go() */;
568
569 /* setting a mode goes wrong in 32 bpp ... 8 and 16 seem OK */
570 vidcvideo_setmode(vidc_currentmode);
571 vidcvideo_blank(0); /* display on */
572
573 vidcvideo_textpalette();
574
575 if (cold_init == 0) {
576 vidcvideo_write(VIDC_CP1, 0x0);
577 vidcvideo_write(VIDC_CP2, 0x0);
578 vidcvideo_write(VIDC_CP3, 0x0);
579 } else {
580 vidcvideo_cursor_init(CURSOR_MAX_WIDTH, CURSOR_MAX_HEIGHT);
581 };
582
583 cold_init=1;
584 return 0;
585 }
586
587
588 /* reinitialise the vidcvideo */
589 void
590 vidcvideo_reinit()
591 {
592 vidcvideo_coldinit();
593 vidcvideo_setmode(vidc_currentmode);
594 }
595
596
597 paddr_t
598 vidcvideo_mmap(vc, offset, nprot)
599 struct vconsole *vc;
600 off_t offset;
601 int nprot;
602 {
603 if ((u_int)offset >= videomemory.vidm_size)
604 return (-1);
605 return(arm_byte_to_page(((videomemory.vidm_pbase) + (offset))));
606 }
607
608
609 int
610 vidcvideo_cursor_init(int width, int height)
611 {
612 static char *cursor_data = NULL;
613 int counter;
614 int line;
615 paddr_t pa;
616
617 cursor_width = width;
618 cursor_height = height;
619
620 if (!cursor_data) {
621 /* Allocate cursor memory first time round */
622 cursor_data = (char *)uvm_km_zalloc(kernel_map, NBPG);
623 if (!cursor_data)
624 panic("Cannot allocate memory for hardware cursor\n");
625 (void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_data, &pa);
626 IOMD_WRITE_WORD(IOMD_CURSINIT, pa);
627 }
628
629 /* Blank the cursor while initialising it's sprite */
630
631 vidcvideo_write ( VIDC_CP1, 0x0 );
632 vidcvideo_write ( VIDC_CP2, 0x0 );
633 vidcvideo_write ( VIDC_CP3, 0x0 );
634
635 cursor_normal = cursor_data;
636 cursor_transparent = cursor_data + (height * width);
637
638 cursor_transparent += 32; /* ALIGN */
639 cursor_transparent = (char *)((int)cursor_transparent & (~31) );
640
641 for ( line = 0; line<height; ++ line )
642 {
643 for ( counter=0; counter<width/4;counter++ )
644 cursor_normal[line * width + counter]=0x55; /* why 0x55 ? */
645 for ( ; counter<8; counter++ )
646 cursor_normal[line * width + counter]=0;
647 }
648
649 for ( line = 0; line<height; ++ line )
650 {
651 for ( counter=0; counter<width/4;counter++ )
652 cursor_transparent[line * width + counter]=0x00;
653 for ( ; counter<8; counter++ )
654 cursor_transparent[line * width + counter]=0;
655 }
656
657
658 (void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_normal,
659 (paddr_t *)&p_cursor_normal);
660 (void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_transparent,
661 (paddr_t *)&p_cursor_transparent);
662
663 memset ( cursor_normal, 0x55, width*height ); /* white? */
664 memset ( cursor_transparent, 0x00, width*height ); /* to see the diffence */
665
666 /* Ok, now program the cursor; should be blank */
667 vidcvideo_enablecursor(0);
668
669 return 0;
670 }
671
672
673 void
674 vidcvideo_updatecursor(xcur, ycur)
675 int xcur, ycur;
676 {
677 int frontporch = vidc_currentmode->hswr + vidc_currentmode->hbsr + vidc_currentmode->hdsr;
678 int topporch = vidc_currentmode->vswr + vidc_currentmode->vbsr + vidc_currentmode->vdsr;
679
680 vidcvideo_write(VIDC_HCSR, frontporch -17 + xcur);
681 vidcvideo_write(VIDC_VCSR, topporch -2 + (ycur+1)-2 + 3 - cursor_height);
682 vidcvideo_write(VIDC_VCER, topporch -2 + (ycur+3)+2 + 3 );
683 return;
684 }
685
686
687 void
688 vidcvideo_enablecursor(on)
689 int on;
690 {
691 if (on) {
692 IOMD_WRITE_WORD(IOMD_CURSINIT,p_cursor_normal);
693 } else {
694 IOMD_WRITE_WORD(IOMD_CURSINIT,p_cursor_transparent);
695 };
696 vidcvideo_write ( VIDC_CP1, 0xffffff ); /* enable */
697
698 return;
699 }
700
701
702 int
703 vidcvideo_textpalette()
704 {
705 vidcvideo_write(VIDC_PALREG, 0x00000000);
706 vidcvideo_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0));
707 vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 0, 0));
708 vidcvideo_write(VIDC_PALETTE, VIDC_COL( 0, 255, 0));
709 vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 0));
710 vidcvideo_write(VIDC_PALETTE, VIDC_COL( 0, 0, 255));
711 vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 0, 255));
712 vidcvideo_write(VIDC_PALETTE, VIDC_COL( 0, 255, 255));
713 vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 255));
714 vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 128, 128));
715 vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 128, 128));
716 vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 255, 128));
717 vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 128));
718 vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 128, 255));
719 vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 128, 255));
720 vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 255));
721
722 return 0;
723 }
724
725 int
726 vidcvideo_blank(video_off)
727 int video_off;
728 {
729 int ereg;
730
731 ereg = 1<<12;
732 if (vidc_currentmode->sync_pol & 0x01)
733 ereg |= 1<<16;
734 if (vidc_currentmode->sync_pol & 0x02)
735 ereg |= 1<<18;
736
737 if (!video_off) {
738 vidcvideo_write(VIDC_EREG, ereg);
739 } else {
740 vidcvideo_write(VIDC_EREG, 0);
741 };
742 return 0;
743 }
744
745 /* end of vidc20config.c */
746