📄 atafb.c
字号:
fix->type=FB_TYPE_PACKED_PIXELS; fix->type_aux=0; if (mode == TT_SHIFTER_TTHIGH) fix->visual=FB_VISUAL_MONO01; } fix->xpanstep=0; fix->ypanstep=1; fix->ywrapstep=0; fix->line_length = 0; fix->accel = FB_ACCEL_ATARIBLITT; return 0;}static int tt_decode_var( struct fb_var_screeninfo *var, struct atafb_par *par ){ int xres=var->xres; int yres=var->yres; int bpp=var->bits_per_pixel; int linelen; int yres_virtual = var->yres_virtual; if (mono_moni) { if (bpp > 1 || xres > sttt_xres*2 || yres >tt_yres*2) return -EINVAL; par->hw.tt.mode=TT_SHIFTER_TTHIGH; xres=sttt_xres*2; yres=tt_yres*2; bpp=1; } else { if (bpp > 8 || xres > sttt_xres || yres > tt_yres) return -EINVAL; if (bpp > 4) { if (xres > sttt_xres/2 || yres > tt_yres) return -EINVAL; par->hw.tt.mode=TT_SHIFTER_TTLOW; xres=sttt_xres/2; yres=tt_yres; bpp=8; } else if (bpp > 2) { if (xres > sttt_xres || yres > tt_yres) return -EINVAL; if (xres > sttt_xres/2 || yres > st_yres/2) { par->hw.tt.mode=TT_SHIFTER_TTMID; xres=sttt_xres; yres=tt_yres; bpp=4; } else { par->hw.tt.mode=TT_SHIFTER_STLOW; xres=sttt_xres/2; yres=st_yres/2; bpp=4; } } else if (bpp > 1) { if (xres > sttt_xres || yres > st_yres/2) return -EINVAL; par->hw.tt.mode=TT_SHIFTER_STMID; xres=sttt_xres; yres=st_yres/2; bpp=2; } else if (var->xres > sttt_xres || var->yres > st_yres) { return -EINVAL; } else { par->hw.tt.mode=TT_SHIFTER_STHIGH; xres=sttt_xres; yres=st_yres; bpp=1; } } if (yres_virtual <= 0) yres_virtual = 0; else if (yres_virtual < yres) yres_virtual = yres; if (var->sync & FB_SYNC_EXT) par->hw.tt.sync=0; else par->hw.tt.sync=1; linelen=xres*bpp/8; if (yres_virtual * linelen > screen_len && screen_len) return -EINVAL; if (yres * linelen > screen_len && screen_len) return -EINVAL; if (var->yoffset + yres > yres_virtual && yres_virtual) return -EINVAL; par->yres_virtual = yres_virtual; par->screen_base = screen_base + var->yoffset * linelen; return 0;}static int tt_encode_var( struct fb_var_screeninfo *var, struct atafb_par *par ){ int linelen; memset(var, 0, sizeof(struct fb_var_screeninfo)); var->red.offset=0; var->red.length=4; var->red.msb_right=0; var->grayscale=0; var->pixclock=31041; var->left_margin=120; /* these may be incorrect */ var->right_margin=100; var->upper_margin=8; var->lower_margin=16; var->hsync_len=140; var->vsync_len=30; var->height=-1; var->width=-1; if (par->hw.tt.sync & 1) var->sync=0; else var->sync=FB_SYNC_EXT; switch (par->hw.tt.mode & TT_SHIFTER_MODEMASK) { case TT_SHIFTER_STLOW: var->xres=sttt_xres/2; var->xres_virtual=sttt_xres_virtual/2; var->yres=st_yres/2; var->bits_per_pixel=4; break; case TT_SHIFTER_STMID: var->xres=sttt_xres; var->xres_virtual=sttt_xres_virtual; var->yres=st_yres/2; var->bits_per_pixel=2; break; case TT_SHIFTER_STHIGH: var->xres=sttt_xres; var->xres_virtual=sttt_xres_virtual; var->yres=st_yres; var->bits_per_pixel=1; break; case TT_SHIFTER_TTLOW: var->xres=sttt_xres/2; var->xres_virtual=sttt_xres_virtual/2; var->yres=tt_yres; var->bits_per_pixel=8; break; case TT_SHIFTER_TTMID: var->xres=sttt_xres; var->xres_virtual=sttt_xres_virtual; var->yres=tt_yres; var->bits_per_pixel=4; break; case TT_SHIFTER_TTHIGH: var->red.length=0; var->xres=sttt_xres*2; var->xres_virtual=sttt_xres_virtual*2; var->yres=tt_yres*2; var->bits_per_pixel=1; break; } var->blue=var->green=var->red; var->transp.offset=0; var->transp.length=0; var->transp.msb_right=0; linelen=var->xres_virtual * var->bits_per_pixel / 8; if (! use_hwscroll) var->yres_virtual=var->yres; else if (screen_len) { if (par->yres_virtual) var->yres_virtual = par->yres_virtual; else /* yres_virtual==0 means use maximum */ var->yres_virtual = screen_len / linelen; } else { if (hwscroll < 0) var->yres_virtual = 2 * var->yres; else var->yres_virtual=var->yres+hwscroll * 16; } var->xoffset=0; if (screen_base) var->yoffset=(par->screen_base - screen_base)/linelen; else var->yoffset=0; var->nonstd=0; var->activate=0; var->vmode=FB_VMODE_NONINTERLACED; return 0;}static void tt_get_par( struct atafb_par *par ){ unsigned long addr; par->hw.tt.mode=shifter_tt.tt_shiftmode; par->hw.tt.sync=shifter.syncmode; addr = ((shifter.bas_hi & 0xff) << 16) | ((shifter.bas_md & 0xff) << 8) | ((shifter.bas_lo & 0xff)); par->screen_base = phys_to_virt(addr);}static void tt_set_par( struct atafb_par *par ){ shifter_tt.tt_shiftmode=par->hw.tt.mode; shifter.syncmode=par->hw.tt.sync; /* only set screen_base if really necessary */ if (current_par.screen_base != par->screen_base) fbhw->set_screen_base(par->screen_base);}static int tt_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue, unsigned *transp, struct fb_info *info){ int t, col; if ((shifter_tt.tt_shiftmode & TT_SHIFTER_MODEMASK) == TT_SHIFTER_STHIGH) regno += 254; if (regno > 255) return 1; t = tt_palette[regno]; col = t & 15; col |= col << 4; col |= col << 8; *blue = col; col = (t >> 4) & 15; col |= col << 4; col |= col << 8; *green = col; col = (t >> 8) & 15; col |= col << 4; col |= col << 8; *red = col; *transp = 0; return 0;}static int tt_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info){ if ((shifter_tt.tt_shiftmode & TT_SHIFTER_MODEMASK) == TT_SHIFTER_STHIGH) regno += 254; if (regno > 255) return 1; tt_palette[regno] = (((red >> 12) << 8) | ((green >> 12) << 4) | (blue >> 12)); if ((shifter_tt.tt_shiftmode & TT_SHIFTER_MODEMASK) == TT_SHIFTER_STHIGH && regno == 254) tt_palette[0] = 0; return 0;} static int tt_detect( void ){ struct atafb_par par; /* Determine the connected monitor: The DMA sound must be * disabled before reading the MFP GPIP, because the Sound * Done Signal and the Monochrome Detect are XORed together! * * Even on a TT, we should look if there is a DMA sound. It was * announced that the Eagle is TT compatible, but only the PCM is * missing... */ if (ATARIHW_PRESENT(PCM_8BIT)) { tt_dmasnd.ctrl = DMASND_CTRL_OFF; udelay(20); /* wait a while for things to settle down */ } mono_moni = (mfp.par_dt_reg & 0x80) == 0; tt_get_par(&par); tt_encode_var(&atafb_predefined[0], &par); return 1;}#endif /* ATAFB_TT *//* ------------------- Falcon specific functions ---------------------- */#ifdef ATAFB_FALCONstatic int mon_type; /* Falcon connected monitor */static int f030_bus_width; /* Falcon ram bus width (for vid_control) */#define F_MON_SM 0#define F_MON_SC 1#define F_MON_VGA 2#define F_MON_TV 3static struct pixel_clock { unsigned long f; /* f/[Hz] */ unsigned long t; /* t/[ps] (=1/f) */ int right, hsync, left; /* standard timing in clock cycles, not pixel */ /* hsync initialized in falcon_detect() */ int sync_mask; /* or-mask for hw.falcon.sync to set this clock */ int control_mask; /* ditto, for hw.falcon.vid_control */}f25 = {25175000, 39721, 18, 0, 42, 0x0, VCO_CLOCK25},f32 = {32000000, 31250, 18, 0, 42, 0x0, 0},fext = { 0, 0, 18, 0, 42, 0x1, 0};/* VIDEL-prescale values [mon_type][pixel_length from VCO] */static int vdl_prescale[4][3] = {{4,2,1}, {4,2,1}, {4,2,2}, {4,2,1}};/* Default hsync timing [mon_type] in picoseconds */static long h_syncs[4] = {3000000, 4875000, 4000000, 4875000};#ifdef FBCON_HAS_CFB16static u16 fbcon_cfb16_cmap[16];#endifstatic inline int hxx_prescale(struct falcon_hw *hw){ return hw->ste_mode ? 16 : vdl_prescale[mon_type][hw->vid_mode >> 2 & 0x3];}static int falcon_encode_fix( struct fb_fix_screeninfo *fix, struct atafb_par *par ){ strcpy(fix->id, "Atari Builtin"); fix->smem_start = (unsigned long)real_screen_base; fix->smem_len = screen_len; fix->type = FB_TYPE_INTERLEAVED_PLANES; fix->type_aux = 2; fix->visual = FB_VISUAL_PSEUDOCOLOR; fix->xpanstep = 1; fix->ypanstep = 1; fix->ywrapstep = 0; if (par->hw.falcon.mono) { fix->type = FB_TYPE_PACKED_PIXELS; fix->type_aux = 0; /* no smooth scrolling with longword aligned video mem */ fix->xpanstep = 32; } else if (par->hw.falcon.f_shift & 0x100) { fix->type = FB_TYPE_PACKED_PIXELS; fix->type_aux = 0; /* Is this ok or should it be DIRECTCOLOR? */ fix->visual = FB_VISUAL_TRUECOLOR; fix->xpanstep = 2; } fix->line_length = 0; fix->accel = FB_ACCEL_ATARIBLITT; return 0;}static int falcon_decode_var( struct fb_var_screeninfo *var, struct atafb_par *par ){ int bpp = var->bits_per_pixel; int xres = var->xres; int yres = var->yres; int xres_virtual = var->xres_virtual; int yres_virtual = var->yres_virtual; int left_margin, right_margin, hsync_len; int upper_margin, lower_margin, vsync_len; int linelen; int interlace = 0, doubleline = 0; struct pixel_clock *pclock; int plen; /* width of pixel in clock cycles */ int xstretch; int prescale; int longoffset = 0; int hfreq, vfreq;/* Get the video params out of 'var'. If a value doesn't fit, round it up, if it's too big, return EINVAL. Round up in the following order: bits_per_pixel, xres, yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, bitfields, horizontal timing, vertical timing. There is a maximum of screen resolution determined by pixelclock and minimum frame rate -- (X+hmarg.)*(Y+vmarg.)*vfmin <= pixelclock. In interlace mode this is " * " *vfmin <= pixelclock. Additional constraints: hfreq. Frequency range for multisync monitors is given via command line. For TV and SM124 both frequencies are fixed. X % 16 == 0 to fit 8x?? font (except 1 bitplane modes must use X%32==0) Y % 16 == 0 to fit 8x16 font Y % 8 == 0 if Y<400 Currently interlace and doubleline mode in var are ignored. On SM124 and TV only the standard resolutions can be used.*/ /* Reject uninitialized mode */ if (!xres || !yres || !bpp) return -EINVAL; if (mon_type == F_MON_SM && bpp != 1) { return -EINVAL; } else if (bpp <= 1) { bpp = 1; par->hw.falcon.f_shift = 0x400; par->hw.falcon.st_shift = 0x200; } else if (bpp <= 2) { bpp = 2; par->hw.falcon.f_shift = 0x000; par->hw.falcon.st_shift = 0x100; } else if (bpp <= 4) { bpp = 4; par->hw.falcon.f_shift = 0x000; par->hw.falcon.st_shift = 0x000; } else if (bpp <= 8) { bpp = 8; par->hw.falcon.f_shift = 0x010; } else if (bpp <= 16) { bpp = 16; /* packed pixel mode */ par->hw.falcon.f_shift = 0x100; /* hicolor, no overlay */ } else return -EINVAL; par->hw.falcon.bpp = bpp; if (mon_type == F_MON_SM || DontCalcRes) { /* Skip all calculations. VGA/TV/SC1224 only supported. */ struct fb_var_screeninfo *myvar = &atafb_predefined[0]; if (bpp > myvar->bits_per_pixel || var->xres > myvar->xres || var->yres > myvar->yres) return -EINVAL; fbhw->get_par(par); /* Current par will be new par */ goto set_screen_base; /* Don't forget this */ } /* Only some fixed resolutions < 640x400 */ if (xres <= 320) xres = 320; else if (xres <= 640 && bpp != 16) xres = 640; if (yres <= 200) yres = 200; else if (yres <= 240) yres = 240; else if (yres <= 400) yres = 400; /* 2 planes must use STE compatibility mode */ par->hw.falcon.ste_mode = bpp==2; par->hw.falcon.mono = bpp==1; /* Total and visible scanline length must be a multiple of one longword, * this and the console fontwidth yields the alignment for xres and * xres_virtual. * TODO: this way "odd" fontheights are not supported * * Special case in STE mode: blank and graphic positions don't align, * avoid trash at right margin */ if (par->hw.falcon.ste_mode) xres = (xres + 63) & ~63; else if (bpp == 1) xres = (xres + 31) & ~31; else xres = (xres + 15) & ~15; if (yres >= 400) yres = (yres + 15) & ~15;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -