!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/drivers/video/   drwxr-xr-x
Free 318.38 GB of 458.09 GB (69.5%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     vga16fb.c (25.74 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 * linux/drivers/video/vga16.c -- VGA 16-color framebuffer driver
 * 
 * Copyright 1999 Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz>
 * Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm
 * Based on VESA framebuffer (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
 *
 * This file is subject to the terms and conditions of the GNU General
 * Public License.  See the file COPYING in the main directory of this
 * archive for more details.  */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/console.h>
#include <linux/selection.h>
#include <linux/ioport.h>
#include <linux/init.h>

#include <asm/io.h>

#include <video/fbcon.h>
#include <video/fbcon-vga-planes.h>
#include "vga.h"

#define dac_reg    (0x3c8)
#define dac_val    (0x3c9)

#define VGA_FB_PHYS 0xA0000
#define VGA_FB_PHYS_LEN 65536

/* --------------------------------------------------------------------- */

/*
 * card parameters
 */

static struct vga16fb_info {
    struct fb_info  fb_info;
    char *video_vbase;            /* 0xa0000 map address */
    int isVGA;
    
    /* structure holding original VGA register settings when the
           screen is blanked */
    struct {
        unsigned char    SeqCtrlIndex;        /* Sequencer Index reg.   */
        unsigned char    CrtCtrlIndex;        /* CRT-Contr. Index reg.  */
        unsigned char    CrtMiscIO;        /* Miscellaneous register */
        unsigned char    HorizontalTotal;    /* CRT-Controller:00h */
        unsigned char    HorizDisplayEnd;    /* CRT-Controller:01h */
        unsigned char    StartHorizRetrace;    /* CRT-Controller:04h */
        unsigned char    EndHorizRetrace;    /* CRT-Controller:05h */
        unsigned char    Overflow;        /* CRT-Controller:07h */
        unsigned char    StartVertRetrace;    /* CRT-Controller:10h */
        unsigned char    EndVertRetrace;        /* CRT-Controller:11h */
        unsigned char    ModeControl;        /* CRT-Controller:17h */
        unsigned char    ClockingMode;        /* Seq-Controller:01h */
    } vga_state;

    int palette_blanked;
    int vesa_blanked;
} vga16fb;


struct vga16fb_par {
    u8 crtc[VGA_CRT_C];
    u8 atc[VGA_ATT_C];
    u8 gdc[VGA_GFX_C];
    u8 seq[VGA_SEQ_C];
    u8 misc;
    u8 vss;
    struct fb_var_screeninfo var;
};

/* --------------------------------------------------------------------- */

static struct fb_var_screeninfo vga16fb_defined = {
    640,480,640,480,/* W,H, W, H (virtual) load xres,xres_virtual*/
    0,0,        /* virtual -> visible no offset */
    4,        /* depth -> load bits_per_pixel */
    0,        /* greyscale ? */
    {0,0,0},    /* R */
    {0,0,0},    /* G */
    {0,0,0},    /* B */
    {0,0,0},    /* transparency */
    0,        /* standard pixel format */
    FB_ACTIVATE_NOW,
    -1,-1,
    0,
    39721, 48, 16, 39, 8,
    96, 2, 0,    /* No sync info */
    FB_VMODE_NONINTERLACED,
    {0,0,0,0,0,0}
};

static struct display disp;
static struct { u_short blue, green, red, pad; } palette[256];

static int             currcon   = 0;

/* --------------------------------------------------------------------- */

static void vga16fb_pan_var(struct fb_info *info, struct fb_var_screeninfo *var)
{
    u32 pos = (var->xres_virtual * var->yoffset + var->xoffset) >> 3;
    outb(VGA_CRTC_START_HI, VGA_CRT_IC);
    outb(pos >> 8, VGA_CRT_DC);
    outb(VGA_CRTC_START_LO, VGA_CRT_IC);
    outb(pos & 0xFF, VGA_CRT_DC);
#if 0
    /* if someone supports xoffset in bit resolution */
    inb(VGA_IS1_RC);        /* reset flip-flop */
    outb(VGA_ATC_PEL, VGA_ATT_IW);
    outb(xoffset & 7, VGA_ATT_IW);
    inb(VGA_IS1_RC);
    outb(0x20, VGA_ATT_IW);
#endif
}

static int vga16fb_update_var(int con, struct fb_info *info)
{
    vga16fb_pan_var(info, &fb_display[con].var);
    return 0;
}

static int vga16fb_get_fix(struct fb_fix_screeninfo *fix, int con,
               struct fb_info *info)
{
    struct display *p;

    if (con < 0)
        p = &disp;
    else
        p = fb_display + con;

    memset(fix, 0, sizeof(struct fb_fix_screeninfo));
    strcpy(fix->id,"VGA16 VGA");

    fix->smem_start = VGA_FB_PHYS;
    fix->smem_len = VGA_FB_PHYS_LEN;
    fix->type = FB_TYPE_VGA_PLANES;
    fix->visual = FB_VISUAL_PSEUDOCOLOR;
    fix->xpanstep  = 8;
    fix->ypanstep  = 1;
    fix->ywrapstep = 0;
    fix->line_length = p->var.xres_virtual / 8;
    return 0;
}

static int vga16fb_get_var(struct fb_var_screeninfo *var, int con,
             struct fb_info *info)
{
    if(con==-1)
        memcpy(var, &vga16fb_defined, sizeof(struct fb_var_screeninfo));
    else
        *var=fb_display[con].var;
    return 0;
}

static void vga16fb_set_disp(int con, struct vga16fb_info *info)
{
    struct fb_fix_screeninfo fix;
    struct display *display;

    if (con < 0)
        display = &disp;
    else
        display = fb_display + con;

    
    vga16fb_get_fix(&fix, con, &info->fb_info);

    display->screen_base = info->video_vbase;
    display->visual = fix.visual;
    display->type = fix.type;
    display->type_aux = fix.type_aux;
    display->ypanstep = fix.ypanstep;
    display->ywrapstep = fix.ywrapstep;
    display->line_length = fix.line_length;
    display->next_line = fix.line_length;
    display->can_soft_blank = 1;
    display->inverse = 0;

    if (info->isVGA)
        display->dispsw = &fbcon_vga_planes;
    else
        display->dispsw = &fbcon_ega_planes;
    display->scrollmode = SCROLL_YREDRAW;
}

static void vga16fb_encode_var(struct fb_var_screeninfo *var,
                   const struct vga16fb_par *par,
                   const struct vga16fb_info *info)
{
    *var = par->var;
}

static void vga16fb_clock_chip(struct vga16fb_par *par,
                   unsigned int pixclock,
                   const struct vga16fb_info *info)
{
    static struct {
        u32 pixclock;
        u8  misc;
        u8  seq_clock_mode;
    } *ptr, *best, vgaclocks[] = {
        { 79442 /* 12.587 */, 0x00, 0x08},
        { 70616 /* 14.161 */, 0x04, 0x08},
        { 39721 /* 25.175 */, 0x00, 0x00},
        { 35308 /* 28.322 */, 0x04, 0x00},
        {     0 /* bad */,    0x00, 0x00}};
    int err;

    best = vgaclocks;
    err = pixclock - best->pixclock;
    if (err < 0) err = -err;
    for (ptr = vgaclocks + 1; ptr->pixclock; ptr++) {
        int tmp;

        tmp = pixclock - ptr->pixclock;
        if (tmp < 0) tmp = -tmp;
        if (tmp < err) {
            err = tmp;
            best = ptr;
        }
    }
    par->misc |= best->misc;
    par->seq[VGA_SEQ_CLOCK_MODE] |= best->seq_clock_mode;
    par->var.pixclock = best->pixclock;        
}
                   
#define FAIL(X) return -EINVAL

static int vga16fb_decode_var(const struct fb_var_screeninfo *var,
                  struct vga16fb_par *par,
                  const struct vga16fb_info *info)
{
    u32 xres, right, hslen, left, xtotal;
    u32 yres, lower, vslen, upper, ytotal;
    u32 vxres, xoffset, vyres, yoffset;
    u32 pos;
    u8 r7, rMode;
    int i;

    if (var->bits_per_pixel != 4)
        return -EINVAL;
    xres = (var->xres + 7) & ~7;
    vxres = (var->xres_virtual + 0xF) & ~0xF;
    xoffset = (var->xoffset + 7) & ~7;
    left = (var->left_margin + 7) & ~7;
    right = (var->right_margin + 7) & ~7;
    hslen = (var->hsync_len + 7) & ~7;

    if (vxres < xres)
        vxres = xres;
    if (xres + xoffset > vxres)
        xoffset = vxres - xres;

    par->var.xres = xres;
    par->var.right_margin = right;
    par->var.hsync_len = hslen;
    par->var.left_margin = left;
    par->var.xres_virtual = vxres;
    par->var.xoffset = xoffset;

    xres >>= 3;
    right >>= 3;
    hslen >>= 3;
    left >>= 3;
    vxres >>= 3;
    xtotal = xres + right + hslen + left;
    if (xtotal >= 256)
        FAIL("xtotal too big");
    if (hslen > 32)
        FAIL("hslen too big");
    if (right + hslen + left > 64)
        FAIL("hblank too big");
    par->crtc[VGA_CRTC_H_TOTAL] = xtotal - 5;
    par->crtc[VGA_CRTC_H_BLANK_START] = xres - 1;
    par->crtc[VGA_CRTC_H_DISP] = xres - 1;
    pos = xres + right;
    par->crtc[VGA_CRTC_H_SYNC_START] = pos;
    pos += hslen;
    par->crtc[VGA_CRTC_H_SYNC_END] = pos & 0x1F;
    pos += left - 2; /* blank_end + 2 <= total + 5 */
    par->crtc[VGA_CRTC_H_BLANK_END] = (pos & 0x1F) | 0x80;
    if (pos & 0x20)
        par->crtc[VGA_CRTC_H_SYNC_END] |= 0x80;

    yres = var->yres;
    lower = var->lower_margin;
    vslen = var->vsync_len;
    upper = var->upper_margin;
    vyres = var->yres_virtual;
    yoffset = var->yoffset;

    if (yres > vyres)
        vyres = yres;
    if (vxres * vyres > 65536) {
        vyres = 65536 / vxres;
        if (vyres < yres)
            return -ENOMEM;
    }
    if (yoffset + yres > vyres)
        yoffset = vyres - yres;
    par->var.yres = yres;
    par->var.lower_margin = lower;
    par->var.vsync_len = vslen;
    par->var.upper_margin = upper;
    par->var.yres_virtual = vyres;
    par->var.yoffset = yoffset;

    if (var->vmode & FB_VMODE_DOUBLE) {
        yres <<= 1;
        lower <<= 1;
        vslen <<= 1;
        upper <<= 1;
    }
    ytotal = yres + lower + vslen + upper;
    if (ytotal > 1024) {
        ytotal >>= 1;
        yres >>= 1;
        lower >>= 1;
        vslen >>= 1;
        upper >>= 1;
        rMode = 0x04;
    } else
        rMode = 0x00;
    if (ytotal > 1024)
        FAIL("ytotal too big");
    if (vslen > 16)
        FAIL("vslen too big");
    par->crtc[VGA_CRTC_V_TOTAL] = ytotal - 2;
    r7 = 0x10;    /* disable linecompare */
    if (ytotal & 0x100) r7 |= 0x01;
    if (ytotal & 0x200) r7 |= 0x20;
    par->crtc[VGA_CRTC_PRESET_ROW] = 0;
    par->crtc[VGA_CRTC_MAX_SCAN] = 0x40;    /* 1 scanline, no linecmp */
    par->var.vmode = var->vmode;
    if (var->vmode & FB_VMODE_DOUBLE)
        par->crtc[VGA_CRTC_MAX_SCAN] |= 0x80;
    par->crtc[VGA_CRTC_CURSOR_START] = 0x20;
    par->crtc[VGA_CRTC_CURSOR_END]   = 0x00;
    pos = yoffset * vxres + (xoffset >> 3);
    par->crtc[VGA_CRTC_START_HI]     = pos >> 8;
    par->crtc[VGA_CRTC_START_LO]     = pos & 0xFF;
    par->crtc[VGA_CRTC_CURSOR_HI]    = 0x00;
    par->crtc[VGA_CRTC_CURSOR_LO]    = 0x00;
    pos = yres - 1;
    par->crtc[VGA_CRTC_V_DISP_END] = pos & 0xFF;
    par->crtc[VGA_CRTC_V_BLANK_START] = pos & 0xFF;
    if (pos & 0x100)
        r7 |= 0x0A;    /* 0x02 -> DISP_END, 0x08 -> BLANK_START */
    if (pos & 0x200) {
        r7 |= 0x40;    /* 0x40 -> DISP_END */
        par->crtc[VGA_CRTC_MAX_SCAN] |= 0x20; /* BLANK_START */
    }
    pos += lower;
    par->crtc[VGA_CRTC_V_SYNC_START] = pos & 0xFF;
    if (pos & 0x100)
        r7 |= 0x04;
    if (pos & 0x200)
        r7 |= 0x80;
    pos += vslen;
    par->crtc[VGA_CRTC_V_SYNC_END] = (pos & 0x0F) & ~0x10; /* disabled IRQ */
    pos += upper - 1; /* blank_end + 1 <= ytotal + 2 */
    par->crtc[VGA_CRTC_V_BLANK_END] = pos & 0xFF; /* 0x7F for original VGA,
                     but some SVGA chips requires all 8 bits to set */
    if (vxres >= 512)
        FAIL("vxres too long");
    par->crtc[VGA_CRTC_OFFSET] = vxres >> 1;
    par->crtc[VGA_CRTC_UNDERLINE] = 0x1F;
    par->crtc[VGA_CRTC_MODE] = rMode | 0xE3;
    par->crtc[VGA_CRTC_LINE_COMPARE] = 0xFF;
    par->crtc[VGA_CRTC_OVERFLOW] = r7;

    par->vss = 0x00;    /* 3DA */

    for (i = 0x00; i < 0x10; i++)
        par->atc[i] = i;
    par->atc[VGA_ATC_MODE] = 0x81;
    par->atc[VGA_ATC_OVERSCAN] = 0x00;    /* 0 for EGA, 0xFF for VGA */
    par->atc[VGA_ATC_PLANE_ENABLE] = 0x0F;
    par->atc[VGA_ATC_PEL] = xoffset & 7;
    par->atc[VGA_ATC_COLOR_PAGE] = 0x00;
    
    par->misc = 0xC3;    /* enable CPU, ports 0x3Dx, positive sync */
    par->var.sync = var->sync;
    if (var->sync & FB_SYNC_HOR_HIGH_ACT)
        par->misc &= ~0x40;
    if (var->sync & FB_SYNC_VERT_HIGH_ACT)
        par->misc &= ~0x80;
    
    par->seq[VGA_SEQ_CLOCK_MODE] = 0x01;
    par->seq[VGA_SEQ_PLANE_WRITE] = 0x0F;
    par->seq[VGA_SEQ_CHARACTER_MAP] = 0x00;
    par->seq[VGA_SEQ_MEMORY_MODE] = 0x06;
    
    par->gdc[VGA_GFX_SR_VALUE] = 0x00;
    par->gdc[VGA_GFX_SR_ENABLE] = 0x0F;
    par->gdc[VGA_GFX_COMPARE_VALUE] = 0x00;
    par->gdc[VGA_GFX_DATA_ROTATE] = 0x20;
    par->gdc[VGA_GFX_PLANE_READ] = 0;
    par->gdc[VGA_GFX_MODE] = 0x00;
    par->gdc[VGA_GFX_MISC] = 0x05;
    par->gdc[VGA_GFX_COMPARE_MASK] = 0x0F;
    par->gdc[VGA_GFX_BIT_MASK] = 0xFF;

    vga16fb_clock_chip(par, var->pixclock, info);

    par->var.bits_per_pixel = 4;
    par->var.grayscale = var->grayscale;
    par->var.red.offset = par->var.green.offset = par->var.blue.offset = 
    par->var.transp.offset = 0;
    par->var.red.length = par->var.green.length = par->var.blue.length =
        (info->isVGA) ? 6 : 2;
    par->var.transp.length = 0;
    par->var.nonstd = 0;
    par->var.activate = FB_ACTIVATE_NOW;
    par->var.height = -1;
    par->var.width = -1;
    par->var.accel_flags = 0;
    
    return 0;
}
#undef FAIL

static int vga16fb_set_par(const struct vga16fb_par *par,
               struct vga16fb_info *info)
{
    int i;

    outb(inb(VGA_MIS_R) | 0x01, VGA_MIS_W);

    /* Enable graphics register modification */
    if (!info->isVGA) {
        outb(0x00, EGA_GFX_E0);
        outb(0x01, EGA_GFX_E1);
    }
    
    /* update misc output register */
    outb(par->misc, VGA_MIS_W);
    
    /* synchronous reset on */
    outb(0x00, VGA_SEQ_I);
    outb(0x01, VGA_SEQ_D);
    
    /* write sequencer registers */
    outb(1, VGA_SEQ_I);
    outb(par->seq[1] | 0x20, VGA_SEQ_D);
    for (i = 2; i < VGA_SEQ_C; i++) {
        outb(i, VGA_SEQ_I);
        outb(par->seq[i], VGA_SEQ_D);
    }
    
    /* synchronous reset off */
    outb(0x00, VGA_SEQ_I);
    outb(0x03, VGA_SEQ_D);
    
    /* deprotect CRT registers 0-7 */
    outb(0x11, VGA_CRT_IC);
    outb(par->crtc[0x11], VGA_CRT_DC);

    /* write CRT registers */
    for (i = 0; i < VGA_CRT_C; i++) {
        outb(i, VGA_CRT_IC);
        outb(par->crtc[i], VGA_CRT_DC);
    }
    
    /* write graphics controller registers */
    for (i = 0; i < VGA_GFX_C; i++) {
        outb(i, VGA_GFX_I);
        outb(par->gdc[i], VGA_GFX_D);
    }
    
    /* write attribute controller registers */
    for (i = 0; i < VGA_ATT_C; i++) {
        inb_p(VGA_IS1_RC);        /* reset flip-flop */
        outb_p(i, VGA_ATT_IW);
        outb_p(par->atc[i], VGA_ATT_IW);
    }

    /* Wait for screen to stabilize. */
    mdelay(50);

    outb(0x01, VGA_SEQ_I);
    outb(par->seq[1], VGA_SEQ_D);

    inb(VGA_IS1_RC);
    outb(0x20, VGA_ATT_IW);
    
    return 0;
}

static int vga16fb_set_var(struct fb_var_screeninfo *var, int con,
              struct fb_info *fb)
{
    struct vga16fb_info *info = (struct vga16fb_info*)fb;
    struct vga16fb_par par;
    struct display *display;
    int err;

    if (con < 0)
        display = fb->disp;
    else
        display = fb_display + con;
    if ((err = vga16fb_decode_var(var, &par, info)) != 0)
        return err;
    vga16fb_encode_var(var, &par, info);
    
    if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)
        return 0;

    if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
        u32 oldxres, oldyres, oldvxres, oldvyres, oldbpp;

        oldxres = display->var.xres;
        oldyres = display->var.yres;
        oldvxres = display->var.xres_virtual;
        oldvyres = display->var.yres_virtual;
        oldbpp = display->var.bits_per_pixel;

        display->var = *var;

        if (oldxres != var->xres || oldyres != var->yres ||
            oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
            oldbpp != var->bits_per_pixel) {
            vga16fb_set_disp(con, info);
            if (info->fb_info.changevar)
                info->fb_info.changevar(con);
        }
        if (con == currcon)
            vga16fb_set_par(&par, info);
    }

    return 0;
}

static void ega16_setpalette(int regno, unsigned red, unsigned green, unsigned blue)
{
    static unsigned char map[] = { 000, 001, 010, 011 };
    int val;
    
    val = map[red>>14] | ((map[green>>14]) << 1) | ((map[blue>>14]) << 2);
    inb_p(0x3DA);   /* ! 0x3BA */
    outb_p(regno, 0x3C0);
    outb_p(val, 0x3C0);
    inb_p(0x3DA);   /* some clones need it */
    outb_p(0x20, 0x3C0); /* unblank screen */
}

static int vga16_getcolreg(unsigned regno, unsigned *red, unsigned *green,
              unsigned *blue, unsigned *transp,
              struct fb_info *fb_info)
{
    /*
     *  Read a single color register and split it into colors/transparent.
     *  Return != 0 for invalid regno.
     */

    if (regno >= 16)
        return 1;

    *red   = palette[regno].red;
    *green = palette[regno].green;
    *blue  = palette[regno].blue;
    *transp = 0;
    return 0;
}

static void vga16_setpalette(int regno, unsigned red, unsigned green, unsigned blue)
{
    outb(regno,       dac_reg);
    outb(red   >> 10, dac_val);
    outb(green >> 10, dac_val);
    outb(blue  >> 10, dac_val);
}

static int vga16_setcolreg(unsigned regno, unsigned red, unsigned green,
              unsigned blue, unsigned transp,
              struct fb_info *fb_info)
{
    int gray;

    /*
     *  Set a single color register. The values supplied are
     *  already rounded down to the hardware's capabilities
     *  (according to the entries in the `var' structure). Return
     *  != 0 for invalid regno.
     */
    
    if (regno >= 16)
        return 1;

    palette[regno].red   = red;
    palette[regno].green = green;
    palette[regno].blue  = blue;
    
    if (currcon < 0)
        gray = disp.var.grayscale;
    else
        gray = fb_display[currcon].var.grayscale;
    if (gray) {
        /* gray = 0.30*R + 0.59*G + 0.11*B */
        red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
    }
    if (((struct vga16fb_info *) fb_info)->isVGA) 
        vga16_setpalette(regno,red,green,blue);
    else
        ega16_setpalette(regno,red,green,blue);
    
    return 0;
}

static void do_install_cmap(int con, struct fb_info *info)
{
    if (con != currcon)
        return;
    if (fb_display[con].cmap.len)
        fb_set_cmap(&fb_display[con].cmap, 1, vga16_setcolreg, info);
    else
        fb_set_cmap(fb_default_cmap(16), 1, vga16_setcolreg,
                info);
}

static int vga16fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
               struct fb_info *info)
{
    if (con == currcon) /* current console? */
        return fb_get_cmap(cmap, kspc, vga16_getcolreg, info);
    else if (fb_display[con].cmap.len) /* non default colormap? */
        fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
    else
        fb_copy_cmap(fb_default_cmap(16),
             cmap, kspc ? 0 : 2);
    return 0;
}

