📄 atafb.c
字号:
var->transp.offset=0; var->transp.length=0; var->transp.msb_right=0; var->xres_virtual=sttt_xres_virtual; linelen=var->xres_virtual * var->bits_per_pixel / 8; ovsc_addlen=linelen*(sttt_yres_virtual - st_yres); 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 stste_get_par( struct atafb_par *par ){ unsigned long addr; par->hw.st.mode=shifter_tt.st_shiftmode; par->hw.st.sync=shifter.syncmode; addr = ((shifter.bas_hi & 0xff) << 16) | ((shifter.bas_md & 0xff) << 8); if (ATARIHW_PRESENT(EXTD_SHIFTER)) addr |= (shifter.bas_lo & 0xff); par->screen_base = phys_to_virt(addr);}static void stste_set_par( struct atafb_par *par ){ shifter_tt.st_shiftmode=par->hw.st.mode; shifter.syncmode=par->hw.st.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 stste_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue, unsigned *transp, struct fb_info *info){ unsigned col, t; if (regno > 15) return 1; col = shifter_tt.color_reg[regno]; if (ATARIHW_PRESENT(EXTD_SHIFTER)) { t = ((col >> 7) & 0xe) | ((col >> 11) & 1); t |= t << 4; *red = t | (t << 8); t = ((col >> 3) & 0xe) | ((col >> 7) & 1); t |= t << 4; *green = t | (t << 8); t = ((col << 1) & 0xe) | ((col >> 3) & 1); t |= t << 4; *blue = t | (t << 8); } else { t = (col >> 7) & 0xe; t |= t << 4; *red = t | (t << 8); t = (col >> 3) & 0xe; t |= t << 4; *green = t | (t << 8); t = (col << 1) & 0xe; t |= t << 4; *blue = t | (t << 8); } *transp = 0; return 0;}static int stste_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info){ if (regno > 15) return 1; red >>= 12; blue >>= 12; green >>= 12; if (ATARIHW_PRESENT(EXTD_SHIFTER)) shifter_tt.color_reg[regno] = (((red & 0xe) >> 1) | ((red & 1) << 3) << 8) | (((green & 0xe) >> 1) | ((green & 1) << 3) << 4) | ((blue & 0xe) >> 1) | ((blue & 1) << 3); else shifter_tt.color_reg[regno] = ((red & 0xe) << 7) | ((green & 0xe) << 3) | ((blue & 0xe) >> 1); return 0;} static int stste_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! */ 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; stste_get_par(&par); stste_encode_var(&atafb_predefined[0], &par); if (!ATARIHW_PRESENT(EXTD_SHIFTER)) use_hwscroll = 0; return 1;}static void stste_set_screen_base(void *s_base){ unsigned long addr; addr= virt_to_phys(s_base); /* Setup Screen Memory */ shifter.bas_hi=(unsigned char) ((addr & 0xff0000) >> 16); shifter.bas_md=(unsigned char) ((addr & 0x00ff00) >> 8); if (ATARIHW_PRESENT(EXTD_SHIFTER)) shifter.bas_lo=(unsigned char) (addr & 0x0000ff);}#endif /* ATAFB_STE *//* Switching the screen size should be done during vsync, otherwise * the margins may get messed up. This is a well known problem of * the ST's video system. * * Unfortunately there is hardly any way to find the vsync, as the * vertical blank interrupt is no longer in time on machines with * overscan type modifications. * * We can, however, use Timer B to safely detect the black shoulder, * but then we've got to guess an appropriate delay to find the vsync. * This might not work on every machine. * * martin_rogge @ ki.maus.de, 8th Aug 1995 */#define LINE_DELAY (mono_moni ? 30 : 70)#define SYNC_DELAY (mono_moni ? 1500 : 2000)/* SWITCH_ACIA may be used for Falcon (ScreenBlaster III internal!) */static void st_ovsc_switch(void){ unsigned long flags; register unsigned char old, new; if (!(atari_switches & ATARI_SWITCH_OVSC_MASK)) return; save_flags(flags); cli(); mfp.tim_ct_b = 0x10; mfp.active_edge |= 8; mfp.tim_ct_b = 0; mfp.tim_dt_b = 0xf0; mfp.tim_ct_b = 8; while (mfp.tim_dt_b > 1) /* TOS does it this way, don't ask why */ ; new = mfp.tim_dt_b; do { udelay(LINE_DELAY); old = new; new = mfp.tim_dt_b; } while (old != new); mfp.tim_ct_b = 0x10; udelay(SYNC_DELAY); if (atari_switches & ATARI_SWITCH_OVSC_IKBD) acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID | ACIA_RIE; if (atari_switches & ATARI_SWITCH_OVSC_MIDI) acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID; if (atari_switches & (ATARI_SWITCH_OVSC_SND6|ATARI_SWITCH_OVSC_SND7)) { sound_ym.rd_data_reg_sel = 14; sound_ym.wd_data = sound_ym.rd_data_reg_sel | ((atari_switches&ATARI_SWITCH_OVSC_SND6) ? 0x40:0) | ((atari_switches&ATARI_SWITCH_OVSC_SND7) ? 0x80:0); } restore_flags(flags);}/* ------------------- External Video ---------------------- */#ifdef ATAFB_EXTstatic int ext_encode_fix( struct fb_fix_screeninfo *fix, struct atafb_par *par ){ strcpy(fix->id,"Unknown Extern"); fix->smem_start = (unsigned long)external_addr; fix->smem_len = PAGE_ALIGN(external_len); if (external_depth == 1) { fix->type = FB_TYPE_PACKED_PIXELS; /* The letters 'n' and 'i' in the "atavideo=external:" stand * for "normal" and "inverted", rsp., in the monochrome case */ fix->visual = (external_pmode == FB_TYPE_INTERLEAVED_PLANES || external_pmode == FB_TYPE_PACKED_PIXELS) ? FB_VISUAL_MONO10 : FB_VISUAL_MONO01; } else { /* Use STATIC if we don't know how to access color registers */ int visual = external_vgaiobase ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR; switch (external_pmode) { case -1: /* truecolor */ fix->type=FB_TYPE_PACKED_PIXELS; fix->visual=FB_VISUAL_TRUECOLOR; break; case FB_TYPE_PACKED_PIXELS: fix->type=FB_TYPE_PACKED_PIXELS; fix->visual=visual; break; case FB_TYPE_PLANES: fix->type=FB_TYPE_PLANES; fix->visual=visual; break; case FB_TYPE_INTERLEAVED_PLANES: fix->type=FB_TYPE_INTERLEAVED_PLANES; fix->type_aux=2; fix->visual=visual; break; } } fix->xpanstep = 0; fix->ypanstep = 0; fix->ywrapstep = 0; fix->line_length = 0; return 0;}static int ext_decode_var( struct fb_var_screeninfo *var, struct atafb_par *par ){ struct fb_var_screeninfo *myvar = &atafb_predefined[0]; if (var->bits_per_pixel > myvar->bits_per_pixel || var->xres > myvar->xres || var->xres_virtual > myvar->xres_virtual || var->yres > myvar->yres || var->xoffset > 0 || var->yoffset > 0) return -EINVAL; return 0;}static int ext_encode_var( struct fb_var_screeninfo *var, struct atafb_par *par ){ memset(var, 0, sizeof(struct fb_var_screeninfo)); var->red.offset=0; var->red.length=(external_pmode == -1) ? external_depth/3 : (external_vgaiobase ? external_bitspercol : 0); var->red.msb_right=0; var->grayscale=0; var->pixclock=31041; var->left_margin=120; /* these are surely 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; var->sync=0; var->xres = external_xres; var->yres = external_yres; var->xres_virtual = external_xres_virtual; var->bits_per_pixel = external_depth; var->blue=var->green=var->red; var->transp.offset=0; var->transp.length=0; var->transp.msb_right=0; var->yres_virtual=var->yres; var->xoffset=0; var->yoffset=0; var->nonstd=0; var->activate=0; var->vmode=FB_VMODE_NONINTERLACED; return 0;}static void ext_get_par( struct atafb_par *par ){ par->screen_base = external_addr;}static void ext_set_par( struct atafb_par *par ){}#define OUTB(port,val) \ *((unsigned volatile char *) ((port)+external_vgaiobase))=(val)#define INB(port) \ (*((unsigned volatile char *) ((port)+external_vgaiobase)))#define DACDelay \ do { \ unsigned char tmp=INB(0x3da); \ tmp=INB(0x3da); \ } while (0)static int ext_getcolreg( unsigned regno, unsigned *red, unsigned *green, unsigned *blue, unsigned *transp, struct fb_info *info ){ if (! external_vgaiobase) return 1; *red = ext_color[regno].red; *green = ext_color[regno].green; *blue = ext_color[regno].blue; *transp=0; return 0;} static int ext_setcolreg( unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info ){ unsigned char colmask = (1 << external_bitspercol) - 1; if (! external_vgaiobase) return 1; ext_color[regno].red = red; ext_color[regno].green = green; ext_color[regno].blue = blue; switch (external_card_type) { case IS_VGA: OUTB(0x3c8, regno); DACDelay; OUTB(0x3c9, red & colmask); DACDelay; OUTB(0x3c9, green & colmask); DACDelay; OUTB(0x3c9, blue & colmask); DACDelay; return 0; case IS_MV300: OUTB((MV300_reg[regno] << 2)+1, red); OUTB((MV300_reg[regno] << 2)+1, green); OUTB((MV300_reg[regno] << 2)+1, blue); return 0; default: return 1; }} static int ext_detect( void ){ struct fb_var_screeninfo *myvar = &atafb_predefined[0]; struct atafb_par dummy_par; myvar->xres = external_xres; myvar->xres_virtual = external_xres_virtual; myvar->yres = external_yres; myvar->bits_per_pixel = external_depth; ext_encode_var(myvar, &dummy_par); return 1;}#endif /* ATAFB_EXT *//* ------ This is the same for most hardware types -------- */static void set_screen_base(void *s_base){ unsigned long addr; addr= virt_to_phys(s_base); /* Setup Screen Memory */ shifter.bas_hi=(unsigned char) ((addr & 0xff0000) >> 16); shifter.bas_md=(unsigned char) ((addr & 0x00ff00) >> 8); shifter.bas_lo=(unsigned char) (addr & 0x0000ff);}static int pan_display( struct fb_var_screeninfo *var, struct atafb_par *par ){ if (!fbhw->set_screen_base || (!ATARIHW_PRESENT(EXTD_SHIFTER) && var->xoffset)) return -EINVAL; var->xoffset = up(var->xoffset, 16); par->screen_base = screen_base + (var->yoffset * fb_display[currcon].var.xres_virtual + var->xoffset) * fb_display[currcon].var.bits_per_pixel / 8; fbhw->set_screen_base (par->screen_base); return 0;}/* ------------ Interfaces to hardware functions ------------ */#ifdef ATAFB_TTstatic struct fb_hwswitch tt_switch = { tt_detect, tt_encode_fix, tt_decode_var, tt_encode_var, tt_get_par, tt_set_par, tt_getcolreg, tt_setcolreg, set_screen_base, NULL, pan_display};#endif#ifdef ATAFB_FALCONstatic struct fb_hwswitch falcon_switch = { falcon_detect, falcon_encode_fix, falcon_decode_var, falcon_encode_var, falcon_get_par, falcon_set_par, falcon_getcolreg, falcon_setcolreg, set_screen_base, falcon_blank, falcon_pan_display};#endif#ifdef ATAFB_STEstatic struct fb_hwswitch st_switch = { stste_detect, stste_encode_fix, stste_decode_var, stste_encode_var, stste_get_par, stste_set_par, stste_getcolreg, stste_setcolreg, stste_set_screen_base, NULL, pan_display};#endif#ifdef ATAFB_EXTstatic struct fb_hwswitch ext_switch = { ext_detect, ext_encode_fix, ext_decode_var, ext_encode_var, ext_get_par, ext_set_par, ext_getcolreg, ext_setcolreg, NULL, NULL, NULL};#endifstatic void atafb_g
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -