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