static int vga16fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
               struct fb_info *info)
{
    int err;

    if (!fb_display[con].cmap.len) {    /* no colormap allocated? */
        err = fb_alloc_cmap(&fb_display[con].cmap,16,0);
        if (err)
            return err;
    }
    if (con == currcon)            /* current console? */
        return fb_set_cmap(cmap, kspc, vga16_setcolreg, info);
    else
        fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
    return 0;
}

static int vga16fb_pan_display(struct fb_var_screeninfo *var, int con,
                   struct fb_info *info) 
{
    if (var->xoffset + fb_display[con].var.xres > fb_display[con].var.xres_virtual ||
        var->yoffset + fb_display[con].var.yres > fb_display[con].var.yres_virtual)
        return -EINVAL;
    if (con == currcon)
        vga16fb_pan_var(info, var);
    fb_display[con].var.xoffset = var->xoffset;
    fb_display[con].var.yoffset = var->yoffset;
    fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
    return 0;
}

static struct fb_ops vga16fb_ops = {
    owner:        THIS_MODULE,
    fb_get_fix:    vga16fb_get_fix,
    fb_get_var:    vga16fb_get_var,
    fb_set_var:    vga16fb_set_var,
    fb_get_cmap:    vga16fb_get_cmap,
    fb_set_cmap:    vga16fb_set_cmap,
    fb_pan_display:    vga16fb_pan_display,
};

