📄 imsttfb.c
字号:
cnt = height << 16; if (sy < dy) { sy += height; dy += height; sp |= -(line_pitch) & 0xffff; dp_octl = -(line_pitch) & 0xffff; } else { sp |= line_pitch; dp_octl = line_pitch; } if (sx < dx) { sx += width; dx += width; bltctl |= 0x80; cnt |= -(width) & 0xffff; } else { cnt |= width; } fb_offset_old = sy * line_pitch + sx; fb_offset_new = dy * line_pitch + dx; while(in_le32(&p->dc_regs[SSTATUS]) & 0x80); out_le32(&p->dc_regs[S1SA], fb_offset_old); out_le32(&p->dc_regs[SP], sp); out_le32(&p->dc_regs[DSA], fb_offset_new); out_le32(&p->dc_regs[CNT], cnt); out_le32(&p->dc_regs[DP_OCTL], dp_octl); out_le32(&p->dc_regs[BLTCTL], bltctl); while(in_le32(&p->dc_regs[SSTATUS]) & 0x80); while(in_le32(&p->dc_regs[SSTATUS]) & 0x40);}static voidimsttfbcon_clear (struct vc_data *conp, struct display *disp, int sy, int sx, int height, int width){ struct fb_info_imstt *p = (struct fb_info_imstt *)disp->fb_info; __u32 Bpp, line_pitch, bgc; bgc = attr_bgcol_ec(disp, conp); bgc |= (bgc << 8); bgc |= (bgc << 16); Bpp = disp->var.bits_per_pixel >> 3, line_pitch = disp->line_length; sy *= fontheight(disp); sy *= line_pitch; sx *= fontwidth(disp); sx *= Bpp; height *= fontheight(disp); height--; width *= fontwidth(disp); width *= Bpp; width--; while(in_le32(&p->dc_regs[SSTATUS]) & 0x80); out_le32(&p->dc_regs[DSA], sy + sx); out_le32(&p->dc_regs[CNT], (height << 16) | width); out_le32(&p->dc_regs[DP_OCTL], line_pitch); out_le32(&p->dc_regs[BI], 0xffffffff); out_le32(&p->dc_regs[MBC], 0xffffffff); out_le32(&p->dc_regs[CLR], bgc); out_le32(&p->dc_regs[BLTCTL], 0x840); /* 0x200000 */ while(in_le32(&p->dc_regs[SSTATUS]) & 0x80); while(in_le32(&p->dc_regs[SSTATUS]) & 0x40);}static voidimsttfbcon_revc (struct display *disp, int sx, int sy){ struct fb_info_imstt *p = (struct fb_info_imstt *)disp->fb_info; __u32 Bpp, line_pitch, height, width; Bpp = disp->var.bits_per_pixel >> 3, line_pitch = disp->line_length; height = fontheight(disp); width = fontwidth(disp) * Bpp; sy *= height; sy *= line_pitch; sx *= width; height--; width--; while(in_le32(&p->dc_regs[SSTATUS]) & 0x80); out_le32(&p->dc_regs[DSA], sy + sx); out_le32(&p->dc_regs[S1SA], sy + sx); out_le32(&p->dc_regs[CNT], (height << 16) | width); out_le32(&p->dc_regs[DP_OCTL], line_pitch); out_le32(&p->dc_regs[SP], line_pitch); out_le32(&p->dc_regs[BLTCTL], 0x40005); while(in_le32(&p->dc_regs[SSTATUS]) & 0x80); while(in_le32(&p->dc_regs[SSTATUS]) & 0x40);}#ifdef FBCON_HAS_CFB8static struct display_switch fbcon_imstt8 = { setup: fbcon_cfb8_setup, bmove: imsttfbcon_bmove, clear: imsttfbcon_clear, putc: fbcon_cfb8_putc, putcs: fbcon_cfb8_putcs, revc: imsttfbcon_revc, cursor: imsttfbcon_cursor, set_font: imsttfbcon_set_font, clear_margins: fbcon_cfb8_clear_margins, fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)};#endif#ifdef FBCON_HAS_CFB16static struct display_switch fbcon_imstt16 = { setup: fbcon_cfb16_setup, bmove: imsttfbcon_bmove, clear: imsttfbcon_clear, putc: fbcon_cfb16_putc, putcs: fbcon_cfb16_putcs, revc: imsttfbcon_revc, cursor: imsttfbcon_cursor, set_font: imsttfbcon_set_font, clear_margins: fbcon_cfb16_clear_margins, fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)};#endif#ifdef FBCON_HAS_CFB24static struct display_switch fbcon_imstt24 = { setup: fbcon_cfb24_setup, bmove: imsttfbcon_bmove, clear: imsttfbcon_clear, putc: fbcon_cfb24_putc, putcs: fbcon_cfb24_putcs, revc: imsttfbcon_revc, cursor: imsttfbcon_cursor, set_font: imsttfbcon_set_font, clear_margins: fbcon_cfb24_clear_margins, fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)};#endif#ifdef FBCON_HAS_CFB32static struct display_switch fbcon_imstt32 = { setup: fbcon_cfb32_setup, bmove: imsttfbcon_bmove, clear: imsttfbcon_clear, putc: fbcon_cfb32_putc, putcs: fbcon_cfb32_putcs, revc: imsttfbcon_revc, cursor: imsttfbcon_cursor, set_font: imsttfbcon_set_font, clear_margins: fbcon_cfb32_clear_margins, fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)};#endif#ifdef CONFIG_FB_COMPAT_XPMAC#include <asm/vc_ioctl.h>extern struct vc_mode display_info;extern struct fb_info *console_fb_info;static voidset_display_info (struct display *disp){ display_info.width = disp->var.xres; display_info.height = disp->var.yres; display_info.depth = disp->var.bits_per_pixel; display_info.pitch = disp->line_length; switch (disp->var.xres) { case 512: display_info.mode = 2; break; case 640: display_info.mode = 6; break; case 800: display_info.mode = 12; break; case 832: display_info.mode = 13; break; case 1024: display_info.mode = 17; break; case 1152: display_info.mode = 18; break; case 1280: display_info.mode = disp->var.yres == 960 ? 19 : 20; break; default: display_info.mode = 0; }}#endifstatic intimsttfb_getcolreg (u_int regno, u_int *red, u_int *green, u_int *blue, u_int *transp, struct fb_info *info){ struct fb_info_imstt *p = (struct fb_info_imstt *)info; if (regno > 255) return 1; *red = (p->palette[regno].red << 8) | p->palette[regno].red; *green = (p->palette[regno].green << 8) | p->palette[regno].green; *blue = (p->palette[regno].blue << 8) | p->palette[regno].blue; *transp = 0; return 0;}static intimsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info){ struct fb_info_imstt *p = (struct fb_info_imstt *)info; u_int bpp = fb_display[currcon].var.bits_per_pixel; if (regno > 255) return 1; red >>= 8; green >>= 8; blue >>= 8; p->palette[regno].red = red; p->palette[regno].green = green; p->palette[regno].blue = blue; /* PADDRW/PDATA are the same as TVPPADDRW/TVPPDATA */ if (0 && bpp == 16) /* screws up X */ p->cmap_regs[PADDRW] = regno << 3; else p->cmap_regs[PADDRW] = regno; eieio(); p->cmap_regs[PDATA] = red; eieio(); p->cmap_regs[PDATA] = green; eieio(); p->cmap_regs[PDATA] = blue; eieio(); if (regno < 16) switch (bpp) {#ifdef FBCON_HAS_CFB16 case 16: p->fbcon_cmap.cfb16[regno] = (regno << (fb_display[currcon].var.green.length == 5 ? 10 : 11)) | (regno << 5) | regno; break;#endif#ifdef FBCON_HAS_CFB24 case 24: p->fbcon_cmap.cfb24[regno] = (regno << 16) | (regno << 8) | regno; break;#endif#ifdef FBCON_HAS_CFB32 case 32: { int i = (regno << 8) | regno; p->fbcon_cmap.cfb32[regno] = (i << 16) | i; break; }#endif } return 0;}static voiddo_install_cmap (int con, struct fb_info *info){ if (fb_display[con].cmap.len) fb_set_cmap(&fb_display[con].cmap, 1, imsttfb_setcolreg, info); else { u_int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256; fb_set_cmap(fb_default_cmap(size), 1, imsttfb_setcolreg, info); }}static intimsttfb_get_fix (struct fb_fix_screeninfo *fix, int con, struct fb_info *info){ struct fb_info_imstt *p = (struct fb_info_imstt *)info; struct fb_var_screeninfo *var = &fb_display[con].var; *fix = p->fix; fix->visual = var->bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; fix->line_length = var->xres * (var->bits_per_pixel >> 3); return 0;}static intimsttfb_get_var (struct fb_var_screeninfo *var, int con, struct fb_info *info){ *var = fb_display[con].var; return 0;}static voidset_dispsw (struct display *disp, struct fb_info_imstt *p){ u_int accel = disp->var.accel_flags & FB_ACCELF_TEXT; if (disp->conp && disp->conp->vc_sw && disp->conp->vc_sw->con_cursor) disp->conp->vc_sw->con_cursor(disp->conp, CM_ERASE); p->dispsw = fbcon_dummy; disp->dispsw = &p->dispsw; disp->dispsw_data = 0; switch (disp->var.bits_per_pixel) { case 8: disp->var.red.offset = 0; disp->var.red.length = 8; disp->var.green.offset = 0; disp->var.green.length = 8; disp->var.blue.offset = 0; disp->var.blue.length = 8; disp->var.transp.offset = 0; disp->var.transp.length = 0;#ifdef FBCON_HAS_CFB8 p->dispsw = accel ? fbcon_imstt8 : fbcon_cfb8;#endif break; case 16: /* RGB 555 or 565 */ if (disp->var.green.length != 6) disp->var.red.offset = 10; disp->var.red.length = 5; disp->var.green.offset = 5; if (disp->var.green.length != 6) disp->var.green.length = 5; disp->var.blue.offset = 0; disp->var.blue.length = 5; disp->var.transp.offset = 0; disp->var.transp.length = 0;#ifdef FBCON_HAS_CFB16 p->dispsw = accel ? fbcon_imstt16 : fbcon_cfb16; disp->dispsw_data = p->fbcon_cmap.cfb16;#endif break; case 24: /* RGB 888 */ disp->var.red.offset = 16; disp->var.red.length = 8; disp->var.green.offset = 8; disp->var.green.length = 8; disp->var.blue.offset = 0; disp->var.blue.length = 8; disp->var.transp.offset = 0; disp->var.transp.length = 0;#ifdef FBCON_HAS_CFB24 p->dispsw = accel ? fbcon_imstt24 : fbcon_cfb24; disp->dispsw_data = p->fbcon_cmap.cfb24;#endif break; case 32: /* RGBA 8888 */ disp->var.red.offset = 16; disp->var.red.length = 8; disp->var.green.offset = 8; disp->var.green.length = 8; disp->var.blue.offset = 0; disp->var.blue.length = 8; disp->var.transp.offset = 24; disp->var.transp.length = 8;#ifdef FBCON_HAS_CFB32 p->dispsw = accel ? fbcon_imstt32 : fbcon_cfb32; disp->dispsw_data = p->fbcon_cmap.cfb32;#endif break; } if (accel && p->ramdac != IBM) { p->dispsw.cursor = 0; p->dispsw.set_font = 0; }#ifdef CONFIG_FB_COMPAT_XPMAC set_display_info(disp);#endif}static voidset_disp (struct display *disp, struct fb_info_imstt *p){ u_int accel = disp->var.accel_flags & FB_ACCELF_TEXT; disp->fb_info = &p->info; set_dispsw(disp, p); disp->visual = disp->var.bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; disp->screen_base = (__u8 *)p->frame_buffer; disp->visual = p->fix.visual; disp->type = p->fix.type; disp->type_aux = p->fix.type_aux; disp->line_length = disp->var.xres * (disp->var.bits_per_pixel >> 3); disp->can_soft_blank = 1; disp->inverse = inverse; disp->ypanstep = 1; disp->ywrapstep = 0; if (accel) { disp->scrollmode = SCROLL_YNOMOVE; if (disp->var.yres == disp->var.yres_virtual) { __u32 vram = (p->total_vram - (PAGE_SIZE << 2)); disp->var.yres_virtual = ((vram << 3) / disp->var.bits_per_pixel) / disp->var.xres_virtual; if (disp->var.yres_virtual < disp->var.yres) disp->var.yres_virtual = disp->var.yres; } } else { disp->scrollmode = SCROLL_YREDRAW; } disp->var.activate = 0; disp->var.red.msb_right = 0; disp->var.green.msb_right = 0; disp->var.blue.msb_right = 0; disp->var.transp.msb_right = 0; disp->var.height = -1; disp->var.width = -1; disp->var.vmode = FB_VMODE_NONINTERLACED; disp->var.left_margin = disp->var.right_margin = 16; disp->var.upper_margin = disp->var.lower_margin = 16; disp->var.hsync_len = disp->var.vsync_len = 8;}static intimsttfb_set_var (struct fb_var_screeninfo *var, int con, struct fb_info *info){ struct fb_info_imstt *p = (struct fb_info_imstt *)info; struct display *disp; u_int oldbpp, oldxres, oldyres, oldgreenlen, oldaccel; disp = &fb_display[con]; if ((var->bits_per_pixel != 8 && var->bits_per_pixel != 16 && var->bits_per_pixel != 24 && var->bits_per_pixel != 32) || var->xres_virtual < var->xres || var->yres_virtual < var->yres || var->nonstd || (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) return -EINVAL; if ((var->xres * var->yres) * (var->bits_per_pixel >> 3) > p->total_vram || (var->xres_virtual * var->yres_virtual) * (var->bits_per_pixel >> 3) > p->total_vram) return -EINVAL; if (!((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)) return 0; if (!compute_imstt_regvals(p, var->xres, var->yres)) return -EINVAL; oldbpp = disp->var.bits_per_pixel; oldxres = disp->var.xres; oldyres = disp->var.yres; oldgreenlen = disp->var.green.length; oldaccel = disp->var.accel_flags; disp->var.bits_per_pixel = var->bits_per_pixel; disp->var.xres = var->xres; disp->var.yres = var->yres; disp->var.xres_virtual = var->xres_virtual; disp->var.yres_virtual = var->yres_virtual; disp->var.green.length = var->green.length; disp->var.accel_flags = var->accel_flags; set_disp(disp, p); if (info->changevar) (*info->changevar)(con); if (con == currcon) { if (oldgreenlen != disp->var.green.length) { if (disp->var.green.length == 6) set_565(p); else set_555(p); } if (oldxres != disp->var.xres || oldyres != disp->var.yres || oldbpp != disp->var.bits_per_pixel) set_imstt_regvals(p, disp->var.bits_per_pixel); } disp->var.pixclock = 1000000 / getclkMHz(p); if (oldbpp != disp->var.bits_per_pixel) { int err = fb_alloc_cmap(&disp->cmap, 0, 0); if (err) return err; do_install_cmap(con, info); } *var = disp->var; return 0;}static intimsttfb_pan_display (struct fb_var_screeninfo *var, int con, struct fb_info *info){ struct fb_info_imstt *p = (struct fb_info_imstt *)info; struct display *disp = &fb_display[con]; if (var->xoffset + disp->var.xres > disp->var.xres_virtual || var->yoffset + disp->var.yres > disp->var.yres_virtual) return -EINVAL; disp->var.xoffset = var->xoffset; disp->var.yoffset = var->yoffset; if (con == currcon) set_offset(disp, p); return 0;}static intimsttfb_get_cmap (struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -