FreeBSD/Linux Kernel Cross Reference
sys/i386at/blit.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993,1991,1990,1989 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: blit.c,v $
29 * Revision 2.11 93/11/17 16:41:23 dbg
30 * Changed mmap routines to return physical address instead of
31 * physical page number.
32 * [93/05/24 dbg]
33 *
34 * Revision 2.10 93/05/15 19:31:24 mrt
35 * machparam.h -> machspl.h
36 *
37 * Revision 2.9 93/01/14 17:29:53 danner
38 * Proper spl typing.
39 * [92/12/10 17:44:52 af]
40 *
41 * Revision 2.8 91/05/14 16:19:57 mrt
42 * Correcting copyright
43 *
44 * Revision 2.7 91/03/16 14:45:38 rpd
45 * Updated for new kmem_alloc interface.
46 * [91/03/03 rpd]
47 *
48 * Revision 2.6 91/02/05 17:16:04 mrt
49 * Changed to new Mach copyright
50 * [91/02/01 17:41:44 mrt]
51 *
52 * Revision 2.5 90/12/20 16:37:26 jeffreyh
53 * Changes for __STDC__
54 * [90/12/07 jeffreyh]
55 *
56 * Revision 2.4 90/11/26 14:49:00 rvb
57 * jsb bet me to XMK34, sigh ...
58 * [90/11/26 rvb]
59 * Synched 2.5 & 3.0 at I386q (r1.8.1.5) & XMK35 (r2.4)
60 * [90/11/15 rvb]
61 *
62 * Revision 2.3 90/08/27 21:58:46 dbg
63 * Fix Intel Copyright as per B. Davies authorization.
64 * [90/08/14 dbg]
65 *
66 * Revision 1.8.1.4 90/06/07 08:05:24 rvb
67 * Fix to prevent obnoxious flickering. [kupfer]
68 *
69 * Revision 2.2 90/05/03 15:40:41 dbg
70 * Convert for pure kernel.
71 * [90/04/27 dbg]
72 *
73 * Revision 1.8.1.3 90/02/28 15:48:54 rvb
74 * Fix numerous typo's in Olivetti disclaimer.
75 * [90/02/28 rvb]
76 *
77 * Revision 1.8.1.2 90/01/08 13:32:23 rvb
78 * Add Intel copyright.
79 * Add Olivetti copyright.
80 * [90/01/08 rvb]
81 *
82 * Revision 1.8.1.1 89/10/22 11:33:45 rvb
83 * Received from Intel October 13, 1989.
84 *
85 * Revision 1.14 89/09/27 16:02:37 kupfer
86 * Add support for resetting display before reboot.
87 * [89/10/13 rvb]
88 *
89 * Revision 1.13 89/09/21 12:05:32 lance
90 * X108 checkin
91 *
92 * Revision 1.8 89/09/20 17:27:14 rvb
93 * Revision 1.12 89/07/26 22:38:08 kupfer
94 * Merge in support for user programs that want to use the 786.
95 *
96 * Revision 1.11 89/07/10 15:52:10 kupfer
97 * Fold in the branch with code to better track boot status.
98 *
99 * Revision 1.10 89/07/07 17:56:06 kupfer
100 * X79 merge, 2nd attempt.
101 *
102 * Revision 1.5 89/04/05 13:00:37 rvb
103 * Forward Declarations for gcc.
104 * [89/03/21 rvb]
105 *
106 * Revision 1.4 89/03/09 20:04:46 rpd
107 * More cleanup.
108 *
109 * Revision 1.3 89/02/26 12:40:54 gm0w
110 * Changes for cleanup.
111 *
112 */
113
114 /* **********************************************************************
115 File: blit.c
116 Description: Device Driver for Bell Tech Blit card
117
118 $ Header: $
119
120 Copyright Ing. C. Olivetti & C. S.p.A. 1988, 1989.
121 All rights reserved.
122 ********************************************************************** */
123 /*
124 Copyright 1988, 1989 by Olivetti Advanced Technology Center, Inc.,
125 Cupertino, California.
126
127 All Rights Reserved
128
129 Permission to use, copy, modify, and distribute this software and
130 its documentation for any purpose and without fee is hereby
131 granted, provided that the above copyright notice appears in all
132 copies and that both the copyright notice and this permission notice
133 appear in supporting documentation, and that the name of Olivetti
134 not be used in advertising or publicity pertaining to distribution
135 of the software without specific, written prior permission.
136
137 OLIVETTI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
138 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
139 IN NO EVENT SHALL OLIVETTI BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
140 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
141 LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
142 NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION
143 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
144 */
145
146 /*
147 Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
148
149 All Rights Reserved
150
151 Permission to use, copy, modify, and distribute this software and
152 its documentation for any purpose and without fee is hereby
153 granted, provided that the above copyright notice appears in all
154 copies and that both the copyright notice and this permission notice
155 appear in supporting documentation, and that the name of Intel
156 not be used in advertising or publicity pertaining to distribution
157 of the software without specific, written prior permission.
158
159 INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
160 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
161 IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
162 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
163 LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
164 NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
165 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
166 */
167
168 #ifdef MACH_KERNEL
169 #include <sys/types.h>
170 #include <device/errno.h>
171 #else MACH_KERNEL
172 #include <sys/types.h>
173 #include <sys/errno.h>
174 #include <sys/param.h>
175 #include <sys/dir.h>
176 #include <sys/signal.h>
177 #include <sys/user.h>
178 #endif MACH_KERNEL
179 #include <vm/vm_kern.h>
180 #include <mach/vm_param.h>
181 #include <machine/machspl.h>
182
183 #include <i386at/blitreg.h>
184 #include <i386at/blitvar.h>
185 #include <i386at/blituser.h>
186 #include <i386at/kd.h>
187 #include <i386at/kdsoft.h>
188
189 #include <blit.h>
190
191
192 /*
193 * This driver really only supports 1 card, though parts of it were
194 * written to support multiple cards. If you want to finish the job
195 * and really support multiple cards, then you'll have to:
196 *
197 * (1) make sure that driver functions pass around a pointer telling
198 * which card they're talking about.
199 *
200 * (2) coordinate things with the kd driver, so that one card is used
201 * for the console and the other is simply an additional display.
202 */
203 #define MAXBLITS 1
204
205 #if NBLIT > MAXBLITS
206 /* oh, no, you don't want to do this...; */
207
208 #else
209 #if NBLIT > 0
210
211 #define AUTOINIT 0
212
213 /*
214 * Forward Declarations
215 */
216 static tiledesc();
217 static loadall();
218
219 #if AUTOINIT
220 int blitattach(), blitprobe();
221 #endif
222
223 int blitioctl(), blitopen(), blitclose(), blitmmap();
224
225
226 static void setstatus();
227 #define CARD_RESET 0
228 #define CARD_MAPPED 1
229 #define CARD_MAYBE_PRESENT 2
230 #define CARD_PRESENT 3
231 #define BIU_INIT 4
232 #define UNUSED1 5
233 #define DP_INIT 6
234 #define UNUSED2 7
235
236
237 #if AUTOINIT
238 struct mb_device *blitinfo[NBLIT];
239
240 struct mb_driver blitdriver = {
241 blitprobe,
242 0, /* slave routine */
243 blitattach,
244 0, 0, 0, /* go, done, intr routines */
245 BLIT_MAPPED_SIZE,
246 "blit", blitinfo, /* device info */
247 0, 0, /* no controller */
248 0 /* no flags */
249 /* rest zeros */
250 };
251 #endif /* AUTOINIT */
252
253
254 /*
255 * Per-card bookkeeping information for driver.
256 *
257 * "scrstrip" and "dpctlregs" point to data areas that are passed to
258 * the Display Processor. They are allocated out of the spare
259 * graphics memory. "scrstrip" is used to describe an entire screen.
260 * "dpctlregs" contains assorted parameters for the display
261 * controller.
262 *
263 * "firstfree" is an offset into the graphics memory. Memory starting
264 * there can be allocated by users.
265 */
266
267 struct blitsoft {
268 struct blitdev *blt; /* ptr to mapped card */
269 caddr_t physaddr; /* start of mapped card */
270 boolean_t open; /* is device open? */
271 struct screen_descrip *scrstrip;
272 DPCONTROLBLK *dpctlregs;
273 int firstfree;
274 } blitsoft[NBLIT];
275
276
277 /*
278 * The following array contains the initial settings for
279 * the Display Processor Control Block Registers.
280 * The video timing signals in this array are for the
281 * Bell Technologies Blit Express running in 1664 x 1200 x 1 mode.
282 * Please treat as read-only.
283 */
284
285 DPCONTROLBLK blit_mparm = {
286 DP_DSP_ON, /* video status */
287 0x00ff, /* interrupt mask - all disabled */
288 0x0010, /* trip point */
289 0x00ff, /* frame interrupt interval */
290 0x0000, /* reserved */
291 CRTM_NONINTER | CRTM_SUPHIGH_SPEED, /* CRT controller mode */
292 41, /* horizontal synch stop */
293 57, /* horiz field start */
294 265, /* horiz field stop */
295 265, /* line length */
296 15, /* vert synch stop */
297 43, /* vert field start */
298 1243, /* vert field stop */
299 1244, /* frame length */
300 0x0000, 0x0000, /* descriptor pointer */
301 0x0000, /* reserved */
302 0x0101, /* x, y zoom factors */
303 0x0000, /* FldColor */
304 0x00ff, /* BdrColor */
305 0x0000, /* 1Bpp Pad */
306 0x0000, /* 2Bpp Pad */
307 0x0000, /* 4Bpp Pad */
308 DP_CURSOR_CROSSHAIR, /* cursor style & mode */
309 0x00A0, 0x0050, /* cursor x & y loc. */
310 /* cursor pattern */
311 0xfffe, 0xfffc, 0xc018, 0xc030, 0xc060, 0xc0c0, 0xc0c0, 0xc060,
312 0xc430, 0xce18, 0xdb0c, 0xf186, 0xe0c3, 0xc066, 0x803c, 0x0018
313 };
314
315 void blitreboot();
316
317 /***********
318 *
319 * Initialization.
320 *
321 ***********/
322
323
324 /*
325 * Probe - is the board there?
326 *
327 * in: reg = start of mapped Blit memory.
328 *
329 * out: returns size of mapped Blit memory if the board is present,
330 * 0 otherwise.
331 *
332 * effects: if the board is present, it is reset and left visible in
333 * Unix mode.
334 */
335
336 #if AUTOINIT
337 /*ARGSUSED*/
338 int
339 blitprobe(reg, unit)
340 caddr_t reg;
341 int unit;
342 {
343 struct blitdev *blt = (struct blitdev *)reg;
344
345 if (blit_present())
346 return(BLIT_MAPPED_SIZE); /* go */
347 else
348 return(0); /* no-go */
349 }
350 #endif /* AUTOINIT */
351
352
353 /*
354 * Temporary initialization routine. This will go away when we have
355 * autoconfig.
356 */
357
358 blitinit()
359 {
360 if (!blit_present())
361 return;
362
363 blit_init();
364 }
365
366
367 /*
368 * Allocate needed objects from Blit's memory.
369 */
370 blit_memory_init(bs)
371 struct blitsoft *bs;
372 {
373 struct blitdev *blt = bs->blt;
374 struct blitmem *bm = (struct blitmem *)blt->graphmem;
375 u_char *p = bm->spare;
376
377 if ((int)p % 2 == 1)
378 ++p;
379
380 bs->scrstrip = (struct screen_descrip *)p;
381 p += sizeof(struct screen_descrip);
382 if ((int)p % 2 == 1)
383 ++p;
384
385 bs->dpctlregs = (DPCONTROLBLK *)p;
386 p += sizeof(DPCONTROLBLK);
387 if ((int)p % 2 == 1)
388 ++p;
389
390 /*
391 * Note: if you use the 786 graphics processor for character
392 * processing, you should copy the font from the ROM into
393 * graphics memory and change font_start to point to it.
394 * Otherwise, the 786 will have problems accessing the font.
395 */
396
397 bs->firstfree = p - blt->graphmem;
398 }
399
400
401 /*
402 * Reset the Blit board and leave it visible.
403 */
404
405 blit_reset_board()
406 {
407 union blit_config_reg config;
408
409 config.byte = inb(BLIT_CONFIG_ADDR);
410 config.reg.reset = 1;
411 outb(BLIT_CONFIG_ADDR, config.byte);
412 config.reg.reset = 0;
413 config.reg.mode = BLIT_UNIX_MODE;
414 config.reg.invisible = BLIT_VISIBLE;
415 outb(BLIT_CONFIG_ADDR, config.byte);
416 setstatus(CARD_RESET);
417 }
418
419
420 #if AUTOINIT
421 /*
422 * Attach - finish initialization by setting up the 786.
423 */
424
425 blitattach(md)
426 struct mb_device *md;
427 {
428 struct blitdev *blt = (struct blitdev *)md->md_addr;
429
430 blit_init(xyz);
431 }
432 #endif /* AUTOINIT */
433
434
435 /*
436 * Initialize Bus Interface Unit.
437 */
438
439 init_biu(blt)
440 struct blitdev *blt;
441 {
442 WRITEREG8(blt, INTER_RELOC, 0);
443 WRITEREG8(blt, BIU_CONTROL, BIU_16BIT);
444
445 /* WRITEREG16(blt, DRAM_REFRESH, 0x003f); */
446 WRITEREG16(blt, DRAM_REFRESH, 0x0018); /* refresh rate */
447 WRITEREG16(blt, DRAM_CONTROL,
448 MEMROWS1 | FASTPG_INTERLV | HEIGHT_256K);
449 WRITEREG16(blt, DP_PRIORITY, (7 << 3) | 7); /* max pri */
450 WRITEREG16(blt, GP_PRIORITY, (1 << 3) | 1); /* almost min pri */
451 WRITEREG16(blt, EXT_PRIORITY, 5 << 3);
452
453 /* now freeze the settings */
454 WRITEREG16(blt, BIU_CONTROL, BIU_16BIT | BIU_WP1);
455
456 /* Put graphics processor into Poll state. */
457 WRITEREG16(blt, GP_OPCODE_REG, (OP_LINK|GECL));
458 }
459
460
461 /*
462 * Initialize the Display Processor.
463 * XXX - assumes only 1 card is installed, assumes monochrome display.
464 */
465
466 init_dp(bs)
467 struct blitsoft *bs;
468 {
469 struct blitdev *blt = bs->blt;
470 struct blitmem *bm = (struct blitmem *)blt->graphmem;
471
472 /*
473 * Set up strip header and tile descriptor for the whole
474 * screen. It's not clear why the C bit should be turned on,
475 * but it seems to get rid of the nasty flickering you can get
476 * by positioning an xterm window along the top of the screen.
477 */
478 bs->scrstrip->strip.lines = BLIT_MONOHEIGHT - 1;
479 bs->scrstrip->strip.linkl = 0;
480 bs->scrstrip->strip.linkh = 0;
481 bs->scrstrip->strip.tiles = DP_C_BIT | (1 - 1);
482 tiledesc(&bs->scrstrip->tile,
483 0, 0, /* x, y */
484 BLIT_MONOWIDTH, /* width of strip */
485 BLIT_MONOWIDTH, /* width of bitmap */
486 VM_TO_ADDR786(bm->fb.mono_fb, blt), /* the actual bitmap */
487 1); /* bits per pixel */
488
489 /* Copy into DP register block. */
490 *(bs->dpctlregs) = blit_mparm;
491 bs->dpctlregs->descl = DP_ADDRLOW(VM_TO_ADDR786(bs->scrstrip, blt));
492 bs->dpctlregs->desch = DP_ADDRHIGH(VM_TO_ADDR786(bs->scrstrip, blt));
493
494 /* Load the DP with the register block */
495 loadall(blt, bs->dpctlregs);
496 }
497
498
499 /*
500 * Fill in a tile descriptor.
501 */
502
503 static
504 tiledesc(tile, x, y, w, ww, adx, bpp)
505 TILEDESC *tile; /* pointer to tile descriptor */
506 int x; /* starting x in bitmap */
507 int y; /* starting y in bitmap */
508 int w; /* width of strip (in bits_) */
509 int ww; /* actual width of bitmap (bits) */
510 addr786_t adx; /* start of bitmap */
511 int bpp; /* bits per pixel */
512 {
513 u_short bm_width;
514 short rghtp;
515 short adr_left, adr_right;
516 addr786_t bmstadr;
517 u_short start_stop_bit;
518
519 bm_width = 2 * (((ww + 1) * bpp) / 16);
520 rghtp = x + w - 1;
521 adr_left = ((x * bpp) / 16) * 2;
522 adr_right = ((rghtp * bpp) / 16) * 2;
523 bmstadr = (ww * y) + adr_left + (int)adx;
524 start_stop_bit = ((((16 - 1) - ((x * bpp) % 16)) << 4) +
525 ((16 - ((rghtp + 1) * bpp) % 16) % 16) +
526 (bpp << 8));
527
528 tile->bitmapw = bm_width;
529 tile->meml = DP_ADDRLOW(bmstadr);
530 tile->memh = DP_ADDRHIGH(bmstadr);
531 tile->bppss = start_stop_bit;
532 tile->fetchcnt = adr_right - adr_left;
533 tile->flags = 0;
534 }
535
536
537 /*
538 * Cause the Display Processor to load its Control Registers from
539 * "vm_addr".
540 */
541
542 static
543 loadall(blt, vm_addr)
544 struct blitdev *blt;
545 DPCONTROLBLK *vm_addr;
546 {
547 addr786_t blit_addr = VM_TO_ADDR786(vm_addr, blt);
548 int i;
549
550 /* set up dp address */
551 WRITEREG16(blt, DP_PARM1_REG, DP_ADDRLOW(blit_addr));
552 WRITEREG16(blt, DP_PARM2_REG, DP_ADDRHIGH(blit_addr));
553
554 /* set blanking video */
555 WRITEREG16(blt, DEF_VIDEO_REG, 0);
556
557 /* load opcode to start dp */
558 WRITEREG16(blt, DP_OPCODE_REG, DP_LOADALL);
559
560 /* wait for acceptance */
561 for (i = 0; i < DP_RDYTIMEOUT; ++i)
562 if (READREG(blt, DP_OPCODE_REG) & DECL)
563 break;
564
565 if (i >= DP_RDYTIMEOUT) {
566 printf("Blit Display Processor timeout (loading registers)\n");
567 hang:
568 goto hang;
569 }
570
571 #ifdef notdef
572 /* wait for acceptance */
573 CDELAY((READREG(blt, DP_OPCODE_REG) & DECL) != 0, DP_RDYTIMEOUT);
574 if ((READREG(blt, DP_OPCODE_REG) & DECL) == 0) {
575 printf("Blit Display Processor timeout (loading registers)\n");
576 hang:
577 goto hang;
578 }
579 #endif /* notdef */
580 }
581
582
583 /*
584 * blit_present: returns YES if Blit is present. For the first call,
585 * the hardware is probed. After that, a flag is used.
586 * Sets blitsoft[0].blt and blitsoft[0].physaddr.
587 */
588
589 #define TEST_BYTE 0xa5 /* should not be all 0's or 1's */
590
591 boolean_t
592 blit_present()
593 {
594 static boolean_t present = FALSE;
595 static boolean_t initialized = FALSE;
596 struct blitdev *blt;
597 boolean_t blit_rom_ok();
598 struct blitdev *mapblit();
599 void freeblit();
600
601 /*
602 * We set "initialized" early on so that if the Blit init. code
603 * fails, kdb will still be able to use the EGA or VGA display
604 * (if present).
605 */
606 if (initialized)
607 return(present);
608 initialized = TRUE;
609
610 blit_reset_board();
611 blt = mapblit((caddr_t)BLIT_BASE_ADDR, BLIT_MAPPED_SIZE);
612 setstatus(CARD_MAPPED);
613 if (blt == NULL)
614 panic("blit: can't map display");
615 blt->graphmem[0] = TEST_BYTE;
616 present = FALSE;
617 if (blt->graphmem[0] == TEST_BYTE) {
618 setstatus(CARD_MAYBE_PRESENT);
619 present = blit_rom_ok(blt);
620 }
621 if (present) {
622 blitsoft[0].blt = blt;
623 blitsoft[0].physaddr = (caddr_t)BLIT_BASE_ADDR;
624 setstatus(CARD_PRESENT);
625 }
626 else
627 freeblit((vm_offset_t)blt, BLIT_MAPPED_SIZE);
628 return(present);
629 }
630
631 #undef TEST_BYTE
632
633
634 /*
635 * mapblit: map the card into kernel vm and return the (virtual)
636 * address.
637 */
638 struct blitdev *
639 mapblit(physaddr, length)
640 caddr_t physaddr; /* start of card */
641 int length; /* num bytes to map */
642 {
643 vm_offset_t vmaddr;
644 #ifdef MACH_KERNEL
645 vm_offset_t io_map();
646 #else MACH_KERNEL
647 vm_offset_t pmap_map_bd();
648 #endif MACH_KERNEL
649
650 if (physaddr != (caddr_t)trunc_page(physaddr))
651 panic("Blit card not on page boundary");
652
653 #ifdef MACH_KERNEL
654 vmaddr = io_map((vm_offset_t)physaddr, length);
655 if (vmaddr == 0)
656 #else MACH_KERNEL
657 if (kmem_alloc_pageable(kernel_map,
658 &vmaddr, round_page(BLIT_MAPPED_SIZE))
659 != KERN_SUCCESS)
660 #endif MACH_KERNEL
661 panic("can't alloc VM for Blit card");
662
663 (void)pmap_map_bd(vmaddr, (vm_offset_t)physaddr,
664 (vm_offset_t)physaddr+length,
665 VM_PROT_READ | VM_PROT_WRITE);
666 return((struct blitdev *)vmaddr);
667 }
668
669
670 /*
671 * freeblit: free card from memory.
672 * XXX - currently a no-op.
673 */
674 void
675 freeblit(va, length)
676 vm_offset_t va; /* virt addr start of card */
677 int length;
678 {
679 }
680
681
682 /*
683 * blit_init: initialize globals & hardware, and set cursor. Could be
684 * called twice, once as part of kd initialization and once as part of
685 * blit initialization. Should not be called before blit_present() is
686 * called.
687 */
688
689 void
690 blit_init()
691 {
692 static boolean_t initialized = FALSE;
693 struct blitmem *gmem; /* start of blit graphics memory */
694 int card;
695 void getfontinfo(), clear_blit();
696
697 if (initialized)
698 return;
699
700 for (card = 0; card < NBLIT; ++card) {
701 if (card > 0) {
702 blitsoft[card].blt = NULL;
703 blitsoft[card].physaddr = NULL;
704 }
705 blitsoft[card].open = FALSE;
706 blitsoft[card].scrstrip = NULL;
707 blitsoft[card].dpctlregs = NULL;
708 blitsoft[card].firstfree = 0;
709 }
710
711 /*
712 * blit_memory_init allocates memory used by the Display Processor,
713 * so it comes before the call to init_dp. blit_memory_init
714 * potentially copies the font from ROM into the graphics memory,
715 * so it comes after the call to getfontinfo.
716 */
717 getfontinfo(blitsoft[0].blt); /* get info & check assumptions */
718 blit_memory_init(&blitsoft[0]);
719
720 /* init 786 */
721 init_biu(blitsoft[0].blt);
722 setstatus(BIU_INIT);
723 init_dp(&blitsoft[0]);
724 setstatus(DP_INIT);
725
726 gmem = (struct blitmem *)blitsoft[0].blt->graphmem;
727 vid_start = gmem->fb.mono_fb;
728 kd_lines = 25;
729 kd_cols = 80;
730 kd_attr = KA_NORMAL;
731
732 /*
733 * Use generic bitmap routines, no 786 assist (see
734 * blit_memory_init).
735 */
736 kd_dput = bmpput;
737 kd_dmvup = bmpmvup;
738 kd_dmvdown = bmpmvdown;
739 kd_dclear = bmpclear;
740 kd_dsetcursor = bmpsetcursor;
741 kd_dreset = blitreboot;
742
743 clear_blit(blitsoft[0].blt);
744 (*kd_dsetcursor)(0);
745
746 initialized = TRUE;
747 }
748
749
750 /*
751 * blit_rom_ok: make sure we're looking at the ROM for a monochrome
752 * Blit.
753 */
754
755 boolean_t
756 blit_rom_ok(blt)
757 struct blitdev *blt;
758 {
759 short magic;
760 short bpp;
761
762 magic = READROM(blt->eprom, EP_MAGIC1);
763 if (magic != EP_MAGIC1_VAL) {
764 #ifdef notdef
765 printf("blit: magic1 bad (0x%x)\n", magic);
766 #endif
767 return(FALSE);
768 }
769 magic = READROM(blt->eprom, EP_MAGIC2);
770 if (magic != EP_MAGIC2_VAL) {
771 #ifdef notdef
772 printf("blit: magic2 bad (0x%x)\n", magic);
773 #endif
774 return(FALSE);
775 }
776 bpp = READROM(blt->eprom, EP_BPP);
777 if (bpp != 1) {
778 #ifdef notdef
779 printf("blit: not monochrome board (bpp = 0x%x)\n", bpp);
780 #endif
781 return(FALSE);
782 }
783
784 return(TRUE);
785 }
786
787
788 /*
789 * getfontinfo: get information about the font and make sure that
790 * our simplifying assumptions are valid.
791 */
792
793 void
794 getfontinfo(blt)
795 struct blitdev *blt;
796 {
797 u_char *rom = blt->eprom;
798 short fontoffset;
799 short pick_cursor_height();
800
801 fb_width = BLIT_MONOWIDTH;
802 fb_height = BLIT_MONOHEIGHT;
803 chars_in_font = READROM(rom, EP_NUMCHARS);
804 char_width = READROM(rom, EP_CHARWIDTH);
805 char_height = READROM(rom, EP_CHARHEIGHT);
806 fontoffset = READROM(rom, EP_FONTSTART);
807 xstart = READROM(rom, EP_XSTART);
808 ystart = READROM(rom, EP_YSTART);
809 char_black = BLIT_BLACK_BYTE;
810 char_white = BLIT_WHITE_BYTE;
811
812 font_start = rom + fontoffset;
813
814 /*
815 * Check byte-alignment assumption.
816 * XXX - does it do any good to panic when initializing the
817 * console driver?
818 */
819 if (char_width % 8 != 0)
820 panic("blit: char width not integral num of bytes");
821 if (xstart % 8 != 0) {
822 /* move it to a more convenient location */
823 printf("blit: console corner moved.\n");
824 xstart = 8 * (xstart/8);
825 }
826
827 cursor_height = pick_cursor_height();
828 char_byte_width = char_width / 8;
829 fb_byte_width = BLIT_MONOWIDTH / 8;
830 font_byte_width = char_byte_width * chars_in_font;
831 }
832
833
834 /*
835 * pick_cursor_height: pick a size for the cursor, based on the font
836 * size.
837 */
838
839 short
840 pick_cursor_height()
841 {
842 int scl_avail; /* scan lines available for console */
843 int scl_per_line; /* scan lines per console line */
844
845 /*
846 * scan lines avail. = total lines - top margin;
847 * no bottom margin (XXX).
848 */
849 scl_avail = BLIT_MONOHEIGHT - ystart;
850
851 scl_per_line = scl_avail / kd_lines;
852 if (scl_per_line < char_height)
853 return(1);
854 else
855 return(scl_per_line - char_height);
856 }
857
858
859 /*
860 * setstatus: Give a status indication to the user. Ideally, we'd
861 * just set the 3 user-controlled LED's. Unfortunately, that doesn't
862 * seem to work. So, we ring the bell.
863 */
864
865 static void
866 setstatus(val)
867 int val;
868 {
869 union blit_diag_reg diag;
870
871 diag.byte = inb(BLIT_DIAG_ADDR);
872 diag.reg.led0 = (val & 1) ? BLIT_LED_ON : BLIT_LED_OFF;
873 diag.reg.led1 = (val & 2) ? BLIT_LED_ON : BLIT_LED_OFF;
874 diag.reg.led2 = (val & 4) ? BLIT_LED_ON : BLIT_LED_OFF;
875 outb(BLIT_DIAG_ADDR, diag.byte);
876
877 #ifdef DEBUG
878 for (val &= 7; val > 0; val--) {
879 feep();
880 pause();
881 }
882 for (val = 0; val < 10; val++) {
883 pause();
884 }
885 #endif
886 }
887
888
889
890 /***********
891 *
892 * Other (non-initialization) routines.
893 *
894 ***********/
895
896
897 /*
898 * Open - Verify that minor device is OK and not in use, then clear
899 * the screen.
900 */
901
902 /*ARGSUSED*/
903 int
904 blitopen(dev, flag)
905 dev_t dev;
906 int flag;
907 {
908 void clear_blit();
909 int which = minor(dev);
910
911 if (!blit_present() || which >= NBLIT)
912 return(ENXIO);
913 if (blitsoft[which].open)
914 return(EBUSY);
915
916 clear_blit(blitsoft[which].blt);
917 blitsoft[which].open = TRUE;
918 return(0); /* ok */
919 }
920
921
922 /*
923 * Close - free any kernel memory structures that were allocated while
924 * the device was open (currently none).
925 */
926
927 /*ARGSUSED*/
928 blitclose(dev, flag)
929 dev_t dev;
930 int flag;
931 {
932 int which = minor(dev);
933
934 if (!blitsoft[which].open)
935 panic("blit: closing not-open device??");
936 blitsoft[which].open = FALSE;
937 }
938
939
940 /*
941 * Mmap.
942 */
943
944 /*ARGSUSED*/
945 int
946 blitmmap(dev, off, prot)
947 dev_t dev;
948 off_t off;
949 int prot;
950 {
951 if ((u_int) off >= BLIT_MAPPED_SIZE)
952 return(-1);
953
954 /* Get page frame number for the page to be mapped. */
955 return blitsoft[minor(dev)].physaddr + off;
956 }
957
958
959 /*
960 * Ioctl.
961 */
962
963 #ifdef MACH_KERNEL
964 io_return_t blit_get_stat(dev, flavor, data, count)
965 dev_t dev;
966 int flavor;
967 int *data; /* pointer to OUT array */
968 unsigned int *count; /* OUT */
969 {
970 int which = minor(dev);
971
972 switch (flavor) {
973 case BLIT_1ST_UNUSED:
974 if (*count < 1)
975 return (D_INVALID_OPERATION);
976 *data = blitsoft[which].firstfree;
977 *count = 1;
978 break;
979 default:
980 return (D_INVALID_OPERATION);
981 }
982 return (D_SUCCESS);
983 }
984 #else MACH_KERNEL
985 /*ARGSUSED*/
986 int
987 blitioctl(dev, cmd, data, flag)
988 dev_t dev;
989 int cmd;
990 caddr_t data;
991 int flag;
992 {
993 int which = minor(dev);
994 int err = 0;
995
996 switch (cmd) {
997 case BLIT_1ST_UNUSED:
998 *(int *)data = blitsoft[which].firstfree;
999 break;
1000 default:
1001 err = ENOTTY;
1002 }
1003
1004 return(err);
1005 }
1006 #endif MACH_KERNEL
1007
1008 /*
1009 * clear_blit: clear blit's screen.
1010 */
1011
1012 void
1013 clear_blit(blt)
1014 struct blitdev *blt;
1015 {
1016 (*kd_dclear)(0, kd_lines*kd_cols, KA_NORMAL);
1017 }
1018
1019 /*
1020 * Put the board into DOS mode in preparation for rebooting.
1021 */
1022
1023 void
1024 blitreboot()
1025 {
1026 union blit_config_reg config;
1027
1028 config.byte = inb(BLIT_CONFIG_ADDR);
1029 config.reg.mode = BLIT_DOS_MODE;
1030 config.reg.invisible = BLIT_VISIBLE;
1031 outb(BLIT_CONFIG_ADDR, config.byte);
1032 }
1033
1034 #endif /* NBLIT > 0 */
1035 #endif /* NBLIT > MAXBLITS */
Cache object: c79f295643930c42f83a442ff1306875
|