int vga16fb_setup(char *options)
{
    char *this_opt;
    
    vga16fb.fb_info.fontname[0] = '\0';
    
    if (!options || !*options)
        return 0;
    
    while ((this_opt = strsep(&options, ",")) != NULL) {
        if (!*this_opt) continue;
        
        if (!strncmp(this_opt, "font:", 5))
            strcpy(vga16fb.fb_info.fontname, this_opt+5);
    }
    return 0;
}

static int vga16fb_switch(int con, struct fb_info *fb)
{
    struct vga16fb_par par;
    struct vga16fb_info *info = (struct vga16fb_info*)fb;

    /* Do we have to save the colormap? */
    if (fb_display[currcon].cmap.len)
        fb_get_cmap(&fb_display[currcon].cmap, 1, vga16_getcolreg,
                fb);
    
    currcon = con;
    vga16fb_decode_var(&fb_display[con].var, &par, info);
    vga16fb_set_par(&par, info);
    vga16fb_set_disp(con, info);

    /* Install new colormap */
    do_install_cmap(con, fb);
/*    vga16fb_update_var(con, fb); */
    return 1;
}

/* The following VESA blanking code is taken from vgacon.c.  The VGA
   blanking code was originally by Huang shi chao, and modified by
   Christoph Rimek (chrimek@toppoint.de) and todd j. derr
   (tjd@barefoot.org) for Linux. */
