/* $NetBSD: vidcconsole.c,v 1.14 1997/01/28 04:20:58 mark Exp $ */ /* * Copyright (c) 1996 Mark Brinicombe * Copyright (c) 1996 Robert Black * Copyright (c) 1994-1995 Melvyn Tang-Richardson * Copyright (c) 1994-1995 RiscBSD kernel team * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the RiscBSD kernel team * 4. The name of the company nor the name of the author may be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE RISCBSD TEAM ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * * RiscBSD kernel project * * vidcconsole.c * * Console assembly functions * * Created : 17/09/94 * Last updated : 07/02/96 */ /* woo */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BCOPY bcopy #ifndef DEBUGTERM #define dprintf(x) ; #endif /* Options */ #define ACTIVITY_WARNING #define SCREENBLANKER #undef INVERSE_CONSOLE /* Internal defines only */ #define DEVLOPING #undef SELFTEST #undef SILLIES #ifdef SILLIES #define PRETTYCURSOR #endif extern int physcon_major; extern struct vconsole *vconsole_default; extern videomemory_t videomemory; extern font_struct font_terminal_14normal; extern font_struct font_terminal_14bold; extern font_struct font_terminal_14italic; #define font_normal font_terminal_14normal #define font_bold font_terminal_14bold #define font_italic font_terminal_14italic #define VIDC_ENGINE_NAME "VIDC" #define R_DATA ((struct vidc_info *)vc->r_data) #define MODE (R_DATA->mode) static int cold_init = 0; extern struct vconsole *vconsole_master; extern struct vconsole *vconsole_current; static struct vidc_mode vidc_initialmode; static struct vidc_mode *vidc_currentmode; unsigned int dispstart; unsigned int dispsize; unsigned int dispbase; unsigned int dispend; unsigned int ptov; unsigned int transfersize; unsigned int vmem_base; unsigned int phys_base; int flash; int cursor_flash; char *cursor_normal; char *cursor_transparent; int p_cursor_normal; int p_cursor_transparent; /* Local function prototypes */ static void vidcconsole_cls __P((struct vconsole *vc)); static int vidc_cursor_init __P((struct vconsole *vc)); int vidcconsole_cursorintr __P((void *arg)); int vidcconsole_flashintr __P((void *arg)); static int vidcconsole_textpalette __P((struct vconsole *vc)); static void vidcconsole_render __P((struct vconsole *vc, char c)); static void vidcconsole_mode __P((struct vconsole *vc, struct vidc_mode *mode)); int vidcconsole_flash __P((struct vconsole *vc, int flash)); int vidcconsole_cursorflash __P((struct vconsole *vc, int flash)); int vidcconsole_flash_go __P((struct vconsole *vc)); int vidcconsole_blank __P((struct vconsole *vc, int /*type*/)); void vidcconsole_putchar __P((dev_t dev, char c, struct vconsole *vc)); extern int vidcconsolemc_cls __P((unsigned char *, unsigned char *, int)); struct vconsole *vconsole_spawn_re __P((dev_t dev, struct vconsole *vc)); /* * This will be called while still in the mode that we were left * in after exiting from riscos */ static irqhandler_t cursor_ih; irqhandler_t flash_ih; #ifndef HARDCODEDMODES /* The table of modes is separately compiled */ extern struct vidc_mode vidcmodes[]; #else /* HARDCODEDMODES */ #ifdef RC7500 static struct vidc_mode vidcmodes[] = { {31500,/**/48, 84, 30, 640, 30, 0,/**/3, 28, 0, 480, 0, 9,/**/0,/**/3}, {36000,/**/72, 84, 34, 800, 34, 0,/**/2, 22, 0, 600, 0, 1,/**/0,/**/3}, }; #else /* RC7500 */ /* We have a hard compiled table of modes and a list of definable modes */ static struct vidc_mode vidcmodes[] = { {32500,/**/52, 64, 30, 640, 30, 14,/**/3, 28, 0, 480, 0, 9,/**/0,/**/3}, {65000,/**/128, 36, 60, 1024, 60 ,36,/**/6, 29, 0, 768, 0, 3,/**/0,/**/3}, }; #endif /* RC7500 */ #endif /* HARDCODEDMODES */ #ifdef RC7500 struct vfreq { u_int frqcon; int freq; }; static struct vfreq vfreq[] = { { VIDFREQ_25_18, 25175}, { VIDFREQ_25_18, 25180}, { VIDFREQ_28_32, 28320}, { VIDFREQ_31_50, 31500}, { VIDFREQ_36_00, 36000}, { VIDFREQ_40_00, 40000}, { VIDFREQ_44_90, 44900}, { VIDFREQ_50_00, 50000}, { VIDFREQ_65_00, 65000}, { VIDFREQ_72_00, 72000}, { VIDFREQ_75_00, 75000}, { VIDFREQ_77_00, 77000}, { VIDFREQ_80_00, 80000}, { VIDFREQ_94_50, 94500}, { VIDFREQ_110_0, 110000}, { VIDFREQ_120_0, 120000}, { VIDFREQ_130_0, 130000} }; #define NFREQ (sizeof (vfreq) / sizeof(struct vfreq)) u_int vfreqcon = 0; #else /* RC7500 */ struct fsyn { int r, v, f; }; static struct fsyn fsyn_pref[] = { { 6, 2, 8000 }, { 4, 2, 12000 }, { 3, 2, 16000 }, { 2, 2, 24000 }, { 41, 43, 25171 }, { 50, 59, 28320 }, { 3, 4, 32000 }, { 2, 3, 36000 }, { 31, 58, 44903 }, { 12, 35, 70000 }, { 0, 0, 00000 } }; #endif /* RC7500 */ /*#define mod(x) (((x) > 0) ? (x) : (-x))*/ static __inline int mod(int n) { if (n < 0) return(-n); else return(n); } static int vidcconsole_coldinit(vc) struct vconsole *vc; { int found; int loop; /* Blank out the cursor */ vidc_write(VIDC_CP1, 0x0); vidc_write(VIDC_CP2, 0x0); vidc_write(VIDC_CP3, 0x0); /* Try to determine the current mode */ vidc_initialmode.hder = bootconfig.width+1; vidc_initialmode.vder = bootconfig.height+1; vidc_initialmode.bitsperpixel = 1 << bootconfig.bitsperpixel; dispbase = vmem_base = dispstart = videomemory.vidm_vbase; phys_base = videomemory.vidm_pbase; /* Nut - should be using videomemory.vidm_size - mark */ if (videomemory.vidm_type == VIDEOMEM_TYPE_DRAM) { dispsize = videomemory.vidm_size; transfersize = 16; } else { dispsize = bootconfig.vram[0].pages * NBPG; transfersize = dispsize >> 10; } ptov = dispbase - phys_base; dispend = dispstart+dispsize; vidc_currentmode = &vidcmodes[0]; loop = 0; found = 0; while (vidcmodes[loop].pixel_rate != 0) { if (vidcmodes[loop].hder == (bootconfig.width + 1) && vidcmodes[loop].vder == (bootconfig.height + 1) && vidcmodes[loop].frame_rate == bootconfig.framerate) { vidc_currentmode = &vidcmodes[loop]; found = 1; } ++loop; } if (!found) { vidc_currentmode = &vidcmodes[0]; loop = 0; found = 0; while (vidcmodes[loop].pixel_rate != 0) { if (vidcmodes[loop].hder == (bootconfig.width + 1) && vidcmodes[loop].vder == (bootconfig.height + 1)) { vidc_currentmode = &vidcmodes[loop]; found = 1; } ++loop; } } /* vidc_currentmode = &vidcmodes[0]; */ vidc_currentmode->bitsperpixel = 1 << bootconfig.bitsperpixel; if (vc) R_DATA->flash = R_DATA->cursor_flash = 0; dispstart = dispbase; dispend = dispstart+dispsize; WriteWord(IOMD_VIDINIT, dispstart-ptov); WriteWord(IOMD_VIDSTART, dispstart-ptov); WriteWord(IOMD_VIDEND, (dispend-transfersize)-ptov); return 0; } struct vidc_mode newmode; static const int bpp_mask_table[] = { 0, /* 1bpp */ 1, /* 2bpp */ 2, /* 4bpp */ 3, /* 8bpp */ 4, /* 16bpp */ 6 /* 32bpp */ }; void vidcconsole_mode(vc, mode) struct vconsole *vc; struct vidc_mode *mode; { register int acc; int bpp_mask; int log_bpp; int tmp_bpp; int ereg; #ifndef RC7500 int best_r, best_v, best_match; #endif /* * Find out what bit mask we need to or with the vidc20 control register * in order to generate the desired number of bits per pixel. * log_bpp is log base 2 of the number of bits per pixel. */ tmp_bpp = mode->bitsperpixel; if (tmp_bpp < 1 || tmp_bpp > 32) tmp_bpp = 8; /* Set 8 bpp if we get asked for something silly */ for (log_bpp = 0; tmp_bpp != 1; tmp_bpp >>= 1) log_bpp++; bpp_mask = bpp_mask_table[log_bpp]; /* printf ( "res = (%d, %d) rate = %d\n", mode->hder, mode->vder, mode->pixel_rate ); */ newmode = *mode; vidc_currentmode = &newmode; #ifdef RC7500 { int i; int old, new; u_int nfreq; old = vfreq[0].freq; nfreq = vfreq[0].frqcon; for (i = 0; i < (NFREQ - 1); i++) { new = vfreq[i].freq - mode->pixel_rate; if (new < 0) new = -new; if (new < old) { nfreq = vfreq[i].frqcon; old = new; } if (new == 0) break; } nfreq |= (vfreqcon & 0xf0); vfreqcon = nfreq; } #else /* RC7500 */ /* Program the VCO Look up a preferred value before choosing one */ { int least_error = mod(fsyn_pref[0].f - vidc_currentmode->pixel_rate); int counter; best_r = fsyn_pref[0].r; best_match = fsyn_pref[0].f; best_v = fsyn_pref[0].v; /* Look up */ counter=0; while (fsyn_pref[counter].r != 0) { if (least_error > mod(fsyn_pref[counter].f - vidc_currentmode->pixel_rate)) { best_match = fsyn_pref[counter].f; least_error = mod(fsyn_pref[counter].f - vidc_currentmode->pixel_rate); best_r = fsyn_pref[counter].r; best_v = fsyn_pref[counter].v; } counter++; } if (least_error > 0) { /* Accuracy of 1000Hz */ int r, v, f; for (v = 63; v > 0; v--) for (r = 63; r > 0; r--) { f = (v * VIDC_FREF/1000) / r; if (least_error >= mod(f - vidc_currentmode->pixel_rate)) { best_match = f; least_error = mod(f - vidc_currentmode->pixel_rate); best_r = r; best_v = v; } } } if (best_r > 63) best_r=63; if (best_v > 63) best_v=63; if (best_r < 1) best_r= 1; if (best_v < 1) best_v= 1; } /* printf ( "best_v = %d best_r = %d best_f = %d\n", best_v, best_r, best_match ); */ #endif /* RC7500 */ if (vc==vconsole_current) { #ifdef RC7500 outb(FREQCON, vfreqcon); /* * Need to program the control register first. */ if (dispsize>1024*1024) { if (vidc_currentmode->hder>=800) vidc_write(VIDC_CONREG, 7<<8 | bpp_mask<<5); else vidc_write(VIDC_CONREG, 6<<8 | bpp_mask<<5); } else { vidc_write(VIDC_CONREG, 7<<8 | bpp_mask<<5); } /* * We don't use VIDC_FSYNREG. Program it low. */ vidc_write(VIDC_FSYNREG, 0x2020); #else /* RC7500 */ vidc_write(VIDC_FSYNREG, (best_v-1)<<8 | (best_r-1)<<0); #endif /* RC7500 */ acc=0; acc+=vidc_currentmode->hswr; vidc_write(VIDC_HSWR, (acc - 8 ) & (~1)); acc+=vidc_currentmode->hbsr; vidc_write(VIDC_HBSR, (acc - 12) & (~1)); acc+=vidc_currentmode->hdsr; vidc_write(VIDC_HDSR, (acc - 18) & (~1)); acc+=vidc_currentmode->hder; vidc_write(VIDC_HDER, (acc - 18) & (~1)); acc+=vidc_currentmode->hber; vidc_write(VIDC_HBER, (acc - 12) & (~1)); acc+=vidc_currentmode->hcr; vidc_write(VIDC_HCR, (acc - 8 ) & (~3)); acc=0; acc+=vidc_currentmode->vswr; vidc_write(VIDC_VSWR, (acc - 1)); acc+=vidc_currentmode->vbsr; vidc_write(VIDC_VBSR, (acc - 1)); acc+=vidc_currentmode->vdsr; vidc_write(VIDC_VDSR, (acc - 1)); acc+=vidc_currentmode->vder; vidc_write(VIDC_VDER, (acc - 1)); acc+=vidc_currentmode->vber; vidc_write(VIDC_VBER, (acc - 1)); acc+=vidc_currentmode->vcr; vidc_write(VIDC_VCR, (acc - 1)); #ifdef RC7500 vidc_write(VIDC_DCTL, vidc_currentmode->hder>>2 | 1<<16 | 1<<12); if (vidc_currentmode->hder>=800) vidc_write(VIDC_EREG, 0x41<<12); else vidc_write(VIDC_EREG, 0x51<<12); #else WriteWord(IOMD_FSIZE, vidc_currentmode->vcr + vidc_currentmode->vswr + vidc_currentmode->vber + vidc_currentmode->vbsr - 1); if (dispsize <= 1024*1024) vidc_write(VIDC_DCTL, vidc_currentmode->hder>>2 | 1<<16 | 1<<12); else vidc_write(VIDC_DCTL, vidc_currentmode->hder>>2 | 3<<16 | 1<<12); ereg = 1<<12; if (vidc_currentmode->sync_pol & 0x01) ereg |= 1<<16; if (vidc_currentmode->sync_pol & 0x02) ereg |= 1<<18; vidc_write(VIDC_EREG, ereg); if (dispsize > 1024*1024) { if (vidc_currentmode->hder >= 800) vidc_write(VIDC_CONREG, 7<<8 | bpp_mask<<5); else vidc_write(VIDC_CONREG, 6<<8 | bpp_mask<<5); } else { vidc_write(VIDC_CONREG, 7<<8 | bpp_mask<<5); } #endif } R_DATA->mode = *vidc_currentmode; R_DATA->screensize = R_DATA->XRES * R_DATA->YRES * R_DATA->BITSPERPIXEL/8; R_DATA->pixelsperbyte = 8 / R_DATA->BITSPERPIXEL; R_DATA->frontporch = MODE.hswr + MODE.hbsr + MODE.hdsr; R_DATA->topporch = MODE.vswr + MODE.vbsr + MODE.vdsr; R_DATA->bytes_per_line = R_DATA->XRES * R_DATA->font->y_spacing/R_DATA->pixelsperbyte; R_DATA->bytes_per_scroll = (vc->ycur % R_DATA->font->y_spacing) * vc->xcur / R_DATA->pixelsperbyte; R_DATA->text_width = R_DATA->XRES / R_DATA->font->x_spacing; R_DATA->text_height = R_DATA->YRES / R_DATA->font->y_spacing; vc->xchars = R_DATA->text_width; vc->ychars = R_DATA->text_height; } void physcon_display_base(base) u_int base; { dispstart = dispstart-dispbase + base; dispbase = vmem_base = base; dispend = base + dispsize; ptov = dispbase - phys_base; } static struct vidc_info masterinfo; static int cursor_init = 0; int vidcconsole_init(vc) struct vconsole *vc; { struct vidc_info *new; int loop; if (cold_init == 0) { vidcconsole_coldinit(vc); } else { if (cursor_init == 0) vidcconsole_flash_go(vc); } /* * If vc->r_data is initialised then this means that the previous * render engine on this vconsole was not freed properly. I should * not try to clear it up, since I could panic the kernel. Instead * I forget about its memory, which could cause a memory leak, but * this would be easily detectable and fixable */ #ifdef SELFTEST if (vc->r_data != 0) { printf( "*********************************************************\n" ); printf( "You have configured SELFTEST mode in the console driver\n" ); printf( "vc->rdata non zero. This could mean a new console\n" ); printf( "render engine has not freed up its data structure when\n" ); printf( "exiting.\n" ); printf( "DO NOT COMPILE NON DEVELOPMENT KERNELS WITH SELFTEST\n" ); printf( "*********************************************************" ); } #endif if (vc == vconsole_master) { vc->r_data = (char *)&masterinfo; } else { MALLOC((vc->r_data), char *, sizeof(struct vidc_info), M_DEVBUF, M_NOWAIT); } if (vc->r_data==0) panic("render engine initialisation failed. CLEAN THIS UP!"); R_DATA->normalfont = &font_normal; R_DATA->italicfont = &font_italic; R_DATA->boldfont = &font_bold; R_DATA->font = R_DATA->normalfont; vidcconsole_mode(vc, vidc_currentmode); R_DATA->scrollback_end = dispstart; new = (struct vidc_info *)vc->r_data; R_DATA->text_colours = 1 << R_DATA->BITSPERPIXEL; if (R_DATA->text_colours > 8) R_DATA->text_colours = 8; #ifdef INVERSE_CONSOLE R_DATA->n_backcolour = R_DATA->text_colours - 1; R_DATA->n_forecolour = 0; #else R_DATA->n_backcolour = 0; R_DATA->n_forecolour = R_DATA->text_colours - 1; #endif R_DATA->backcolour = R_DATA->n_backcolour; R_DATA->forecolour = R_DATA->n_forecolour; R_DATA->forefillcolour = 0; R_DATA->backfillcolour = 0; R_DATA->bold = 0; R_DATA->reverse = 0; for (loop = 0; loop < R_DATA->pixelsperbyte; ++loop) { R_DATA->forefillcolour |= (R_DATA->forecolour << loop * R_DATA->BITSPERPIXEL); R_DATA->backfillcolour |= (R_DATA->backcolour << loop * R_DATA->BITSPERPIXEL); } R_DATA->fast_render = R_DATA->forecolour | (R_DATA->backcolour<<8) | (R_DATA->font->pixel_height<<16); R_DATA->blanked=0; vc->BLANK(vc, BLANK_NONE); if (vc == vconsole_current) vidcconsole_textpalette(vc); if (cold_init == 0) { vidc_write(VIDC_CP1, 0x0); vidc_write(VIDC_CP2, 0x0); vidc_write(VIDC_CP3, 0x0); } else vidc_cursor_init(vc) ; cold_init=1; return 0; } void vidcconsole_reinit() { vidcconsole_coldinit(vconsole_current); vidcconsole_mode(vconsole_current, vidc_currentmode); } void vidcconsole_putchar(dev, c, vc) dev_t dev; char c; struct vconsole *vc; { vc->PUTSTRING(&c, 1, vc); } int vidcconsole_spawn(vc) struct vconsole *vc; { vc->xchars = R_DATA->text_width; vc->ychars = R_DATA->text_height; vc->xcur = 0; vc->ycur = 0; vc->flags = 0; return 0; } int vidcconsole_redraw(vc, x, y, a, b) struct vconsole *vc; int x, y; int a, b; { int xs, ys; struct vidc_state vidc; font_struct *p_font = R_DATA->font; int p_forecol = R_DATA->forecolour; int p_backcol = R_DATA->backcolour; if (x<0) x=0; if (y<0) y=0; if (x>(vc->xchars-1)) x=vc->xchars-1; if (y>(vc->ychars-1)) x=vc->ychars-1; if (a>(vc->xchars-1)) a=vc->xchars-1; if (b>(vc->ychars-1)) b=vc->ychars-1; if (axcur; ys=vc->ycur; vc->xcur = 0; vc->ycur = 0; if ((vc->flags&LOSSY) == 0) { register int c; /* This has *GOT* to be turboed */ for ( vc->ycur=y; vc->ycur<=b; vc->ycur++ ) { for ( vc->xcur=x; vc->xcur<=a; vc->xcur++ ) { c = (vc->charmap)[vc->xcur+vc->ycur*vc->xchars]; if ((c&BOLD)!=0) R_DATA->font = R_DATA->boldfont; else R_DATA->font = R_DATA->normalfont; R_DATA->fast_render = ((c>>8)&0x7)|(((c>>11)&0x7)<<8)| (R_DATA->font->pixel_height<<16); if ( c & BLINKING ) c+=1<<8 | 1; if ((c&BLINKING)!=0) { R_DATA->forecolour+=16; R_DATA->backcolour+=16; } vidcconsole_render( vc, c&0xff ); } } } vc->xcur = xs; vc->ycur = ys; R_DATA->forecolour = p_forecol; R_DATA->backcolour = p_backcol; R_DATA->font = p_font; return 0; } int vidcconsole_swapin(vc) struct vconsole *vc; { register int counter; int xs, ys; struct vidc_state vidc; font_struct *p_font = R_DATA->font; int p_forecol = R_DATA->forecolour; int p_backcol = R_DATA->backcolour; #ifdef ACTIVITY_WARNING vconsole_pending = 0; #endif vidc_write ( VIDC_CP1, 0x0 ); vidc = *vidc_current; vidc_write ( VIDC_PALREG, 0x00000000 ); for ( counter=0; counter<255; counter++ ) vidc_write ( VIDC_PALETTE, 0x00000000 ); xs=vc->xcur; ys=vc->ycur; /*TODO This needs to be vidc_restore (something) */ vidcconsole_mode ( vc, &MODE ); vc->xcur = 0; vc->ycur = 0; if ( (vc->flags&LOSSY) == 0 ) { register int c; /* This has *GOT* to be turboed */ for ( vc->ycur=0; vc->ycurychars; vc->ycur++ ) { for ( vc->xcur=0; vc->xcurxchars; vc->xcur++ ) { c = (vc->charmap)[vc->xcur+vc->ycur*vc->xchars]; if ((c&BOLD)!=0) R_DATA->font = R_DATA->boldfont; else R_DATA->font = R_DATA->normalfont; /* R_DATA->forecolour = ((c>>8)&0x7); R_DATA->backcolour = ((c>>11)&0x7); */ R_DATA->fast_render = ((c>>8)&0x7)|(((c>>11)&0x7)<<8)| (R_DATA->font->pixel_height<<16); if ( c & BLINKING ) c+=1<<8 | 1; if ((c&BLINKING)!=0) { R_DATA->forecolour+=16; R_DATA->backcolour+=16; } vidcconsole_render( vc, c&0xff ); } } } else { vc->CLS ( vc ); } if ( vc->vtty==1 ) { vc->xcur = xs; vc->ycur = ys; vidcconsole_textpalette ( vc ); vidc_write ( VIDC_CP1, 0xffffff ); R_DATA->forecolour = p_forecol; R_DATA->backcolour = p_backcol; R_DATA->font = p_font; } /* Make the cursor blank */ WriteWord(IOMD_CURSINIT,p_cursor_transparent); return 0; } int vidcconsole_mmap(vc, offset, nprot) struct vconsole *vc; int offset; int nprot; { if (offset > videomemory.vidm_size) return (-1); return(arm_byte_to_page(((videomemory.vidm_pbase) + (offset)))); } extern void vidcconsolemc_render __P(( unsigned char *addr, unsigned char *fontaddr, int fast_render, int xres )); void vidcconsole_render(vc, c) struct vconsole *vc; char c; { register unsigned char *fontaddr; register unsigned char *addr; /* Calculate the font's address */ fontaddr = R_DATA->font->data + ((c-(0x20)) * R_DATA->font->height * R_DATA->font->width); addr = (unsigned char *)dispstart + (vc->xcur * R_DATA->font->x_spacing) + (vc->ycur * R_DATA->bytes_per_line); vidcconsolemc_render ( addr, fontaddr, R_DATA->fast_render, R_DATA->XRES ); } /* * Uugh. vidc graphics dont support scrolling regions so we have to emulate * it here. This would normally require much software scrolling which is * horriblly slow, so I'm going to try and do a composite scroll, which * causes problems for scrollback but it's less speed critical */ void vidcconsole_scrollup(vc, low, high) struct vconsole *vc; int low; int high; { unsigned char *start, *end; if ( ( low==0 ) && ( high==vc->ychars-1 )) { /* All hardware scroll */ dispstart+=R_DATA->bytes_per_line; if ( dispstart >= dispend ) dispstart -= dispsize; high=high+1; /* Big hack */ WriteWord(IOMD_VIDINIT, dispstart - ptov ); } else { char *oldstart=(char *)dispstart; /* Composite scroll */ if ( (high-low) > (vc->ychars>>1) ) { /* Scroll region greater than half the screen */ dispstart+=R_DATA->bytes_per_line; if ( dispstart >= dispend ) dispstart -= dispsize; WriteWord(IOMD_VIDINIT, dispstart - ptov ); if ( low!=0 ) { start = (unsigned char *)oldstart; end=(unsigned char*)oldstart+((low+1) * R_DATA->bytes_per_line); BCOPY ( start, start+R_DATA->bytes_per_line, end-start-R_DATA->bytes_per_line); } if ( high!=(vc->ychars-1) ) { start =(unsigned char *)dispstart+(high)*R_DATA->bytes_per_line; end=(unsigned char*)dispstart+((vc->ychars)*R_DATA->bytes_per_line); BCOPY ( start, start+R_DATA->bytes_per_line, end-start-R_DATA->bytes_per_line); } high++; } else { /* Scroll region less than half the screen */ /* NO COMPOSITE SCROLL YET */ high++; if (low<0) low=0; if (high>(vc->ychars)) high=vc->ychars; if (low>high) return; /* yuck */ start = (unsigned char *)dispstart + ((low)*R_DATA->bytes_per_line); end = (unsigned char *)dispstart + ((high)*R_DATA->bytes_per_line); BCOPY ( start+R_DATA->bytes_per_line, start, (end-start)-R_DATA->bytes_per_line ); R_DATA->scrollback_end = dispstart; } } memset ( (char *) dispstart + ((high-1)*R_DATA->bytes_per_line) , R_DATA->backfillcolour, R_DATA->bytes_per_line ); } void vidcconsole_scrolldown(vc, low, high) struct vconsole *vc; int low; int high; { unsigned char *start; unsigned char *end; if ( low<0 ) low = 0; if ( high>(vc->ychars-1) ) high=vc->ychars-1; if ( ( low==0 ) && ( high==vc->ychars-1 )) { dispstart-=R_DATA->bytes_per_line; if ( dispstart < dispbase ) dispstart += dispsize; WriteWord(IOMD_VIDINIT, dispstart - ptov ); } else { if ( ((high-low) > (vc->ychars>>1)) ) { high--; if (high!=(vc->ychars-1)) { start =(unsigned char*)dispstart+((high+1)*R_DATA->bytes_per_line); end=(unsigned char*)dispstart+((vc->ychars)*R_DATA->bytes_per_line); BCOPY ( start+R_DATA->bytes_per_line, start, (end-start)-R_DATA->bytes_per_line ); } dispstart-=R_DATA->bytes_per_line; if ( dispstart < dispbase ) dispstart += dispsize; WriteWord(IOMD_VIDINIT, dispstart - ptov ); start = (unsigned char *)dispstart + (low * R_DATA->bytes_per_line); if (low!=0) { end = (unsigned char *)dispstart + ((low+1)*R_DATA->bytes_per_line); BCOPY ( (char*)(dispstart+R_DATA->bytes_per_line), (char *)dispstart, (int)((end-dispstart)-R_DATA->bytes_per_line )); } } else { start = (unsigned char *)dispstart + (low * R_DATA->bytes_per_line); end = (unsigned char *)dispstart + ((high+1) * R_DATA->bytes_per_line); BCOPY ( start, start+R_DATA->bytes_per_line, end-start-R_DATA->bytes_per_line); } } memset ((char*) dispstart + (low*R_DATA->bytes_per_line) , R_DATA->backfillcolour, R_DATA->bytes_per_line ); } void vidcconsole_cls(vc) struct vconsole *vc; { #ifdef RC7500 dispstart = dispbase; dispend = dispstart+dispsize; WriteWord ( IOMD_VIDINIT, dispstart-ptov ); WriteWord ( IOMD_VIDSTART, dispstart-ptov ); WriteWord ( IOMD_VIDEND, (dispend-transfersize)-ptov ); #endif vidcconsolemc_cls ( (char *)dispstart, (char *)dispstart+R_DATA->screensize, R_DATA->backfillcolour ); /* memset((char *)dispstart, R_DATA->backfillcolour, R_DATA->screensize); */ vc->xcur = vc->ycur = 0; } void vidcconsole_update(vc) struct vconsole *vc; { } static char vidcconsole_name[] = VIDC_ENGINE_NAME; static int scrollback_ptr = 0; int vidcconsole_scrollback(vc) struct vconsole *vc; { int temp; if (scrollback_ptr==0) scrollback_ptr=dispstart; temp = scrollback_ptr; scrollback_ptr-=R_DATA->bytes_per_line * (vc->ychars-2); if ( scrollback_ptr < dispbase ) scrollback_ptr += dispsize; if ( (scrollback_ptr>dispstart)&& (scrollback_ptr<(dispstart+R_DATA->screensize) ) ) { scrollback_ptr=temp; return 0; } vc->r_scrolledback = 1; WriteWord(IOMD_VIDINIT, scrollback_ptr - ptov ); return 0; } int vidcconsole_scrollforward(vc) struct vconsole *vc; { register int temp; if (scrollback_ptr==0) return 0; temp = scrollback_ptr; scrollback_ptr+=R_DATA->bytes_per_line * (vc->ychars - 2); if ( scrollback_ptr >= dispend ) scrollback_ptr -= dispsize; if ( scrollback_ptr == dispstart ) { WriteWord(IOMD_VIDINIT, scrollback_ptr - ptov ); scrollback_ptr=0; vc->r_scrolledback = 0; return 0; } WriteWord(IOMD_VIDINIT, scrollback_ptr - ptov ); return 0; } int vidcconsole_scrollbackend(vc) struct vconsole *vc; { scrollback_ptr = 0; WriteWord(IOMD_VIDINIT, dispstart - ptov ); vc->r_scrolledback = 0; return 0; } int vidcconsole_clreos(vc, code) struct vconsole *vc; int code; { char *addr; char *endofscreen; addr = (unsigned char *)dispstart + (vc->xcur * R_DATA->font->x_spacing) + (vc->ycur * R_DATA->bytes_per_line); endofscreen = (unsigned char *)dispstart + (vc->xchars * R_DATA->font->x_spacing) + (vc->ychars * R_DATA->bytes_per_line); switch (code) { case 0: vidcconsolemc_cls ( addr, (unsigned char *)dispend, R_DATA->backfillcolour ); if ((unsigned char *)endofscreen > (unsigned char *)dispend) { char string[80]; sprintf(string, "(addr=%08x eos=%08x dispend=%08x dispstart=%08x base=%08x)", (u_int)addr, (u_int)endofscreen, dispend, dispstart, dispbase); dprintf(string); vidcconsolemc_cls((unsigned char *)dispbase, (unsigned char *)(dispbase + (endofscreen - dispend)), R_DATA->backfillcolour); } break; case 1: vidcconsolemc_cls ( (unsigned char *)dispstart+R_DATA->screensize, addr, R_DATA->backfillcolour ); break; case 2: default: vidcconsole_cls ( vc ); break; } return 0; } #define VIDC R_DATA->vidc int vidcconsole_debugprint(vc) struct vconsole *vc; { #ifdef DEVLOPING printf ( "VIDCCONSOLE DEBUG INFORMATION\n\n" ); printf ( "res (%d, %d) charsize (%d, %d) cursor (%d, %d)\n" , R_DATA->XRES, R_DATA->YRES , vc->xchars, vc->ychars, vc->xcur, vc->ycur ); printf ( "bytes_per_line %d\n" , R_DATA->bytes_per_line ); printf ( "pixelsperbyte %d\n" , R_DATA->pixelsperbyte ); printf ( "dispstart %08x\n" , dispstart ); printf ( "dispend %08x\n" , dispend ); printf ( "screensize %08x\n" , R_DATA->screensize ); printf ( "fontwidth %08x\n" , R_DATA->font->pixel_width ); printf ( "fontheight %08x\n" , R_DATA->font->pixel_height ); printf ( "\n" ); printf ( "palreg = %08x bcol = %08x\n" , VIDC.palreg, VIDC.bcol ); printf ( "cp1 = %08x cp2 = %08x cp3 = %08x\n" , VIDC.cp1, VIDC.cp2, VIDC.cp3 ); printf ( "hcr = %08x hswr = %08x hbsr = %08x\n" , VIDC.hcr, VIDC.hswr, VIDC.hbsr ); printf ( "hder = %08x hber = %08x hcsr = %08x\n" , VIDC.hder, VIDC.hber, VIDC.hcsr ); printf ( "hir = %08x\n" , VIDC.hir ); printf ( "vcr = %08x vswr = %08x vbsr = %08x\n" , VIDC.vcr, VIDC.vswr, VIDC.vbsr ); printf ( "vder = %08x vber = %08x vcsr = %08x\n" , VIDC.vder, VIDC.vber, VIDC.vcsr ); printf ( "vcer = %08x\n" , VIDC.vcer ); printf ( "ereg = %08x fsynreg = %08x conreg = %08x\n" , VIDC.ereg, VIDC.fsynreg, VIDC.conreg ); printf ( "\n" ); printf ( "flash %08x, cursor_flash %08x", R_DATA->flash, R_DATA->cursor_flash ); #else printf ( "VIDCCONSOLE - NO DEBUG INFO\n" ); #endif return 0; } #ifdef NICE_UPDATE static int need_update = 0; void vidcconsole_updatecursor(arg) void *arg; { struct vconsole *vc = vconsole_current; vidc_write(VIDC_HCSR, R_DATA->frontporch-17+ (vc->xcur)*R_DATA->font->pixel_width ); vidc_write(VIDC_VCSR, R_DATA->topporch-2+ (vc->ycur+1)*R_DATA->font->pixel_height-2 + 3 - R_DATA->font->pixel_height); vidc_write(VIDC_VCER, R_DATA->topporch-2+ (vc->ycur+3)*R_DATA->font->pixel_height+2 + 3 ); return; } int vidcconsole_cursorupdate(vc) struct vconsole *vc; { timeout ( vidcconsole_updatecursor, NULL, 20 ); return 0; } #else static int vidcconsole_cursorupdate(vc) struct vconsole *vc; { vidc_write(VIDC_HCSR, R_DATA->frontporch-17+ (vc->xcur)*R_DATA->font->pixel_width ); vidc_write(VIDC_VCSR, R_DATA->topporch-2+ (vc->ycur+1)*R_DATA->font->pixel_height-2 + 3 - R_DATA->font->pixel_height); vidc_write(VIDC_VCER, R_DATA->topporch-2+ (vc->ycur+3)*R_DATA->font->pixel_height+2 + 3 ); return (0); } #endif #define DEFAULT_CURSORSPEED (25) static int CURSORSPEED = DEFAULT_CURSORSPEED; static int vidcconsole_cursorflashrate(vc, rate) struct vconsole *vc; int rate; { CURSORSPEED = 60/rate; return(0); } static int cursorcounter=DEFAULT_CURSORSPEED; static int flashcounter=DEFAULT_CURSORSPEED; #ifdef PRETTYCURSOR static int pretty=0xff; #endif static int cursor_col = 0x0; int vidcconsole_cursorintr(arg) void *arg; { struct vconsole *vc = arg; if ( cursor_flash==0 ) return 0; /* * We don't need this. */ #ifndef RC7500 if (vconsole_blankcounter >= 0) vconsole_blankcounter--; if (vconsole_blankcounter == 0) { vconsole_blankcounter=vconsole_blankinit; vidcconsole_blank ( vc, BLANK_OFF ); } #endif cursorcounter--; if (cursorcounter<=0) { cursorcounter=CURSORSPEED; cursor_col = cursor_col ^ 0xffffff; #ifdef ACTIVITY_WARNING if (vconsole_pending) { if ( cursor_col==0 ) WriteWord(IOMD_CURSINIT,p_cursor_transparent); else WriteWord(IOMD_CURSINIT,p_cursor_normal); vidc_write ( VIDC_CP1, cursor_col&0xff ); } else #endif { if ( cursor_col==0 ) WriteWord(IOMD_CURSINIT,p_cursor_transparent); else WriteWord(IOMD_CURSINIT,p_cursor_normal); vidc_write ( VIDC_CP1, 0xffffff ); } } return(0); /* Pass interrupt on down the chain */ } int vidcconsole_flashintr(arg) void *arg; { struct vconsole *vc = arg; if ( flash==0 ) return 0; flashcounter--; if (flashcounter<=0) { flashcounter=CURSORSPEED; if ( cursor_col == 0 ) { vidc_write(VIDC_PALREG, 0x00000010); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL(255, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 255, 0)); vidc_write(VIDC_PALETTE, VIDC_COL(255, 255, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 255)); vidc_write(VIDC_PALETTE, VIDC_COL(255, 0, 255)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 255, 255)); vidc_write(VIDC_PALETTE, VIDC_COL(255, 255, 255)); vidc_write(VIDC_PALETTE, VIDC_COL(128, 128, 128)); vidc_write(VIDC_PALETTE, VIDC_COL(255, 128, 128)); vidc_write(VIDC_PALETTE, VIDC_COL(128, 255, 128)); vidc_write(VIDC_PALETTE, VIDC_COL(255, 255, 128)); vidc_write(VIDC_PALETTE, VIDC_COL(128, 128, 255)); vidc_write(VIDC_PALETTE, VIDC_COL(255, 128, 255)); vidc_write(VIDC_PALETTE, VIDC_COL(255, 255, 255)); } else { vidc_write(VIDC_PALREG, 0x00000010); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); vidc_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0)); } } return(0); /* Pass interrupt on down the chain */ } static int vidc_cursor_init(vc) struct vconsole *vc; { static char *cursor_data = NULL; int counter; int line; if (!cursor_data) { /* Allocate cursor memory first time round */ cursor_data = (char *)kmem_alloc(kernel_map, NBPG); if (!cursor_data) panic("Cannot allocate memory for hardware cursor\n"); WriteWord(IOMD_CURSINIT, pmap_extract(kernel_pmap, (vm_offset_t)cursor_data)); } /* Blank the cursor while initialising it's sprite */ vidc_write ( VIDC_CP1, 0x0 ); vidc_write ( VIDC_CP2, 0x0 ); vidc_write ( VIDC_CP3, 0x0 ); cursor_normal = cursor_data; cursor_transparent = cursor_data + (R_DATA->font->pixel_height * R_DATA->font->pixel_width); cursor_transparent += 32; cursor_transparent = (char *)((int)cursor_transparent & (~31) ); for ( line = 0; linefont->pixel_height; ++ line ) { for ( counter=0; counterfont->pixel_width/4;counter++ ) cursor_normal[line*R_DATA->font->pixel_width + counter]=0x55; for ( ; counter<8; counter++ ) cursor_normal[line*R_DATA->font->pixel_width + counter]=0; } for ( line = 0; linefont->pixel_height; ++ line ) { for ( counter=0; counterfont->pixel_width/4;counter++ ) cursor_transparent[line*R_DATA->font->pixel_width + counter]=0x00; for ( ; counter<8; counter++ ) cursor_transparent[line*R_DATA->font->pixel_width + counter]=0; } p_cursor_normal = pmap_extract(kernel_pmap,(vm_offset_t)cursor_normal ); p_cursor_transparent = pmap_extract(kernel_pmap,(vm_offset_t)cursor_transparent); /* memset ( cursor_normal, 0x55, R_DATA->font->pixel_width*R_DATA->font->pixel_height ); memset ( cursor_transparent, 0x55, R_DATA->font->pixel_width*R_DATA->font->pixel_height ); */ /* Ok, now see the cursor */ vidc_write ( VIDC_CP1, 0xffffff ); return 0; } int vidcconsole_setfgcol(vc, col) struct vconsole *vc; int col; { register int loop; if ( R_DATA->forecolour >= 16 ) R_DATA->forecolour=16; else R_DATA->forecolour=0; R_DATA->forefillcolour = 0; R_DATA->forecolour += col; /*TODO if ( R_DATA->forecolour >> 1<BITSPERPIXEL ) R_DATA->forecolour>>1; */ for (loop = 0; loop < R_DATA->pixelsperbyte; ++loop) { R_DATA->forefillcolour |= (R_DATA->forecolour << loop * R_DATA->BITSPERPIXEL); } R_DATA->fast_render = R_DATA->forecolour | (R_DATA->backcolour<<8) | (R_DATA->font->pixel_height<<16); return 0; } int vidcconsole_setbgcol(vc, col) struct vconsole *vc; int col; { register int loop; if ( R_DATA->backcolour >= 16 ) R_DATA->backcolour=16; else R_DATA->backcolour=0; R_DATA->backfillcolour = 0; R_DATA->backcolour += col; /*TODO if ( R_DATA->backcolour >> 1<BITSPERPIXEL ) R_DATA->backcolour>>1; */ for (loop = 0; loop < R_DATA->pixelsperbyte; ++loop) { R_DATA->backfillcolour |= (R_DATA->backcolour << loop * R_DATA->BITSPERPIXEL); } return 0; } int vidcconsole_textpalette(vc) struct vconsole *vc; { R_DATA->forecolour = COLOUR_WHITE_8; R_DATA->backcolour = COLOUR_BLACK_8; vidc_write( VIDC_PALREG , 0x00000000); vidc_write( VIDC_PALETTE , VIDC_COL( 0, 0, 0)); vidc_write( VIDC_PALETTE , VIDC_COL(255, 0, 0)); vidc_write( VIDC_PALETTE , VIDC_COL( 0, 255, 0)); vidc_write( VIDC_PALETTE , VIDC_COL(255, 255, 0)); vidc_write( VIDC_PALETTE , VIDC_COL( 0, 0, 255)); vidc_write( VIDC_PALETTE , VIDC_COL(255, 0, 255)); vidc_write( VIDC_PALETTE , VIDC_COL( 0, 255, 255)); vidc_write( VIDC_PALETTE , VIDC_COL(255, 255, 255)); vidc_write( VIDC_PALETTE , VIDC_COL(128, 128, 128)); vidc_write( VIDC_PALETTE , VIDC_COL(255, 128, 128)); vidc_write( VIDC_PALETTE , VIDC_COL(128, 255, 128)); vidc_write( VIDC_PALETTE , VIDC_COL(255, 255, 128)); vidc_write( VIDC_PALETTE , VIDC_COL(128, 128, 255)); vidc_write( VIDC_PALETTE , VIDC_COL(255, 128, 255)); vidc_write( VIDC_PALETTE , VIDC_COL(255, 255, 255)); R_DATA->fast_render = R_DATA->forecolour | (R_DATA->backcolour<<8) | (R_DATA->font->pixel_height<<16); return 0; } int vidcconsole_sgr(vc, type) struct vconsole *vc; int type; { switch(type) { case 0: /* Normal */ if (R_DATA->BITSPERPIXEL == 8) { R_DATA->n_forecolour = COLOUR_WHITE_8; R_DATA->n_backcolour = COLOUR_BLACK_8; } R_DATA->forecolour = R_DATA->n_forecolour; R_DATA->backcolour = R_DATA->n_backcolour; R_DATA->font = R_DATA->normalfont; break; case 1: /* bold */ R_DATA->font = R_DATA->boldfont; break; case 22: /* not bold */ R_DATA->font = R_DATA->normalfont; break; case 5: /* blinking */ if ( R_DATA->forecolour < 16 ) { R_DATA->forecolour+=16; R_DATA->backcolour+=16; R_DATA->n_forecolour+=16; R_DATA->n_backcolour+=16; } break; case 25: /* not blinking */ if ( R_DATA->forecolour >= 16 ) { R_DATA->forecolour-=16; R_DATA->backcolour-=16; R_DATA->n_forecolour-=16; R_DATA->n_backcolour-=16; } break; case 7: /* reverse */ R_DATA->forecolour = R_DATA->n_backcolour; R_DATA->backcolour = R_DATA->n_forecolour; break; case 27: /* not reverse */ R_DATA->forecolour = R_DATA->n_forecolour; R_DATA->backcolour = R_DATA->n_backcolour; break; } R_DATA->fast_render = R_DATA->forecolour | (R_DATA->backcolour<<8) | (R_DATA->font->pixel_height<<16); return 0; } int vidcconsole_scrollregion(vc, low, high) struct vconsole *vc; int low; int high; { return 0; } int vidcconsole_blank(vc, type) struct vconsole *vc; int type; { int ereg; vc->blanked=type; ereg = 1<<12; if (vidc_currentmode->sync_pol & 0x01) ereg |= 1<<16; if (vidc_currentmode->sync_pol & 0x02) ereg |= 1<<18; switch (type) { case 0: #ifdef RC7500 vidc_write(VIDC_EREG, 0x51<<12); #else vidc_write(VIDC_EREG, ereg); #endif break; case 1: /* not implemented yet */ case 2: case 3: vidc_write(VIDC_EREG, 0); break; } return 0; } extern struct tty *find_tp __P((dev_t dev)); int vidcconsole_ioctl ( struct vconsole *vc, dev_t dev, int cmd, caddr_t data, int flag, struct proc *p ) { int error; struct tty *tp; struct winsize ws; switch ( cmd ) { case CONSOLE_MODE: tp = find_tp(dev); /* printf ( "mode ioctl called\n" );*/ vidcconsole_mode ( vc, (struct vidc_mode *)data ); vc->MODECHANGE ( vc ); ws.ws_row=vc->ychars; ws.ws_col=vc->xchars; error = (*linesw[tp->t_line].l_ioctl)(tp, TIOCSWINSZ, (char *)&ws, flag, p); error = ttioctl(tp, TIOCSWINSZ, (char *)&ws, flag, p); return 0; break; case CONSOLE_RESETSCREEN: { extern unsigned int dispbase; extern unsigned int dispsize; extern unsigned int ptov; extern unsigned int transfersize; WriteWord ( IOMD_VIDINIT, dispbase-ptov ); WriteWord ( IOMD_VIDSTART, dispbase-ptov ); WriteWord ( IOMD_VIDEND, (dispbase+dispsize-transfersize)-ptov ); return 0; } case CONSOLE_RESTORESCREEN: { extern unsigned int dispstart; extern unsigned int dispsize; extern unsigned int ptov; extern unsigned int transfersize; WriteWord ( IOMD_VIDINIT, dispstart-ptov ); WriteWord ( IOMD_VIDSTART, dispstart-ptov ); WriteWord ( IOMD_VIDEND, (dispstart+dispsize-transfersize)-ptov ); vidc_stdpalette(); return 0; } case CONSOLE_GETINFO: { extern videomemory_t videomemory; register struct console_info *inf = (void *)data; inf->videomemory = videomemory; inf->width = R_DATA->mode.hder; inf->height = R_DATA->mode.vder; inf->bpp = R_DATA->mode.bitsperpixel; return 0; } case CONSOLE_PALETTE: { register struct console_palette *pal = (void *)data; vidc_write(VIDC_PALREG, pal->entry); vidc_write(VIDC_PALETTE, VIDC_COL(pal->red, pal->green, pal->blue)); return 0; } } return -1; } int vidcconsole_attach(vc, parent, self, aux) struct vconsole *vc; struct device *parent; struct device *self; void *aux; { vidc_cursor_init ( vc ); vidcconsole_flash_go ( vc ); return 0; } int vidcconsole_flash_go(vc) struct vconsole *vc; { static int irqclaimed = 0; static int lock=0; if (lock==1) return -1; lock=0; if (!irqclaimed) { cursor_ih.ih_func = vidcconsole_cursorintr; cursor_ih.ih_arg = vc; cursor_ih.ih_level = IPL_TTY; cursor_ih.ih_name = "vsync"; irq_claim ( IRQ_FLYBACK, &cursor_ih ); irqclaimed = 1; } cursor_init = 0; return 0; } /* What does this function do ? */ int vidcconsole_flash(vc, flash) struct vconsole *vc; int flash; { flash = flash; return(0); } int vidcconsole_cursorflash(vc, flash) struct vconsole *vc; int flash; { cursor_flash = flash; return(0); } struct render_engine vidcconsole = { vidcconsole_name, vidcconsole_init, vidcconsole_putchar, vidcconsole_spawn, vidcconsole_swapin, vidcconsole_mmap, vidcconsole_render, vidcconsole_scrollup, vidcconsole_scrolldown, vidcconsole_cls, vidcconsole_update, vidcconsole_scrollback, vidcconsole_scrollforward, vidcconsole_scrollbackend, vidcconsole_clreos, vidcconsole_debugprint, vidcconsole_cursorupdate, vidcconsole_cursorflashrate, vidcconsole_setfgcol, vidcconsole_setbgcol, vidcconsole_textpalette, vidcconsole_sgr, vidcconsole_blank, vidcconsole_ioctl, vidcconsole_redraw, vidcconsole_attach, vidcconsole_flash, vidcconsole_cursorflash }; struct vidcvideo_softc { struct device device; int sc_opened; }; int vidcvideo_probe(parent, match, aux) struct device *parent; void *match; void *aux; { return 1; } void vidcvideo_attach(parent, self, aux) struct device *parent; struct device *self; void *aux; { struct vidcvideo_softc *vidcvideosoftc = (void *)self; vidcvideosoftc->sc_opened=0; printf(": vidc20 refclk=%dMHz %dKB %s\n", (VIDC_FREF / 1000000), videomemory.vidm_size / 1024, (videomemory.vidm_type == VIDEOMEM_TYPE_VRAM) ? "VRAM" : "DRAM"); } struct cfattach vidcvideo_ca = { sizeof (struct vidcvideo_softc), vidcvideo_probe, vidcvideo_attach }; struct cfdriver vidcvideo_cd = { NULL, "vidcvideo", DV_DULL }; int vidcvideoopen(dev, flags, fmt, p) dev_t dev; int flags; int fmt; struct proc *p; { struct vidcvideo_softc *sc; struct vconsole vconsole_new; int unit = minor(dev); int s; if (unit >= vidcvideo_cd.cd_ndevs) return ENXIO; sc = vidcvideo_cd.cd_devs[unit]; if (!sc) return ENXIO; s = spltty(); /* if (sc->sc_opened) { (void)splx(s); return(EBUSY); }*/ ++sc->sc_opened; (void)splx(s); if (sc->sc_opened == 1) { vconsole_new = *vconsole_default; vconsole_new.render_engine = &vidcconsole; vconsole_spawn_re ( makedev ( physcon_major, 64 + minor(dev) ), &vconsole_new ); } else { log(LOG_WARNING, "Multiple open of/dev/vidcvideo0 by proc %d\n", p->p_pid); } return 0; } int vidcvideoclose(dev, flags, fmt, p) dev_t dev; int flags; int fmt; struct proc *p; { struct vidcvideo_softc *sc; int unit = minor(dev); int s; if ( unit >= vidcvideo_cd.cd_ndevs ) return ENXIO; sc = vidcvideo_cd.cd_devs[unit]; if (!sc) return ENXIO; s = spltty(); --sc->sc_opened; (void)splx(s); return 0; } extern int physconioctl __P(( dev_t, int, caddr_t, int, struct proc *)); int vidcvideoioctl(dev, cmd, data, flag, p) dev_t dev; int cmd; caddr_t data; int flag; struct proc *p; { dev = makedev(physcon_major, 64 + minor(dev)); return ( physconioctl ( dev, cmd, data, flag, p )); } extern int physconmmap __P((dev_t, int, int)); int vidcvideommap(dev, offset, prot) dev_t dev; int offset; int prot; { dev = makedev(physcon_major, 64 + minor(dev)); return(physconmmap(dev, offset, prot)); }