Subversion Repositories shark

Rev

Rev 486 | Rev 488 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include <ll/i386/hw-data.h>
#include <ll/i386/mem.h>
#include <linux/fb.h>

#include <drivers/grx_fb.h>

static unsigned char font_table[127][8] =
      {
        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        {0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e},
        {0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e},
        {0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00},
        {0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00},
        {0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c},
        {0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c},
        {0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00},
        {0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff},
        {0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00},
        {0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff},
        {0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78},
        {0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18},
        {0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0},
        {0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0},
        {0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99},
        {0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00},
        {0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00},
        {0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18},
        {0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00},
        {0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00},
        {0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78},
        {0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00},
        {0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff},
        {0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00},
        {0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00},
        {0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00},
        {0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00},
        {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00},
        {0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00},
        {0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00},
        {0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00},
        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        {0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00},
        {0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00},
        {0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00},
        {0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00},
        {0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00},
        {0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00},
        {0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00},
        {0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00},
        {0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00},
        {0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00},
        {0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00},
        {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60},
        {0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00},
        {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00},
        {0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00},
        {0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00},
        {0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00},
        {0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00},
        {0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00},
        {0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00},
        {0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00},
        {0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00},
        {0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00},
        {0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00},
        {0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00},
        {0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00},
        {0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60},
        {0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00},
        {0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00},
        {0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00},
        {0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00},
        {0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00},
        {0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00},
        {0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00},
        {0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00},
        {0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00},
        {0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00},
        {0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00},
        {0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00},
        {0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00},
        {0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00},
        {0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00},
        {0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00},
        {0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00},
        {0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00},
        {0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00},
        {0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00},
        {0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
        {0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00},
        {0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00},
        {0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00},
        {0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00},
        {0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00},
        {0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00},
        {0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00},
        {0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00},
        {0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00},
        {0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00},
        {0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00},
        {0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00},
        {0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00},
        {0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff},
        {0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
        {0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00},
        {0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00},
        {0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00},
        {0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00},
        {0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00},
        {0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00},
        {0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8},
        {0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00},
        {0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00},
        {0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78},
        {0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00},
        {0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00},
        {0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00},
        {0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00},
        {0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00},
        {0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0},
        {0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e},
        {0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00},
        {0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00},
        {0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00},
        {0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00},
        {0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00},
        {0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00},
        {0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00},
        {0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8},
        {0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00},
        {0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00},
        {0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00},
        {0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00},
        {0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
      };

#define memsetw(addr, val, n) {LIN_ADDR i; for(i = addr; i < addr + n; i += 2) *(WORD *)i = val;}

struct fb_info *grx_info = NULL;
extern struct fb_info *registered_fb[FB_MAX];

void grx_fb_init(int num)
{

  grx_info = registered_fb[num];
  grx_info->fix.visual = FB_VISUAL_DIRECTCOLOR;

}

void grx_putimage(WORD x1, WORD y1, WORD x2, WORD y2, BYTE *buf)
{

  struct fb_image image;

  if (!grx_info || grx_info->var.bits_per_pixel != 16) return;

  image.depth = grx_info->var.bits_per_pixel;
  image.data = buf;
  image.width = x2-x1+1;
  image.height = y2-y1+1;
  image.dy = y1;
  image.dx = x1;

  grx_info->fbops->fb_imageblit(grx_info, &image);

}

void grx_getimage(WORD x1, WORD y1, WORD x2, WORD y2, BYTE *buf)
{
    WORD bpr;
    LIN_ADDR addr, p;
    WORD dx, y;
   
    if (!grx_info || grx_info->var.bits_per_pixel != 16) return;

    bpr = grx_info->var.xres * 2;
    p = buf;
    addr = (LIN_ADDR)(grx_info->screen_base + x1 * 2 + bpr * y1);
    dx = (x2 - x1 + 1) * 2;

    for (y = y1; y <= y2; y++) {
        memcpy(p, addr, dx);
        p += dx;
        addr += bpr;
    }

}

void grx_box(WORD x1, WORD y1, WORD x2, WORD y2, DWORD color)
{
 
  struct fb_fillrect rect;

  if (!grx_info || grx_info->var.bits_per_pixel != 16) return;
 
  rect.dx = x1;
  rect.dy = y1;
  rect.width = x2-x1+1;
  rect.height = y2-y1+1;
  rect.color = color;
  rect.rop = ROP_COPY;
                                                                                                                             
  grx_info->fbops->fb_fillrect(grx_info, &rect);
 
}

void grx_rect(WORD x1, WORD y1, WORD x2, WORD y2, DWORD color)
{
    WORD bpr;
    DWORD addr;
    WORD dx, y;

    if (!grx_info || grx_info->var.bits_per_pixel != 16) return;
   
    bpr = grx_info->var.xres * 2;
    addr = (DWORD)(grx_info->screen_base + x1 * 2 + bpr * y1);
    dx = (x2 - x1) * 2;

    memsetw((LIN_ADDR)addr, color, dx+2);
    addr += bpr;

    for (y = y1 + 1; y <= y2 - 1; y++) {
        *(WORD *)addr = color;
        *(WORD *)(addr + dx) = color;
        addr += bpr;
    }
    memsetw((LIN_ADDR)addr, color, dx+2);
}

void grx_text(char *text, WORD x, WORD y, DWORD fg, DWORD bg)
{
    DWORD fp, addr;
    WORD bpr;
    int r, c, bits;

    if (!grx_info || grx_info->var.bits_per_pixel != 16) return;

    bpr = grx_info->var.xres * 2;
    addr = (DWORD)(grx_info->screen_base);
    while (*text) {
        fp = (DWORD)&(font_table[*(BYTE *)text][0]);
        for (r=0; r<8; r++) {
            bits = *(BYTE *)(fp++);
            for (c=0; c<8; c++)
                if (bits & (0x80>>c))
                    *(WORD *)(addr + (y + r) * bpr + ((x + c) * 2)) =  fg;
                else
                    *(WORD *)(addr + (y + r) * bpr + ((x + c) * 2)) = bg;
        }
        text++;
        x += 8;
    }
}

void grx_line(WORD x1, WORD y1, WORD x2, WORD y2, DWORD color)
{
    register int t, distance;
    register DWORD addr;
    register WORD bpr;
    int xerr=0, yerr=0, deltax, deltay;
    int incx, incy;

    bpr = grx_info->var.xres * 2;
    addr = (DWORD)(grx_info->screen_base);
    deltax = x2 - x1;                   /* compute both distances */
    deltay = y2 - y1;

    if (deltax > 0)                     /* compute increments */
        incx = 1;
    else if (deltax == 0)
        incx = 0;
    else
        incx = -1;

    if (deltay > 0)
        incy = 1;
    else if (deltay == 0)
        incy = 0;
    else
        incy = -1;

    deltax = abs(deltax);               /* determine greater distance */
    deltay = abs(deltay);
    if (deltax > deltay)
        distance = deltax;
    else
        distance = deltay;

    for (t=0; t<=distance+1; t++) {     /* draw the line */
        *(WORD *)(addr + y1 * bpr + (x1 * 2)) = color;
        xerr += deltax;
        yerr += deltay;
        if (xerr > distance) {
            xerr -= distance;
            x1 += incx;
        }
        if (yerr > distance) {
            yerr -= distance;
            y1 += incy;
        }
    }
}

void grx_plot(WORD x, WORD y, DWORD color)
{
    WORD bpr;

    if (!grx_info || grx_info->var.bits_per_pixel != 16) return;

    bpr = grx_info->var.xres * 2;
    *(WORD *)(grx_info->screen_base + y * bpr + (x * 2)) = color;
}

DWORD grx_getpixel(WORD x, WORD y)
{
    WORD bpr;
    DWORD rv;

    if (!grx_info || grx_info->var.bits_per_pixel != 16) return -1;

    bpr = grx_info->var.xres * 2;
    rv = *(WORD *)(grx_info->screen_base + y * bpr + (x * 2));
    return rv;

}

static void circlepixels(WORD x, WORD y, WORD sx, WORD sy, DWORD c)
{
    grx_plot(sx + x, sy + y, c);
    grx_plot(sx - x, sy + y, c);
    grx_plot(sx + x, sy - y, c);
    grx_plot(sx - x, sy - y, c);
    grx_plot(sx + y, sy + x, c);
    grx_plot(sx - y, sy + x, c);
    grx_plot(sx + y, sy - x, c);
    grx_plot(sx - y, sy - x, c);
}

void grx_circle(WORD sx, WORD sy, WORD r, DWORD c)
{
    int x, y, d;
   
    if (!grx_info || grx_info->var.bits_per_pixel != 16) return;

    if (r < 1) {
        grx_plot(sx, sy, c);
        return;
    }

    x = 0;
    y = r;
    d = 1 - r;
    circlepixels(x, y, sx, sy, c);
    while (x < y) {
        if (d < 0)
            d += x * 2 + 3;
        else {
            d += x * 2 - y * 2 + 5;
            y--;
        }
        x++;
        circlepixels(x, y, sx, sy, c);
    }
}

static __inline__ void discpixels(WORD x, WORD y, WORD sx, WORD sy, DWORD c)
{
    grx_line(sx + x, sy + y, sx + x, sy - y, c);
    grx_line(sx - x, sy + y, sx - x, sy - y, c);
    grx_line(sx + y, sy + x, sx + y, sy - x , c);
    grx_line(sx - y, sy + x, sx - y, sy - x , c);
}

void grx_disc(WORD sx, WORD sy, WORD r, DWORD c)
{
    int x, y, d;

    if (!grx_info || grx_info->var.bits_per_pixel != 16) return;
   
    if (r < 1) {
        grx_plot(sx, sy, c);
        return;
    }
    x = 0;
    y = r;
    d = 1 - r;
    discpixels(x, y, sx, sy, c);
    while (x < y) {
        if (d < 0)
            d += x * 2 + 3;
        else {
            d += x * 2 - y * 2 + 5;
            y--;
        }
        x++;   
        discpixels(x, y, sx, sy, c);
    }
}