1 /* $NetBSD: hpcfb.c,v 1.51 2009/11/23 02:13:45 rmind Exp $ */
5 * Shin Takemura and PocketBSD Project. All rights reserved.
6 * Copyright (c) 2000,2001
7 * SATO Kazumi. All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the PocketBSD project
20 * and its contributors.
21 * 4. Neither the name of the project nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * jump scroll, scroll thread, multiscreen, virtual text vram
41 * and hpcfb_emulops functions
42 * written by SATO Kazumi.
45 #include <sys/cdefs.h>
46 __KERNEL_RCSID(0, "$NetBSD: hpcfb.c,v 1.51 2009/11/23 02:13:45 rmind Exp $");
49 #include "opt_hpcfb.h"
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/kernel.h>
55 #include <sys/signalvar.h>
57 #include <sys/kthread.h>
58 #include <sys/device.h>
60 #include <sys/malloc.h>
62 #include <sys/ioctl.h>
64 #include <uvm/uvm_extern.h>
68 #include <dev/wscons/wsconsio.h>
69 #include <dev/wscons/wsdisplayvar.h>
70 #include <dev/wscons/wscons_callbacks.h>
72 #include <dev/wsfont/wsfont.h>
73 #include <dev/rasops/rasops.h>
75 #include <dev/hpc/hpcfbvar.h>
76 #include <dev/hpc/hpcfbio.h>
80 #include <dev/hpc/bivideovar.h>
85 #define DPRINTF(arg) if (hpcfb_debug) printf arg
87 #define DPRINTF(arg) do {} while (/* CONSTCOND */ 0)
90 #ifndef HPCFB_MAX_COLUMN
91 #define HPCFB_MAX_COLUMN 130
92 #endif /* HPCFB_MAX_COLUMN */
94 #define HPCFB_MAX_ROW 80
95 #endif /* HPCFB_MAX_ROW */
98 * currently experimental
110 struct hpcfb_vchar col
[HPCFB_MAX_COLUMN
];
113 struct hpcfb_devconfig
{
114 struct rasops_info dc_rinfo
; /* rasops information */
116 int dc_blanked
; /* currently had video disabled */
117 struct hpcfb_softc
*dc_sc
;
120 struct hpcfb_tvrow
*dc_tvram
;
127 struct callout dc_scroll_ch
;
131 #endif /* HPCFB_JUMP */
132 volatile int dc_state
;
133 #define HPCFB_DC_CURRENT 0x80000000
134 #define HPCFB_DC_DRAWING 0x01 /* drawing raster ops */
135 #define HPCFB_DC_TDRAWING 0x02 /* drawing tvram */
136 #define HPCFB_DC_SCROLLPENDING 0x04 /* scroll is pending */
137 #define HPCFB_DC_UPDATE 0x08 /* tvram update */
138 #define HPCFB_DC_SCRDELAY 0x10 /* scroll time but delay it */
139 #define HPCFB_DC_SCRTHREAD 0x20 /* in scroll thread or callout */
140 #define HPCFB_DC_UPDATEALL 0x40 /* need to redraw all */
141 #define HPCFB_DC_ABORT 0x80 /* abort redrawing */
142 #define HPCFB_DC_SWITCHREQ 0x100 /* switch request exist */
147 #define IS_DRAWABLE(dc) \
148 (((dc)->dc_state&HPCFB_DC_CURRENT)&& \
149 (((dc)->dc_state&(HPCFB_DC_DRAWING|HPCFB_DC_SWITCHREQ)) == 0))
151 #define HPCFB_MAX_SCREEN 5
152 #define HPCFB_MAX_JUMP 5
156 struct hpcfb_devconfig
*sc_dc
; /* device configuration */
157 const struct hpcfb_accessops
*sc_accessops
;
159 void *sc_powerhook
; /* power management hook */
160 device_t sc_wsdisplay
;
161 int sc_screen_resumed
;
164 struct proc
*sc_thread
;
165 void *sc_wantedscreen
;
166 void (*sc_switchcb
)(void *, int, int);
167 void *sc_switchcbarg
;
168 struct callout sc_switch_callout
;
170 struct hpcfb_fbconf
*sc_fbconflist
;
174 * function prototypes
176 int hpcfbmatch(device_t
, cfdata_t
, void *);
177 void hpcfbattach(device_t
, device_t
, void *);
178 int hpcfbprint(void *, const char *);
180 int hpcfb_ioctl(void *, void *, u_long
, void *, int, struct lwp
*);
181 paddr_t
hpcfb_mmap(void *, void *, off_t
, int);
183 void hpcfb_refresh_screen(struct hpcfb_softc
*);
184 void hpcfb_doswitch(struct hpcfb_softc
*);
187 static void hpcfb_thread(void *);
188 #endif /* HPCFB_JUMP */
190 static int hpcfb_init(struct hpcfb_fbconf
*, struct hpcfb_devconfig
*);
191 static int hpcfb_alloc_screen(void *, const struct wsscreen_descr
*,
192 void **, int *, int *, long *);
193 static void hpcfb_free_screen(void *, void *);
194 static int hpcfb_show_screen(void *, void *, int,
195 void (*) (void *, int, int), void *);
196 static void hpcfb_pollc(void *, int);
197 static void hpcfb_cmap_reorder(struct hpcfb_fbconf
*,
198 struct hpcfb_devconfig
*);
200 static void hpcfb_power(int, void *);
201 static bool hpcfb_suspend(device_t
, pmf_qual_t
);
202 static bool hpcfb_resume(device_t
, pmf_qual_t
);
205 void hpcfb_cursor(void *, int, int, int);
206 int hpcfb_mapchar(void *, int, unsigned int *);
207 void hpcfb_putchar(void *, int, int, u_int
, long);
208 void hpcfb_copycols(void *, int, int, int, int);
209 void hpcfb_erasecols(void *, int, int, int, long);
210 void hpcfb_redraw(void *, int, int, int);
211 void hpcfb_copyrows(void *, int, int, int);
212 void hpcfb_eraserows(void *, int, int, long);
213 int hpcfb_allocattr(void *, int, int, int, long *);
214 void hpcfb_cursor_raw(void *, int, int, int);
217 void hpcfb_update(void *);
218 void hpcfb_do_scroll(void *);
219 void hpcfb_check_update(void *);
220 #endif /* HPCFB_JUMP */
222 struct wsdisplay_emulops hpcfb_emulops
= {
223 .cursor
= hpcfb_cursor
,
224 .mapchar
= hpcfb_mapchar
,
225 .putchar
= hpcfb_putchar
,
226 .copycols
= hpcfb_copycols
,
227 .erasecols
= hpcfb_erasecols
,
228 .copyrows
= hpcfb_copyrows
,
229 .eraserows
= hpcfb_eraserows
,
230 .allocattr
= hpcfb_allocattr
,
237 CFATTACH_DECL_NEW(hpcfb
, sizeof(struct hpcfb_softc
),
238 hpcfbmatch
, hpcfbattach
, NULL
, NULL
);
240 struct wsscreen_descr hpcfb_stdscreen
= {
242 .textops
= &hpcfb_emulops
, /* XXX */
243 .capabilities
= WSSCREEN_REVERSE
,
244 /* XXX: ncols/nrows will be filled in -- shouldn't, they are global */
247 const struct wsscreen_descr
*_hpcfb_scrlist
[] = {
249 /* XXX other formats, graphics screen? */
252 struct wsscreen_list hpcfb_screenlist
= {
253 .nscreens
= __arraycount(_hpcfb_scrlist
),
254 .screens
= _hpcfb_scrlist
,
257 struct wsdisplay_accessops hpcfb_accessops
= {
258 .ioctl
= hpcfb_ioctl
,
260 .alloc_screen
= hpcfb_alloc_screen
,
261 .free_screen
= hpcfb_free_screen
,
262 .show_screen
= hpcfb_show_screen
,
264 .pollc
= hpcfb_pollc
,
268 void hpcfb_tv_putchar(struct hpcfb_devconfig
*, int, int, u_int
, long);
269 void hpcfb_tv_copycols(struct hpcfb_devconfig
*, int, int, int, int);
270 void hpcfb_tv_erasecols(struct hpcfb_devconfig
*, int, int, int, long);
271 void hpcfb_tv_copyrows(struct hpcfb_devconfig
*, int, int, int);
272 void hpcfb_tv_eraserows(struct hpcfb_devconfig
*, int, int, long);
274 struct wsdisplay_emulops rasops_emul
;
276 static int hpcfbconsole
;
277 struct hpcfb_devconfig hpcfb_console_dc
;
278 struct wsscreen_descr hpcfb_console_wsscreen
;
279 struct hpcfb_tvrow hpcfb_console_tvram
[HPCFB_MAX_ROW
];
286 hpcfbmatch(device_t parent
, cfdata_t match
, void *aux
)
292 hpcfbattach(device_t parent
, device_t self
, void *aux
)
294 struct hpcfb_softc
*sc
;
295 struct hpcfb_attach_args
*ha
= aux
;
296 struct wsemuldisplaydev_attach_args wa
;
298 sc
= device_private(self
);
301 sc
->sc_accessops
= ha
->ha_accessops
;
302 sc
->sc_accessctx
= ha
->ha_accessctx
;
303 sc
->sc_nfbconf
= ha
->ha_nfbconf
;
304 sc
->sc_fbconflist
= ha
->ha_fbconflist
;
307 sc
->sc_dc
= &hpcfb_console_dc
;
308 hpcfb_console_dc
.dc_sc
= sc
;
309 printf(": %dx%d pixels, %d colors, %dx%d chars",
310 sc
->sc_dc
->dc_rinfo
.ri_width
,sc
->sc_dc
->dc_rinfo
.ri_height
,
311 (1 << sc
->sc_dc
->dc_rinfo
.ri_depth
),
312 sc
->sc_dc
->dc_rinfo
.ri_cols
,sc
->sc_dc
->dc_rinfo
.ri_rows
);
313 /* Set video chip dependent CLUT if any. */
314 if (sc
->sc_accessops
->setclut
)
315 sc
->sc_accessops
->setclut(sc
->sc_accessctx
,
316 &hpcfb_console_dc
.dc_rinfo
);
320 sc
->sc_polling
= 0; /* XXX */
321 sc
->sc_mapping
= 0; /* XXX */
322 callout_init(&sc
->sc_switch_callout
, 0);
324 wa
.console
= hpcfbconsole
;
325 wa
.scrdata
= &hpcfb_screenlist
;
326 wa
.accessops
= &hpcfb_accessops
;
327 wa
.accesscookie
= sc
;
329 sc
->sc_wsdisplay
= config_found(self
, &wa
, wsemuldisplaydevprint
);
333 * Create a kernel thread to scroll,
335 if (kthread_create(PRI_NONE
, 0, NULL
, hpcfb_thread
, sc
,
336 &sc
->sc_thread
, "%s", device_xname(sc
->sc_dev
)) != 0) {
338 * We were unable to create the HPCFB thread; bail out.
341 aprint_error_dev(sc
->sc_dev
, "unable to create thread, kernel "
342 "hpcfb scroll support disabled\n");
344 #endif /* HPCFB_JUMP */
347 * apmdev(4) uses dopowerhooks(9), apm(4) uses pmf(9), and the
348 * two apm drivers are mutually exclusive. Register power
351 sc
->sc_powerhook
= powerhook_establish(device_xname(sc
->sc_dev
),
353 if (sc
->sc_powerhook
== NULL
)
354 aprint_error_dev(self
,
355 "WARNING: unable to establish power hook\n");
357 if (!pmf_device_register(self
, hpcfb_suspend
, hpcfb_resume
))
358 aprint_error_dev(self
, "unable to establish power handler\n");
363 hpcfb_thread(void *arg
)
365 struct hpcfb_softc
*sc
= arg
;
368 * Loop forever, doing a periodic check for update events.
371 /* HPCFB_LOCK(sc); */
372 sc
->sc_dc
->dc_state
|= HPCFB_DC_SCRTHREAD
;
373 if (!sc
->sc_mapping
) /* draw only EMUL mode */
374 hpcfb_update(sc
->sc_dc
);
375 sc
->sc_dc
->dc_state
&= ~HPCFB_DC_SCRTHREAD
;
376 /* APM_UNLOCK(sc); */
377 (void) tsleep(sc
, PWAIT
, "hpcfb", (8 * hz
) / 7 / 10);
380 #endif /* HPCFB_JUMP */
382 /* Print function (for parent devices). */
384 hpcfbprint(void *aux
, const char *pnp
)
387 aprint_normal("hpcfb at %s", pnp
);
393 hpcfb_cnattach(struct hpcfb_fbconf
*fbconf
)
396 struct hpcfb_fbconf __fbconf
;
400 DPRINTF(("%s(%d): hpcfb_cnattach()\n", __FILE__
, __LINE__
));
402 if (fbconf
== NULL
) {
403 memset(&__fbconf
, 0, sizeof(struct hpcfb_fbconf
));
404 if (bivideo_getcnfb(&__fbconf
) != 0)
408 #endif /* NBIVIDEO > 0 */
409 memset(&hpcfb_console_dc
, 0, sizeof(struct hpcfb_devconfig
));
410 if (hpcfb_init(fbconf
, &hpcfb_console_dc
) != 0)
412 hpcfb_console_dc
.dc_state
|= HPCFB_DC_CURRENT
;
414 hpcfb_console_dc
.dc_tvram
= hpcfb_console_tvram
;
416 memset(hpcfb_console_tvram
, 0, sizeof(hpcfb_console_tvram
));
417 hpcfb_redraw(&hpcfb_console_dc
, 0, hpcfb_console_dc
.dc_rows
, 1);
419 hpcfb_console_wsscreen
= hpcfb_stdscreen
;
420 hpcfb_console_wsscreen
.nrows
= hpcfb_console_dc
.dc_rows
;
421 hpcfb_console_wsscreen
.ncols
= hpcfb_console_dc
.dc_cols
;
422 hpcfb_console_wsscreen
.capabilities
= hpcfb_console_dc
.dc_rinfo
.ri_caps
;
423 hpcfb_allocattr(&hpcfb_console_dc
,
424 WSCOL_WHITE
, WSCOL_BLACK
, 0, &defattr
);
425 wsdisplay_cnattach(&hpcfb_console_wsscreen
, &hpcfb_console_dc
,
433 hpcfb_init(struct hpcfb_fbconf
*fbconf
, struct hpcfb_devconfig
*dc
)
435 struct rasops_info
*ri
;
438 fbaddr
= (vaddr_t
)fbconf
->hf_baseaddr
;
439 dc
->dc_fbaddr
= (u_char
*)fbaddr
;
443 memset(ri
, 0, sizeof(struct rasops_info
));
444 ri
->ri_depth
= fbconf
->hf_pixel_width
;
445 ri
->ri_bits
= (void *)fbaddr
;
446 ri
->ri_width
= fbconf
->hf_width
;
447 ri
->ri_height
= fbconf
->hf_height
;
448 ri
->ri_stride
= fbconf
->hf_bytes_per_line
;
450 ri
->ri_flg
= RI_FORCEMONO
| RI_CURSOR
;
452 ri
->ri_flg
= RI_CURSOR
;
454 switch (ri
->ri_depth
) {
456 if (32 <= fbconf
->hf_pack_width
&&
457 (fbconf
->hf_order_flags
& HPCFB_REVORDER_BYTE
) &&
458 (fbconf
->hf_order_flags
& HPCFB_REVORDER_WORD
)) {
459 ri
->ri_flg
|= RI_BSWAP
;
463 if (fbconf
->hf_order_flags
& HPCFB_REVORDER_BYTE
) {
464 #if BYTE_ORDER == BIG_ENDIAN
465 ri
->ri_flg
|= RI_BSWAP
;
468 #if BYTE_ORDER == LITTLE_ENDIAN
469 ri
->ri_flg
|= RI_BSWAP
;
475 if (fbconf
->hf_class
== HPCFB_CLASS_RGBCOLOR
) {
476 ri
->ri_rnum
= fbconf
->hf_u
.hf_rgb
.hf_red_width
;
477 ri
->ri_rpos
= fbconf
->hf_u
.hf_rgb
.hf_red_shift
;
478 ri
->ri_gnum
= fbconf
->hf_u
.hf_rgb
.hf_green_width
;
479 ri
->ri_gpos
= fbconf
->hf_u
.hf_rgb
.hf_green_shift
;
480 ri
->ri_bnum
= fbconf
->hf_u
.hf_rgb
.hf_blue_width
;
481 ri
->ri_bpos
= fbconf
->hf_u
.hf_rgb
.hf_blue_shift
;
484 if (rasops_init(ri
, HPCFB_MAX_ROW
, HPCFB_MAX_COLUMN
)) {
485 panic("%s(%d): rasops_init() failed!", __FILE__
, __LINE__
);
488 /* over write color map of rasops */
489 hpcfb_cmap_reorder (fbconf
, dc
);
493 dc
->dc_rows
= dc
->dc_rinfo
.ri_rows
;
494 dc
->dc_cols
= dc
->dc_rinfo
.ri_cols
;
497 dc
->dc_min_row
= dc
->dc_rows
;
499 callout_init(&dc
->dc_scroll_ch
, 0);
500 #endif /* HPCFB_JUMP */
501 dc
->dc_memsize
= ri
->ri_stride
* ri
->ri_height
;
502 /* hook rasops in hpcfb_ops */
503 rasops_emul
= ri
->ri_ops
; /* struct copy */
504 ri
->ri_ops
= hpcfb_emulops
; /* struct copy */
510 hpcfb_cmap_reorder(struct hpcfb_fbconf
*fbconf
, struct hpcfb_devconfig
*dc
)
512 struct rasops_info
*ri
= &dc
->dc_rinfo
;
513 int reverse
= fbconf
->hf_access_flags
& HPCFB_ACCESS_REVERSE
;
514 int *cmap
= ri
->ri_devcmap
;
515 int i
, j
, bg
, fg
, tmp
;
518 * Set forground and background so that the screen
519 * looks black on white.
520 * Normally, black = 00 and white = ff.
521 * HPCFB_ACCESS_REVERSE means black = ff and white = 00.
523 switch (fbconf
->hf_pixel_width
) {
536 /* for gray-scale LCD, hi-contrast color map */
538 for (i
= 1; i
< 16; i
++)
545 for (i
= 0, j
= 15; i
< 8; i
++, j
--) {
556 hpcfb_ioctl(void *v
, void *vs
, u_long cmd
, void *data
, int flag
,
559 struct hpcfb_softc
*sc
= v
;
560 struct hpcfb_devconfig
*dc
= sc
->sc_dc
;
561 struct wsdisplay_fbinfo
*wdf
;
563 DPRINTF(("hpcfb_ioctl(cmd=0x%lx)\n", cmd
));
569 case WSDISPLAYIO_GTYPE
:
570 *(u_int
*)data
= WSDISPLAY_TYPE_HPCFB
;
573 case WSDISPLAYIO_GINFO
:
575 wdf
->height
= dc
->dc_rinfo
.ri_height
;
576 wdf
->width
= dc
->dc_rinfo
.ri_width
;
577 wdf
->depth
= dc
->dc_rinfo
.ri_depth
;
578 wdf
->cmsize
= 256; /* XXXX */
581 case WSDISPLAYIO_SMODE
:
582 if (*(int *)data
== WSDISPLAYIO_MODE_EMUL
){
585 if (dc
->dc_state
&HPCFB_DC_DRAWING
)
586 dc
->dc_state
&= ~HPCFB_DC_ABORT
;
587 #ifdef HPCFB_FORCE_REDRAW
588 hpcfb_refresh_screen(sc
);
590 dc
->dc_state
|= HPCFB_DC_UPDATEALL
;
594 if (!sc
->sc_mapping
) {
596 dc
->dc_state
|= HPCFB_DC_ABORT
;
600 if (sc
&& sc
->sc_accessops
->iodone
)
601 (*sc
->sc_accessops
->iodone
)(sc
->sc_accessctx
);
604 case WSDISPLAYIO_GETCMAP
:
605 case WSDISPLAYIO_PUTCMAP
:
606 case WSDISPLAYIO_SVIDEO
:
607 case WSDISPLAYIO_GVIDEO
:
608 case WSDISPLAYIO_GETPARAM
:
609 case WSDISPLAYIO_SETPARAM
:
612 case HPCFBIO_GDSPCONF
:
613 case HPCFBIO_SDSPCONF
:
616 return ((*sc
->sc_accessops
->ioctl
)(sc
->sc_accessctx
,
617 cmd
, data
, flag
, l
));
620 if (IOCGROUP(cmd
) != 't')
621 DPRINTF(("%s(%d): hpcfb_ioctl(%lx, %lx) grp=%c num=%ld\n",
623 cmd
, (u_long
)data
, (char)IOCGROUP(cmd
), cmd
&0xff));
627 return (EPASSTHROUGH
); /* Inappropriate ioctl for device */
631 hpcfb_mmap(void *v
, void *vs
, off_t offset
, int prot
)
633 struct hpcfb_softc
*sc
= v
;
635 return ((*sc
->sc_accessops
->mmap
)(sc
->sc_accessctx
, offset
, prot
));
639 hpcfb_power(int why
, void *arg
)
641 struct hpcfb_softc
*sc
= arg
;
643 if (sc
->sc_dc
== NULL
)
644 return; /* You have no screen yet. */
649 case PWR_SOFTSUSPEND
: {
650 struct wsdisplay_softc
*wsc
= device_private(sc
->sc_wsdisplay
);
652 sc
->sc_screen_resumed
= wsdisplay_getactivescreen(wsc
);
654 if (wsdisplay_switch(sc
->sc_wsdisplay
,
655 WSDISPLAY_NULLSCREEN
, 1 /* waitok */) == 0) {
656 wsscreen_switchwait(wsc
, WSDISPLAY_NULLSCREEN
);
658 sc
->sc_screen_resumed
= WSDISPLAY_NULLSCREEN
;
661 sc
->sc_dc
->dc_state
&= ~HPCFB_DC_CURRENT
;
665 sc
->sc_dc
->dc_state
|= HPCFB_DC_CURRENT
;
666 if (sc
->sc_screen_resumed
!= WSDISPLAY_NULLSCREEN
)
667 wsdisplay_switch(sc
->sc_wsdisplay
,
668 sc
->sc_screen_resumed
, 1 /* waitok */);
674 hpcfb_suspend(device_t self
, pmf_qual_t qual
)
676 struct hpcfb_softc
*sc
= device_private(self
);
678 hpcfb_power(PWR_SOFTSUSPEND
, sc
);
683 hpcfb_resume(device_t self
, pmf_qual_t qual
)
685 struct hpcfb_softc
*sc
= device_private(self
);
687 hpcfb_power(PWR_SOFTRESUME
, sc
);
692 hpcfb_refresh_screen(struct hpcfb_softc
*sc
)
694 struct hpcfb_devconfig
*dc
= sc
->sc_dc
;
697 DPRINTF(("hpcfb_refres_screen()\n"));
702 if (dc
->dc_state
&HPCFB_DC_SCROLLPENDING
) {
703 dc
->dc_state
&= ~HPCFB_DC_SCROLLPENDING
;
704 dc
->dc_state
&= ~HPCFB_DC_UPDATE
;
705 callout_stop(&dc
->dc_scroll_ch
);
707 #endif /* HPCFB_JUMP */
711 dc
->dc_state
&= ~HPCFB_DC_UPDATEALL
;
714 if (0 <= x
&& 0 <= y
)
715 hpcfb_cursor_raw(dc
, 0, y
, x
); /* disable cursor */
716 /* redraw all text */
717 hpcfb_redraw(dc
, 0, dc
->dc_rows
, 1);
718 if (0 <= x
&& 0 <= y
)
719 hpcfb_cursor_raw(dc
, 1, y
, x
); /* enable cursor */
723 hpcfb_alloc_screen(void *v
, const struct wsscreen_descr
*type
,
724 void **cookiep
, int *curxp
, int *curyp
, long *attrp
)
726 struct hpcfb_softc
*sc
= v
;
727 struct hpcfb_devconfig
*dc
;
729 DPRINTF(("%s(%d): hpcfb_alloc_screen()\n", __FILE__
, __LINE__
));
731 dc
= malloc(sizeof(struct hpcfb_devconfig
), M_DEVBUF
, M_WAITOK
|M_ZERO
);
736 if (hpcfb_init(&sc
->sc_fbconflist
[0], dc
) != 0)
738 if (sc
->sc_accessops
->font
) {
739 sc
->sc_accessops
->font(sc
->sc_accessctx
,
740 dc
->dc_rinfo
.ri_font
);
742 /* Set video chip dependent CLUT if any. */
743 if (sc
->sc_accessops
->setclut
)
744 sc
->sc_accessops
->setclut(sc
->sc_accessctx
, &dc
->dc_rinfo
);
745 printf("hpcfb: %dx%d pixels, %d colors, %dx%d chars\n",
746 dc
->dc_rinfo
.ri_width
, dc
->dc_rinfo
.ri_height
,
747 (1 << dc
->dc_rinfo
.ri_depth
),
748 dc
->dc_rinfo
.ri_cols
, dc
->dc_rinfo
.ri_rows
);
751 * XXX, wsdisplay won't reffer the information in wsscreen_descr
752 * structure until alloc_screen will be called, at least, under
753 * current implementation...
755 hpcfb_stdscreen
.nrows
= dc
->dc_rows
;
756 hpcfb_stdscreen
.ncols
= dc
->dc_cols
;
757 hpcfb_stdscreen
.capabilities
= dc
->dc_rinfo
.ri_caps
;
759 dc
->dc_fbaddr
= dc
->dc_rinfo
.ri_bits
;
760 dc
->dc_rows
= dc
->dc_rinfo
.ri_rows
;
761 dc
->dc_cols
= dc
->dc_rinfo
.ri_cols
;
762 dc
->dc_memsize
= dc
->dc_rinfo
.ri_stride
* dc
->dc_rinfo
.ri_height
;
766 dc
->dc_tvram
= malloc(sizeof(struct hpcfb_tvrow
)*dc
->dc_rows
,
767 M_DEVBUF
, M_WAITOK
|M_ZERO
);
768 if (dc
->dc_tvram
== NULL
){
776 hpcfb_allocattr(*cookiep
, WSCOL_WHITE
, WSCOL_BLACK
, 0, attrp
);
777 DPRINTF(("%s(%d): hpcfb_alloc_screen(): %p\n",
778 __FILE__
, __LINE__
, dc
));
784 hpcfb_free_screen(void *v
, void *cookie
)
786 struct hpcfb_devconfig
*dc
= cookie
;
788 DPRINTF(("%s(%d): hpcfb_free_screen(%p)\n",
789 __FILE__
, __LINE__
, cookie
));
791 if (dc
== &hpcfb_console_dc
)
792 panic("hpcfb_free_screen: console");
794 free(dc
->dc_tvram
, M_DEVBUF
);
799 hpcfb_show_screen(void *v
, void *cookie
, int waitok
,
800 void (*cb
)(void *, int, int), void *cbarg
)
802 struct hpcfb_softc
*sc
= v
;
803 struct hpcfb_devconfig
*dc
= (struct hpcfb_devconfig
*)cookie
;
804 struct hpcfb_devconfig
*odc
;
806 DPRINTF(("%s(%d): hpcfb_show_screen(%p)\n",
807 __FILE__
, __LINE__
, dc
));
811 if (dc
== NULL
|| odc
== dc
) {
812 hpcfb_refresh_screen(sc
);
817 odc
->dc_state
|= HPCFB_DC_SWITCHREQ
;
819 if ((odc
->dc_state
&HPCFB_DC_DRAWING
) != 0) {
820 odc
->dc_state
|= HPCFB_DC_ABORT
;
824 sc
->sc_wantedscreen
= cookie
;
825 sc
->sc_switchcb
= cb
;
826 sc
->sc_switchcbarg
= cbarg
;
828 callout_reset(&sc
->sc_switch_callout
, 0,
829 (void(*)(void *))hpcfb_doswitch
, sc
);
838 hpcfb_doswitch(struct hpcfb_softc
*sc
)
840 struct hpcfb_devconfig
*dc
;
841 struct hpcfb_devconfig
*odc
;
843 DPRINTF(("hpcfb_doswitch()\n"));
845 dc
= sc
->sc_wantedscreen
;
848 (*sc
->sc_switchcb
)(sc
->sc_switchcbarg
, EIO
, 0);
849 odc
->dc_state
&= ~HPCFB_DC_SWITCHREQ
;
854 odc
->dc_state
&= ~HPCFB_DC_SWITCHREQ
;
860 odc
->dc_state
|= HPCFB_DC_ABORT
;
861 #endif /* HPCFB_JUMP */
863 if (odc
->dc_curx
>= 0 && odc
->dc_cury
>= 0)
864 hpcfb_cursor_raw(odc
, 0, odc
->dc_cury
, odc
->dc_curx
);
866 /* disable old screen */
867 odc
->dc_state
&= ~HPCFB_DC_CURRENT
;
868 /* XXX, This is too dangerous.
869 odc->dc_rinfo.ri_bits = NULL;
872 /* switch screen to new one */
873 dc
->dc_state
|= HPCFB_DC_CURRENT
;
874 dc
->dc_state
&= ~HPCFB_DC_ABORT
;
875 dc
->dc_rinfo
.ri_bits
= dc
->dc_fbaddr
;
878 /* redraw screen image */
879 hpcfb_refresh_screen(sc
);
881 sc
->sc_wantedscreen
= NULL
;
883 (*sc
->sc_switchcb
)(sc
->sc_switchcbarg
, 0, 0);
886 odc
->dc_state
&= ~HPCFB_DC_SWITCHREQ
;
887 dc
->dc_state
&= ~HPCFB_DC_SWITCHREQ
;
892 hpcfb_pollc(void *v
, int on
)
894 struct hpcfb_softc
*sc
= v
;
899 if (sc
->sc_accessops
->iodone
)
900 (*sc
->sc_accessops
->iodone
)(sc
->sc_accessctx
);
902 hpcfb_refresh_screen(sc
);
903 if (sc
->sc_accessops
->iodone
)
904 (*sc
->sc_accessops
->iodone
)(sc
->sc_accessctx
);
914 hpcfb_cursor(void *cookie
, int on
, int row
, int col
)
916 struct hpcfb_devconfig
*dc
= (struct hpcfb_devconfig
*)cookie
;
926 hpcfb_cursor_raw(cookie
, on
, row
, col
);
930 hpcfb_cursor_raw(void *cookie
, int on
, int row
, int col
)
932 struct hpcfb_devconfig
*dc
= (struct hpcfb_devconfig
*)cookie
;
933 struct hpcfb_softc
*sc
= dc
->dc_sc
;
934 struct rasops_info
*ri
= &dc
->dc_rinfo
;
935 int curwidth
, curheight
;
939 if (dc
->dc_state
&HPCFB_DC_SCROLLPENDING
) {
940 dc
->dc_state
|= HPCFB_DC_UPDATE
;
943 #endif /* HPCFB_JUMP */
944 if (!IS_DRAWABLE(dc
)) {
948 if (ri
->ri_bits
== NULL
)
951 dc
->dc_state
|= HPCFB_DC_DRAWING
;
952 if (sc
&& sc
->sc_accessops
->cursor
) {
953 xoff
= col
* ri
->ri_font
->fontwidth
;
954 yoff
= row
* ri
->ri_font
->fontheight
;
955 curheight
= ri
->ri_font
->fontheight
;
956 curwidth
= ri
->ri_font
->fontwidth
;
957 (*sc
->sc_accessops
->cursor
)(sc
->sc_accessctx
,
958 on
, xoff
, yoff
, curwidth
, curheight
);
960 rasops_emul
.cursor(ri
, on
, row
, col
);
961 dc
->dc_state
&= ~HPCFB_DC_DRAWING
;
968 hpcfb_mapchar(void *cookie
, int c
, unsigned int *cp
)
970 struct hpcfb_devconfig
*dc
= (struct hpcfb_devconfig
*)cookie
;
971 struct rasops_info
*ri
= &dc
->dc_rinfo
;
973 return (rasops_emul
.mapchar(ri
, c
, cp
));
980 hpcfb_tv_putchar(struct hpcfb_devconfig
*dc
, int row
, int col
, u_int uc
,
983 struct hpcfb_tvrow
*vscn
= dc
->dc_tvram
;
984 struct hpcfb_vchar
*vc
= &vscn
[row
].col
[col
];
985 struct hpcfb_vchar
*vcb
;
990 dc
->dc_state
|= HPCFB_DC_TDRAWING
;
992 if (row
< dc
->dc_min_row
)
993 dc
->dc_min_row
= row
;
994 if (row
> dc
->dc_max_row
)
995 dc
->dc_max_row
= row
;
997 #endif /* HPCFB_JUMP */
998 if (vscn
[row
].maxcol
+1 == col
)
999 vscn
[row
].maxcol
= col
;
1000 else if (vscn
[row
].maxcol
< col
) {
1001 vcb
= &vscn
[row
].col
[vscn
[row
].maxcol
+1];
1003 sizeof(struct hpcfb_vchar
)*(col
-vscn
[row
].maxcol
-1));
1004 vscn
[row
].maxcol
= col
;
1008 dc
->dc_state
&= ~HPCFB_DC_TDRAWING
;
1010 hpcfb_check_update(dc
);
1011 #endif /* HPCFB_JUMP */
1015 hpcfb_putchar(void *cookie
, int row
, int col
, u_int uc
, long attr
)
1017 struct hpcfb_devconfig
*dc
= (struct hpcfb_devconfig
*)cookie
;
1018 struct hpcfb_softc
*sc
= dc
->dc_sc
;
1019 struct rasops_info
*ri
= &dc
->dc_rinfo
;
1023 struct wsdisplay_font
*font
;
1025 hpcfb_tv_putchar(dc
, row
, col
, uc
, attr
);
1027 if (dc
->dc_state
&HPCFB_DC_SCROLLPENDING
) {
1028 dc
->dc_state
|= HPCFB_DC_UPDATE
;
1031 #endif /* HPCFB_JUMP */
1033 if (!IS_DRAWABLE(dc
)) {
1037 if (ri
->ri_bits
== NULL
)
1040 dc
->dc_state
|= HPCFB_DC_DRAWING
;
1041 if (sc
&& sc
->sc_accessops
->putchar
1042 && (dc
->dc_state
&HPCFB_DC_CURRENT
)) {
1044 yoff
= row
* ri
->ri_font
->fontheight
;
1045 xoff
= col
* ri
->ri_font
->fontwidth
;
1046 fclr
= ri
->ri_devcmap
[((u_int
)attr
>> 24) & 15];
1047 uclr
= ri
->ri_devcmap
[((u_int
)attr
>> 16) & 15];
1049 (*sc
->sc_accessops
->putchar
)(sc
->sc_accessctx
,
1050 xoff
, yoff
, font
, fclr
, uclr
, uc
, attr
);
1052 rasops_emul
.putchar(ri
, row
, col
, uc
, attr
);
1053 dc
->dc_state
&= ~HPCFB_DC_DRAWING
;
1055 hpcfb_check_update(dc
);
1056 #endif /* HPCFB_JUMP */
1063 hpcfb_tv_copycols(struct hpcfb_devconfig
*dc
, int row
, int srccol
, int dstcol
,
1066 struct hpcfb_tvrow
*vscn
= dc
->dc_tvram
;
1067 struct hpcfb_vchar
*svc
= &vscn
[row
].col
[srccol
];
1068 struct hpcfb_vchar
*dvc
= &vscn
[row
].col
[dstcol
];
1073 dc
->dc_state
|= HPCFB_DC_TDRAWING
;
1075 if (row
< dc
->dc_min_row
)
1076 dc
->dc_min_row
= row
;
1077 if (row
> dc
->dc_max_row
)
1078 dc
->dc_max_row
= row
;
1079 #endif /* HPCFB_JUMP */
1081 memcpy(dvc
, svc
, ncols
*sizeof(struct hpcfb_vchar
));
1082 if (vscn
[row
].maxcol
< srccol
+ncols
-1)
1083 vscn
[row
].maxcol
= srccol
+ncols
-1;
1084 if (vscn
[row
].maxcol
< dstcol
+ncols
-1)
1085 vscn
[row
].maxcol
= dstcol
+ncols
-1;
1086 dc
->dc_state
&= ~HPCFB_DC_TDRAWING
;
1088 hpcfb_check_update(dc
);
1089 #endif /* HPCFB_JUMP */
1093 hpcfb_copycols(void *cookie
, int row
, int srccol
, int dstcol
, int ncols
)
1095 struct hpcfb_devconfig
*dc
= (struct hpcfb_devconfig
*)cookie
;
1096 struct hpcfb_softc
*sc
= dc
->dc_sc
;
1097 struct rasops_info
*ri
= &dc
->dc_rinfo
;
1098 int srcxoff
,dstxoff
;
1099 int srcyoff
,dstyoff
;
1102 hpcfb_tv_copycols(dc
, row
, srccol
, dstcol
, ncols
);
1104 if (dc
->dc_state
&HPCFB_DC_SCROLLPENDING
) {
1105 dc
->dc_state
|= HPCFB_DC_UPDATE
;
1108 #endif /* HPCFB_JUMP */
1109 if (!IS_DRAWABLE(dc
)) {
1113 if (ri
->ri_bits
== NULL
)
1116 dc
->dc_state
|= HPCFB_DC_DRAWING
;
1117 if (sc
&& sc
->sc_accessops
->bitblit
1118 && (dc
->dc_state
&HPCFB_DC_CURRENT
)) {
1119 srcxoff
= srccol
* ri
->ri_font
->fontwidth
;
1120 srcyoff
= row
* ri
->ri_font
->fontheight
;
1121 dstxoff
= dstcol
* ri
->ri_font
->fontwidth
;
1122 dstyoff
= row
* ri
->ri_font
->fontheight
;
1123 width
= ncols
* ri
->ri_font
->fontwidth
;
1124 height
= ri
->ri_font
->fontheight
;
1125 (*sc
->sc_accessops
->bitblit
)(sc
->sc_accessctx
,
1126 srcxoff
, srcyoff
, dstxoff
, dstyoff
, height
, width
);
1128 rasops_emul
.copycols(ri
, row
, srccol
, dstcol
, ncols
);
1129 dc
->dc_state
&= ~HPCFB_DC_DRAWING
;
1131 hpcfb_check_update(dc
);
1132 #endif /* HPCFB_JUMP */
1140 hpcfb_tv_erasecols(struct hpcfb_devconfig
*dc
,
1141 int row
, int startcol
, int ncols
, long attr
)
1143 struct hpcfb_tvrow
*vscn
= dc
->dc_tvram
;
1148 dc
->dc_state
|= HPCFB_DC_TDRAWING
;
1150 if (row
< dc
->dc_min_row
)
1151 dc
->dc_min_row
= row
;
1152 if (row
> dc
->dc_max_row
)
1153 dc
->dc_max_row
= row
;
1154 #endif /* HPCFB_JUMP */
1156 vscn
[row
].maxcol
= startcol
-1;
1157 if (vscn
[row
].spacecol
< startcol
+ncols
-1)
1158 vscn
[row
].spacecol
= startcol
+ncols
-1;
1159 dc
->dc_state
&= ~HPCFB_DC_TDRAWING
;
1161 hpcfb_check_update(dc
);
1162 #endif /* HPCFB_JUMP */
1166 hpcfb_erasecols(void *cookie
, int row
, int startcol
, int ncols
, long attr
)
1168 struct hpcfb_devconfig
*dc
= (struct hpcfb_devconfig
*)cookie
;
1169 struct hpcfb_softc
*sc
= dc
->dc_sc
;
1170 struct rasops_info
*ri
= &dc
->dc_rinfo
;
1174 hpcfb_tv_erasecols(dc
, row
, startcol
, ncols
, attr
);
1176 if (dc
->dc_state
&HPCFB_DC_SCROLLPENDING
) {
1177 dc
->dc_state
|= HPCFB_DC_UPDATE
;
1180 #endif /* HPCFB_JUMP */
1181 if (!IS_DRAWABLE(dc
)) {
1185 if (ri
->ri_bits
== NULL
)
1188 dc
->dc_state
|= HPCFB_DC_DRAWING
;
1189 if (sc
&& sc
->sc_accessops
->erase
1190 && (dc
->dc_state
&HPCFB_DC_CURRENT
)) {
1191 xoff
= startcol
* ri
->ri_font
->fontwidth
;
1192 yoff
= row
* ri
->ri_font
->fontheight
;
1193 width
= ncols
* ri
->ri_font
->fontwidth
;
1194 height
= ri
->ri_font
->fontheight
;
1195 (*sc
->sc_accessops
->erase
)(sc
->sc_accessctx
,
1196 xoff
, yoff
, height
, width
, attr
);
1198 rasops_emul
.erasecols(ri
, row
, startcol
, ncols
, attr
);
1199 dc
->dc_state
&= ~HPCFB_DC_DRAWING
;
1201 hpcfb_check_update(dc
);
1202 #endif /* HPCFB_JUMP */
1209 hpcfb_tv_copyrows(struct hpcfb_devconfig
*dc
, int src
, int dst
, int num
)
1211 struct hpcfb_tvrow
*vscn
= dc
->dc_tvram
;
1212 struct hpcfb_tvrow
*svc
= &vscn
[src
];
1213 struct hpcfb_tvrow
*dvc
= &vscn
[dst
];
1220 dc
->dc_state
|= HPCFB_DC_TDRAWING
;
1222 if (dst
< dc
->dc_min_row
)
1223 dc
->dc_min_row
= dst
;
1224 if (dst
+ num
> dc
->dc_max_row
)
1225 dc
->dc_max_row
= dst
+ num
-1;
1226 #endif /* HPCFB_JUMP */
1230 else if (svc
< dvc
) {
1235 dc
->dc_state
&= ~HPCFB_DC_TDRAWING
;
1237 hpcfb_check_update(dc
);
1238 #endif /* HPCFB_JUMP */
1242 for (i
= 0; i
< num
; i
++) {
1243 memcpy(&dvc
->col
[0], &svc
->col
[0], sizeof(struct hpcfb_vchar
)*(svc
->maxcol
+1));
1244 if (svc
->maxcol
< dvc
->maxcol
&& dvc
->spacecol
< dvc
->maxcol
)
1245 dvc
->spacecol
= dvc
->maxcol
;
1246 dvc
->maxcol
= svc
->maxcol
;
1250 dc
->dc_state
&= ~HPCFB_DC_TDRAWING
;
1252 hpcfb_check_update(dc
);
1253 #endif /* HPCFB_JUMP */
1257 hpcfb_redraw(void *cookie
, int row
, int num
, int all
)
1259 struct hpcfb_devconfig
*dc
= (struct hpcfb_devconfig
*)cookie
;
1260 struct rasops_info
*ri
= &dc
->dc_rinfo
;
1262 struct hpcfb_tvrow
*vscn
= dc
->dc_tvram
;
1263 struct hpcfb_vchar
*svc
;
1267 if (dc
->dc_state
&HPCFB_DC_SCROLLPENDING
) {
1268 dc
->dc_state
|= HPCFB_DC_UPDATE
;
1271 #endif /* HPCFB_JUMP */
1272 if (dc
->dc_sc
!= NULL
1273 && !dc
->dc_sc
->sc_polling
1274 && dc
->dc_sc
->sc_mapping
)
1277 dc
->dc_state
&= ~HPCFB_DC_ABORT
;
1282 if (!IS_DRAWABLE(dc
)) {
1286 if (ri
->ri_bits
== NULL
)
1289 dc
->dc_state
|= HPCFB_DC_DRAWING
;
1290 dc
->dc_state
|= HPCFB_DC_TDRAWING
;
1291 for (i
= 0; i
< num
; i
++) {
1292 if (dc
->dc_state
&HPCFB_DC_ABORT
)
1294 if ((dc
->dc_state
&HPCFB_DC_CURRENT
) == 0)
1296 cols
= vscn
[row
+i
].maxcol
;
1297 for (j
= 0; j
<= cols
; j
++) {
1298 if (dc
->dc_state
&HPCFB_DC_ABORT
)
1300 if ((dc
->dc_state
&HPCFB_DC_CURRENT
) == 0)
1302 svc
= &vscn
[row
+i
].col
[j
];
1303 rasops_emul
.putchar(ri
, row
+ i
, j
, svc
->c
, svc
->attr
);
1306 cols
= dc
->dc_cols
-1;
1308 cols
= vscn
[row
+i
].spacecol
;
1309 for (; j
<= cols
; j
++) {
1310 if (dc
->dc_state
&HPCFB_DC_ABORT
)
1312 if ((dc
->dc_state
&HPCFB_DC_CURRENT
) == 0)
1314 rasops_emul
.putchar(ri
, row
+ i
, j
, ' ', 0);
1316 vscn
[row
+i
].spacecol
= 0;
1318 if (dc
->dc_state
&HPCFB_DC_ABORT
)
1319 dc
->dc_state
&= ~HPCFB_DC_ABORT
;
1320 dc
->dc_state
&= ~HPCFB_DC_DRAWING
;
1321 dc
->dc_state
&= ~HPCFB_DC_TDRAWING
;
1323 hpcfb_check_update(dc
);
1324 #endif /* HPCFB_JUMP */
1329 hpcfb_update(void *v
)
1331 struct hpcfb_devconfig
*dc
= (struct hpcfb_devconfig
*)v
;
1333 /* callout_stop(&dc->dc_scroll_ch); */
1334 dc
->dc_state
&= ~HPCFB_DC_SCROLLPENDING
;
1335 if (dc
->dc_curx
> 0 && dc
->dc_cury
> 0)
1336 hpcfb_cursor_raw(dc
, 0, dc
->dc_cury
, dc
->dc_curx
);
1337 if ((dc
->dc_state
&HPCFB_DC_UPDATEALL
)) {
1338 hpcfb_redraw(dc
, 0, dc
->dc_rows
, 1);
1339 dc
->dc_state
&= ~(HPCFB_DC_UPDATE
|HPCFB_DC_UPDATEALL
);
1340 } else if ((dc
->dc_state
&HPCFB_DC_UPDATE
)) {
1341 hpcfb_redraw(dc
, dc
->dc_min_row
,
1342 dc
->dc_max_row
- dc
->dc_min_row
, 0);
1343 dc
->dc_state
&= ~HPCFB_DC_UPDATE
;
1345 hpcfb_redraw(dc
, dc
->dc_scroll_dst
, dc
->dc_scroll_num
, 0);
1347 if (dc
->dc_curx
> 0 && dc
->dc_cury
> 0)
1348 hpcfb_cursor_raw(dc
, 1, dc
->dc_cury
, dc
->dc_curx
);
1352 hpcfb_do_scroll(void *v
)
1354 struct hpcfb_devconfig
*dc
= (struct hpcfb_devconfig
*)v
;
1356 dc
->dc_state
|= HPCFB_DC_SCRTHREAD
;
1357 if (dc
->dc_state
&(HPCFB_DC_DRAWING
|HPCFB_DC_TDRAWING
))
1358 dc
->dc_state
|= HPCFB_DC_SCRDELAY
;
1359 else if (dc
->dc_sc
!= NULL
&& dc
->dc_sc
->sc_thread
)
1361 else if (dc
->dc_sc
!= NULL
&& !dc
->dc_sc
->sc_mapping
) {
1362 /* draw only EMUL mode */
1365 dc
->dc_state
&= ~HPCFB_DC_SCRTHREAD
;
1369 hpcfb_check_update(void *v
)
1371 struct hpcfb_devconfig
*dc
= (struct hpcfb_devconfig
*)v
;
1373 if (dc
->dc_sc
!= NULL
1374 && dc
->dc_sc
->sc_polling
1375 && (dc
->dc_state
&HPCFB_DC_SCROLLPENDING
)){
1376 callout_stop(&dc
->dc_scroll_ch
);
1377 dc
->dc_state
&= ~HPCFB_DC_SCRDELAY
;
1380 else if (dc
->dc_state
&HPCFB_DC_SCRDELAY
){
1381 dc
->dc_state
&= ~HPCFB_DC_SCRDELAY
;
1383 } else if (dc
->dc_state
&HPCFB_DC_UPDATEALL
){
1384 dc
->dc_state
&= ~HPCFB_DC_UPDATEALL
;
1388 #endif /* HPCFB_JUMP */
1391 hpcfb_copyrows(void *cookie
, int src
, int dst
, int num
)
1393 struct hpcfb_devconfig
*dc
= (struct hpcfb_devconfig
*)cookie
;
1394 struct rasops_info
*ri
= &dc
->dc_rinfo
;
1395 struct hpcfb_softc
*sc
= dc
->dc_sc
;
1396 int srcyoff
, dstyoff
;
1399 hpcfb_tv_copyrows(cookie
, src
, dst
, num
);
1401 if (!IS_DRAWABLE(dc
)) {
1405 if (ri
->ri_bits
== NULL
)
1408 if (sc
&& sc
->sc_accessops
->bitblit
1409 && (dc
->dc_state
&HPCFB_DC_CURRENT
)) {
1410 dc
->dc_state
|= HPCFB_DC_DRAWING
;
1411 srcyoff
= src
* ri
->ri_font
->fontheight
;
1412 dstyoff
= dst
* ri
->ri_font
->fontheight
;
1413 width
= dc
->dc_cols
* ri
->ri_font
->fontwidth
;
1414 height
= num
* ri
->ri_font
->fontheight
;
1415 (*sc
->sc_accessops
->bitblit
)(sc
->sc_accessctx
,
1416 0, srcyoff
, 0, dstyoff
, height
, width
);
1417 dc
->dc_state
&= ~HPCFB_DC_DRAWING
;
1421 if (sc
&& sc
->sc_polling
) {
1422 hpcfb_check_update(dc
);
1423 } else if ((dc
->dc_state
&HPCFB_DC_SCROLLPENDING
) == 0) {
1424 dc
->dc_state
|= HPCFB_DC_SCROLLPENDING
;
1426 dc
->dc_scroll_src
= src
;
1427 dc
->dc_scroll_dst
= dst
;
1428 dc
->dc_scroll_num
= num
;
1429 callout_reset(&dc
->dc_scroll_ch
, hz
/100, &hpcfb_do_scroll
, dc
);
1431 } else if (dc
->dc_scroll
++ < dc
->dc_rows
/HPCFB_MAX_JUMP
) {
1432 dc
->dc_state
|= HPCFB_DC_UPDATE
;
1435 dc
->dc_state
&= ~HPCFB_DC_SCROLLPENDING
;
1436 callout_stop(&dc
->dc_scroll_ch
);
1438 if (dc
->dc_state
&HPCFB_DC_UPDATE
) {
1439 dc
->dc_state
&= ~HPCFB_DC_UPDATE
;
1440 hpcfb_redraw(cookie
, dc
->dc_min_row
,
1441 dc
->dc_max_row
- dc
->dc_min_row
, 0);
1443 dc
->dc_min_row
= dc
->dc_rows
;
1444 if (dc
->dc_curx
> 0 && dc
->dc_cury
> 0)
1445 hpcfb_cursor(dc
, 1, dc
->dc_cury
, dc
->dc_curx
);
1448 #endif /* HPCFB_JUMP */
1449 hpcfb_redraw(cookie
, dst
, num
, 0);
1452 hpcfb_check_update(dc
);
1453 #endif /* HPCFB_JUMP */
1460 hpcfb_tv_eraserows(struct hpcfb_devconfig
*dc
,
1461 int row
, int nrow
, long attr
)
1463 struct hpcfb_tvrow
*vscn
= dc
->dc_tvram
;
1470 dc
->dc_state
|= HPCFB_DC_TDRAWING
;
1471 dc
->dc_state
&= ~HPCFB_DC_TDRAWING
;
1473 if (row
< dc
->dc_min_row
)
1474 dc
->dc_min_row
= row
;
1475 if (row
+ nrow
> dc
->dc_max_row
)
1476 dc
->dc_max_row
= row
+ nrow
;
1477 #endif /* HPCFB_JUMP */
1479 for (i
= 0; i
< nrow
; i
++) {
1480 cols
= vscn
[row
+i
].maxcol
;
1481 if (vscn
[row
+i
].spacecol
< cols
)
1482 vscn
[row
+i
].spacecol
= cols
;
1483 vscn
[row
+i
].maxcol
= -1;
1486 hpcfb_check_update(dc
);
1487 #endif /* HPCFB_JUMP */
1491 hpcfb_eraserows(void *cookie
, int row
, int nrow
, long attr
)
1493 struct hpcfb_devconfig
*dc
= (struct hpcfb_devconfig
*)cookie
;
1494 struct hpcfb_softc
*sc
= dc
->dc_sc
;
1495 struct rasops_info
*ri
= &dc
->dc_rinfo
;
1500 hpcfb_tv_eraserows(dc
, row
, nrow
, attr
);
1502 if (dc
->dc_state
&HPCFB_DC_SCROLLPENDING
) {
1503 dc
->dc_state
|= HPCFB_DC_UPDATE
;
1506 #endif /* HPCFB_JUMP */
1507 if (!IS_DRAWABLE(dc
)) {
1511 if (ri
->ri_bits
== NULL
)
1514 dc
->dc_state
|= HPCFB_DC_DRAWING
;
1515 if (sc
&& sc
->sc_accessops
->erase
1516 && (dc
->dc_state
&HPCFB_DC_CURRENT
)) {
1517 yoff
= row
* ri
->ri_font
->fontheight
;
1518 width
= dc
->dc_cols
* ri
->ri_font
->fontwidth
;
1519 height
= nrow
* ri
->ri_font
->fontheight
;
1520 (*sc
->sc_accessops
->erase
)(sc
->sc_accessctx
,
1521 0, yoff
, height
, width
, attr
);
1523 rasops_emul
.eraserows(ri
, row
, nrow
, attr
);
1524 dc
->dc_state
&= ~HPCFB_DC_DRAWING
;
1526 hpcfb_check_update(dc
);
1527 #endif /* HPCFB_JUMP */
1534 hpcfb_allocattr(void *cookie
, int fg
, int bg
, int flags
, long *attrp
)
1536 struct hpcfb_devconfig
*dc
= (struct hpcfb_devconfig
*)cookie
;
1537 struct rasops_info
*ri
= &dc
->dc_rinfo
;
1539 return (rasops_emul
.allocattr(ri
, fg
, bg
, flags
, attrp
));