#define attrib_port    0x3c0
#define seq_port_reg    0x3c4
#define seq_port_val    0x3c5
#define gr_port_reg    0x3ce
#define gr_port_val    0x3cf
#define video_misc_rd    0x3cc
#define video_misc_wr    0x3c2
#define vga_video_port_reg    0x3d4
#define vga_video_port_val    0x3d5

static void vga_vesa_blank(struct vga16fb_info *info, int mode)
{
    unsigned char SeqCtrlIndex;
    unsigned char CrtCtrlIndex;
    
    cli();
    SeqCtrlIndex = inb_p(seq_port_reg);
    CrtCtrlIndex = inb_p(vga_video_port_reg);

    /* save original values of VGA controller registers */
    if(!info->vesa_blanked) {
        info->vga_state.CrtMiscIO = inb_p(video_misc_rd);
        sti();

        outb_p(0x00,vga_video_port_reg);    /* HorizontalTotal */
        info->vga_state.HorizontalTotal = inb_p(vga_video_port_val);
        outb_p(0x01,vga_video_port_reg);    /* HorizDisplayEnd */
        info->vga_state.HorizDisplayEnd = inb_p(vga_video_port_val);
        outb_p(0x04,vga_video_port_reg);    /* StartHorizRetrace */
        info->vga_state.StartHorizRetrace = inb_p(vga_video_port_val);
        outb_p(0x05,vga_video_port_reg);    /* EndHorizRetrace */
        info->vga_state.EndHorizRetrace = inb_p(vga_video_port_val);
        outb_p(0x07,vga_video_port_reg);    /* Overflow */
        info->vga_state.Overflow = inb_p(vga_video_port_val);
        outb_p(0x10,vga_video_port_reg);    /* StartVertRetrace */
        info->vga_state.StartVertRetrace = inb_p(vga_video_port_val);
        outb_p(0x11,vga_video_port_reg);    /* EndVertRetrace */
        info->vga_state.EndVertRetrace = inb_p(vga_video_port_val);
        outb_p(0x17,vga_video_port_reg);    /* ModeControl */
        info->vga_state.ModeControl = inb_p(vga_video_port_val);
        outb_p(0x01,seq_port_reg);        /* ClockingMode */
        info->vga_state.ClockingMode = inb_p(seq_port_val);
    }

    /* assure that video is enabled */
    /* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */
    cli();
    outb_p(0x01,seq_port_reg);
    outb_p(info->vga_state.ClockingMode | 0x20,seq_port_val);

    /* test for vertical retrace in process.... */
    if ((info->vga_state.CrtMiscIO & 0x80) == 0x80)
        outb_p(info->vga_state.CrtMiscIO & 0xef,video_misc_wr);

    /*
     * Set <End of vertical retrace> to minimum (0) and
     * <Start of vertical Retrace> to maximum (incl. overflow)
     * Result: turn off vertical sync (VSync) pulse.
     */
    if (mode & VESA_VSYNC_SUSPEND) {
        outb_p(0x10,vga_video_port_reg);    /* StartVertRetrace */
        outb_p(0xff,vga_video_port_val);     /* maximum value */
        outb_p(0x11,vga_video_port_reg);    /* EndVertRetrace */
        outb_p(0x40,vga_video_port_val);    /* minimum (bits 0..3)  */
        outb_p(0x07,vga_video_port_reg);    /* Overflow */
        outb_p(info->vga_state.Overflow | 0x84,vga_video_port_val); /* bits 9,10 of vert. retrace */
    }

    if (mode & VESA_HSYNC_SUSPEND) {
        /*
         * Set <End of horizontal retrace> to minimum (0) and
         *  <Start of horizontal Retrace> to maximum
         * Result: turn off horizontal sync (HSync) pulse.
         */
        outb_p(0x04,vga_video_port_reg);    /* StartHorizRetrace */
        outb_p(0xff,vga_video_port_val);    /* maximum */
        outb_p(0x05,vga_video_port_reg);    /* EndHorizRetrace */
        outb_p(0x00,vga_video_port_val);    /* minimum (0) */
    }

    /* restore both index registers */
    outb_p(SeqCtrlIndex,seq_port_reg);
    outb_p(CrtCtrlIndex,vga_video_port_reg);
    sti();
}

static void vga_vesa_unblank(struct vga16fb_info *info)
{
    unsigned char SeqCtrlIndex;
    unsigned char CrtCtrlIndex;
    
    cli();
    SeqCtrlIndex = inb_p(seq_port_reg);
    CrtCtrlIndex = inb_p(vga_video_port_reg);

    /* restore original values of VGA controller registers */
    outb_p(info->vga_state.CrtMiscIO,video_misc_wr);

    outb_p(0x00,vga_video_port_reg);        /* HorizontalTotal */
    outb_p(info->vga_state.HorizontalTotal,vga_video_port_val);
    outb_p(0x01,vga_video_port_reg);        /* HorizDisplayEnd */
    outb_p(info->vga_state.HorizDisplayEnd,vga_video_port_val);
    outb_p(0x04,vga_video_port_reg);        /* StartHorizRetrace */
    outb_p(info->vga_state.StartHorizRetrace,vga_video_port_val);
    outb_p(0x05,vga_video_port_reg);        /* EndHorizRetrace */
    outb_p(info->vga_state.EndHorizRetrace,vga_video_port_val);
    outb_p(0x07,vga_video_port_reg);        /* Overflow */
    outb_p(info->vga_state.Overflow,vga_video_port_val);
    outb_p(0x10,vga_video_port_reg);        /* StartVertRetrace */
    outb_p(info->vga_state.StartVertRetrace,vga_video_port_val);
    outb_p(0x11,vga_video_port_reg);        /* EndVertRetrace */
    outb_p(info->vga_state.EndVertRetrace,vga_video_port_val);
    outb_p(0x17,vga_video_port_reg);        /* ModeControl */
    outb_p(info->vga_state.ModeControl,vga_video_port_val);
    outb_p(0x01,seq_port_reg);        /* ClockingMode */
    outb_p(info->vga_state.ClockingMode,seq_port_val);

    /* restore index/control registers */
    outb_p(SeqCtrlIndex,seq_port_reg);
    outb_p(CrtCtrlIndex,vga_video_port_reg);
    sti();
}

static void vga_pal_blank(void)
{
    int i;

    for (i=0; i<16; i++) {
        outb_p (i, dac_reg) ;
        outb_p (0, dac_val) ;
        outb_p (0, dac_val) ;
        outb_p (0, dac_val) ;
    }
}

/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
static void vga16fb_blank(int blank, struct fb_info *fb_info)
{
    struct vga16fb_info *info = (struct vga16fb_info*)fb_info;

    switch (blank) {
    case 0:                /* Unblank */
        if (info->vesa_blanked) {
            vga_vesa_unblank(info);
            info->vesa_blanked = 0;
        }
        if (info->palette_blanked) {
            do_install_cmap(currcon, fb_info);
            info->palette_blanked = 0;
        }
        break;
    case 1:                /* blank */
        vga_pal_blank();
        info->palette_blanked = 1;
        break;
    default:            /* VESA blanking */
        vga_vesa_blank(info, blank-1);
        info->vesa_blanked = 1;
        break;
    }
}

int __init vga16fb_init(void)
{
    int i,j;

    printk(KERN_DEBUG "vga16fb: initializing\n");

    /* XXX share VGA_FB_PHYS region with vgacon */

        vga16fb.video_vbase = ioremap(VGA_FB_PHYS, VGA_FB_PHYS_LEN);
    if (!vga16fb.video_vbase) {
        printk(KERN_ERR "vga16fb: unable to map device\n");
        return -ENOMEM;
    }
    printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.video_vbase);

    vga16fb.isVGA = ORIG_VIDEO_ISVGA;
    vga16fb.palette_blanked = 0;
    vga16fb.vesa_blanked = 0;

    i = vga16fb.isVGA? 6 : 2;
    
    vga16fb_defined.red.length   = i;
    vga16fb_defined.green.length = i;
    vga16fb_defined.blue.length  = i;    
    for(i = 0; i < 16; i++) {
        j = color_table[i];
        palette[i].red   = default_red[j];
        palette[i].green = default_grn[j];
        palette[i].blue  = default_blu[j];
    }

    /* XXX share VGA I/O region with vgacon and others */

    disp.var = vga16fb_defined;

    /* name should not depend on EGA/VGA */
    strcpy(vga16fb.fb_info.modename, "VGA16 VGA");
    vga16fb.fb_info.changevar = NULL;
    vga16fb.fb_info.node = -1;
    vga16fb.fb_info.fbops = &vga16fb_ops;
    vga16fb.fb_info.disp=&disp;
    vga16fb.fb_info.switch_con=&vga16fb_switch;
    vga16fb.fb_info.updatevar=&vga16fb_update_var;
    vga16fb.fb_info.blank=&vga16fb_blank;
    vga16fb.fb_info.flags=FBINFO_FLAG_DEFAULT;
    vga16fb_set_disp(-1, &vga16fb);

    if (register_framebuffer(&vga16fb.fb_info)<0) {
        iounmap(vga16fb.video_vbase);
        return -EINVAL;
    }

    printk(KERN_INFO "fb%d: %s frame buffer device\n",
           GET_FB_IDX(vga16fb.fb_info.node), vga16fb.fb_info.modename);

    return 0;
}

static void __exit vga16fb_exit(void)
{
    unregister_framebuffer(&vga16fb.fb_info);
    iounmap(vga16fb.video_vbase);
    /* XXX unshare VGA regions */
}

#ifdef MODULE
MODULE_LICENSE("GPL");
module_init(vga16fb_init);
#endif
module_exit(vga16fb_exit);


/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-basic-offset: 8
 * End:
 */


:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0198 ]--