📄 cyberfb.c
字号:
static int Cyber_encode_var(struct fb_var_screeninfo *var, struct cyberfb_par *par){ DPRINTK("ENTER\n"); var->xres = par->var.xres; var->yres = par->var.yres; var->xres_virtual = par->var.xres_virtual; var->yres_virtual = par->var.yres_virtual; var->xoffset = par->var.xoffset; var->yoffset = par->var.yoffset; var->bits_per_pixel = par->var.bits_per_pixel; var->grayscale = par->var.grayscale; var->red = par->var.red; var->green = par->var.green; var->blue = par->var.blue; var->transp = par->var.transp; var->nonstd = par->var.nonstd; var->activate = par->var.activate; var->height = par->var.height; var->width = par->var.width; var->accel_flags = par->var.accel_flags; var->pixclock = par->var.pixclock; var->left_margin = par->var.left_margin; var->right_margin = par->var.right_margin; var->upper_margin = par->var.upper_margin; var->lower_margin = par->var.lower_margin; var->hsync_len = par->var.hsync_len; var->vsync_len = par->var.vsync_len; var->sync = par->var.sync; var->vmode = par->var.vmode; DPRINTK("EXIT\n"); return(0);}/* * Set a single color register. Return != 0 for invalid regno. */static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info){ volatile unsigned char *regs = CyberRegs; /*DPRINTK("ENTER\n");*/ if (regno > 255) { DPRINTK("EXIT - Register # > 255\n"); return (1); } wb_64(regs, 0x3c8, (unsigned char) regno); red >>= 10; green >>= 10; blue >>= 10; Cyber_colour_table [regno][0] = red; Cyber_colour_table [regno][1] = green; Cyber_colour_table [regno][2] = blue; wb_64(regs, 0x3c9, red); wb_64(regs, 0x3c9, green); wb_64(regs, 0x3c9, blue); /*DPRINTK("EXIT\n");*/ return (0);}/** Read a single color register and split it into* colors/transparent. Return != 0 for invalid regno.*/static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, u_int *transp, struct fb_info *info){ int t; /*DPRINTK("ENTER\n");*/ if (regno > 255) { DPRINTK("EXIT - Register # > 255\n"); return (1); } /* ARB This shifting & oring seems VERY strange */ t = Cyber_colour_table [regno][0]; *red = (t<<10) | (t<<4) | (t>>2); t = Cyber_colour_table [regno][1]; *green = (t<<10) | (t<<4) | (t>>2); t = Cyber_colour_table [regno][2]; *blue = (t<<10) | (t<<4) | (t>>2); *transp = 0; /*DPRINTK("EXIT\n");*/ return (0);}/** (Un)Blank the screen* blank: 1 = zero fb cmap* 0 = restore fb cmap from local cmap*/void Cyberfb_blank(int blank, struct fb_info *info){ volatile unsigned char *regs = CyberRegs; int i; DPRINTK("ENTER\n");#if 0/* Blank by turning gfx off */ gfx_on_off (1, regs);#else if (blank) { for (i = 0; i < 256; i++) { wb_64(regs, 0x3c8, (unsigned char) i); /* ARB Pale red to detect this blanking method */ wb_64(regs, 0x3c9, 48); wb_64(regs, 0x3c9, 0); wb_64(regs, 0x3c9, 0); } } else { for (i = 0; i < 256; i++) { wb_64(regs, 0x3c8, (unsigned char) i); wb_64(regs, 0x3c9, Cyber_colour_table[i][0]); wb_64(regs, 0x3c9, Cyber_colour_table[i][1]); wb_64(regs, 0x3c9, Cyber_colour_table[i][2]); } }#endif DPRINTK("EXIT\n");}/************************************************************** * We are waiting for "fifo" FIFO-slots empty */static void Cyber_WaitQueue (u_short fifo){ unsigned short status; DPRINTK("ENTER\n"); do { status = *((u_short volatile *)(CyberRegs + S3_GP_STAT)); } while (status & fifo); DPRINTK("EXIT\n");}/************************************************************** * We are waiting for Hardware (Graphics Engine) not busy */static void Cyber_WaitBlit (void){ unsigned short status; DPRINTK("ENTER\n"); do { status = *((u_short volatile *)(CyberRegs + S3_GP_STAT)); } while (status & S3_HDW_BUSY); DPRINTK("EXIT\n");}/************************************************************** * BitBLT - Through the Plane */static void Cyber_BitBLT (u_short curx, u_short cury, u_short destx, u_short desty, u_short width, u_short height, u_short mode){ volatile unsigned char *regs = CyberRegs; u_short blitcmd = S3_BITBLT; DPRINTK("ENTER\n"); /* Set drawing direction */ /* -Y, X maj, -X (default) */ if (curx > destx) { blitcmd |= 0x0020; /* Drawing direction +X */ } else { curx += (width - 1); destx += (width - 1); } if (cury > desty) { blitcmd |= 0x0080; /* Drawing direction +Y */ } else { cury += (height - 1); desty += (height - 1); } Cyber_WaitQueue (0x8000); *((u_short volatile *)(regs + S3_PIXEL_CNTL)) = 0xa000; *((u_short volatile *)(regs + S3_FRGD_MIX)) = (0x0060 | mode); *((u_short volatile *)(regs + S3_CUR_X)) = curx; *((u_short volatile *)(regs + S3_CUR_Y)) = cury; *((u_short volatile *)(regs + S3_DESTX_DIASTP)) = destx; *((u_short volatile *)(regs + S3_DESTY_AXSTP)) = desty; *((u_short volatile *)(regs + S3_MIN_AXIS_PCNT)) = height - 1; *((u_short volatile *)(regs + S3_MAJ_AXIS_PCNT)) = width - 1; *((u_short volatile *)(regs + S3_CMD)) = blitcmd; DPRINTK("EXIT\n");}/************************************************************** * Rectangle Fill Solid */static void Cyber_RectFill (u_short x, u_short y, u_short width, u_short height, u_short mode, u_short color){ volatile unsigned char *regs = CyberRegs; u_short blitcmd = S3_FILLEDRECT; DPRINTK("ENTER\n"); Cyber_WaitQueue (0x8000); *((u_short volatile *)(regs + S3_PIXEL_CNTL)) = 0xa000; *((u_short volatile *)(regs + S3_FRGD_MIX)) = (0x0020 | mode); *((u_short volatile *)(regs + S3_MULT_MISC)) = 0xe000; *((u_short volatile *)(regs + S3_FRGD_COLOR)) = color; *((u_short volatile *)(regs + S3_CUR_X)) = x; *((u_short volatile *)(regs + S3_CUR_Y)) = y; *((u_short volatile *)(regs + S3_MIN_AXIS_PCNT)) = height - 1; *((u_short volatile *)(regs + S3_MAJ_AXIS_PCNT)) = width - 1; *((u_short volatile *)(regs + S3_CMD)) = blitcmd; DPRINTK("EXIT\n");}#if 0/************************************************************** * Move cursor to x, y */static void Cyber_MoveCursor (u_short x, u_short y){ volatile unsigned char *regs = CyberRegs; DPRINTK("ENTER\n"); *(regs + S3_CRTC_ADR) = 0x39; *(regs + S3_CRTC_DATA) = 0xa0; *(regs + S3_CRTC_ADR) = S3_HWGC_ORGX_H; *(regs + S3_CRTC_DATA) = (char)((x & 0x0700) >> 8); *(regs + S3_CRTC_ADR) = S3_HWGC_ORGX_L; *(regs + S3_CRTC_DATA) = (char)(x & 0x00ff); *(regs + S3_CRTC_ADR) = S3_HWGC_ORGY_H; *(regs + S3_CRTC_DATA) = (char)((y & 0x0700) >> 8); *(regs + S3_CRTC_ADR) = S3_HWGC_ORGY_L; *(regs + S3_CRTC_DATA) = (char)(y & 0x00ff); DPRINTK("EXIT\n");}#endif/* -------------------- Generic routines ---------------------------------- *//* * Fill the hardware's `par' structure. */static void cyberfb_get_par(struct cyberfb_par *par){ DPRINTK("ENTER\n"); if (current_par_valid) { *par = current_par; } else { Cyber_decode_var(&cyberfb_default, par); } DPRINTK("EXIT\n");}static void cyberfb_set_par(struct cyberfb_par *par){ DPRINTK("ENTER\n"); current_par = *par; current_par_valid = 1; DPRINTK("EXIT\n");}static void cyber_set_video(struct fb_var_screeninfo *var){ /* Load the video mode defined by the 'var' data */ cv64_load_video_mode (var);#ifdef CYBERFBDEBUG DPRINTK("Register state after loading video mode\n"); cv64_dump();#endif}static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive){ int err, activate; struct cyberfb_par par; DPRINTK("ENTER\n"); if ((err = Cyber_decode_var(var, &par))) { DPRINTK("EXIT - decode_var failed\n"); return(err); } activate = var->activate; if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive) cyberfb_set_par(&par); Cyber_encode_var(var, &par); var->activate = activate; cyber_set_video(var); DPRINTK("EXIT\n"); return 0;}static void do_install_cmap(int con, struct fb_info *info){ DPRINTK("ENTER\n"); if (con != currcon) { DPRINTK("EXIT - Not current console\n"); return; } if (fb_display[con].cmap.len) { DPRINTK("Use console cmap\n"); fb_set_cmap(&fb_display[con].cmap, 1, Cyber_setcolreg, info); } else { DPRINTK("Use default cmap\n"); fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), 1, Cyber_setcolreg, info); } DPRINTK("EXIT\n");}/* * Get the Fixed Part of the Display */static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info){ struct cyberfb_par par; int error = 0; DPRINTK("ENTER\n"); if (con == -1) { cyberfb_get_par(&par); } else { error = Cyber_decode_var(&fb_display[con].var, &par); } DPRINTK("EXIT\n"); return(error ? error : Cyber_encode_fix(fix, &par));}/* * Get the User Defined Part of the Display */static int cyberfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){ struct cyberfb_par par; int error = 0; DPRINTK("ENTER\n"); if (con == -1) { cyberfb_get_par(&par); error = Cyber_encode_var(var, &par); disp.var = *var; /* ++Andre: don't know if this is the right place */ } else { *var = fb_display[con].var; } DPRINTK("EXIT\n"); return(error);}static void cyberfb_set_disp(int con, struct fb_info *info){ struct fb_fix_screeninfo fix; struct display *display; DPRINTK("ENTER\n"); if (con >= 0) display = &fb_display[con]; else display = &disp; /* used during initialization */ cyberfb_get_fix(&fix, con, info); if (con == -1) con = 0; display->screen_base = (unsigned char *)CyberMem; display->visual = fix.visual; display->type = fix.type; display->type_aux = fix.type_aux; display->ypanstep = fix.ypanstep; display->ywrapstep = fix.ywrapstep; display->can_soft_blank = 1; display->inverse = Cyberfb_inverse; switch (display->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8 case 8: if (display->var.accel_flags & FB_ACCELF_TEXT) { display->dispsw = &fbcon_cyber8;#warning FIXME: We should reinit the graphics engine here } else display->dispsw = &fbcon_cfb8; break;#endif#ifdef FBCON_HAS_CFB16 case 16: display->dispsw = &fbcon_cfb16; break;#endif default: display->dispsw = NULL; break; } DPRINTK("EXIT\n");}/* * Set the User Defined Part of the Display */static int cyberfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){ int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel; DPRINTK("ENTER\n"); if ((err = do_fb_set_var(var, con == currcon))) { DPRINTK("EXIT - do_fb_set_var failed\n"); return(err); } if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { oldxres = fb_display[con].var.xres; oldyres = fb_display[con].var.yres; oldvxres = fb_display[con].var.xres_virtual; oldvyres = fb_display[con].var.yres_virtual; oldbpp = fb_display[con].var.bits_per_pixel; oldaccel = fb_display[con].var.accel_flags; fb_display[con].var = *var; if (oldxres != var->xres || oldyres != var->yres || oldvxres != var->xres_virtual || oldvyres != var->yres_virtual || oldbpp != var->bits_per_pixel || oldaccel != var->accel_flags) { cyberfb_set_disp(con, info); (*fb_info.changevar)(con); fb_alloc_cmap(&fb_display[con].cmap, 0, 0); do_install_cmap(con, info); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -