📄 imsttfb.c
字号:
break; case 1152: hes = 0x0012; heb = 0x0022; veb = 0x0031; htp = 4; vtp = 3; MHz = 101 /* .6_ */ ; break; case 1280: hes = 0x0012; heb = 0x002f; veb = 0x0029; htp = 4; vtp = 1; MHz = yres == 960 ? 126 : 135; break; case 1600: hes = 0x0018; heb = 0x0040; veb = 0x002a; htp = 4; vtp = 3; MHz = 200; break; default: return 0; } setclkMHz(p, MHz); init->hes = hes; init->heb = heb; init->hsb = init->heb + (xres >> 3); init->ht = init->hsb + htp; init->ves = 0x0003; init->veb = veb; init->vsb = init->veb + yres; init->vt = init->vsb + vtp; init->vil = init->vsb; init->pitch = xres; return init;}static struct imstt_regvals *compute_imstt_regvals_tvp (struct fb_info_imstt *p, int xres, int yres){ struct imstt_regvals *init; switch (xres) { case 512: init = &tvp_reg_init_2; break; case 640: init = &tvp_reg_init_6; break; case 800: init = &tvp_reg_init_12; break; case 832: init = &tvp_reg_init_13; break; case 1024: init = &tvp_reg_init_17; break; case 1152: init = &tvp_reg_init_18; break; case 1280: init = yres == 960 ? &tvp_reg_init_19 : &tvp_reg_init_20; break; default: return 0; } p->init = *init; return init;}static struct imstt_regvals *compute_imstt_regvals (struct fb_info_imstt *p, u_int xres, u_int yres){ if (p->ramdac == IBM) return compute_imstt_regvals_ibm(p, xres, yres); else return compute_imstt_regvals_tvp(p, xres, yres);}static voidset_imstt_regvals_ibm (struct fb_info_imstt *p, u_int bpp){ struct imstt_regvals *init = &p->init; __u8 pformat = (bpp >> 3) + 2; p->cmap_regs[PIDXHI] = 0; eieio(); p->cmap_regs[PIDXLO] = PIXM0; eieio(); p->cmap_regs[PIDXDATA] = init->pclk_m; eieio(); p->cmap_regs[PIDXLO] = PIXN0; eieio(); p->cmap_regs[PIDXDATA] = init->pclk_n; eieio(); p->cmap_regs[PIDXLO] = PIXP0; eieio(); p->cmap_regs[PIDXDATA] = init->pclk_p; eieio(); p->cmap_regs[PIDXLO] = PIXC0; eieio(); p->cmap_regs[PIDXDATA] = 0x02; eieio(); p->cmap_regs[PIDXLO] = PIXFMT; eieio(); p->cmap_regs[PIDXDATA] = pformat; eieio();}static voidset_imstt_regvals_tvp (struct fb_info_imstt *p, u_int bpp){ struct imstt_regvals *init = &p->init; __u8 tcc, mxc, lckl_n, mic; __u8 mlc, lckl_p; switch (bpp) { case 8: tcc = 0x80; mxc = 0x4d; lckl_n = 0xc1; mlc = init->mlc[0]; lckl_p = init->lckl_p[0]; break; case 16: tcc = 0x44; mxc = 0x55; lckl_n = 0xe1; mlc = init->mlc[1]; lckl_p = init->lckl_p[1]; break; case 24: tcc = 0x5e; mxc = 0x5d; lckl_n = 0xf1; mlc = init->mlc[2]; lckl_p = init->lckl_p[2]; break; case 32: tcc = 0x46; mxc = 0x5d; lckl_n = 0xf1; mlc = init->mlc[2]; lckl_p = init->lckl_p[2]; break; } mic = 0x08; p->cmap_regs[TVPADDRW] = TVPIRPLA; eieio(); p->cmap_regs[TVPIDATA] = 0x00; eieio(); p->cmap_regs[TVPADDRW] = TVPIRPPD; eieio(); p->cmap_regs[TVPIDATA] = init->pclk_m; eieio(); p->cmap_regs[TVPADDRW] = TVPIRPPD; eieio(); p->cmap_regs[TVPIDATA] = init->pclk_n; eieio(); p->cmap_regs[TVPADDRW] = TVPIRPPD; eieio(); p->cmap_regs[TVPIDATA] = init->pclk_p; eieio(); p->cmap_regs[TVPADDRW] = TVPIRTCC; eieio(); p->cmap_regs[TVPIDATA] = tcc; eieio(); p->cmap_regs[TVPADDRW] = TVPIRMXC; eieio(); p->cmap_regs[TVPIDATA] = mxc; eieio(); p->cmap_regs[TVPADDRW] = TVPIRMIC; eieio(); p->cmap_regs[TVPIDATA] = mic; eieio(); p->cmap_regs[TVPADDRW] = TVPIRPLA; eieio(); p->cmap_regs[TVPIDATA] = 0x00; eieio(); p->cmap_regs[TVPADDRW] = TVPIRLPD; eieio(); p->cmap_regs[TVPIDATA] = lckl_n; eieio(); p->cmap_regs[TVPADDRW] = TVPIRPLA; eieio(); p->cmap_regs[TVPIDATA] = 0x15; eieio(); p->cmap_regs[TVPADDRW] = TVPIRMLC; eieio(); p->cmap_regs[TVPIDATA] = mlc; eieio(); p->cmap_regs[TVPADDRW] = TVPIRPLA; eieio(); p->cmap_regs[TVPIDATA] = 0x2a; eieio(); p->cmap_regs[TVPADDRW] = TVPIRLPD; eieio(); p->cmap_regs[TVPIDATA] = lckl_p; eieio();}static voidset_imstt_regvals (struct fb_info_imstt *p, u_int bpp){ struct imstt_regvals *init = &p->init; __u32 ctl, pitch, byteswap, scr; if (p->ramdac == IBM) set_imstt_regvals_ibm(p, bpp); else set_imstt_regvals_tvp(p, bpp); /* * From what I (jsk) can gather poking around with MacsBug, * bits 8 and 9 in the SCR register control endianness * correction (byte swapping). These bits must be set according * to the color depth as follows: * Color depth Bit 9 Bit 8 * ========== ===== ===== * 8bpp 0 0 * 16bpp 0 1 * 32bpp 1 1 */ switch (bpp) { case 8: ctl = 0x17b1; pitch = init->pitch >> 2; byteswap = 0x000; break; case 16: ctl = 0x17b3; pitch = init->pitch >> 1; byteswap = 0x100; break; case 24: ctl = 0x17b9; pitch = init->pitch - (p->init.pitch >> 2); byteswap = 0x200; break; case 32: ctl = 0x17b5; pitch = init->pitch; byteswap = 0x300; break; } if (p->ramdac == TVP) ctl -= 0x30; out_le32(&p->dc_regs[HES], init->hes); out_le32(&p->dc_regs[HEB], init->heb); out_le32(&p->dc_regs[HSB], init->hsb); out_le32(&p->dc_regs[HT], init->ht); out_le32(&p->dc_regs[VES], init->ves); out_le32(&p->dc_regs[VEB], init->veb); out_le32(&p->dc_regs[VSB], init->vsb); out_le32(&p->dc_regs[VT], init->vt); out_le32(&p->dc_regs[VIL], init->vil); out_le32(&p->dc_regs[HCIV], 1); out_le32(&p->dc_regs[VCIV], 1); out_le32(&p->dc_regs[TCDR], 4); out_le32(&p->dc_regs[RRCIV], 1); out_le32(&p->dc_regs[RRSC], 0x980); out_le32(&p->dc_regs[RRCR], 0x11); if (p->ramdac == IBM) { out_le32(&p->dc_regs[HRIR], 0x0100); out_le32(&p->dc_regs[CMR], 0x00ff); out_le32(&p->dc_regs[SRGCTL], 0x0073); } else { out_le32(&p->dc_regs[HRIR], 0x0200); out_le32(&p->dc_regs[CMR], 0x01ff); out_le32(&p->dc_regs[SRGCTL], 0x0003); } switch (p->total_vram) { case 0x200000: scr = 0x059d | byteswap; break; /* case 0x400000: case 0x800000: */ default: pitch >>= 1; scr = 0x150dd | byteswap; break; } out_le32(&p->dc_regs[SCR], scr); out_le32(&p->dc_regs[SPR], pitch); out_le32(&p->dc_regs[STGCTL], ctl);}static inline voidset_offset (struct display *disp, struct fb_info_imstt *p){ __u32 off = disp->var.yoffset * (disp->line_length >> 3) + ((disp->var.xoffset * (disp->var.bits_per_pixel >> 3)) >> 3); out_le32(&p->dc_regs[SSR], off);}static inline voidset_555 (struct fb_info_imstt *p){ if (p->ramdac == IBM) { p->cmap_regs[PIDXHI] = 0; eieio(); p->cmap_regs[PIDXLO] = BPP16; eieio(); p->cmap_regs[PIDXDATA] = 0x01; eieio(); } else { p->cmap_regs[TVPADDRW] = TVPIRTCC; eieio(); p->cmap_regs[TVPIDATA] = 0x44; eieio(); }}static inline voidset_565 (struct fb_info_imstt *p){ if (p->ramdac == IBM) { p->cmap_regs[PIDXHI] = 0; eieio(); p->cmap_regs[PIDXLO] = BPP16; eieio(); p->cmap_regs[PIDXDATA] = 0x03; eieio(); } else { p->cmap_regs[TVPADDRW] = TVPIRTCC; eieio(); p->cmap_regs[TVPIDATA] = 0x45; eieio(); }}static voidimstt_set_cursor (struct fb_info_imstt *p, int on){ struct imstt_cursor *c = &p->cursor; if (p->ramdac == IBM) { p->cmap_regs[PIDXHI] = 0; eieio(); if (!on) { p->cmap_regs[PIDXLO] = CURSCTL; eieio(); p->cmap_regs[PIDXDATA] = 0x00; eieio(); } else { p->cmap_regs[PIDXLO] = CURSXHI; eieio(); p->cmap_regs[PIDXDATA] = c->x >> 8; eieio(); p->cmap_regs[PIDXLO] = CURSXLO; eieio(); p->cmap_regs[PIDXDATA] = c->x & 0xff; eieio(); p->cmap_regs[PIDXLO] = CURSYHI; eieio(); p->cmap_regs[PIDXDATA] = c->y >> 8; eieio(); p->cmap_regs[PIDXLO] = CURSYLO; eieio(); p->cmap_regs[PIDXDATA] = c->y & 0xff; eieio(); p->cmap_regs[PIDXLO] = CURSCTL; eieio(); p->cmap_regs[PIDXDATA] = 0x02; eieio(); } } else { if (!on) { p->cmap_regs[TVPADDRW] = TVPIRICC; eieio(); p->cmap_regs[TVPIDATA] = 0x00; eieio(); } else { __u16 x = c->x + 0x40, y = c->y + 0x40; p->cmap_regs[TVPCXPOH] = x >> 8; eieio(); p->cmap_regs[TVPCXPOL] = x & 0xff; eieio(); p->cmap_regs[TVPCYPOH] = y >> 8; eieio(); p->cmap_regs[TVPCYPOL] = y & 0xff; eieio(); p->cmap_regs[TVPADDRW] = TVPIRICC; eieio(); p->cmap_regs[TVPIDATA] = 0x02; eieio(); } }}static voidimsttfbcon_cursor (struct display *disp, int mode, int x, int y){ struct fb_info_imstt *p = (struct fb_info_imstt *)disp->fb_info; struct imstt_cursor *c = &p->cursor; x *= fontwidth(disp); y *= fontheight(disp); if (c->x == x && c->y == y && (mode == CM_ERASE) == !c->enable) return; c->enable = 0; if (c->on) imstt_set_cursor(p, 0); c->x = x - disp->var.xoffset; c->y = y - disp->var.yoffset; switch (mode) { case CM_ERASE: c->on = 0; break; case CM_DRAW: case CM_MOVE: if (c->on) imstt_set_cursor(p, c->on); else c->vbl_cnt = CURSOR_DRAW_DELAY; c->enable = 1; break; }}static intimsttfbcon_set_font (struct display *disp, int width, int height){ struct fb_info_imstt *p = (struct fb_info_imstt *)disp->fb_info; struct imstt_cursor *c = &p->cursor; u_int x, y; __u8 fgc; if (width > 32 || height > 32) return -EINVAL; c->height = height; c->width = width; fgc = ~attr_bgcol_ec(disp, disp->conp); if (p->ramdac == IBM) { p->cmap_regs[PIDXHI] = 1; eieio(); for (x = 0; x < 0x100; x++) { p->cmap_regs[PIDXLO] = x; eieio(); p->cmap_regs[PIDXDATA] = 0x00; eieio(); } p->cmap_regs[PIDXHI] = 1; eieio(); for (y = 0; y < height; y++) for (x = 0; x < width >> 2; x++) { p->cmap_regs[PIDXLO] = x + y * 8; eieio(); p->cmap_regs[PIDXDATA] = 0xff; eieio(); } p->cmap_regs[PIDXHI] = 0; eieio(); p->cmap_regs[PIDXLO] = CURS1R; eieio(); p->cmap_regs[PIDXDATA] = fgc; eieio(); p->cmap_regs[PIDXLO] = CURS1G; eieio(); p->cmap_regs[PIDXDATA] = fgc; eieio(); p->cmap_regs[PIDXLO] = CURS1B; eieio(); p->cmap_regs[PIDXDATA] = fgc; eieio(); p->cmap_regs[PIDXLO] = CURS2R; eieio(); p->cmap_regs[PIDXDATA] = fgc; eieio(); p->cmap_regs[PIDXLO] = CURS2G; eieio(); p->cmap_regs[PIDXDATA] = fgc; eieio(); p->cmap_regs[PIDXLO] = CURS2B; eieio(); p->cmap_regs[PIDXDATA] = fgc; eieio(); p->cmap_regs[PIDXLO] = CURS3R; eieio(); p->cmap_regs[PIDXDATA] = fgc; eieio(); p->cmap_regs[PIDXLO] = CURS3G; eieio(); p->cmap_regs[PIDXDATA] = fgc; eieio(); p->cmap_regs[PIDXLO] = CURS3B; eieio(); p->cmap_regs[PIDXDATA] = fgc; eieio(); } else { p->cmap_regs[TVPADDRW] = TVPIRICC; eieio(); p->cmap_regs[TVPIDATA] &= 0x03; eieio(); p->cmap_regs[TVPADDRW] = 0; eieio(); for (x = 0; x < 0x200; x++) { p->cmap_regs[TVPCRDAT] = 0x00; eieio(); } for (x = 0; x < 0x200; x++) { p->cmap_regs[TVPCRDAT] = 0xff; eieio(); } p->cmap_regs[TVPADDRW] = TVPIRICC; eieio(); p->cmap_regs[TVPIDATA] &= 0x03; eieio(); for (y = 0; y < height; y++) for (x = 0; x < width >> 3; x++) { p->cmap_regs[TVPADDRW] = x + y * 8; eieio(); p->cmap_regs[TVPCRDAT] = 0xff; eieio(); } p->cmap_regs[TVPADDRW] = TVPIRICC; eieio(); p->cmap_regs[TVPIDATA] |= 0x08; eieio(); for (y = 0; y < height; y++) for (x = 0; x < width >> 3; x++) { p->cmap_regs[TVPADDRW] = x + y * 8; eieio(); p->cmap_regs[TVPCRDAT] = 0xff; eieio(); } p->cmap_regs[TVPCADRW] = 0x00; eieio(); for (x = 0; x < 12; x++) { p->cmap_regs[TVPCDATA] = fgc; eieio(); } } return 1;}static voidimstt_cursor_timer_handler (unsigned long dev_addr){ struct fb_info_imstt *p = (struct fb_info_imstt *)dev_addr; struct imstt_cursor *c = &p->cursor; if (!c->enable) goto out; if (c->vbl_cnt && --c->vbl_cnt == 0) { c->on ^= 1; imstt_set_cursor(p, c->on); c->vbl_cnt = c->blink_rate; }out: c->timer.expires = jiffies + (HZ / 50); add_timer(&c->timer);}static void __init imstt_cursor_init (struct fb_info_imstt *p){ struct imstt_cursor *c = &p->cursor; imsttfbcon_set_font(&p->disp, fontwidth(&p->disp), fontheight(&p->disp)); c->enable = 1; c->on = 1; c->x = c->y = 0; c->blink_rate = 0; c->vbl_cnt = CURSOR_DRAW_DELAY; if (curblink) { c->blink_rate = CURSOR_BLINK_RATE; init_timer(&c->timer); c->timer.expires = jiffies + (HZ / 50); c->timer.data = (unsigned long)p; c->timer.function = imstt_cursor_timer_handler; add_timer(&c->timer); }}static voidimsttfbcon_bmove (struct display *disp, int sy, int sx, int dy, int dx, int height, int width){ struct fb_info_imstt *p = (struct fb_info_imstt *)disp->fb_info; __u32 Bpp, line_pitch, fb_offset_old, fb_offset_new, sp, dp_octl, cnt, bltctl; Bpp = disp->var.bits_per_pixel >> 3, sy *= fontheight(disp); sx *= fontwidth(disp); sx *= Bpp; dy *= fontheight(disp); dx *= fontwidth(disp); dx *= Bpp; height *= fontheight(disp); height--; width *= fontwidth(disp); width *= Bpp; width--; line_pitch = disp->line_length; bltctl = 0x05; sp = line_pitch << 16;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -