newport_con.c

来自「讲述linux的初始化过程」· C语言 代码 · 共 615 行 · 第 1/2 页

C
615
字号
{    int xend = ((sx + width) << 3) - 1;    int ystart = ((sy << 4) + topscan) & 0x3ff;    int yend = (((sy + height) << 4) + topscan - 1) & 0x3ff;    if (logo_active)	return;        if (ystart < yend) {	newport_clear_screen(sx << 3, ystart, xend, yend,			     (vc->vc_color & 0xf0) >> 4);    } else {	newport_clear_screen(sx << 3, ystart, xend, 1023,			     (vc->vc_color & 0xf0) >> 4);	newport_clear_screen(sx << 3, 0, xend, yend,			     (vc->vc_color & 0xf0) >> 4);    }}static void newport_putc(struct vc_data *vc, int charattr, int ypos, int xpos){    unsigned char *p;        p = &FONT_DATA[(charattr & 0xff) << 4];    charattr = (charattr >> 8) & 0xff;    xpos <<= 3;    ypos <<= 4;    newport_render_background(xpos, ypos, xpos, ypos, (charattr & 0xf0) >> 4);        /* Set the color and drawing mode. */    newport_wait();    npregs->set.colori = charattr & 0xf;    npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |			     NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |			     NPORT_DMODE0_L32);        /* Set coordinates for bitmap operation. */    npregs->set.xystarti = (xpos << 16) | ((ypos + topscan) & 0x3ff);    npregs->set.xyendi = ((xpos + 7) << 16);    newport_wait();        /* Go, baby, go... */    RENDER(npregs, p);}static void newport_putcs(struct vc_data *vc, const unsigned short *s,			  int count, int ypos, int xpos){    int i;    int charattr;    unsigned char *p;     charattr = (*s >> 8) & 0xff;    xpos <<= 3;    ypos <<= 4;    if (!logo_active)	/* Clear the area behing the string */	newport_render_background(xpos, ypos, xpos + ((count-1) << 3), ypos,				  (charattr & 0xf0) >> 4);    newport_wait();    /* Set the color and drawing mode. */    npregs->set.colori = charattr & 0xf;    npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |			     NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |			     NPORT_DMODE0_L32);        for (i = 0; i < count; i++, xpos += 8) {	p = &FONT_DATA[(s[i] & 0xff) << 4];	newport_wait();	/* Set coordinates for bitmap operation. */	npregs->set.xystarti = (xpos << 16) | ((ypos + topscan) & 0x3ff);	npregs->set.xyendi = ((xpos + 7) << 16);	/* Go, baby, go... */	RENDER(npregs, p);    }}static void newport_cursor(struct vc_data *vc, int mode){    unsigned short treg;    int xcurs, ycurs;        switch (mode) {     case CM_ERASE:	treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);	newport_vc2_set(npregs, VC2_IREG_CONTROL, (treg & ~(VC2_CTRL_ECDISP)));	break;     case CM_MOVE:     case CM_DRAW:	treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);	newport_vc2_set(npregs, VC2_IREG_CONTROL, (treg | VC2_CTRL_ECDISP));	xcurs = (vc->vc_pos - vc->vc_visible_origin) / 2;	ycurs = ((xcurs / vc->vc_cols) << 4) + 31;	xcurs = ((xcurs % vc->vc_cols) << 3) + xcurs_correction;	newport_vc2_set(npregs, VC2_IREG_CURSX, xcurs);	newport_vc2_set(npregs, VC2_IREG_CURSY, ycurs);    }}static int newport_switch(struct vc_data *vc){    static int logo_drawn = 0;    topscan = 0;    npregs->cset.topscan = 0x3ff;    if (!logo_drawn) {	newport_show_logo();	logo_drawn = 1;	logo_active = 1;    }    return 1;}static int newport_blank(struct vc_data *c, int blank){    unsigned short treg;        if (blank == 0) {	/* unblank console */	treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);	newport_vc2_set(npregs, VC2_IREG_CONTROL, (treg | VC2_CTRL_EDISP));    } else {	/* blank console */	treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);	newport_vc2_set(npregs, VC2_IREG_CONTROL, (treg & ~(VC2_CTRL_EDISP)));    }    return 1;}static int newport_font_op(struct vc_data *vc, struct console_font_op *f){    return -ENOSYS;}static int newport_set_palette(struct vc_data *vc, unsigned char *table){    return -EINVAL;}static int newport_scrolldelta(struct vc_data *vc, int lines){    /* there is (nearly) no off-screen memory, so we can't scroll back */    return 0;}static int newport_scroll(struct vc_data *vc, int t, int b, int dir, int lines){    int count,x,y;    unsigned short *s, *d;    unsigned short chattr;    logo_active = 0;	/* it's time to disable the logo now.. */    if (t == 0 && b == vc->vc_rows) {	if (dir == SM_UP) {	    topscan = (topscan + (lines << 4)) & 0x3ff;	    newport_clear_lines (vc->vc_rows-lines,vc->vc_rows-1,				 (vc->vc_color & 0xf0) >> 4);	} else {	    topscan = (topscan + (-lines << 4)) & 0x3ff;	    newport_clear_lines (0,lines-1, (vc->vc_color & 0xf0) >> 4);	}	npregs->cset.topscan = (topscan - 1) & 0x3ff;	return 0;    }        count = (b-t-lines) * vc->vc_cols;    if (dir == SM_UP) {	x = 0; y = t;	s = (unsigned short *)(vc->vc_origin + vc->vc_size_row*(t+lines));	d = (unsigned short *)(vc->vc_origin + vc->vc_size_row*t);	while (count--) {	    chattr = scr_readw (s++);	    if (chattr != scr_readw(d)) {		newport_putc (vc, chattr, y, x);		scr_writew (chattr, d);	    }	    d++;	    if (++x == vc->vc_cols) {		x = 0; y++;	    }	}	d = (unsigned short *)(vc->vc_origin + vc->vc_size_row*(b-lines));	x = 0; y = b-lines;	for (count = 0; count < (lines * vc->vc_cols); count++) {	    if (scr_readw(d) != vc->vc_video_erase_char) {		newport_putc (vc, vc->vc_video_erase_char, y, x);		scr_writew (vc->vc_video_erase_char, d);	    }	    d++;	    if (++x == vc->vc_cols) {		x = 0; y++;	    }	}    } else {	x = vc->vc_cols-1; y = b-1;	s = (unsigned short *)(vc->vc_origin + vc->vc_size_row*(b-lines)-2);	d = (unsigned short *)(vc->vc_origin + vc->vc_size_row*b-2);	while (count--) {	    chattr = scr_readw (s--);	    if (chattr != scr_readw(d)) {		newport_putc (vc, chattr, y, x);		scr_writew (chattr, d);	    }	    d--;	    if (x-- == 0) {		x = vc->vc_cols-1; y--;	    }	}	d = (unsigned short *)(vc->vc_origin + vc->vc_size_row*t);	x = 0; y = t;	for (count = 0; count < (lines * vc->vc_cols); count++) {	    if (scr_readw(d) != vc->vc_video_erase_char) {		newport_putc (vc, vc->vc_video_erase_char, y, x);		scr_writew (vc->vc_video_erase_char, d);	    }	    d++;	    if (++x == vc->vc_cols) {		x = 0; y++;	    }	}    }    return 1;}static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, int h, int w){    short xs, ys, xe, ye, xoffs, yoffs, tmp;    xs = sx << 3; xe = ((sx+w) << 3)-1;    /*     * as bmove is only used to move stuff around in the same line     * (h == 1), we don't care about wrap arounds caused by topscan != 0     */    ys = ((sy << 4) + topscan) & 0x3ff; ye = (((sy+h) << 4)-1+topscan) & 0x3ff;    xoffs = (dx - sx) << 3;    yoffs = (dy - sy) << 4;    if (xoffs > 0) {	/* move to the right, exchange starting points */	tmp = xe; xe = xs; xs = tmp;    }    newport_wait();    npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK |			     NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX |			     NPORT_DMODE0_STOPY);    npregs->set.xystarti = (xs << 16) | ys;    npregs->set.xyendi = (xe << 16) | ye;    npregs->go.xymove = (xoffs << 16) | yoffs;}static int newport_dummy(struct vc_data *c){    return 0;}#define DUMMY (void *) newport_dummyconst struct consw newport_con = {    con_startup:	newport_startup,    con_init:		newport_init,    con_deinit:		DUMMY,    con_clear:		newport_clear,    con_putc:		newport_putc,    con_putcs:		newport_putcs,    con_cursor:		newport_cursor,    con_scroll:		newport_scroll,    con_bmove:		newport_bmove,    con_switch:		newport_switch,    con_blank:		newport_blank,    con_font_op:	newport_font_op,    con_set_palette:	newport_set_palette,    con_scrolldelta:	newport_scrolldelta,    con_set_origin:	DUMMY,    con_save_screen:	DUMMY,};#ifdef MODULEint init_module(void) {    if (!newport_startup())        printk("Error loading SGI Newport Console driver\n");    else        printk("Loading SGI Newport Console Driver\n");    take_over_console(&newport_con,0,MAX_NR_CONSOLES-1,1);    return 0;}int cleanup_module(void) {    printk("Unloading SGI Newport Console Driver\n");    return 0;}#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?